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.app.ActivityManager;
23 import android.content.ComponentName;
24 import android.content.Context;
25 import android.content.Intent;
26 import android.nfc.INfcCardEmulation;
27 import android.nfc.INfcFCardEmulation;
28 import android.nfc.NfcAdapter;
29 import android.nfc.cardemulation.AidGroup;
30 import android.nfc.cardemulation.ApduServiceInfo;
31 import android.nfc.cardemulation.NfcFServiceInfo;
32 import android.nfc.cardemulation.CardEmulation;
33 import android.nfc.cardemulation.NfcFCardEmulation;
34 import android.os.Binder;
35 import android.os.RemoteException;
36 import android.os.UserHandle;
37 import android.os.PowerManager;
38 import android.os.SystemClock;
39 import android.provider.Settings;
40 import android.util.Log;
41 import android.util.proto.ProtoOutputStream;
42 
43 import com.android.nfc.NfcPermissions;
44 import com.android.nfc.NfcService;
45 import com.android.nfc.cardemulation.RegisteredServicesCache;
46 import com.android.nfc.cardemulation.RegisteredNfcFServicesCache;
47 
48 /**
49  * CardEmulationManager is the central entity
50  * responsible for delegating to individual components
51  * implementing card emulation:
52  * - RegisteredServicesCache keeping track of HCE and SE services on the device
53  * - RegisteredNfcFServicesCache keeping track of HCE-F services on the device
54  * - RegisteredAidCache keeping track of AIDs registered by those services and manages
55  *   the routing table in the NFCC.
56  * - RegisteredT3tIdentifiersCache keeping track of T3T Identifier registered by
57  *   those services and manages the routing table in the NFCC.
58  * - HostEmulationManager handles incoming APDUs for the host and forwards to HCE
59  *   services as necessary.
60  * - HostNfcFEmulationManager handles incoming NFC-F packets for the host and
61  *   forwards to HCE-F services as necessary.
62  */
63 public class CardEmulationManager implements RegisteredServicesCache.Callback,
64         RegisteredNfcFServicesCache.Callback, PreferredServices.Callback,
65         EnabledNfcFServices.Callback {
66     static final String TAG = "CardEmulationManager";
67     static final boolean DBG = false;
68 
69     static final int NFC_HCE_APDU = 0x01;
70     static final int NFC_HCE_NFCF = 0x04;
71 
72     final RegisteredAidCache mAidCache;
73     final RegisteredT3tIdentifiersCache mT3tIdentifiersCache;
74     final RegisteredServicesCache mServiceCache;
75     final RegisteredNfcFServicesCache mNfcFServicesCache;
76     final HostEmulationManager mHostEmulationManager;
77     final HostNfcFEmulationManager mHostNfcFEmulationManager;
78     final PreferredServices mPreferredServices;
79     final EnabledNfcFServices mEnabledNfcFServices;
80     final Context mContext;
81     final CardEmulationInterface mCardEmulationInterface;
82     final NfcFCardEmulationInterface mNfcFCardEmulationInterface;
83     final PowerManager mPowerManager;
84 
CardEmulationManager(Context context)85     public CardEmulationManager(Context context) {
86         mContext = context;
87         mCardEmulationInterface = new CardEmulationInterface();
88         mNfcFCardEmulationInterface = new NfcFCardEmulationInterface();
89         mAidCache = new RegisteredAidCache(context);
90         mT3tIdentifiersCache = new RegisteredT3tIdentifiersCache(context);
91         mHostEmulationManager = new HostEmulationManager(context, mAidCache);
92         mHostNfcFEmulationManager = new HostNfcFEmulationManager(context, mT3tIdentifiersCache);
93         mServiceCache = new RegisteredServicesCache(context, this);
94         mNfcFServicesCache = new RegisteredNfcFServicesCache(context, this);
95         mPreferredServices = new PreferredServices(context, mServiceCache, mAidCache, this);
96         mEnabledNfcFServices = new EnabledNfcFServices(
97                 context, mNfcFServicesCache, mT3tIdentifiersCache, this);
98         mServiceCache.initialize();
99         mNfcFServicesCache.initialize();
100         mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
101     }
102 
getNfcCardEmulationInterface()103     public INfcCardEmulation getNfcCardEmulationInterface() {
104         return mCardEmulationInterface;
105     }
106 
getNfcFCardEmulationInterface()107     public INfcFCardEmulation getNfcFCardEmulationInterface() {
108         return mNfcFCardEmulationInterface;
109     }
110 
111 
onHostCardEmulationActivated(int technology)112     public void onHostCardEmulationActivated(int technology) {
113         if (mPowerManager != null) {
114             mPowerManager.userActivity(SystemClock.uptimeMillis(), PowerManager.USER_ACTIVITY_EVENT_TOUCH, 0);
115         }
116         if (technology == NFC_HCE_APDU) {
117             mHostEmulationManager.onHostEmulationActivated();
118             mPreferredServices.onHostEmulationActivated();
119         } else if (technology == NFC_HCE_NFCF) {
120             mHostNfcFEmulationManager.onHostEmulationActivated();
121             mNfcFServicesCache.onHostEmulationActivated();
122             mEnabledNfcFServices.onHostEmulationActivated();
123         }
124     }
125 
onHostCardEmulationData(int technology, byte[] data)126     public void onHostCardEmulationData(int technology, byte[] data) {
127         if (mPowerManager != null) {
128             mPowerManager.userActivity(SystemClock.uptimeMillis(), PowerManager.USER_ACTIVITY_EVENT_TOUCH, 0);
129         }
130         if (technology == NFC_HCE_APDU) {
131             mHostEmulationManager.onHostEmulationData(data);
132         } else if (technology == NFC_HCE_NFCF) {
133             mHostNfcFEmulationManager.onHostEmulationData(data);
134         }
135     }
136 
onHostCardEmulationDeactivated(int technology)137     public void onHostCardEmulationDeactivated(int technology) {
138         if (technology == NFC_HCE_APDU) {
139             mHostEmulationManager.onHostEmulationDeactivated();
140             mPreferredServices.onHostEmulationDeactivated();
141         } else if (technology == NFC_HCE_NFCF) {
142             mHostNfcFEmulationManager.onHostEmulationDeactivated();
143             mNfcFServicesCache.onHostEmulationDeactivated();
144             mEnabledNfcFServices.onHostEmulationDeactivated();
145         }
146     }
147 
onOffHostAidSelected()148     public void onOffHostAidSelected() {
149         mHostEmulationManager.onOffHostAidSelected();
150     }
151 
onUserSwitched(int userId)152     public void onUserSwitched(int userId) {
153         // for HCE
154         mServiceCache.invalidateCache(userId);
155         mPreferredServices.onUserSwitched(userId);
156         // for HCE-F
157         mHostNfcFEmulationManager.onUserSwitched();
158         mT3tIdentifiersCache.onUserSwitched();
159         mEnabledNfcFServices.onUserSwitched(userId);
160         mNfcFServicesCache.onUserSwitched();
161         mNfcFServicesCache.invalidateCache(userId);
162     }
163 
onNfcEnabled()164     public void onNfcEnabled() {
165         // for HCE
166         mAidCache.onNfcEnabled();
167         // for HCE-F
168         mT3tIdentifiersCache.onNfcEnabled();
169     }
170 
onNfcDisabled()171     public void onNfcDisabled() {
172         // for HCE
173         mAidCache.onNfcDisabled();
174         // for HCE-F
175         mHostNfcFEmulationManager.onNfcDisabled();
176         mNfcFServicesCache.onNfcDisabled();
177         mT3tIdentifiersCache.onNfcDisabled();
178         mEnabledNfcFServices.onNfcDisabled();
179     }
180 
onSecureNfcToggled()181     public void onSecureNfcToggled() {
182         mAidCache.onSecureNfcToggled();
183         mT3tIdentifiersCache.onSecureNfcToggled();
184     }
185 
dump(FileDescriptor fd, PrintWriter pw, String[] args)186     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
187         mServiceCache.dump(fd, pw, args);
188         mNfcFServicesCache.dump(fd, pw ,args);
189         mPreferredServices.dump(fd, pw, args);
190         mEnabledNfcFServices.dump(fd, pw, args);
191         mAidCache.dump(fd, pw, args);
192         mT3tIdentifiersCache.dump(fd, pw, args);
193         mHostEmulationManager.dump(fd, pw, args);
194         mHostNfcFEmulationManager.dump(fd, pw, args);
195     }
196 
197     /**
198      * Dump debugging information as a CardEmulationManagerProto
199      *
200      * Note:
201      * See proto definition in frameworks/base/core/proto/android/nfc/card_emulation.proto
202      * When writing a nested message, must call {@link ProtoOutputStream#start(long)} before and
203      * {@link ProtoOutputStream#end(long)} after.
204      * Never reuse a proto field number. When removing a field, mark it as reserved.
205      */
dumpDebug(ProtoOutputStream proto)206     public void dumpDebug(ProtoOutputStream proto) {
207         long token = proto.start(CardEmulationManagerProto.REGISTERED_SERVICES_CACHE);
208         mServiceCache.dumpDebug(proto);
209         proto.end(token);
210 
211         token = proto.start(CardEmulationManagerProto.REGISTERED_NFC_F_SERVICES_CACHE);
212         mNfcFServicesCache.dumpDebug(proto);
213         proto.end(token);
214 
215         token = proto.start(CardEmulationManagerProto.PREFERRED_SERVICES);
216         mPreferredServices.dumpDebug(proto);
217         proto.end(token);
218 
219         token = proto.start(CardEmulationManagerProto.ENABLED_NFC_F_SERVICES);
220         mEnabledNfcFServices.dumpDebug(proto);
221         proto.end(token);
222 
223         token = proto.start(CardEmulationManagerProto.AID_CACHE);
224         mAidCache.dumpDebug(proto);
225         proto.end(token);
226 
227         token = proto.start(CardEmulationManagerProto.T3T_IDENTIFIERS_CACHE);
228         mT3tIdentifiersCache.dumpDebug(proto);
229         proto.end(token);
230 
231         token = proto.start(CardEmulationManagerProto.HOST_EMULATION_MANAGER);
232         mHostEmulationManager.dumpDebug(proto);
233         proto.end(token);
234 
235         token = proto.start(CardEmulationManagerProto.HOST_NFC_F_EMULATION_MANAGER);
236         mHostNfcFEmulationManager.dumpDebug(proto);
237         proto.end(token);
238     }
239 
240     @Override
onServicesUpdated(int userId, List<ApduServiceInfo> services)241     public void onServicesUpdated(int userId, List<ApduServiceInfo> services) {
242         // Verify defaults are still sane
243         verifyDefaults(userId, services);
244         // Update the AID cache
245         mAidCache.onServicesUpdated(userId, services);
246         // Update the preferred services list
247         mPreferredServices.onServicesUpdated();
248 
249         NfcService.getInstance().onPreferredPaymentChanged(NfcAdapter.PREFERRED_PAYMENT_UPDATED);
250     }
251 
252     @Override
onNfcFServicesUpdated(int userId, List<NfcFServiceInfo> services)253     public void onNfcFServicesUpdated(int userId, List<NfcFServiceInfo> services) {
254         // Update the T3T identifier cache
255         mT3tIdentifiersCache.onServicesUpdated(userId, services);
256         // Update the enabled services list
257         mEnabledNfcFServices.onServicesUpdated();
258     }
259 
verifyDefaults(int userId, List<ApduServiceInfo> services)260     void verifyDefaults(int userId, List<ApduServiceInfo> services) {
261         ComponentName defaultPaymentService =
262                 getDefaultServiceForCategory(userId, CardEmulation.CATEGORY_PAYMENT, true);
263         if (DBG) Log.d(TAG, "Current default: " + defaultPaymentService);
264         if (defaultPaymentService == null) {
265             // A payment service may have been removed, set default payment selection to "not set".
266             if (DBG) Log.d(TAG, "No default set, last payment service removed.");
267             setDefaultServiceForCategoryChecked(userId, null, CardEmulation.CATEGORY_PAYMENT);
268         }
269     }
270 
getDefaultServiceForCategory(int userId, String category, boolean validateInstalled)271     ComponentName getDefaultServiceForCategory(int userId, String category,
272              boolean validateInstalled) {
273         if (!CardEmulation.CATEGORY_PAYMENT.equals(category)) {
274             Log.e(TAG, "Not allowing defaults for category " + category);
275             return null;
276         }
277         // Load current payment default from settings
278         String name = Settings.Secure.getStringForUser(
279                 mContext.getContentResolver(), Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT,
280                 userId);
281         if (name != null) {
282             ComponentName service = ComponentName.unflattenFromString(name);
283             if (!validateInstalled || service == null) {
284                 return service;
285             } else {
286                 return mServiceCache.hasService(userId, service) ? service : null;
287              }
288         } else {
289             return null;
290         }
291     }
292 
setDefaultServiceForCategoryChecked(int userId, ComponentName service, String category)293     boolean setDefaultServiceForCategoryChecked(int userId, ComponentName service,
294             String category) {
295         if (!CardEmulation.CATEGORY_PAYMENT.equals(category)) {
296             Log.e(TAG, "Not allowing defaults for category " + category);
297             return false;
298         }
299         // TODO Not really nice to be writing to Settings.Secure here...
300         // ideally we overlay our local changes over whatever is in
301         // Settings.Secure
302         if (service == null || mServiceCache.hasService(userId, service)) {
303             Settings.Secure.putStringForUser(mContext.getContentResolver(),
304                     Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT,
305                     service != null ? service.flattenToString() : null, userId);
306         } else {
307             Log.e(TAG, "Could not find default service to make default: " + service);
308         }
309         return true;
310     }
311 
isServiceRegistered(int userId, ComponentName service)312     boolean isServiceRegistered(int userId, ComponentName service) {
313         boolean serviceFound = mServiceCache.hasService(userId, service);
314         if (!serviceFound) {
315             // If we don't know about this service yet, it may have just been enabled
316             // using PackageManager.setComponentEnabledSetting(). The PackageManager
317             // broadcasts are delayed by 10 seconds in that scenario, which causes
318             // calls to our APIs referencing that service to fail.
319             // Hence, update the cache in case we don't know about the service.
320             if (DBG) Log.d(TAG, "Didn't find passed in service, invalidating cache.");
321             mServiceCache.invalidateCache(userId);
322         }
323         return mServiceCache.hasService(userId, service);
324     }
325 
isNfcFServiceInstalled(int userId, ComponentName service)326     boolean isNfcFServiceInstalled(int userId, ComponentName service) {
327         boolean serviceFound = mNfcFServicesCache.hasService(userId, service);
328         if (!serviceFound) {
329             // If we don't know about this service yet, it may have just been enabled
330             // using PackageManager.setComponentEnabledSetting(). The PackageManager
331             // broadcasts are delayed by 10 seconds in that scenario, which causes
332             // calls to our APIs referencing that service to fail.
333             // Hence, update the cache in case we don't know about the service.
334             if (DBG) Log.d(TAG, "Didn't find passed in service, invalidating cache.");
335             mNfcFServicesCache.invalidateCache(userId);
336         }
337         return mNfcFServicesCache.hasService(userId, service);
338     }
339 
340     /**
341      * Returns whether a service in this package is preferred,
342      * either because it's the default payment app or it's running
343      * in the foreground.
344      */
packageHasPreferredService(String packageName)345     public boolean packageHasPreferredService(String packageName) {
346         return mPreferredServices.packageHasPreferredService(packageName);
347     }
348 
349     /**
350      * This class implements the application-facing APIs and are called
351      * from binder. All calls must be permission-checked.
352      */
353     final class CardEmulationInterface extends INfcCardEmulation.Stub {
354         @Override
isDefaultServiceForCategory(int userId, ComponentName service, String category)355         public boolean isDefaultServiceForCategory(int userId, ComponentName service,
356                 String category) {
357             NfcPermissions.enforceUserPermissions(mContext);
358             NfcPermissions.validateUserId(userId);
359             if (!isServiceRegistered(userId, service)) {
360                 return false;
361             }
362             ComponentName defaultService =
363                     getDefaultServiceForCategory(userId, category, true);
364             return (defaultService != null && defaultService.equals(service));
365         }
366 
367         @Override
isDefaultServiceForAid(int userId, ComponentName service, String aid)368         public boolean isDefaultServiceForAid(int userId,
369                 ComponentName service, String aid) throws RemoteException {
370             NfcPermissions.validateUserId(userId);
371             NfcPermissions.enforceUserPermissions(mContext);
372             if (!isServiceRegistered(userId, service)) {
373                 return false;
374             }
375             return mAidCache.isDefaultServiceForAid(userId, service, aid);
376         }
377 
378         @Override
setDefaultServiceForCategory(int userId, ComponentName service, String category)379         public boolean setDefaultServiceForCategory(int userId,
380                 ComponentName service, String category) throws RemoteException {
381             NfcPermissions.validateUserId(userId);
382             NfcPermissions.enforceAdminPermissions(mContext);
383             if (!isServiceRegistered(userId, service)) {
384                 return false;
385             }
386             return setDefaultServiceForCategoryChecked(userId, service, category);
387         }
388 
389         @Override
setDefaultForNextTap(int userId, ComponentName service)390         public boolean setDefaultForNextTap(int userId, ComponentName service)
391                 throws RemoteException {
392             NfcPermissions.validateUserId(userId);
393             NfcPermissions.enforceAdminPermissions(mContext);
394             if (service != null && !isServiceRegistered(userId, service)) {
395                 return false;
396             }
397             return mPreferredServices.setDefaultForNextTap(service);
398         }
399 
400         @Override
registerAidGroupForService(int userId, ComponentName service, AidGroup aidGroup)401         public boolean registerAidGroupForService(int userId,
402                 ComponentName service, AidGroup aidGroup) throws RemoteException {
403             NfcPermissions.validateUserId(userId);
404             NfcPermissions.enforceUserPermissions(mContext);
405             if (!isServiceRegistered(userId, service)) {
406                 return false;
407             }
408             if (!mServiceCache.registerAidGroupForService(userId, Binder.getCallingUid(), service,
409                     aidGroup)) {
410                 return false;
411             }
412             NfcService.getInstance().onPreferredPaymentChanged(
413                     NfcAdapter.PREFERRED_PAYMENT_UPDATED);
414             return true;
415         }
416 
417         @Override
setOffHostForService(int userId, ComponentName service, String offHostSE)418         public boolean setOffHostForService(int userId, ComponentName service, String offHostSE) {
419             NfcPermissions.validateUserId(userId);
420             NfcPermissions.enforceUserPermissions(mContext);
421             if (!isServiceRegistered(userId, service)) {
422                 return false;
423             }
424             if (!mServiceCache.setOffHostSecureElement(userId, Binder.getCallingUid(), service,
425                     offHostSE)) {
426                 return false;
427             }
428             NfcService.getInstance().onPreferredPaymentChanged(
429                     NfcAdapter.PREFERRED_PAYMENT_UPDATED);
430             return true;
431         }
432 
433         @Override
unsetOffHostForService(int userId, ComponentName service)434         public boolean unsetOffHostForService(int userId, ComponentName service) {
435             NfcPermissions.validateUserId(userId);
436             NfcPermissions.enforceUserPermissions(mContext);
437             if (!isServiceRegistered(userId, service)) {
438                 return false;
439             }
440             if (!mServiceCache.unsetOffHostSecureElement(userId, Binder.getCallingUid(), service)) {
441                 return false;
442             }
443             NfcService.getInstance().onPreferredPaymentChanged(
444                     NfcAdapter.PREFERRED_PAYMENT_UPDATED);
445             return true;
446         }
447 
448         @Override
getAidGroupForService(int userId, ComponentName service, String category)449         public AidGroup getAidGroupForService(int userId,
450                 ComponentName service, String category) throws RemoteException {
451             NfcPermissions.validateUserId(userId);
452             NfcPermissions.enforceUserPermissions(mContext);
453             if (!isServiceRegistered(userId, service)) {
454                 return null;
455             }
456             return mServiceCache.getAidGroupForService(userId, Binder.getCallingUid(), service,
457                     category);
458         }
459 
460         @Override
removeAidGroupForService(int userId, ComponentName service, String category)461         public boolean removeAidGroupForService(int userId,
462                 ComponentName service, String category) throws RemoteException {
463             NfcPermissions.validateUserId(userId);
464             NfcPermissions.enforceUserPermissions(mContext);
465             if (!isServiceRegistered(userId, service)) {
466                 return false;
467             }
468             if (!mServiceCache.removeAidGroupForService(userId, Binder.getCallingUid(), service,
469                     category)) {
470                 return false;
471             }
472             NfcService.getInstance().onPreferredPaymentChanged(
473                     NfcAdapter.PREFERRED_PAYMENT_UPDATED);
474             return true;
475         }
476 
477         @Override
getServices(int userId, String category)478         public List<ApduServiceInfo> getServices(int userId, String category)
479                 throws RemoteException {
480             NfcPermissions.validateUserId(userId);
481             NfcPermissions.enforceAdminPermissions(mContext);
482             return mServiceCache.getServicesForCategory(userId, category);
483         }
484 
485         @Override
setPreferredService(ComponentName service)486         public boolean setPreferredService(ComponentName service)
487                 throws RemoteException {
488             NfcPermissions.enforceUserPermissions(mContext);
489             if (!isServiceRegistered(UserHandle.getCallingUserId(), service)) {
490                 Log.e(TAG, "setPreferredService: unknown component.");
491                 return false;
492             }
493             return mPreferredServices.registerPreferredForegroundService(service,
494                     Binder.getCallingUid());
495         }
496 
497         @Override
unsetPreferredService()498         public boolean unsetPreferredService() throws RemoteException {
499             NfcPermissions.enforceUserPermissions(mContext);
500             return mPreferredServices.unregisteredPreferredForegroundService(
501                     Binder.getCallingUid());
502         }
503 
504         @Override
supportsAidPrefixRegistration()505         public boolean supportsAidPrefixRegistration() throws RemoteException {
506             return mAidCache.supportsAidPrefixRegistration();
507         }
508 
509         @Override
getPreferredPaymentService(int userId)510         public ApduServiceInfo getPreferredPaymentService(int userId) throws RemoteException {
511             NfcPermissions.validateUserId(userId);
512             NfcPermissions.enforceUserPermissions(mContext);
513             NfcPermissions.enforcePreferredPaymentInfoPermissions(mContext);
514             return mServiceCache.getService(userId, mAidCache.getPreferredService());
515         }
516 
517         @Override
isDefaultPaymentRegistered()518         public boolean isDefaultPaymentRegistered() throws RemoteException {
519             String defaultComponent = Settings.Secure.getString(mContext.getContentResolver(),
520                     Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT);
521             return defaultComponent != null ? true : false;
522         }
523     }
524 
525     /**
526      * This class implements the application-facing APIs and are called
527      * from binder. All calls must be permission-checked.
528      */
529     final class NfcFCardEmulationInterface extends INfcFCardEmulation.Stub {
530         @Override
getSystemCodeForService(int userId, ComponentName service)531         public String getSystemCodeForService(int userId, ComponentName service)
532                 throws RemoteException {
533             NfcPermissions.validateUserId(userId);
534             NfcPermissions.enforceUserPermissions(mContext);
535             if (!isNfcFServiceInstalled(userId, service)) {
536                 return null;
537             }
538             return mNfcFServicesCache.getSystemCodeForService(
539                     userId, Binder.getCallingUid(), service);
540         }
541 
542         @Override
registerSystemCodeForService(int userId, ComponentName service, String systemCode)543         public boolean registerSystemCodeForService(int userId, ComponentName service,
544                 String systemCode)
545                 throws RemoteException {
546             NfcPermissions.validateUserId(userId);
547             NfcPermissions.enforceUserPermissions(mContext);
548             if (!isNfcFServiceInstalled(userId, service)) {
549                 return false;
550             }
551             return mNfcFServicesCache.registerSystemCodeForService(
552                     userId, Binder.getCallingUid(), service, systemCode);
553         }
554 
555         @Override
removeSystemCodeForService(int userId, ComponentName service)556         public boolean removeSystemCodeForService(int userId, ComponentName service)
557                 throws RemoteException {
558             NfcPermissions.validateUserId(userId);
559             NfcPermissions.enforceUserPermissions(mContext);
560             if (!isNfcFServiceInstalled(userId, service)) {
561                 return false;
562             }
563             return mNfcFServicesCache.removeSystemCodeForService(
564                     userId, Binder.getCallingUid(), service);
565         }
566 
567         @Override
getNfcid2ForService(int userId, ComponentName service)568         public String getNfcid2ForService(int userId, ComponentName service)
569                 throws RemoteException {
570             NfcPermissions.validateUserId(userId);
571             NfcPermissions.enforceUserPermissions(mContext);
572             if (!isNfcFServiceInstalled(userId, service)) {
573                 return null;
574             }
575             return mNfcFServicesCache.getNfcid2ForService(
576                     userId, Binder.getCallingUid(), service);
577         }
578 
579         @Override
setNfcid2ForService(int userId, ComponentName service, String nfcid2)580         public boolean setNfcid2ForService(int userId,
581                 ComponentName service, String nfcid2) throws RemoteException {
582             NfcPermissions.validateUserId(userId);
583             NfcPermissions.enforceUserPermissions(mContext);
584             if (!isNfcFServiceInstalled(userId, service)) {
585                 return false;
586             }
587             return mNfcFServicesCache.setNfcid2ForService(
588                     userId, Binder.getCallingUid(), service, nfcid2);
589         }
590 
591         @Override
enableNfcFForegroundService(ComponentName service)592         public boolean enableNfcFForegroundService(ComponentName service)
593                 throws RemoteException {
594             NfcPermissions.enforceUserPermissions(mContext);
595             if (isNfcFServiceInstalled(UserHandle.getCallingUserId(), service)) {
596                 return mEnabledNfcFServices.registerEnabledForegroundService(service,
597                         Binder.getCallingUid());
598             }
599             return false;
600         }
601 
602         @Override
disableNfcFForegroundService()603         public boolean disableNfcFForegroundService() throws RemoteException {
604             NfcPermissions.enforceUserPermissions(mContext);
605             return mEnabledNfcFServices.unregisteredEnabledForegroundService(
606                     Binder.getCallingUid());
607         }
608 
609         @Override
getNfcFServices(int userId)610         public List<NfcFServiceInfo> getNfcFServices(int userId)
611                 throws RemoteException {
612             NfcPermissions.validateUserId(userId);
613             NfcPermissions.enforceUserPermissions(mContext);
614             return mNfcFServicesCache.getServices(userId);
615         }
616 
617         @Override
getMaxNumOfRegisterableSystemCodes()618         public int getMaxNumOfRegisterableSystemCodes()
619                 throws RemoteException {
620             NfcPermissions.enforceUserPermissions(mContext);
621             return NfcService.getInstance().getLfT3tMax();
622         }
623     }
624 
625     @Override
onPreferredPaymentServiceChanged(ComponentName service)626     public void onPreferredPaymentServiceChanged(ComponentName service) {
627         mAidCache.onPreferredPaymentServiceChanged(service);
628         mHostEmulationManager.onPreferredPaymentServiceChanged(service);
629 
630         NfcService.getInstance().onPreferredPaymentChanged(
631                 NfcAdapter.PREFERRED_PAYMENT_CHANGED);
632     }
633 
634     @Override
onPreferredForegroundServiceChanged(ComponentName service)635     public void onPreferredForegroundServiceChanged(ComponentName service) {
636         mAidCache.onPreferredForegroundServiceChanged(service);
637         mHostEmulationManager.onPreferredForegroundServiceChanged(service);
638 
639         NfcService.getInstance().onPreferredPaymentChanged(
640                 NfcAdapter.PREFERRED_PAYMENT_CHANGED);
641     }
642 
643     @Override
onEnabledForegroundNfcFServiceChanged(ComponentName service)644     public void onEnabledForegroundNfcFServiceChanged(ComponentName service) {
645         mT3tIdentifiersCache.onEnabledForegroundNfcFServiceChanged(service);
646         mHostNfcFEmulationManager.onEnabledForegroundNfcFServiceChanged(service);
647     }
648 }
649