1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.nfc.cardemulation;
17 
18 import java.io.FileDescriptor;
19 import java.io.PrintWriter;
20 import java.util.List;
21 
22 import android.content.ComponentName;
23 import android.content.Context;
24 import android.content.Intent;
25 import android.nfc.INfcCardEmulation;
26 import android.nfc.INfcFCardEmulation;
27 import android.nfc.cardemulation.AidGroup;
28 import android.nfc.cardemulation.ApduServiceInfo;
29 import android.nfc.cardemulation.NfcFServiceInfo;
30 import android.nfc.cardemulation.CardEmulation;
31 import android.nfc.cardemulation.NfcFCardEmulation;
32 import android.os.Binder;
33 import android.os.RemoteException;
34 import android.os.UserHandle;
35 import android.provider.Settings;
36 import android.util.Log;
37 
38 import com.android.nfc.NfcPermissions;
39 import com.android.nfc.NfcService;
40 import com.android.nfc.cardemulation.RegisteredServicesCache;
41 import com.android.nfc.cardemulation.RegisteredNfcFServicesCache;
42 
43 /**
44  * CardEmulationManager is the central entity
45  * responsible for delegating to individual components
46  * implementing card emulation:
47  * - RegisteredServicesCache keeping track of HCE and SE services on the device
48  * - RegisteredNfcFServicesCache keeping track of HCE-F services on the device
49  * - RegisteredAidCache keeping track of AIDs registered by those services and manages
50  *   the routing table in the NFCC.
51  * - RegisteredT3tIdentifiersCache keeping track of T3T Identifier registered by
52  *   those services and manages the routing table in the NFCC.
53  * - HostEmulationManager handles incoming APDUs for the host and forwards to HCE
54  *   services as necessary.
55  * - HostNfcFEmulationManager handles incoming NFC-F packets for the host and
56  *   forwards to HCE-F services as necessary.
57  */
58 public class CardEmulationManager implements RegisteredServicesCache.Callback,
59         RegisteredNfcFServicesCache.Callback, PreferredServices.Callback,
60         EnabledNfcFServices.Callback {
61     static final String TAG = "CardEmulationManager";
62     static final boolean DBG = false;
63 
64     static final int NFC_HCE_APDU = 0x01;
65     static final int NFC_HCE_NFCF = 0x04;
66 
67     final RegisteredAidCache mAidCache;
68     final RegisteredT3tIdentifiersCache mT3tIdentifiersCache;
69     final RegisteredServicesCache mServiceCache;
70     final RegisteredNfcFServicesCache mNfcFServicesCache;
71     final HostEmulationManager mHostEmulationManager;
72     final HostNfcFEmulationManager mHostNfcFEmulationManager;
73     final PreferredServices mPreferredServices;
74     final EnabledNfcFServices mEnabledNfcFServices;
75     final Context mContext;
76     final CardEmulationInterface mCardEmulationInterface;
77     final NfcFCardEmulationInterface mNfcFCardEmulationInterface;
78 
CardEmulationManager(Context context)79     public CardEmulationManager(Context context) {
80         mContext = context;
81         mCardEmulationInterface = new CardEmulationInterface();
82         mNfcFCardEmulationInterface = new NfcFCardEmulationInterface();
83         mAidCache = new RegisteredAidCache(context);
84         mT3tIdentifiersCache = new RegisteredT3tIdentifiersCache(context);
85         mHostEmulationManager = new HostEmulationManager(context, mAidCache);
86         mHostNfcFEmulationManager = new HostNfcFEmulationManager(context, mT3tIdentifiersCache);
87         mServiceCache = new RegisteredServicesCache(context, this);
88         mNfcFServicesCache = new RegisteredNfcFServicesCache(context, this);
89         mPreferredServices = new PreferredServices(context, mServiceCache, mAidCache, this);
90         mEnabledNfcFServices = new EnabledNfcFServices(
91                 context, mNfcFServicesCache, mT3tIdentifiersCache, this);
92         mServiceCache.initialize();
93         mNfcFServicesCache.initialize();
94     }
95 
getNfcCardEmulationInterface()96     public INfcCardEmulation getNfcCardEmulationInterface() {
97         return mCardEmulationInterface;
98     }
99 
getNfcFCardEmulationInterface()100     public INfcFCardEmulation getNfcFCardEmulationInterface() {
101         return mNfcFCardEmulationInterface;
102     }
103 
104 
onHostCardEmulationActivated(int technology)105     public void onHostCardEmulationActivated(int technology) {
106         if (technology == NFC_HCE_APDU) {
107             mHostEmulationManager.onHostEmulationActivated();
108             mPreferredServices.onHostEmulationActivated();
109         } else if (technology == NFC_HCE_NFCF) {
110             mHostNfcFEmulationManager.onHostEmulationActivated();
111             mNfcFServicesCache.onHostEmulationActivated();
112             mEnabledNfcFServices.onHostEmulationActivated();
113         }
114     }
115 
onHostCardEmulationData(int technology, byte[] data)116     public void onHostCardEmulationData(int technology, byte[] data) {
117         if (technology == NFC_HCE_APDU) {
118             mHostEmulationManager.onHostEmulationData(data);
119         } else if (technology == NFC_HCE_NFCF) {
120             mHostNfcFEmulationManager.onHostEmulationData(data);
121         }
122     }
123 
onHostCardEmulationDeactivated(int technology)124     public void onHostCardEmulationDeactivated(int technology) {
125         if (technology == NFC_HCE_APDU) {
126             mHostEmulationManager.onHostEmulationDeactivated();
127             mPreferredServices.onHostEmulationDeactivated();
128         } else if (technology == NFC_HCE_NFCF) {
129             mHostNfcFEmulationManager.onHostEmulationDeactivated();
130             mNfcFServicesCache.onHostEmulationDeactivated();
131             mEnabledNfcFServices.onHostEmulationDeactivated();
132         }
133     }
134 
onOffHostAidSelected()135     public void onOffHostAidSelected() {
136         mHostEmulationManager.onOffHostAidSelected();
137     }
138 
onUserSwitched(int userId)139     public void onUserSwitched(int userId) {
140         // for HCE
141         mServiceCache.invalidateCache(userId);
142         mPreferredServices.onUserSwitched(userId);
143         // for HCE-F
144         mHostNfcFEmulationManager.onUserSwitched();
145         mT3tIdentifiersCache.onUserSwitched();
146         mEnabledNfcFServices.onUserSwitched(userId);
147         mNfcFServicesCache.invalidateCache(userId);
148     }
149 
onNfcEnabled()150     public void onNfcEnabled() {
151         // for HCE
152         mAidCache.onNfcEnabled();
153         // for HCE-F
154         mT3tIdentifiersCache.onNfcEnabled();
155     }
156 
onNfcDisabled()157     public void onNfcDisabled() {
158         // for HCE
159         mAidCache.onNfcDisabled();
160         // for HCE-F
161         mHostNfcFEmulationManager.onNfcDisabled();
162         mNfcFServicesCache.onNfcDisabled();
163         mT3tIdentifiersCache.onNfcDisabled();
164         mEnabledNfcFServices.onNfcDisabled();
165     }
166 
dump(FileDescriptor fd, PrintWriter pw, String[] args)167     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
168         mServiceCache.dump(fd, pw, args);
169         mNfcFServicesCache.dump(fd, pw ,args);
170         mPreferredServices.dump(fd, pw, args);
171         mEnabledNfcFServices.dump(fd, pw, args);
172         mAidCache.dump(fd, pw, args);
173         mT3tIdentifiersCache.dump(fd, pw, args);
174         mHostEmulationManager.dump(fd, pw, args);
175         mHostNfcFEmulationManager.dump(fd, pw, args);
176     }
177 
178     @Override
onServicesUpdated(int userId, List<ApduServiceInfo> services)179     public void onServicesUpdated(int userId, List<ApduServiceInfo> services) {
180         // Verify defaults are still sane
181         verifyDefaults(userId, services);
182         // Update the AID cache
183         mAidCache.onServicesUpdated(userId, services);
184         // Update the preferred services list
185         mPreferredServices.onServicesUpdated();
186     }
187 
188     @Override
onNfcFServicesUpdated(int userId, List<NfcFServiceInfo> services)189     public void onNfcFServicesUpdated(int userId, List<NfcFServiceInfo> services) {
190         // Update the T3T identifier cache
191         mT3tIdentifiersCache.onServicesUpdated(userId, services);
192         // Update the enabled services list
193         mEnabledNfcFServices.onServicesUpdated();
194     }
195 
verifyDefaults(int userId, List<ApduServiceInfo> services)196     void verifyDefaults(int userId, List<ApduServiceInfo> services) {
197         ComponentName defaultPaymentService =
198                 getDefaultServiceForCategory(userId, CardEmulation.CATEGORY_PAYMENT, false);
199         if (DBG) Log.d(TAG, "Current default: " + defaultPaymentService);
200         if (defaultPaymentService != null) {
201             // Validate the default is still installed and handling payment
202             ApduServiceInfo serviceInfo = mServiceCache.getService(userId, defaultPaymentService);
203             if (serviceInfo == null || !serviceInfo.hasCategory(CardEmulation.CATEGORY_PAYMENT)) {
204                 if (serviceInfo == null) {
205                     Log.e(TAG, "Default payment service unexpectedly removed.");
206                 } else if (!serviceInfo.hasCategory(CardEmulation.CATEGORY_PAYMENT)) {
207                     if (DBG) Log.d(TAG, "Default payment service had payment category removed");
208                 }
209                 int numPaymentServices = 0;
210                 ComponentName lastFoundPaymentService = null;
211                 for (ApduServiceInfo service : services) {
212                     if (service.hasCategory(CardEmulation.CATEGORY_PAYMENT))  {
213                         numPaymentServices++;
214                         lastFoundPaymentService = service.getComponent();
215                     }
216                 }
217                 if (DBG) Log.d(TAG, "Number of payment services is " +
218                         Integer.toString(numPaymentServices));
219                 if (numPaymentServices == 0) {
220                     if (DBG) Log.d(TAG, "Default removed, no services left.");
221                     // No payment services left, unset default and don't ask the user
222                     setDefaultServiceForCategoryChecked(userId, null, CardEmulation.CATEGORY_PAYMENT);
223                 } else if (numPaymentServices == 1) {
224                     // Only one left, automatically make it the default
225                     if (DBG) Log.d(TAG, "Default removed, making remaining service default.");
226                     setDefaultServiceForCategoryChecked(userId, lastFoundPaymentService,
227                             CardEmulation.CATEGORY_PAYMENT);
228                 } else if (numPaymentServices > 1) {
229                     // More than one left, unset default and ask the user if he wants
230                     // to set a new one
231                     if (DBG) Log.d(TAG, "Default removed, asking user to pick.");
232                     setDefaultServiceForCategoryChecked(userId, null,
233                             CardEmulation.CATEGORY_PAYMENT);
234                     Intent intent = new Intent(mContext, DefaultRemovedActivity.class);
235                     intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
236                     mContext.startActivityAsUser(intent, UserHandle.CURRENT);
237                 }
238             } else {
239                 // Default still exists and handles the category, nothing do
240                 if (DBG) Log.d(TAG, "Default payment service still ok.");
241             }
242         } else {
243             // A payment service may have been removed, leaving only one;
244             // in that case, automatically set that app as default.
245             int numPaymentServices = 0;
246             ComponentName lastFoundPaymentService = null;
247             for (ApduServiceInfo service : services) {
248                 if (service.hasCategory(CardEmulation.CATEGORY_PAYMENT))  {
249                     numPaymentServices++;
250                     lastFoundPaymentService = service.getComponent();
251                 }
252             }
253             if (numPaymentServices > 1) {
254                 // More than one service left, leave default unset
255                 if (DBG) Log.d(TAG, "No default set, more than one service left.");
256             } else if (numPaymentServices == 1) {
257                 // Make single found payment service the default
258                 if (DBG) Log.d(TAG, "No default set, making single service default.");
259                 setDefaultServiceForCategoryChecked(userId, lastFoundPaymentService,
260                         CardEmulation.CATEGORY_PAYMENT);
261             } else {
262                 // No payment services left, leave default at null
263                 if (DBG) Log.d(TAG, "No default set, last payment service removed.");
264             }
265         }
266     }
267 
getDefaultServiceForCategory(int userId, String category, boolean validateInstalled)268     ComponentName getDefaultServiceForCategory(int userId, String category,
269              boolean validateInstalled) {
270         if (!CardEmulation.CATEGORY_PAYMENT.equals(category)) {
271             Log.e(TAG, "Not allowing defaults for category " + category);
272             return null;
273         }
274         // Load current payment default from settings
275         String name = Settings.Secure.getStringForUser(
276                 mContext.getContentResolver(), Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT,
277                 userId);
278         if (name != null) {
279             ComponentName service = ComponentName.unflattenFromString(name);
280             if (!validateInstalled || service == null) {
281                 return service;
282             } else {
283                 return mServiceCache.hasService(userId, service) ? service : null;
284              }
285         } else {
286             return null;
287         }
288     }
289 
setDefaultServiceForCategoryChecked(int userId, ComponentName service, String category)290     boolean setDefaultServiceForCategoryChecked(int userId, ComponentName service,
291             String category) {
292         if (!CardEmulation.CATEGORY_PAYMENT.equals(category)) {
293             Log.e(TAG, "Not allowing defaults for category " + category);
294             return false;
295         }
296         // TODO Not really nice to be writing to Settings.Secure here...
297         // ideally we overlay our local changes over whatever is in
298         // Settings.Secure
299         if (service == null || mServiceCache.hasService(userId, service)) {
300             Settings.Secure.putStringForUser(mContext.getContentResolver(),
301                     Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT,
302                     service != null ? service.flattenToString() : null, userId);
303         } else {
304             Log.e(TAG, "Could not find default service to make default: " + service);
305         }
306         return true;
307     }
308 
isServiceRegistered(int userId, ComponentName service)309     boolean isServiceRegistered(int userId, ComponentName service) {
310         boolean serviceFound = mServiceCache.hasService(userId, service);
311         if (!serviceFound) {
312             // If we don't know about this service yet, it may have just been enabled
313             // using PackageManager.setComponentEnabledSetting(). The PackageManager
314             // broadcasts are delayed by 10 seconds in that scenario, which causes
315             // calls to our APIs referencing that service to fail.
316             // Hence, update the cache in case we don't know about the service.
317             if (DBG) Log.d(TAG, "Didn't find passed in service, invalidating cache.");
318             mServiceCache.invalidateCache(userId);
319         }
320         return mServiceCache.hasService(userId, service);
321     }
322 
isNfcFServiceInstalled(int userId, ComponentName service)323     boolean isNfcFServiceInstalled(int userId, ComponentName service) {
324         boolean serviceFound = mNfcFServicesCache.hasService(userId, service);
325         if (!serviceFound) {
326             // If we don't know about this service yet, it may have just been enabled
327             // using PackageManager.setComponentEnabledSetting(). The PackageManager
328             // broadcasts are delayed by 10 seconds in that scenario, which causes
329             // calls to our APIs referencing that service to fail.
330             // Hence, update the cache in case we don't know about the service.
331             if (DBG) Log.d(TAG, "Didn't find passed in service, invalidating cache.");
332             mNfcFServicesCache.invalidateCache(userId);
333         }
334         return mNfcFServicesCache.hasService(userId, service);
335     }
336 
337     /**
338      * Returns whether a service in this package is preferred,
339      * either because it's the default payment app or it's running
340      * in the foreground.
341      */
packageHasPreferredService(String packageName)342     public boolean packageHasPreferredService(String packageName) {
343         return mPreferredServices.packageHasPreferredService(packageName);
344     }
345 
346     /**
347      * This class implements the application-facing APIs and are called
348      * from binder. All calls must be permission-checked.
349      */
350     final class CardEmulationInterface extends INfcCardEmulation.Stub {
351         @Override
isDefaultServiceForCategory(int userId, ComponentName service, String category)352         public boolean isDefaultServiceForCategory(int userId, ComponentName service,
353                 String category) {
354             NfcPermissions.enforceUserPermissions(mContext);
355             NfcPermissions.validateUserId(userId);
356             if (!isServiceRegistered(userId, service)) {
357                 return false;
358             }
359             ComponentName defaultService =
360                     getDefaultServiceForCategory(userId, category, true);
361             return (defaultService != null && defaultService.equals(service));
362         }
363 
364         @Override
isDefaultServiceForAid(int userId, ComponentName service, String aid)365         public boolean isDefaultServiceForAid(int userId,
366                 ComponentName service, String aid) throws RemoteException {
367             NfcPermissions.validateUserId(userId);
368             NfcPermissions.enforceUserPermissions(mContext);
369             if (!isServiceRegistered(userId, service)) {
370                 return false;
371             }
372             return mAidCache.isDefaultServiceForAid(userId, service, aid);
373         }
374 
375         @Override
setDefaultServiceForCategory(int userId, ComponentName service, String category)376         public boolean setDefaultServiceForCategory(int userId,
377                 ComponentName service, String category) throws RemoteException {
378             NfcPermissions.validateUserId(userId);
379             NfcPermissions.enforceAdminPermissions(mContext);
380             if (!isServiceRegistered(userId, service)) {
381                 return false;
382             }
383             return setDefaultServiceForCategoryChecked(userId, service, category);
384         }
385 
386         @Override
setDefaultForNextTap(int userId, ComponentName service)387         public boolean setDefaultForNextTap(int userId, ComponentName service)
388                 throws RemoteException {
389             NfcPermissions.validateUserId(userId);
390             NfcPermissions.enforceAdminPermissions(mContext);
391             if (!isServiceRegistered(userId, service)) {
392                 return false;
393             }
394             return mPreferredServices.setDefaultForNextTap(service);
395         }
396 
397         @Override
registerAidGroupForService(int userId, ComponentName service, AidGroup aidGroup)398         public boolean registerAidGroupForService(int userId,
399                 ComponentName service, AidGroup aidGroup) throws RemoteException {
400             NfcPermissions.validateUserId(userId);
401             NfcPermissions.enforceUserPermissions(mContext);
402             if (!isServiceRegistered(userId, service)) {
403                 return false;
404             }
405             return mServiceCache.registerAidGroupForService(userId, Binder.getCallingUid(), service,
406                     aidGroup);
407         }
408 
409         @Override
getAidGroupForService(int userId, ComponentName service, String category)410         public AidGroup getAidGroupForService(int userId,
411                 ComponentName service, String category) throws RemoteException {
412             NfcPermissions.validateUserId(userId);
413             NfcPermissions.enforceUserPermissions(mContext);
414             if (!isServiceRegistered(userId, service)) {
415                 return null;
416             }
417             return mServiceCache.getAidGroupForService(userId, Binder.getCallingUid(), service,
418                     category);
419         }
420 
421         @Override
removeAidGroupForService(int userId, ComponentName service, String category)422         public boolean removeAidGroupForService(int userId,
423                 ComponentName service, String category) throws RemoteException {
424             NfcPermissions.validateUserId(userId);
425             NfcPermissions.enforceUserPermissions(mContext);
426             if (!isServiceRegistered(userId, service)) {
427                 return false;
428             }
429             return mServiceCache.removeAidGroupForService(userId, Binder.getCallingUid(), service,
430                     category);
431         }
432 
433         @Override
getServices(int userId, String category)434         public List<ApduServiceInfo> getServices(int userId, String category)
435                 throws RemoteException {
436             NfcPermissions.validateUserId(userId);
437             NfcPermissions.enforceAdminPermissions(mContext);
438             return mServiceCache.getServicesForCategory(userId, category);
439         }
440 
441         @Override
setPreferredService(ComponentName service)442         public boolean setPreferredService(ComponentName service)
443                 throws RemoteException {
444             NfcPermissions.enforceUserPermissions(mContext);
445             if (!isServiceRegistered(UserHandle.getCallingUserId(), service)) {
446                 Log.e(TAG, "setPreferredService: unknown component.");
447                 return false;
448             }
449             return mPreferredServices.registerPreferredForegroundService(service,
450                     Binder.getCallingUid());
451         }
452 
453         @Override
unsetPreferredService()454         public boolean unsetPreferredService() throws RemoteException {
455             NfcPermissions.enforceUserPermissions(mContext);
456             return mPreferredServices.unregisteredPreferredForegroundService(
457                     Binder.getCallingUid());
458         }
459 
460         @Override
supportsAidPrefixRegistration()461         public boolean supportsAidPrefixRegistration() throws RemoteException {
462             return mAidCache.supportsAidPrefixRegistration();
463         }
464     }
465 
466     /**
467      * This class implements the application-facing APIs and are called
468      * from binder. All calls must be permission-checked.
469      */
470     final class NfcFCardEmulationInterface extends INfcFCardEmulation.Stub {
471         @Override
getSystemCodeForService(int userId, ComponentName service)472         public String getSystemCodeForService(int userId, ComponentName service)
473                 throws RemoteException {
474             NfcPermissions.validateUserId(userId);
475             NfcPermissions.enforceUserPermissions(mContext);
476             if (!isNfcFServiceInstalled(userId, service)) {
477                 return null;
478             }
479             return mNfcFServicesCache.getSystemCodeForService(
480                     userId, Binder.getCallingUid(), service);
481         }
482 
483         @Override
registerSystemCodeForService(int userId, ComponentName service, String systemCode)484         public boolean registerSystemCodeForService(int userId, ComponentName service,
485                 String systemCode)
486                 throws RemoteException {
487             NfcPermissions.validateUserId(userId);
488             NfcPermissions.enforceUserPermissions(mContext);
489             if (!isNfcFServiceInstalled(userId, service)) {
490                 return false;
491             }
492             return mNfcFServicesCache.registerSystemCodeForService(
493                     userId, Binder.getCallingUid(), service, systemCode);
494         }
495 
496         @Override
removeSystemCodeForService(int userId, ComponentName service)497         public boolean removeSystemCodeForService(int userId, ComponentName service)
498                 throws RemoteException {
499             NfcPermissions.validateUserId(userId);
500             NfcPermissions.enforceUserPermissions(mContext);
501             if (!isNfcFServiceInstalled(userId, service)) {
502                 return false;
503             }
504             return mNfcFServicesCache.removeSystemCodeForService(
505                     userId, Binder.getCallingUid(), service);
506         }
507 
508         @Override
getNfcid2ForService(int userId, ComponentName service)509         public String getNfcid2ForService(int userId, ComponentName service)
510                 throws RemoteException {
511             NfcPermissions.validateUserId(userId);
512             NfcPermissions.enforceUserPermissions(mContext);
513             if (!isNfcFServiceInstalled(userId, service)) {
514                 return null;
515             }
516             return mNfcFServicesCache.getNfcid2ForService(
517                     userId, Binder.getCallingUid(), service);
518         }
519 
520         @Override
setNfcid2ForService(int userId, ComponentName service, String nfcid2)521         public boolean setNfcid2ForService(int userId,
522                 ComponentName service, String nfcid2) throws RemoteException {
523             NfcPermissions.validateUserId(userId);
524             NfcPermissions.enforceUserPermissions(mContext);
525             if (!isNfcFServiceInstalled(userId, service)) {
526                 return false;
527             }
528             return mNfcFServicesCache.setNfcid2ForService(
529                     userId, Binder.getCallingUid(), service, nfcid2);
530         }
531 
532         @Override
enableNfcFForegroundService(ComponentName service)533         public boolean enableNfcFForegroundService(ComponentName service)
534                 throws RemoteException {
535             NfcPermissions.enforceUserPermissions(mContext);
536             if (isNfcFServiceInstalled(UserHandle.getCallingUserId(), service)) {
537                 return mEnabledNfcFServices.registerEnabledForegroundService(service,
538                         Binder.getCallingUid());
539             }
540             return false;
541         }
542 
543         @Override
disableNfcFForegroundService()544         public boolean disableNfcFForegroundService() throws RemoteException {
545             NfcPermissions.enforceUserPermissions(mContext);
546             return mEnabledNfcFServices.unregisteredEnabledForegroundService(
547                     Binder.getCallingUid());
548         }
549 
550         @Override
getNfcFServices(int userId)551         public List<NfcFServiceInfo> getNfcFServices(int userId)
552                 throws RemoteException {
553             NfcPermissions.validateUserId(userId);
554             NfcPermissions.enforceUserPermissions(mContext);
555             return mNfcFServicesCache.getServices(userId);
556         }
557 
558         @Override
getMaxNumOfRegisterableSystemCodes()559         public int getMaxNumOfRegisterableSystemCodes()
560                 throws RemoteException {
561             NfcPermissions.enforceUserPermissions(mContext);
562             return NfcService.getInstance().getLfT3tMax();
563         }
564     }
565 
566     @Override
onPreferredPaymentServiceChanged(ComponentName service)567     public void onPreferredPaymentServiceChanged(ComponentName service) {
568         mAidCache.onPreferredPaymentServiceChanged(service);
569         mHostEmulationManager.onPreferredPaymentServiceChanged(service);
570     }
571 
572     @Override
onPreferredForegroundServiceChanged(ComponentName service)573     public void onPreferredForegroundServiceChanged(ComponentName service) {
574         mAidCache.onPreferredForegroundServiceChanged(service);
575         mHostEmulationManager.onPreferredForegroundServiceChanged(service);
576     }
577 
578     @Override
onEnabledForegroundNfcFServiceChanged(ComponentName service)579     public void onEnabledForegroundNfcFServiceChanged(ComponentName service) {
580         mT3tIdentifiersCache.onEnabledForegroundNfcFServiceChanged(service);
581         mHostNfcFEmulationManager.onEnabledForegroundNfcFServiceChanged(service);
582     }
583 }
584