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