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 android.annotation.TargetApi; 19 import android.annotation.FlaggedApi; 20 import android.app.ActivityManager; 21 import android.app.role.RoleManager; 22 import android.content.ComponentName; 23 import android.content.Context; 24 import android.content.pm.ApplicationInfo; 25 import android.content.pm.PackageManager; 26 import android.content.pm.PackageManager.NameNotFoundException; 27 import android.nfc.Constants; 28 import android.nfc.INfcCardEmulation; 29 import android.nfc.INfcFCardEmulation; 30 import android.nfc.NfcAdapter; 31 import android.nfc.cardemulation.AidGroup; 32 import android.nfc.cardemulation.ApduServiceInfo; 33 import android.nfc.cardemulation.CardEmulation; 34 import android.nfc.cardemulation.NfcFServiceInfo; 35 import android.nfc.cardemulation.PollingFrame; 36 import android.os.Binder; 37 import android.os.Bundle; 38 import android.os.Looper; 39 import android.os.PowerManager; 40 import android.os.Process; 41 import android.os.RemoteException; 42 import android.os.SystemClock; 43 import android.os.UserHandle; 44 import android.os.UserManager; 45 import android.provider.Settings; 46 import android.sysprop.NfcProperties; 47 import android.util.Log; 48 import android.util.proto.ProtoOutputStream; 49 50 import com.android.internal.annotations.VisibleForTesting; 51 import com.android.nfc.ForegroundUtils; 52 import com.android.nfc.NfcInjector; 53 import com.android.nfc.NfcPermissions; 54 import com.android.nfc.NfcService; 55 56 import java.io.FileDescriptor; 57 import java.io.PrintWriter; 58 import java.util.Arrays; 59 import java.util.List; 60 import java.util.Objects; 61 62 import com.android.nfc.R; 63 import android.permission.flags.Flags; 64 65 /** 66 * CardEmulationManager is the central entity 67 * responsible for delegating to individual components 68 * implementing card emulation: 69 * - RegisteredServicesCache keeping track of HCE and SE services on the device 70 * - RegisteredNfcFServicesCache keeping track of HCE-F services on the device 71 * - RegisteredAidCache keeping track of AIDs registered by those services and manages 72 * the routing table in the NFCC. 73 * - RegisteredT3tIdentifiersCache keeping track of T3T Identifier registered by 74 * those services and manages the routing table in the NFCC. 75 * - HostEmulationManager handles incoming APDUs for the host and forwards to HCE 76 * services as necessary. 77 * - HostNfcFEmulationManager handles incoming NFC-F packets for the host and 78 * forwards to HCE-F services as necessary. 79 */ 80 public class CardEmulationManager implements RegisteredServicesCache.Callback, 81 RegisteredNfcFServicesCache.Callback, PreferredServices.Callback, 82 EnabledNfcFServices.Callback, WalletRoleObserver.Callback { 83 static final String TAG = "CardEmulationManager"; 84 static final boolean DBG = NfcProperties.debug_enabled().orElse(true); 85 86 static final int NFC_HCE_APDU = 0x01; 87 static final int NFC_HCE_NFCF = 0x04; 88 /** Minimum AID length as per ISO7816 */ 89 static final int MINIMUM_AID_LENGTH = 5; 90 /** Length of Select APDU header including length byte */ 91 static final int SELECT_APDU_HDR_LENGTH = 5; 92 /** Length of the NDEF Tag application AID */ 93 static final int NDEF_AID_LENGTH = 7; 94 /** AID of the NDEF Tag application Mapping Version 1.0 */ 95 static final byte[] NDEF_AID_V1 = 96 new byte[] {(byte) 0xd2, 0x76, 0x00, 0x00, (byte) 0x85, 0x01, 0x00}; 97 /** AID of the NDEF Tag application Mapping Version 2.0 */ 98 static final byte[] NDEF_AID_V2 = 99 new byte[] {(byte) 0xd2, 0x76, 0x00, 0x00, (byte) 0x85, 0x01, 0x01}; 100 /** Select APDU header */ 101 static final byte[] SELECT_AID_HDR = new byte[] {0x00, (byte) 0xa4, 0x04, 0x00}; 102 103 final RegisteredAidCache mAidCache; 104 final RegisteredT3tIdentifiersCache mT3tIdentifiersCache; 105 final RegisteredServicesCache mServiceCache; 106 final RegisteredNfcFServicesCache mNfcFServicesCache; 107 final HostEmulationManager mHostEmulationManager; 108 final HostNfcFEmulationManager mHostNfcFEmulationManager; 109 final PreferredServices mPreferredServices; 110 111 final WalletRoleObserver mWalletRoleObserver; 112 final EnabledNfcFServices mEnabledNfcFServices; 113 final Context mContext; 114 final CardEmulationInterface mCardEmulationInterface; 115 final NfcFCardEmulationInterface mNfcFCardEmulationInterface; 116 final PowerManager mPowerManager; 117 boolean mNotSkipAid; 118 119 final ForegroundUtils mForegroundUtils; 120 private int mForegroundUid; 121 122 RoutingOptionManager mRoutingOptionManager; 123 final byte[] mOffHostRouteUicc; 124 final byte[] mOffHostRouteEse; 125 126 // TODO: Move this object instantiation and dependencies to NfcInjector. CardEmulationManager(Context context, NfcInjector nfcInjector)127 public CardEmulationManager(Context context, NfcInjector nfcInjector) { 128 mContext = context; 129 mCardEmulationInterface = new CardEmulationInterface(); 130 mNfcFCardEmulationInterface = new NfcFCardEmulationInterface(); 131 mForegroundUtils = ForegroundUtils.getInstance( 132 context.getSystemService(ActivityManager.class)); 133 mWalletRoleObserver = new WalletRoleObserver(context, 134 context.getSystemService(RoleManager.class), this, nfcInjector); 135 mAidCache = new RegisteredAidCache(context, mWalletRoleObserver); 136 mT3tIdentifiersCache = new RegisteredT3tIdentifiersCache(context); 137 mHostEmulationManager = 138 new HostEmulationManager(context, Looper.getMainLooper(), mAidCache); 139 mHostNfcFEmulationManager = new HostNfcFEmulationManager(context, mT3tIdentifiersCache); 140 mServiceCache = new RegisteredServicesCache(context, this); 141 mNfcFServicesCache = new RegisteredNfcFServicesCache(context, this); 142 mPreferredServices = new PreferredServices(context, mServiceCache, mAidCache, 143 mWalletRoleObserver, this); 144 mEnabledNfcFServices = new EnabledNfcFServices( 145 context, mNfcFServicesCache, mT3tIdentifiersCache, this); 146 mPowerManager = context.getSystemService(PowerManager.class); 147 mRoutingOptionManager = RoutingOptionManager.getInstance(); 148 mOffHostRouteEse = mRoutingOptionManager.getOffHostRouteEse(); 149 mOffHostRouteUicc = mRoutingOptionManager.getOffHostRouteUicc(); 150 initialize(); 151 } 152 153 @VisibleForTesting CardEmulationManager(Context context, ForegroundUtils foregroundUtils, WalletRoleObserver walletRoleObserver, RegisteredAidCache registeredAidCache, RegisteredT3tIdentifiersCache registeredT3tIdentifiersCache, HostEmulationManager hostEmulationManager, HostNfcFEmulationManager hostNfcFEmulationManager, RegisteredServicesCache registeredServicesCache, RegisteredNfcFServicesCache registeredNfcFServicesCache, PreferredServices preferredServices, EnabledNfcFServices enabledNfcFServices, RoutingOptionManager routingOptionManager, PowerManager powerManager)154 CardEmulationManager(Context context, 155 ForegroundUtils foregroundUtils, 156 WalletRoleObserver walletRoleObserver, 157 RegisteredAidCache registeredAidCache, 158 RegisteredT3tIdentifiersCache registeredT3tIdentifiersCache, 159 HostEmulationManager hostEmulationManager, 160 HostNfcFEmulationManager hostNfcFEmulationManager, 161 RegisteredServicesCache registeredServicesCache, 162 RegisteredNfcFServicesCache registeredNfcFServicesCache, 163 PreferredServices preferredServices, 164 EnabledNfcFServices enabledNfcFServices, 165 RoutingOptionManager routingOptionManager, 166 PowerManager powerManager) { 167 mContext = context; 168 mCardEmulationInterface = new CardEmulationInterface(); 169 mNfcFCardEmulationInterface = new NfcFCardEmulationInterface(); 170 mForegroundUtils = foregroundUtils; 171 mWalletRoleObserver = walletRoleObserver; 172 mAidCache = registeredAidCache; 173 mT3tIdentifiersCache = registeredT3tIdentifiersCache; 174 mHostEmulationManager = hostEmulationManager; 175 mHostNfcFEmulationManager = hostNfcFEmulationManager; 176 mServiceCache = registeredServicesCache; 177 mNfcFServicesCache = registeredNfcFServicesCache; 178 mPreferredServices = preferredServices; 179 mEnabledNfcFServices = enabledNfcFServices; 180 mPowerManager = powerManager; 181 mRoutingOptionManager = routingOptionManager; 182 mOffHostRouteEse = mRoutingOptionManager.getOffHostRouteEse(); 183 mOffHostRouteUicc = mRoutingOptionManager.getOffHostRouteUicc(); 184 initialize(); 185 } 186 initialize()187 private void initialize() { 188 mServiceCache.initialize(); 189 mNfcFServicesCache.initialize(); 190 mForegroundUid = Process.INVALID_UID; 191 if (mWalletRoleObserver.isWalletRoleFeatureEnabled()) { 192 int currentUser = ActivityManager.getCurrentUser(); 193 onWalletRoleHolderChanged( 194 mWalletRoleObserver.getDefaultWalletRoleHolder(currentUser), currentUser); 195 } 196 } 197 getNfcCardEmulationInterface()198 public INfcCardEmulation getNfcCardEmulationInterface() { 199 return mCardEmulationInterface; 200 } 201 getNfcFCardEmulationInterface()202 public INfcFCardEmulation getNfcFCardEmulationInterface() { 203 return mNfcFCardEmulationInterface; 204 } 205 206 @FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP) onPollingLoopDetected(List<PollingFrame> pollingFrames)207 public void onPollingLoopDetected(List<PollingFrame> pollingFrames) { 208 mHostEmulationManager.onPollingLoopDetected(pollingFrames); 209 } 210 onFieldChangeDetected(boolean fieldOn)211 public void onFieldChangeDetected(boolean fieldOn) { 212 mHostEmulationManager.onFieldChangeDetected(fieldOn); 213 } 214 onHostCardEmulationActivated(int technology)215 public void onHostCardEmulationActivated(int technology) { 216 if (mPowerManager != null) { 217 // Use USER_ACTIVITY_FLAG_INDIRECT to applying power hints without resets 218 // the screen timeout 219 mPowerManager.userActivity(SystemClock.uptimeMillis(), 220 PowerManager.USER_ACTIVITY_EVENT_TOUCH, 221 PowerManager.USER_ACTIVITY_FLAG_INDIRECT); 222 } 223 if (technology == NFC_HCE_APDU) { 224 mHostEmulationManager.onHostEmulationActivated(); 225 mPreferredServices.onHostEmulationActivated(); 226 mNotSkipAid = false; 227 } else if (technology == NFC_HCE_NFCF) { 228 mHostNfcFEmulationManager.onHostEmulationActivated(); 229 mNfcFServicesCache.onHostEmulationActivated(); 230 mEnabledNfcFServices.onHostEmulationActivated(); 231 } 232 } 233 onHostCardEmulationData(int technology, byte[] data)234 public void onHostCardEmulationData(int technology, byte[] data) { 235 if (technology == NFC_HCE_APDU) { 236 mHostEmulationManager.onHostEmulationData(data); 237 } else if (technology == NFC_HCE_NFCF) { 238 mHostNfcFEmulationManager.onHostEmulationData(data); 239 } 240 // Don't trigger userActivity if it's selecting NDEF AID 241 if (mPowerManager != null && !(technology == NFC_HCE_APDU && isSkipAid(data))) { 242 // Caution!! USER_ACTIVITY_EVENT_TOUCH resets the screen timeout 243 mPowerManager.userActivity(SystemClock.uptimeMillis(), 244 PowerManager.USER_ACTIVITY_EVENT_TOUCH, 0); 245 } 246 } 247 onHostCardEmulationDeactivated(int technology)248 public void onHostCardEmulationDeactivated(int technology) { 249 if (technology == NFC_HCE_APDU) { 250 mHostEmulationManager.onHostEmulationDeactivated(); 251 mPreferredServices.onHostEmulationDeactivated(); 252 } else if (technology == NFC_HCE_NFCF) { 253 mHostNfcFEmulationManager.onHostEmulationDeactivated(); 254 mNfcFServicesCache.onHostEmulationDeactivated(); 255 mEnabledNfcFServices.onHostEmulationDeactivated(); 256 } 257 } 258 onOffHostAidSelected()259 public void onOffHostAidSelected() { 260 mHostEmulationManager.onOffHostAidSelected(); 261 } 262 onUserSwitched(int userId)263 public void onUserSwitched(int userId) { 264 mWalletRoleObserver.onUserSwitched(userId); 265 // for HCE 266 mServiceCache.onUserSwitched(); 267 mPreferredServices.onUserSwitched(userId); 268 // for HCE-F 269 mHostNfcFEmulationManager.onUserSwitched(); 270 mT3tIdentifiersCache.onUserSwitched(); 271 mEnabledNfcFServices.onUserSwitched(userId); 272 mNfcFServicesCache.onUserSwitched(); 273 } 274 onManagedProfileChanged()275 public void onManagedProfileChanged() { 276 // for HCE 277 mServiceCache.onManagedProfileChanged(); 278 // for HCE-F 279 mNfcFServicesCache.onManagedProfileChanged(); 280 } 281 onNfcEnabled()282 public void onNfcEnabled() { 283 // for HCE 284 mAidCache.onNfcEnabled(); 285 // for HCE-F 286 mT3tIdentifiersCache.onNfcEnabled(); 287 } 288 onNfcDisabled()289 public void onNfcDisabled() { 290 // for HCE 291 mAidCache.onNfcDisabled(); 292 // for HCE-F 293 mHostNfcFEmulationManager.onNfcDisabled(); 294 mNfcFServicesCache.onNfcDisabled(); 295 mT3tIdentifiersCache.onNfcDisabled(); 296 mEnabledNfcFServices.onNfcDisabled(); 297 } 298 onSecureNfcToggled()299 public void onSecureNfcToggled() { 300 mAidCache.onSecureNfcToggled(); 301 mT3tIdentifiersCache.onSecureNfcToggled(); 302 } 303 dump(FileDescriptor fd, PrintWriter pw, String[] args)304 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 305 mServiceCache.dump(fd, pw, args); 306 mNfcFServicesCache.dump(fd, pw ,args); 307 mPreferredServices.dump(fd, pw, args); 308 mEnabledNfcFServices.dump(fd, pw, args); 309 mAidCache.dump(fd, pw, args); 310 mT3tIdentifiersCache.dump(fd, pw, args); 311 mHostEmulationManager.dump(fd, pw, args); 312 mHostNfcFEmulationManager.dump(fd, pw, args); 313 } 314 315 /** 316 * Dump debugging information as a CardEmulationManagerProto 317 * 318 * Note: 319 * See proto definition in frameworks/base/core/proto/android/nfc/card_emulation.proto 320 * When writing a nested message, must call {@link ProtoOutputStream#start(long)} before and 321 * {@link ProtoOutputStream#end(long)} after. 322 * Never reuse a proto field number. When removing a field, mark it as reserved. 323 */ dumpDebug(ProtoOutputStream proto)324 public void dumpDebug(ProtoOutputStream proto) { 325 long token = proto.start(CardEmulationManagerProto.REGISTERED_SERVICES_CACHE); 326 mServiceCache.dumpDebug(proto); 327 proto.end(token); 328 329 token = proto.start(CardEmulationManagerProto.REGISTERED_NFC_F_SERVICES_CACHE); 330 mNfcFServicesCache.dumpDebug(proto); 331 proto.end(token); 332 333 token = proto.start(CardEmulationManagerProto.PREFERRED_SERVICES); 334 mPreferredServices.dumpDebug(proto); 335 proto.end(token); 336 337 token = proto.start(CardEmulationManagerProto.ENABLED_NFC_F_SERVICES); 338 mEnabledNfcFServices.dumpDebug(proto); 339 proto.end(token); 340 341 token = proto.start(CardEmulationManagerProto.AID_CACHE); 342 mAidCache.dumpDebug(proto); 343 proto.end(token); 344 345 token = proto.start(CardEmulationManagerProto.T3T_IDENTIFIERS_CACHE); 346 mT3tIdentifiersCache.dumpDebug(proto); 347 proto.end(token); 348 349 token = proto.start(CardEmulationManagerProto.HOST_EMULATION_MANAGER); 350 mHostEmulationManager.dumpDebug(proto); 351 proto.end(token); 352 353 token = proto.start(CardEmulationManagerProto.HOST_NFC_F_EMULATION_MANAGER); 354 mHostNfcFEmulationManager.dumpDebug(proto); 355 proto.end(token); 356 } 357 358 @Override onServicesUpdated(int userId, List<ApduServiceInfo> services, boolean validateInstalled)359 public void onServicesUpdated(int userId, List<ApduServiceInfo> services, 360 boolean validateInstalled) { 361 if (!mWalletRoleObserver.isWalletRoleFeatureEnabled()) { 362 // Verify defaults are still the same 363 verifyDefaults(userId, services, validateInstalled); 364 } 365 // Update the AID cache 366 mAidCache.onServicesUpdated(userId, services); 367 // Update the preferred services list 368 mPreferredServices.onServicesUpdated(); 369 if (android.nfc.Flags.nfcReadPollingLoop()) { 370 mHostEmulationManager.updatePollingLoopFilters(userId, services); 371 } 372 NfcService.getInstance().onPreferredPaymentChanged(NfcAdapter.PREFERRED_PAYMENT_UPDATED); 373 } 374 375 @Override onNfcFServicesUpdated(int userId, List<NfcFServiceInfo> services)376 public void onNfcFServicesUpdated(int userId, List<NfcFServiceInfo> services) { 377 // Update the T3T identifier cache 378 mT3tIdentifiersCache.onServicesUpdated(userId, services); 379 // Update the enabled services list 380 mEnabledNfcFServices.onServicesUpdated(); 381 } 382 verifyDefaults(int userId, List<ApduServiceInfo> services, boolean validateInstalled)383 void verifyDefaults(int userId, List<ApduServiceInfo> services, boolean validateInstalled) { 384 UserManager um = mContext.createContextAsUser( 385 UserHandle.of(userId), /*flags=*/0).getSystemService(UserManager.class); 386 List<UserHandle> luh = um.getEnabledProfiles(); 387 388 ComponentName defaultPaymentService = null; 389 int numDefaultPaymentServices = 0; 390 int userIdDefaultPaymentService = userId; 391 392 for (UserHandle uh : luh) { 393 ComponentName paymentService = getDefaultServiceForCategory(uh.getIdentifier(), 394 CardEmulation.CATEGORY_PAYMENT, 395 validateInstalled && (uh.getIdentifier() == userId)); 396 if (DBG) Log.d(TAG, "default: " + paymentService + " for user:" + uh); 397 if (paymentService != null) { 398 numDefaultPaymentServices++; 399 defaultPaymentService = paymentService; 400 userIdDefaultPaymentService = uh.getIdentifier(); 401 } 402 } 403 if (numDefaultPaymentServices > 1) { 404 Log.e(TAG, "Current default is not aligned across multiple users"); 405 // leave default unset 406 for (UserHandle uh : luh) { 407 setDefaultServiceForCategoryChecked(uh.getIdentifier(), null, 408 CardEmulation.CATEGORY_PAYMENT); 409 } 410 } else { 411 if (DBG) { 412 Log.d(TAG, "Current default: " + defaultPaymentService + " for user:" 413 + userIdDefaultPaymentService); 414 } 415 } 416 if (defaultPaymentService == null) { 417 // A payment service may have been removed, leaving only one; 418 // in that case, automatically set that app as default. 419 int numPaymentServices = 0; 420 ComponentName lastFoundPaymentService = null; 421 PackageManager pm; 422 try { 423 pm = mContext.createPackageContextAsUser("android", /*flags=*/0, 424 UserHandle.of(userId)).getPackageManager(); 425 } catch (NameNotFoundException e) { 426 Log.e(TAG, "Could not create user package context"); 427 return; 428 } 429 430 for (ApduServiceInfo service : services) { 431 if (service.hasCategory(CardEmulation.CATEGORY_PAYMENT) 432 && wasServicePreInstalled(pm, service.getComponent())) { 433 numPaymentServices++; 434 lastFoundPaymentService = service.getComponent(); 435 } 436 } 437 if (numPaymentServices > 1) { 438 // More than one service left, leave default unset 439 if (DBG) Log.d(TAG, "No default set, more than one service left."); 440 setDefaultServiceForCategoryChecked(userId, null, CardEmulation.CATEGORY_PAYMENT); 441 } else if (numPaymentServices == 1) { 442 // Make single found payment service the default 443 if (DBG) Log.d(TAG, "No default set, making single service default."); 444 setDefaultServiceForCategoryChecked(userId, lastFoundPaymentService, 445 CardEmulation.CATEGORY_PAYMENT); 446 } else { 447 // No payment services left, leave default at null 448 if (DBG) Log.d(TAG, "No default set, last payment service removed."); 449 setDefaultServiceForCategoryChecked(userId, null, CardEmulation.CATEGORY_PAYMENT); 450 } 451 } 452 } 453 wasServicePreInstalled(PackageManager packageManager, ComponentName service)454 boolean wasServicePreInstalled(PackageManager packageManager, ComponentName service) { 455 try { 456 ApplicationInfo ai = packageManager 457 .getApplicationInfo(service.getPackageName(), /*flags=*/0); 458 if ((ApplicationInfo.FLAG_SYSTEM & ai.flags) != 0) { 459 if (DBG) Log.d(TAG, "Service was pre-installed on the device"); 460 return true; 461 } 462 } catch (NameNotFoundException e) { 463 Log.e(TAG, "Service is not currently installed on the device."); 464 return false; 465 } 466 if (DBG) Log.d(TAG, "Service was not pre-installed on the device"); 467 return false; 468 } 469 getDefaultServiceForCategory(int userId, String category, boolean validateInstalled)470 ComponentName getDefaultServiceForCategory(int userId, String category, 471 boolean validateInstalled) { 472 if (!CardEmulation.CATEGORY_PAYMENT.equals(category)) { 473 Log.e(TAG, "Not allowing defaults for category " + category); 474 return null; 475 } 476 // Load current payment default from settings 477 String name = Settings.Secure.getString( 478 mContext.createContextAsUser(UserHandle.of(userId), 0).getContentResolver(), 479 Constants.SETTINGS_SECURE_NFC_PAYMENT_DEFAULT_COMPONENT); 480 if (name != null) { 481 ComponentName service = ComponentName.unflattenFromString(name); 482 if (!validateInstalled || service == null) { 483 return service; 484 } else { 485 return mServiceCache.hasService(userId, service) ? service : null; 486 } 487 } else { 488 return null; 489 } 490 } 491 setDefaultServiceForCategoryChecked(int userId, ComponentName service, String category)492 boolean setDefaultServiceForCategoryChecked(int userId, ComponentName service, 493 String category) { 494 if (!CardEmulation.CATEGORY_PAYMENT.equals(category)) { 495 Log.e(TAG, "Not allowing defaults for category " + category); 496 return false; 497 } 498 // TODO Not really nice to be writing to Settings.Secure here... 499 // ideally we overlay our local changes over whatever is in 500 // Settings.Secure 501 if (service == null || mServiceCache.hasService(userId, service)) { 502 Settings.Secure.putString(mContext 503 .createContextAsUser(UserHandle.of(userId), 0).getContentResolver(), 504 Constants.SETTINGS_SECURE_NFC_PAYMENT_DEFAULT_COMPONENT, 505 service != null ? service.flattenToString() : null); 506 } else { 507 Log.e(TAG, "Could not find default service to make default: " + service); 508 } 509 return true; 510 } 511 isServiceRegistered(int userId, ComponentName service)512 boolean isServiceRegistered(int userId, ComponentName service) { 513 boolean serviceFound = mServiceCache.hasService(userId, service); 514 if (!serviceFound) { 515 // If we don't know about this service yet, it may have just been enabled 516 // using PackageManager.setComponentEnabledSetting(). The PackageManager 517 // broadcasts are delayed by 10 seconds in that scenario, which causes 518 // calls to our APIs referencing that service to fail. 519 // Hence, update the cache in case we don't know about the service. 520 if (DBG) Log.d(TAG, "Didn't find passed in service, invalidating cache."); 521 mServiceCache.invalidateCache(userId, true); 522 } 523 return mServiceCache.hasService(userId, service); 524 } 525 isNfcFServiceInstalled(int userId, ComponentName service)526 boolean isNfcFServiceInstalled(int userId, ComponentName service) { 527 boolean serviceFound = mNfcFServicesCache.hasService(userId, service); 528 if (!serviceFound) { 529 // If we don't know about this service yet, it may have just been enabled 530 // using PackageManager.setComponentEnabledSetting(). The PackageManager 531 // broadcasts are delayed by 10 seconds in that scenario, which causes 532 // calls to our APIs referencing that service to fail. 533 // Hence, update the cache in case we don't know about the service. 534 if (DBG) Log.d(TAG, "Didn't find passed in service, invalidating cache."); 535 mNfcFServicesCache.invalidateCache(userId); 536 } 537 return mNfcFServicesCache.hasService(userId, service); 538 } 539 540 /** 541 * Returns true if it's not selecting NDEF AIDs 542 * It's used to skip userActivity if it only selects NDEF AIDs 543 */ isSkipAid(byte[] data)544 boolean isSkipAid(byte[] data) { 545 if (mNotSkipAid || data == null 546 || data.length < SELECT_APDU_HDR_LENGTH + MINIMUM_AID_LENGTH 547 || !Arrays.equals(SELECT_AID_HDR, 0, SELECT_AID_HDR.length, 548 data, 0, SELECT_AID_HDR.length)) { 549 return false; 550 } 551 int aidLength = Byte.toUnsignedInt(data[SELECT_APDU_HDR_LENGTH - 1]); 552 if (data.length >= SELECT_APDU_HDR_LENGTH + NDEF_AID_LENGTH 553 && aidLength == NDEF_AID_LENGTH) { 554 if (Arrays.equals(data, SELECT_APDU_HDR_LENGTH, 555 SELECT_APDU_HDR_LENGTH + NDEF_AID_LENGTH, 556 NDEF_AID_V1, 0, NDEF_AID_LENGTH)) { 557 if (DBG) Log.d(TAG, "Skip for NDEF_V1"); 558 return true; 559 } else if (Arrays.equals(data, SELECT_APDU_HDR_LENGTH, 560 SELECT_APDU_HDR_LENGTH + NDEF_AID_LENGTH, 561 NDEF_AID_V2, 0, NDEF_AID_LENGTH)) { 562 if (DBG) Log.d(TAG, "Skip for NDEF_V2"); 563 return true; 564 } 565 } 566 // The data payload is not selecting the skip AID. 567 mNotSkipAid = true; 568 return false; 569 } 570 571 /** 572 * Returns whether a service in this package is preferred, 573 * either because it's the default payment app or it's running 574 * in the foreground. 575 */ packageHasPreferredService(String packageName)576 public boolean packageHasPreferredService(String packageName) { 577 return mPreferredServices.packageHasPreferredService(packageName); 578 } 579 580 /** 581 * This class implements the application-facing APIs and are called 582 * from binder. All calls must be permission-checked. 583 */ 584 final class CardEmulationInterface extends INfcCardEmulation.Stub { 585 @Override isDefaultServiceForCategory(int userId, ComponentName service, String category)586 public boolean isDefaultServiceForCategory(int userId, ComponentName service, 587 String category) { 588 NfcPermissions.enforceUserPermissions(mContext); 589 NfcPermissions.validateUserId(userId); 590 if (!isServiceRegistered(userId, service)) { 591 return false; 592 } 593 if (mWalletRoleObserver.isWalletRoleFeatureEnabled()) { 594 return service.getPackageName() 595 .equals(mWalletRoleObserver.getDefaultWalletRoleHolder(userId)); 596 } 597 ComponentName defaultService = 598 getDefaultServiceForCategory(userId, category, true); 599 return (defaultService != null && defaultService.equals(service)); 600 } 601 602 @Override isDefaultServiceForAid(int userId, ComponentName service, String aid)603 public boolean isDefaultServiceForAid(int userId, 604 ComponentName service, String aid) throws RemoteException { 605 NfcPermissions.validateUserId(userId); 606 NfcPermissions.enforceUserPermissions(mContext); 607 if (!isServiceRegistered(userId, service)) { 608 return false; 609 } 610 return mAidCache.isDefaultServiceForAid(userId, service, aid); 611 } 612 613 @Override setDefaultServiceForCategory(int userId, ComponentName service, String category)614 public boolean setDefaultServiceForCategory(int userId, 615 ComponentName service, String category) throws RemoteException { 616 NfcPermissions.validateUserId(userId); 617 NfcPermissions.enforceAdminPermissions(mContext); 618 if (!isServiceRegistered(userId, service)) { 619 return false; 620 } 621 return setDefaultServiceForCategoryChecked(userId, service, category); 622 } 623 624 @Override setDefaultForNextTap(int userId, ComponentName service)625 public boolean setDefaultForNextTap(int userId, ComponentName service) 626 throws RemoteException { 627 NfcPermissions.validateProfileId(mContext, userId); 628 NfcPermissions.enforceAdminPermissions(mContext); 629 if (service != null && !isServiceRegistered(userId, service)) { 630 return false; 631 } 632 return mPreferredServices.setDefaultForNextTap(userId, service); 633 } 634 635 @Override setShouldDefaultToObserveModeForService(int userId, ComponentName service, boolean enable)636 public boolean setShouldDefaultToObserveModeForService(int userId, 637 ComponentName service, boolean enable) { 638 NfcPermissions.validateUserId(userId); 639 NfcPermissions.enforceUserPermissions(mContext); 640 if (!isServiceRegistered(userId, service)) { 641 return false; 642 } 643 Log.d(TAG, "Set should default to observe mode for service (" + service + ") to " 644 + enable); 645 boolean currentStatus = mServiceCache.doesServiceShouldDefaultToObserveMode(userId, 646 service); 647 648 if (currentStatus != enable) { 649 if (!mServiceCache.setShouldDefaultToObserveModeForService(userId, 650 Binder.getCallingUid(), service, enable)) { 651 return false; 652 } 653 updateForShouldDefaultToObserveMode(userId); 654 } 655 return true; 656 } 657 658 @Override registerAidGroupForService(int userId, ComponentName service, AidGroup aidGroup)659 public boolean registerAidGroupForService(int userId, 660 ComponentName service, AidGroup aidGroup) throws RemoteException { 661 NfcPermissions.validateUserId(userId); 662 NfcPermissions.enforceUserPermissions(mContext); 663 if (!isServiceRegistered(userId, service)) { 664 Log.e(TAG, "service ("+ service + ") isn't registered for user " + userId); 665 return false; 666 } 667 if (!mServiceCache.registerAidGroupForService(userId, Binder.getCallingUid(), service, 668 aidGroup)) { 669 return false; 670 } 671 NfcService.getInstance().onPreferredPaymentChanged( 672 NfcAdapter.PREFERRED_PAYMENT_UPDATED); 673 return true; 674 } 675 676 @Override 677 @FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP) registerPollingLoopFilterForService(int userId, ComponentName service, String pollingLoopFilter, boolean autoTransact)678 public boolean registerPollingLoopFilterForService(int userId, ComponentName service, 679 String pollingLoopFilter, boolean autoTransact) throws RemoteException { 680 NfcPermissions.validateUserId(userId); 681 NfcPermissions.enforceUserPermissions(mContext); 682 if (!isServiceRegistered(userId, service)) { 683 Log.e(TAG, "service ("+ service + ") isn't registered for user " + userId); 684 return false; 685 } 686 return mServiceCache.registerPollingLoopFilterForService(userId, Binder.getCallingUid(), 687 service, pollingLoopFilter, autoTransact); 688 } 689 690 @Override 691 @FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP) removePollingLoopFilterForService(int userId, ComponentName service, String pollingLoopFilter)692 public boolean removePollingLoopFilterForService(int userId, ComponentName service, 693 String pollingLoopFilter) throws RemoteException { 694 NfcPermissions.validateUserId(userId); 695 NfcPermissions.enforceUserPermissions(mContext); 696 if (!isServiceRegistered(userId, service)) { 697 Log.e(TAG, "service ("+ service + ") isn't registered for user " + userId); 698 return false; 699 } 700 return mServiceCache.removePollingLoopFilterForService(userId, Binder.getCallingUid(), 701 service, pollingLoopFilter); 702 } 703 704 @Override 705 @FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP) registerPollingLoopPatternFilterForService(int userId, ComponentName service, String pollingLoopPatternFilter, boolean autoTransact)706 public boolean registerPollingLoopPatternFilterForService(int userId, ComponentName service, 707 String pollingLoopPatternFilter, boolean autoTransact) throws RemoteException { 708 NfcPermissions.validateUserId(userId); 709 NfcPermissions.enforceUserPermissions(mContext); 710 if (!isServiceRegistered(userId, service)) { 711 Log.e(TAG, "service ("+ service + ") isn't registed for user " + userId); 712 return false; 713 } 714 return mServiceCache.registerPollingLoopPatternFilterForService(userId, 715 Binder.getCallingUid(), service, pollingLoopPatternFilter, autoTransact); 716 } 717 718 @Override 719 @FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP) removePollingLoopPatternFilterForService(int userId, ComponentName service, String pollingLoopPatternFilter)720 public boolean removePollingLoopPatternFilterForService(int userId, ComponentName service, 721 String pollingLoopPatternFilter) throws RemoteException { 722 NfcPermissions.validateUserId(userId); 723 NfcPermissions.enforceUserPermissions(mContext); 724 if (!isServiceRegistered(userId, service)) { 725 Log.e(TAG, "service ("+ service + ") isn't registed for user " + userId); 726 return false; 727 } 728 return mServiceCache.removePollingLoopPatternFilterForService(userId, 729 Binder.getCallingUid(), service, pollingLoopPatternFilter); 730 } 731 732 @Override setOffHostForService(int userId, ComponentName service, String offHostSE)733 public boolean setOffHostForService(int userId, ComponentName service, String offHostSE) { 734 NfcPermissions.validateUserId(userId); 735 NfcPermissions.enforceUserPermissions(mContext); 736 if (!isServiceRegistered(userId, service)) { 737 return false; 738 } 739 if (!mServiceCache.setOffHostSecureElement(userId, Binder.getCallingUid(), service, 740 offHostSE)) { 741 return false; 742 } 743 NfcService.getInstance().onPreferredPaymentChanged( 744 NfcAdapter.PREFERRED_PAYMENT_UPDATED); 745 return true; 746 } 747 748 @Override unsetOffHostForService(int userId, ComponentName service)749 public boolean unsetOffHostForService(int userId, ComponentName service) { 750 NfcPermissions.validateUserId(userId); 751 NfcPermissions.enforceUserPermissions(mContext); 752 if (!isServiceRegistered(userId, service)) { 753 return false; 754 } 755 if (!mServiceCache.resetOffHostSecureElement(userId, Binder.getCallingUid(), service)) { 756 return false; 757 } 758 NfcService.getInstance().onPreferredPaymentChanged( 759 NfcAdapter.PREFERRED_PAYMENT_UPDATED); 760 return true; 761 } 762 763 @Override getAidGroupForService(int userId, ComponentName service, String category)764 public AidGroup getAidGroupForService(int userId, 765 ComponentName service, String category) throws RemoteException { 766 NfcPermissions.validateUserId(userId); 767 NfcPermissions.enforceUserPermissions(mContext); 768 if (!isServiceRegistered(userId, service)) { 769 return null; 770 } 771 return mServiceCache.getAidGroupForService(userId, Binder.getCallingUid(), service, 772 category); 773 } 774 775 @Override removeAidGroupForService(int userId, ComponentName service, String category)776 public boolean removeAidGroupForService(int userId, 777 ComponentName service, String category) throws RemoteException { 778 NfcPermissions.validateUserId(userId); 779 NfcPermissions.enforceUserPermissions(mContext); 780 if (!isServiceRegistered(userId, service)) { 781 return false; 782 } 783 if (!mServiceCache.removeAidGroupForService(userId, Binder.getCallingUid(), service, 784 category)) { 785 return false; 786 } 787 NfcService.getInstance().onPreferredPaymentChanged( 788 NfcAdapter.PREFERRED_PAYMENT_UPDATED); 789 return true; 790 } 791 792 @Override getServices(int userId, String category)793 public List<ApduServiceInfo> getServices(int userId, String category) 794 throws RemoteException { 795 NfcPermissions.validateProfileId(mContext, userId); 796 NfcPermissions.enforceAdminPermissions(mContext); 797 return mServiceCache.getServicesForCategory(userId, category); 798 } 799 800 @Override setPreferredService(ComponentName service)801 public boolean setPreferredService(ComponentName service) 802 throws RemoteException { 803 NfcPermissions.enforceUserPermissions(mContext); 804 if (!isServiceRegistered( UserHandle.getUserHandleForUid( 805 Binder.getCallingUid()).getIdentifier(), service)) { 806 Log.e(TAG, "setPreferredService: unknown component."); 807 return false; 808 } 809 return mPreferredServices.registerPreferredForegroundService(service, 810 Binder.getCallingUid()); 811 } 812 813 @Override unsetPreferredService()814 public boolean unsetPreferredService() throws RemoteException { 815 NfcPermissions.enforceUserPermissions(mContext); 816 return mPreferredServices.unregisteredPreferredForegroundService( 817 Binder.getCallingUid()); 818 } 819 820 @Override supportsAidPrefixRegistration()821 public boolean supportsAidPrefixRegistration() throws RemoteException { 822 return mAidCache.supportsAidPrefixRegistration(); 823 } 824 825 @Override getPreferredPaymentService(int userId)826 public ApduServiceInfo getPreferredPaymentService(int userId) throws RemoteException { 827 NfcPermissions.validateUserId(userId); 828 NfcPermissions.enforceUserPermissions(mContext); 829 NfcPermissions.enforcePreferredPaymentInfoPermissions(mContext); 830 return mServiceCache.getService(userId, mAidCache.getPreferredService().second); 831 } 832 833 @Override setServiceEnabledForCategoryOther(int userId, ComponentName app, boolean status)834 public boolean setServiceEnabledForCategoryOther(int userId, 835 ComponentName app, boolean status) throws RemoteException { 836 if (!mContext.getResources().getBoolean(R.bool.enable_service_for_category_other)) 837 return false; 838 NfcPermissions.enforceUserPermissions(mContext); 839 840 return mServiceCache.registerOtherForService(userId, app, status); 841 } 842 843 @Override isDefaultPaymentRegistered()844 public boolean isDefaultPaymentRegistered() throws RemoteException { 845 if (mWalletRoleObserver.isWalletRoleFeatureEnabled()) { 846 int callingUserId = Binder.getCallingUserHandle().getIdentifier(); 847 return mWalletRoleObserver 848 .getDefaultWalletRoleHolder(callingUserId) != null; 849 } 850 String defaultComponent = Settings.Secure.getString(mContext.getContentResolver(), 851 Constants.SETTINGS_SECURE_NFC_PAYMENT_DEFAULT_COMPONENT); 852 return defaultComponent != null ? true : false; 853 } 854 855 @Override overrideRoutingTable(int userHandle, String protocol, String technology)856 public boolean overrideRoutingTable(int userHandle, String protocol, String technology) { 857 Log.d(TAG, "overrideRoutingTable. userHandle " + userHandle + ", protocol " + protocol + 858 ", technology " + technology); 859 860 int callingUid = Binder.getCallingUid(); 861 if (!mForegroundUtils 862 .registerUidToBackgroundCallback(mForegroundCallback, callingUid)) { 863 Log.e(TAG, "overrideRoutingTable: Caller is not in foreground."); 864 return false; 865 } 866 mForegroundUid = callingUid; 867 868 int protocolRoute = getRouteForSecureElement(protocol); 869 int technologyRoute = getRouteForSecureElement(technology); 870 if (DBG) Log.d(TAG, "protocolRoute " + protocolRoute + 871 ", technologyRoute " + technologyRoute); 872 873 // mRoutingOptionManager.overrideDefaultRoute(protocolRoute); 874 mRoutingOptionManager.overrideDefaultIsoDepRoute(protocolRoute); 875 mRoutingOptionManager.overrideDefaultOffHostRoute(technologyRoute); 876 mAidCache.onRoutingOverridedOrRecovered(); 877 // NfcService.getInstance().commitRouting(); 878 879 return true; 880 } 881 882 @Override recoverRoutingTable(int userHandle)883 public boolean recoverRoutingTable(int userHandle) { 884 Log.d(TAG, "recoverRoutingTable. userHandle " + userHandle); 885 886 if (!mForegroundUtils.isInForeground(Binder.getCallingUid())) { 887 if (DBG) Log.d(TAG, "recoverRoutingTable : not in foreground."); 888 return false; 889 } 890 mForegroundUid = Process.INVALID_UID; 891 892 mRoutingOptionManager.recoverOverridedRoutingTable(); 893 mAidCache.onRoutingOverridedOrRecovered(); 894 // NfcService.getInstance().commitRouting(); 895 896 return true; 897 } 898 } 899 900 final ForegroundUtils.Callback mForegroundCallback = new ForegroundCallbackImpl(); 901 902 class ForegroundCallbackImpl implements ForegroundUtils.Callback { 903 @Override onUidToBackground(int uid)904 public void onUidToBackground(int uid) { 905 synchronized (CardEmulationManager.this) { 906 if (mForegroundUid == uid) { 907 if (DBG) Log.d(TAG, "Uid " + uid + " switch to background."); 908 mForegroundUid = Process.INVALID_UID; 909 mRoutingOptionManager.recoverOverridedRoutingTable(); 910 } 911 } 912 } 913 } 914 getRouteForSecureElement(String se)915 private int getRouteForSecureElement(String se) { 916 String route = se; 917 if (route == null) { 918 return -1; 919 } 920 921 if (route.equals("DH")) { 922 return 0; 923 } 924 925 if (route.length() == 3) { 926 route = route + '1'; 927 } 928 929 try { 930 if (route.startsWith("eSE") && mOffHostRouteEse != null) { 931 int index = Integer.parseInt(route.substring(3)); 932 if (mOffHostRouteEse.length >= index && index > 0) { 933 return mOffHostRouteEse[index - 1] & 0xFF; 934 } 935 } else if (route.startsWith("SIM") && mOffHostRouteUicc != null) { 936 int index = Integer.parseInt(route.substring(3)); 937 if (mOffHostRouteUicc.length >= index && index > 0) { 938 return mOffHostRouteUicc[index - 1] & 0xFF; 939 } 940 } 941 if (mOffHostRouteEse == null && mOffHostRouteUicc == null) 942 return -1; 943 } catch (NumberFormatException ignored) { } 944 945 return 0; 946 } 947 948 /** 949 * This class implements the application-facing APIs and are called 950 * from binder. All calls must be permission-checked. 951 */ 952 final class NfcFCardEmulationInterface extends INfcFCardEmulation.Stub { 953 @Override getSystemCodeForService(int userId, ComponentName service)954 public String getSystemCodeForService(int userId, ComponentName service) 955 throws RemoteException { 956 NfcPermissions.validateUserId(userId); 957 NfcPermissions.enforceUserPermissions(mContext); 958 if (!isNfcFServiceInstalled(userId, service)) { 959 return null; 960 } 961 return mNfcFServicesCache.getSystemCodeForService( 962 userId, Binder.getCallingUid(), service); 963 } 964 965 @Override registerSystemCodeForService(int userId, ComponentName service, String systemCode)966 public boolean registerSystemCodeForService(int userId, ComponentName service, 967 String systemCode) 968 throws RemoteException { 969 NfcPermissions.validateUserId(userId); 970 NfcPermissions.enforceUserPermissions(mContext); 971 if (!isNfcFServiceInstalled(userId, service)) { 972 return false; 973 } 974 return mNfcFServicesCache.registerSystemCodeForService( 975 userId, Binder.getCallingUid(), service, systemCode); 976 } 977 978 @Override removeSystemCodeForService(int userId, ComponentName service)979 public boolean removeSystemCodeForService(int userId, ComponentName service) 980 throws RemoteException { 981 NfcPermissions.validateUserId(userId); 982 NfcPermissions.enforceUserPermissions(mContext); 983 if (!isNfcFServiceInstalled(userId, service)) { 984 return false; 985 } 986 return mNfcFServicesCache.removeSystemCodeForService( 987 userId, Binder.getCallingUid(), service); 988 } 989 990 @Override getNfcid2ForService(int userId, ComponentName service)991 public String getNfcid2ForService(int userId, ComponentName service) 992 throws RemoteException { 993 NfcPermissions.validateUserId(userId); 994 NfcPermissions.enforceUserPermissions(mContext); 995 if (!isNfcFServiceInstalled(userId, service)) { 996 return null; 997 } 998 return mNfcFServicesCache.getNfcid2ForService( 999 userId, Binder.getCallingUid(), service); 1000 } 1001 1002 @Override setNfcid2ForService(int userId, ComponentName service, String nfcid2)1003 public boolean setNfcid2ForService(int userId, 1004 ComponentName service, String nfcid2) throws RemoteException { 1005 NfcPermissions.validateUserId(userId); 1006 NfcPermissions.enforceUserPermissions(mContext); 1007 if (!isNfcFServiceInstalled(userId, service)) { 1008 return false; 1009 } 1010 return mNfcFServicesCache.setNfcid2ForService( 1011 userId, Binder.getCallingUid(), service, nfcid2); 1012 } 1013 1014 @Override enableNfcFForegroundService(ComponentName service)1015 public boolean enableNfcFForegroundService(ComponentName service) 1016 throws RemoteException { 1017 NfcPermissions.enforceUserPermissions(mContext); 1018 if (isNfcFServiceInstalled(UserHandle.getUserHandleForUid( 1019 Binder.getCallingUid()).getIdentifier(), service)) { 1020 return mEnabledNfcFServices.registerEnabledForegroundService(service, 1021 Binder.getCallingUid()); 1022 } 1023 return false; 1024 } 1025 1026 @Override disableNfcFForegroundService()1027 public boolean disableNfcFForegroundService() throws RemoteException { 1028 NfcPermissions.enforceUserPermissions(mContext); 1029 return mEnabledNfcFServices.unregisteredEnabledForegroundService( 1030 Binder.getCallingUid()); 1031 } 1032 1033 @Override getNfcFServices(int userId)1034 public List<NfcFServiceInfo> getNfcFServices(int userId) 1035 throws RemoteException { 1036 NfcPermissions.validateProfileId(mContext, userId); 1037 NfcPermissions.enforceUserPermissions(mContext); 1038 return mNfcFServicesCache.getServices(userId); 1039 } 1040 1041 @Override getMaxNumOfRegisterableSystemCodes()1042 public int getMaxNumOfRegisterableSystemCodes() 1043 throws RemoteException { 1044 NfcPermissions.enforceUserPermissions(mContext); 1045 return NfcService.getInstance().getLfT3tMax(); 1046 } 1047 } 1048 1049 @Override onPreferredPaymentServiceChanged(int userId, ComponentName service)1050 public void onPreferredPaymentServiceChanged(int userId, ComponentName service) { 1051 Log.i(TAG, "onPreferredPaymentServiceChanged"); 1052 ComponentName oldPreferredService = mAidCache.getPreferredService().second; 1053 mAidCache.onPreferredPaymentServiceChanged(userId, service); 1054 mHostEmulationManager.onPreferredPaymentServiceChanged(userId, service); 1055 ComponentName newPreferredService = mAidCache.getPreferredService().second; 1056 1057 NfcService.getInstance().onPreferredPaymentChanged( 1058 NfcAdapter.PREFERRED_PAYMENT_CHANGED); 1059 if (!Objects.equals(oldPreferredService, newPreferredService)) { 1060 updateForShouldDefaultToObserveMode(userId); 1061 } 1062 } 1063 1064 @Override onPreferredForegroundServiceChanged(int userId, ComponentName service)1065 public void onPreferredForegroundServiceChanged(int userId, ComponentName service) { 1066 Log.i(TAG, "onPreferredForegroundServiceChanged"); 1067 ComponentName oldPreferredService = mAidCache.getPreferredService().second; 1068 mAidCache.onPreferredForegroundServiceChanged(userId, service); 1069 mHostEmulationManager.onPreferredForegroundServiceChanged(userId, service); 1070 ComponentName newPreferredService = mAidCache.getPreferredService().second; 1071 1072 NfcService.getInstance().onPreferredPaymentChanged( 1073 NfcAdapter.PREFERRED_PAYMENT_CHANGED); 1074 if (!Objects.equals(oldPreferredService, newPreferredService)) { 1075 updateForShouldDefaultToObserveMode(userId); 1076 } 1077 } 1078 updateForShouldDefaultToObserveMode(int userId)1079 public void updateForShouldDefaultToObserveMode(int userId) { 1080 long token = Binder.clearCallingIdentity(); 1081 try { 1082 if (!android.nfc.Flags.nfcObserveMode()) { 1083 Log.d(TAG, "observe mode isn't enabled"); 1084 return; 1085 } 1086 1087 NfcAdapter adapter = NfcAdapter.getDefaultAdapter(mContext); 1088 if (adapter == null) { 1089 Log.e(TAG, "adapter is null, returning"); 1090 return; 1091 } 1092 ComponentName preferredService = mAidCache.getPreferredService().second; 1093 boolean enableObserveMode = mServiceCache.doesServiceShouldDefaultToObserveMode(userId, 1094 preferredService); 1095 mHostEmulationManager.updateForShouldDefaultToObserveMode(enableObserveMode); 1096 } finally { 1097 Binder.restoreCallingIdentity(token); 1098 } 1099 } 1100 onObserveModeStateChange(boolean enabled)1101 public void onObserveModeStateChange(boolean enabled) { 1102 mHostEmulationManager.onObserveModeStateChange(enabled); 1103 } 1104 1105 @Override onWalletRoleHolderChanged(String holder, int userId)1106 public void onWalletRoleHolderChanged(String holder, int userId) { 1107 mPreferredServices.onWalletRoleHolderChanged(holder, userId); 1108 mAidCache.onWalletRoleHolderChanged(holder, userId); 1109 } 1110 1111 @Override onEnabledForegroundNfcFServiceChanged(int userId, ComponentName service)1112 public void onEnabledForegroundNfcFServiceChanged(int userId, ComponentName service) { 1113 mT3tIdentifiersCache.onEnabledForegroundNfcFServiceChanged(userId, service); 1114 mHostNfcFEmulationManager.onEnabledForegroundNfcFServiceChanged(userId, service); 1115 } 1116 getRegisteredAidCategory(String aid)1117 public String getRegisteredAidCategory(String aid) { 1118 RegisteredAidCache.AidResolveInfo resolvedInfo = mAidCache.resolveAid(aid); 1119 if (resolvedInfo != null) { 1120 return resolvedInfo.getCategory(); 1121 } 1122 return ""; 1123 } 1124 isRequiresScreenOnServiceExist()1125 public boolean isRequiresScreenOnServiceExist() { 1126 return mAidCache.isRequiresScreenOnServiceExist(); 1127 } 1128 isPreferredServicePackageNameForUser(String packageName, int userId)1129 public boolean isPreferredServicePackageNameForUser(String packageName, int userId) { 1130 return mAidCache.isPreferredServicePackageNameForUser(packageName, userId); 1131 } 1132 isHostCardEmulationActivated()1133 public boolean isHostCardEmulationActivated() { 1134 return mHostEmulationManager.isHostCardEmulationActivated(); 1135 } 1136 } 1137