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 static android.content.pm.PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION; 19 import static android.nfc.cardemulation.CardEmulation.SET_SERVICE_ENABLED_STATUS_FAILURE_FEATURE_UNSUPPORTED; 20 21 import android.annotation.NonNull; 22 import android.annotation.Nullable; 23 import android.app.ActivityManager; 24 import android.app.role.RoleManager; 25 import android.content.ComponentName; 26 import android.content.Context; 27 import android.content.pm.ApplicationInfo; 28 import android.content.pm.PackageManager; 29 import android.content.pm.PackageManager.NameNotFoundException; 30 import android.nfc.ComponentNameAndUser; 31 import android.nfc.Constants; 32 import android.nfc.INfcCardEmulation; 33 import android.nfc.INfcEventCallback; 34 import android.nfc.INfcFCardEmulation; 35 import android.nfc.INfcOemExtensionCallback; 36 import android.nfc.NfcAdapter; 37 import android.nfc.NfcOemExtension; 38 import android.nfc.PackageAndUser; 39 import android.nfc.cardemulation.AidGroup; 40 import android.nfc.cardemulation.ApduServiceInfo; 41 import android.nfc.cardemulation.CardEmulation; 42 import android.nfc.cardemulation.NfcFServiceInfo; 43 import android.nfc.cardemulation.PollingFrame; 44 import android.os.Binder; 45 import android.os.Build; 46 import android.os.Looper; 47 import android.os.PowerManager; 48 import android.os.Process; 49 import android.os.RemoteCallbackList; 50 import android.os.RemoteException; 51 import android.os.SystemClock; 52 import android.os.SystemProperties; 53 import android.os.UserHandle; 54 import android.os.UserManager; 55 import android.provider.Settings; 56 import android.sysprop.NfcProperties; 57 import android.telephony.SubscriptionInfo; 58 import android.text.TextUtils; 59 import android.util.Log; 60 import android.util.proto.ProtoOutputStream; 61 62 import com.android.internal.annotations.VisibleForTesting; 63 import com.android.nfc.DeviceConfigFacade; 64 import com.android.nfc.ExitFrame; 65 import com.android.nfc.ForegroundUtils; 66 import com.android.nfc.NfcEventLog; 67 import com.android.nfc.NfcInjector; 68 import com.android.nfc.NfcPermissions; 69 import com.android.nfc.NfcService; 70 import com.android.nfc.R; 71 import com.android.nfc.cardemulation.util.StatsdUtils; 72 import com.android.nfc.cardemulation.util.TelephonyUtils; 73 import com.android.nfc.flags.Flags; 74 import com.android.nfc.proto.NfcEventProto; 75 76 import java.io.FileDescriptor; 77 import java.io.PrintWriter; 78 import java.util.ArrayList; 79 import java.util.Arrays; 80 import java.util.List; 81 import java.util.Objects; 82 import java.util.Optional; 83 import java.util.function.Consumer; 84 import java.util.function.Function; 85 import java.util.function.Supplier; 86 import java.util.regex.Pattern; 87 import java.util.stream.Collectors; 88 import java.util.stream.IntStream; 89 import java.util.stream.Stream; 90 91 /** 92 * CardEmulationManager is the central entity 93 * responsible for delegating to individual components 94 * implementing card emulation: 95 * - RegisteredServicesCache keeping track of HCE and SE services on the device 96 * - RegisteredNfcFServicesCache keeping track of HCE-F services on the device 97 * - RegisteredAidCache keeping track of AIDs registered by those services and manages 98 * the routing table in the NFCC. 99 * - RegisteredT3tIdentifiersCache keeping track of T3T Identifier registered by 100 * those services and manages the routing table in the NFCC. 101 * - HostEmulationManager handles incoming APDUs for the host and forwards to HCE 102 * services as necessary. 103 * - HostNfcFEmulationManager handles incoming NFC-F packets for the host and 104 * forwards to HCE-F services as necessary. 105 */ 106 public class CardEmulationManager implements RegisteredServicesCache.Callback, 107 RegisteredNfcFServicesCache.Callback, PreferredServices.Callback, 108 EnabledNfcFServices.Callback, WalletRoleObserver.Callback, 109 PreferredSubscriptionService.Callback, 110 HostEmulationManager.NfcAidRoutingListener { 111 static final String TAG = "CardEmulationManager"; 112 static final boolean DBG = NfcProperties.debug_enabled().orElse(true); 113 114 static final int NFC_HCE_APDU = 0x01; 115 static final int NFC_HCE_NFCF = 0x04; 116 /** Minimum AID length as per ISO7816 */ 117 static final int MINIMUM_AID_LENGTH = 5; 118 /** Length of Select APDU header including length byte */ 119 static final int SELECT_APDU_HDR_LENGTH = 5; 120 /** Length of the NDEF Tag application AID */ 121 static final int NDEF_AID_LENGTH = 7; 122 /** AID of the NDEF Tag application Mapping Version 1.0 */ 123 static final byte[] NDEF_AID_V1 = 124 new byte[] {(byte) 0xd2, 0x76, 0x00, 0x00, (byte) 0x85, 0x01, 0x00}; 125 /** AID of the NDEF Tag application Mapping Version 2.0 */ 126 static final byte[] NDEF_AID_V2 = 127 new byte[] {(byte) 0xd2, 0x76, 0x00, 0x00, (byte) 0x85, 0x01, 0x01}; 128 /** Select APDU header */ 129 static final byte[] SELECT_AID_HDR = new byte[] {0x00, (byte) 0xa4, 0x04, 0x00}; 130 private static final int FIRMWARE_EXIT_FRAME_TIMEOUT_MS = 5000; 131 132 final RegisteredAidCache mAidCache; 133 final RegisteredT3tIdentifiersCache mT3tIdentifiersCache; 134 final RegisteredServicesCache mServiceCache; 135 final RegisteredNfcFServicesCache mNfcFServicesCache; 136 final HostEmulationManager mHostEmulationManager; 137 final HostNfcFEmulationManager mHostNfcFEmulationManager; 138 final PreferredServices mPreferredServices; 139 140 final WalletRoleObserver mWalletRoleObserver; 141 final EnabledNfcFServices mEnabledNfcFServices; 142 final Context mContext; 143 final CardEmulationInterface mCardEmulationInterface; 144 final NfcFCardEmulationInterface mNfcFCardEmulationInterface; 145 final PowerManager mPowerManager; 146 boolean mNotSkipAid; 147 148 final ForegroundUtils mForegroundUtils; 149 private int mForegroundUid; 150 151 private final RoutingOptionManager mRoutingOptionManager; 152 final byte[] mOffHostRouteUicc; 153 final byte[] mOffHostRouteEse; 154 private INfcOemExtensionCallback mNfcOemExtensionCallback; 155 private final NfcEventLog mNfcEventLog; 156 private final int mVendorApiLevel; 157 private PreferredSubscriptionService mPreferredSubscriptionService = null; 158 private TelephonyUtils mTelephonyUtils = null; 159 @Nullable 160 private final StatsdUtils mStatsdUtils; 161 private final DeviceConfigFacade mDeviceConfigFacade; 162 private final NfcInjector mNfcInjector; 163 164 // TODO: Move this object instantiation and dependencies to NfcInjector. CardEmulationManager(Context context, NfcInjector nfcInjector, DeviceConfigFacade deviceConfigFacade)165 public CardEmulationManager(Context context, NfcInjector nfcInjector, 166 DeviceConfigFacade deviceConfigFacade) { 167 mContext = context; 168 mNfcInjector = nfcInjector; 169 mCardEmulationInterface = new CardEmulationInterface(); 170 mNfcFCardEmulationInterface = new NfcFCardEmulationInterface(); 171 mForegroundUtils = ForegroundUtils.getInstance( 172 context.getSystemService(ActivityManager.class)); 173 mWalletRoleObserver = new WalletRoleObserver(context, 174 context.getSystemService(RoleManager.class), this, nfcInjector); 175 176 mRoutingOptionManager = RoutingOptionManager.getInstance(); 177 mOffHostRouteEse = mRoutingOptionManager.getOffHostRouteEse(); 178 mOffHostRouteUicc = mRoutingOptionManager.getOffHostRouteUicc(); 179 mRoutingOptionManager.readRoutingOptionsFromPrefs(mContext, deviceConfigFacade); 180 181 mTelephonyUtils = TelephonyUtils.getInstance(mContext); 182 mTelephonyUtils.setMepMode(mRoutingOptionManager.getMepMode()); 183 184 mAidCache = new RegisteredAidCache(context, mWalletRoleObserver); 185 mT3tIdentifiersCache = new RegisteredT3tIdentifiersCache(context); 186 mHostEmulationManager = 187 new HostEmulationManager(context, Looper.getMainLooper(), mAidCache, nfcInjector); 188 mHostNfcFEmulationManager = new HostNfcFEmulationManager(context, mT3tIdentifiersCache); 189 mServiceCache = new RegisteredServicesCache(context, this); 190 mNfcFServicesCache = new RegisteredNfcFServicesCache(context, this); 191 mPreferredServices = new PreferredServices(context, mServiceCache, mAidCache, 192 mWalletRoleObserver, this); 193 mEnabledNfcFServices = new EnabledNfcFServices( 194 context, mNfcFServicesCache, mT3tIdentifiersCache, this); 195 mPowerManager = context.getSystemService(PowerManager.class); 196 mNfcEventLog = nfcInjector.getNfcEventLog(); 197 mVendorApiLevel = SystemProperties.getInt( 198 "ro.vendor.api_level", Build.VERSION.DEVICE_INITIAL_SDK_INT); 199 mPreferredSubscriptionService = new PreferredSubscriptionService(mContext, this); 200 mStatsdUtils = nfcInjector.getStatsdUtils(); 201 mDeviceConfigFacade = deviceConfigFacade; 202 initialize(); 203 } 204 205 @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, NfcEventLog nfcEventLog, PreferredSubscriptionService preferredSubscriptionService, StatsdUtils statsdUtils, DeviceConfigFacade deviceConfigFacade, NfcInjector nfcInjector)206 CardEmulationManager(Context context, 207 ForegroundUtils foregroundUtils, 208 WalletRoleObserver walletRoleObserver, 209 RegisteredAidCache registeredAidCache, 210 RegisteredT3tIdentifiersCache registeredT3tIdentifiersCache, 211 HostEmulationManager hostEmulationManager, 212 HostNfcFEmulationManager hostNfcFEmulationManager, 213 RegisteredServicesCache registeredServicesCache, 214 RegisteredNfcFServicesCache registeredNfcFServicesCache, 215 PreferredServices preferredServices, 216 EnabledNfcFServices enabledNfcFServices, 217 RoutingOptionManager routingOptionManager, 218 PowerManager powerManager, 219 NfcEventLog nfcEventLog, 220 PreferredSubscriptionService preferredSubscriptionService, 221 StatsdUtils statsdUtils, 222 DeviceConfigFacade deviceConfigFacade, 223 NfcInjector nfcInjector) { 224 mContext = context; 225 mNfcInjector = nfcInjector; 226 mCardEmulationInterface = new CardEmulationInterface(); 227 mNfcFCardEmulationInterface = new NfcFCardEmulationInterface(); 228 mForegroundUtils = foregroundUtils; 229 mWalletRoleObserver = walletRoleObserver; 230 mAidCache = registeredAidCache; 231 mT3tIdentifiersCache = registeredT3tIdentifiersCache; 232 mHostEmulationManager = hostEmulationManager; 233 mHostNfcFEmulationManager = hostNfcFEmulationManager; 234 mServiceCache = registeredServicesCache; 235 mNfcFServicesCache = registeredNfcFServicesCache; 236 mPreferredServices = preferredServices; 237 mEnabledNfcFServices = enabledNfcFServices; 238 mPowerManager = powerManager; 239 mRoutingOptionManager = routingOptionManager; 240 mOffHostRouteEse = mRoutingOptionManager.getOffHostRouteEse(); 241 mOffHostRouteUicc = mRoutingOptionManager.getOffHostRouteUicc(); 242 mNfcEventLog = nfcEventLog; 243 mVendorApiLevel = SystemProperties.getInt( 244 "ro.vendor.api_level", Build.VERSION.DEVICE_INITIAL_SDK_INT); 245 mPreferredSubscriptionService = preferredSubscriptionService; 246 mStatsdUtils = statsdUtils; 247 mDeviceConfigFacade = deviceConfigFacade; 248 initialize(); 249 } 250 setOemExtension(@ullable INfcOemExtensionCallback nfcOemExtensionCallback)251 public void setOemExtension(@Nullable INfcOemExtensionCallback nfcOemExtensionCallback) { 252 mNfcOemExtensionCallback = nfcOemExtensionCallback; 253 mHostEmulationManager.setOemExtension(mNfcOemExtensionCallback); 254 mAidCache.setOemExtension(nfcOemExtensionCallback); 255 } 256 initialize()257 private void initialize() { 258 if (mPreferredSubscriptionService != null) 259 mPreferredSubscriptionService.initialize(); 260 mServiceCache.initialize(); 261 mNfcFServicesCache.initialize(); 262 mForegroundUid = Process.INVALID_UID; 263 if (mWalletRoleObserver.isWalletRoleFeatureEnabled()) { 264 int currentUser = ActivityManager.getCurrentUser(); 265 PackageAndUser roleHolder = 266 mWalletRoleObserver.getDefaultWalletRoleHolder(currentUser); 267 onWalletRoleHolderChanged(roleHolder.getPackage(), 268 roleHolder.getUserId()); 269 } 270 271 if (android.nfc.Flags.nfcEventListener()) { 272 mHostEmulationManager.setAidRoutingListener(this); 273 } 274 } 275 getNfcCardEmulationInterface()276 public INfcCardEmulation getNfcCardEmulationInterface() { 277 return mCardEmulationInterface; 278 } 279 getNfcFCardEmulationInterface()280 public INfcFCardEmulation getNfcFCardEmulationInterface() { 281 return mNfcFCardEmulationInterface; 282 } 283 onPollingLoopDetected(List<PollingFrame> pollingFrames)284 public void onPollingLoopDetected(List<PollingFrame> pollingFrames) { 285 mHostEmulationManager.onPollingLoopDetected(pollingFrames); 286 } 287 onObserveModeStateChanged(boolean enable)288 public void onObserveModeStateChanged(boolean enable) { 289 mHostEmulationManager.onObserveModeStateChange(enable); 290 } 291 onFieldChangeDetected(boolean fieldOn)292 public void onFieldChangeDetected(boolean fieldOn) { 293 mHostEmulationManager.onFieldChangeDetected(fieldOn); 294 } 295 onHostCardEmulationActivated(int technology)296 public void onHostCardEmulationActivated(int technology) { 297 if (mNfcOemExtensionCallback != null) { 298 try { 299 mNfcOemExtensionCallback.onHceEventReceived(NfcOemExtension.HCE_ACTIVATE); 300 } catch (RemoteException e) { 301 Log.e(TAG, "onHostCardEmulationActivated: failed", e); 302 } 303 } 304 if (mDeviceConfigFacade.getIndicateUserActivityForHce() 305 && mPowerManager != null) { 306 // Use USER_ACTIVITY_FLAG_INDIRECT to applying power hints without resets 307 // the screen timeout 308 mPowerManager.userActivity(SystemClock.uptimeMillis(), 309 PowerManager.USER_ACTIVITY_EVENT_TOUCH, 310 PowerManager.USER_ACTIVITY_FLAG_INDIRECT); 311 } 312 if (technology == NFC_HCE_APDU) { 313 mHostEmulationManager.onHostEmulationActivated(); 314 mPreferredServices.onHostEmulationActivated(); 315 mNotSkipAid = false; 316 } else if (technology == NFC_HCE_NFCF) { 317 mHostNfcFEmulationManager.onHostEmulationActivated(); 318 mNfcFServicesCache.onHostEmulationActivated(); 319 mEnabledNfcFServices.onHostEmulationActivated(); 320 } 321 } 322 onHostCardEmulationData(int technology, byte[] data)323 public void onHostCardEmulationData(int technology, byte[] data) { 324 if (mNfcOemExtensionCallback != null) { 325 try { 326 mNfcOemExtensionCallback.onHceEventReceived(NfcOemExtension.HCE_DATA_TRANSFERRED); 327 } catch (RemoteException e) { 328 Log.e(TAG, "onHostCardEmulationData: failed", e); 329 } 330 } 331 332 if (technology == NFC_HCE_APDU) { 333 mHostEmulationManager.onHostEmulationData(data); 334 } else if (technology == NFC_HCE_NFCF) { 335 mHostNfcFEmulationManager.onHostEmulationData(data); 336 } 337 // Don't trigger userActivity if it's selecting NDEF AID 338 if (mPowerManager != null && !(technology == NFC_HCE_APDU && isSkipAid(data))) { 339 // Caution!! USER_ACTIVITY_EVENT_TOUCH resets the screen timeout 340 mPowerManager.userActivity(SystemClock.uptimeMillis(), 341 PowerManager.USER_ACTIVITY_EVENT_TOUCH, 0); 342 } 343 } 344 onHostCardEmulationDeactivated(int technology)345 public void onHostCardEmulationDeactivated(int technology) { 346 if (technology == NFC_HCE_APDU) { 347 mHostEmulationManager.onHostEmulationDeactivated(); 348 mPreferredServices.onHostEmulationDeactivated(); 349 } else if (technology == NFC_HCE_NFCF) { 350 mHostNfcFEmulationManager.onHostEmulationDeactivated(); 351 mNfcFServicesCache.onHostEmulationDeactivated(); 352 mEnabledNfcFServices.onHostEmulationDeactivated(); 353 } 354 if (mNfcOemExtensionCallback != null) { 355 try { 356 mNfcOemExtensionCallback.onHceEventReceived(NfcOemExtension.HCE_DEACTIVATE); 357 } catch (RemoteException e) { 358 Log.e(TAG, "onHostCardEmulationDeactivated: failed", e); 359 } 360 } 361 } 362 onOffHostAidSelected()363 public void onOffHostAidSelected() { 364 mHostEmulationManager.onOffHostAidSelected(); 365 } 366 onBootCompleted()367 public void onBootCompleted() { 368 mHostEmulationManager.onBootCompleted(); 369 mServiceCache.onBootCompleted(); 370 } 371 onUserSwitched(int userId)372 public void onUserSwitched(int userId) { 373 mWalletRoleObserver.onUserSwitched(userId); 374 // for HCE 375 mServiceCache.onUserSwitched(); 376 mPreferredServices.onUserSwitched(userId); 377 // for HCE-F 378 mHostNfcFEmulationManager.onUserSwitched(); 379 mT3tIdentifiersCache.onUserSwitched(); 380 mEnabledNfcFServices.onUserSwitched(userId); 381 mNfcFServicesCache.onUserSwitched(); 382 } 383 migrateSettingsFilesFromCe(Context ceContext)384 public void migrateSettingsFilesFromCe(Context ceContext) { 385 mServiceCache.migrateSettingsFilesFromCe(ceContext); 386 } 387 onManagedProfileChanged()388 public void onManagedProfileChanged() { 389 // for HCE 390 mServiceCache.onManagedProfileChanged(); 391 // for HCE-F 392 mNfcFServicesCache.onManagedProfileChanged(); 393 } 394 onNfcEnabled()395 public void onNfcEnabled() { 396 // for HCE 397 mAidCache.onNfcEnabled(); 398 // for HCE-F 399 mT3tIdentifiersCache.onNfcEnabled(); 400 } 401 onNfcDisabled()402 public void onNfcDisabled() { 403 // for HCE 404 mAidCache.onNfcDisabled(); 405 // for HCE-F 406 mHostNfcFEmulationManager.onNfcDisabled(); 407 mNfcFServicesCache.onNfcDisabled(); 408 mT3tIdentifiersCache.onNfcDisabled(); 409 mEnabledNfcFServices.onNfcDisabled(); 410 } 411 onTriggerRoutingTableUpdate()412 public void onTriggerRoutingTableUpdate() { 413 if (DBG) Log.d(TAG, "onTriggerRoutingTableUpdate"); 414 mAidCache.onTriggerRoutingTableUpdate(); 415 mT3tIdentifiersCache.onTriggerRoutingTableUpdate(); 416 } 417 dump(FileDescriptor fd, PrintWriter pw, String[] args)418 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 419 mServiceCache.dump(fd, pw, args); 420 mNfcFServicesCache.dump(fd, pw ,args); 421 mPreferredServices.dump(fd, pw, args); 422 mEnabledNfcFServices.dump(fd, pw, args); 423 mAidCache.dump(fd, pw, args); 424 mT3tIdentifiersCache.dump(fd, pw, args); 425 mHostEmulationManager.dump(fd, pw, args); 426 mHostNfcFEmulationManager.dump(fd, pw, args); 427 } 428 429 /** 430 * Dump debugging information as a CardEmulationManagerProto 431 * 432 * Note: 433 * See proto definition in frameworks/base/core/proto/android/nfc/card_emulation.proto 434 * When writing a nested message, must call {@link ProtoOutputStream#start(long)} before and 435 * {@link ProtoOutputStream#end(long)} after. 436 * Never reuse a proto field number. When removing a field, mark it as reserved. 437 */ dumpDebug(ProtoOutputStream proto)438 public void dumpDebug(ProtoOutputStream proto) { 439 long token = proto.start(CardEmulationManagerProto.REGISTERED_SERVICES_CACHE); 440 mServiceCache.dumpDebug(proto); 441 proto.end(token); 442 443 token = proto.start(CardEmulationManagerProto.REGISTERED_NFC_F_SERVICES_CACHE); 444 mNfcFServicesCache.dumpDebug(proto); 445 proto.end(token); 446 447 token = proto.start(CardEmulationManagerProto.PREFERRED_SERVICES); 448 mPreferredServices.dumpDebug(proto); 449 proto.end(token); 450 451 token = proto.start(CardEmulationManagerProto.ENABLED_NFC_F_SERVICES); 452 mEnabledNfcFServices.dumpDebug(proto); 453 proto.end(token); 454 455 token = proto.start(CardEmulationManagerProto.AID_CACHE); 456 mAidCache.dumpDebug(proto); 457 proto.end(token); 458 459 token = proto.start(CardEmulationManagerProto.T3T_IDENTIFIERS_CACHE); 460 mT3tIdentifiersCache.dumpDebug(proto); 461 proto.end(token); 462 463 token = proto.start(CardEmulationManagerProto.HOST_EMULATION_MANAGER); 464 mHostEmulationManager.dumpDebug(proto); 465 proto.end(token); 466 467 token = proto.start(CardEmulationManagerProto.HOST_NFC_F_EMULATION_MANAGER); 468 mHostNfcFEmulationManager.dumpDebug(proto); 469 proto.end(token); 470 } 471 472 @Override onServicesUpdated(int userId, List<ApduServiceInfo> services, boolean validateInstalled)473 public void onServicesUpdated(int userId, List<ApduServiceInfo> services, 474 boolean validateInstalled) { 475 if (!mWalletRoleObserver.isWalletRoleFeatureEnabled()) { 476 // Verify defaults are still the same 477 verifyDefaults(userId, services, validateInstalled); 478 } 479 // Update the AID cache 480 mAidCache.onServicesUpdated(userId, services); 481 // Update the preferred services list 482 mPreferredServices.onServicesUpdated(); 483 mHostEmulationManager.updatePollingLoopFilters(userId, services); 484 if (Flags.exitFrames()) { 485 updateFirmwareExitFramesForWalletRole(userId); 486 } 487 NfcService.getInstance().onPreferredPaymentChanged(NfcAdapter.PREFERRED_PAYMENT_UPDATED); 488 } 489 490 @Override onNfcFServicesUpdated(int userId, List<NfcFServiceInfo> services)491 public void onNfcFServicesUpdated(int userId, List<NfcFServiceInfo> services) { 492 // Update the T3T identifier cache 493 mT3tIdentifiersCache.onServicesUpdated(userId, services); 494 // Update the enabled services list 495 mEnabledNfcFServices.onServicesUpdated(); 496 } 497 onEeListenActivated(boolean isActivated)498 public void onEeListenActivated(boolean isActivated) { 499 if (!isActivated) { 500 Log.d(TAG, "onEeListenActivated: Listen Mode is deactivated, " 501 + "try to recovery routing table"); 502 mPreferredServices.onHostEmulationDeactivated(); 503 } 504 } 505 verifyDefaults(int userId, List<ApduServiceInfo> services, boolean validateInstalled)506 void verifyDefaults(int userId, List<ApduServiceInfo> services, boolean validateInstalled) { 507 UserManager um = mContext.createContextAsUser( 508 UserHandle.of(userId), /*flags=*/0).getSystemService(UserManager.class); 509 List<UserHandle> luh = um.getEnabledProfiles(); 510 511 ComponentName defaultPaymentService = null; 512 int numDefaultPaymentServices = 0; 513 int userIdDefaultPaymentService = userId; 514 515 for (UserHandle uh : luh) { 516 ComponentName paymentService = getDefaultServiceForCategory(uh.getIdentifier(), 517 CardEmulation.CATEGORY_PAYMENT, 518 validateInstalled && (uh.getIdentifier() == userId)); 519 if (DBG) Log.d(TAG, "verifyDefaults: default: " + paymentService + " for user:" + uh); 520 if (paymentService != null) { 521 numDefaultPaymentServices++; 522 defaultPaymentService = paymentService; 523 userIdDefaultPaymentService = uh.getIdentifier(); 524 } 525 } 526 if (numDefaultPaymentServices > 1) { 527 Log.e(TAG, "verifyDefaults: Current default is not aligned across multiple users"); 528 // leave default unset 529 for (UserHandle uh : luh) { 530 setDefaultServiceForCategoryChecked(uh.getIdentifier(), null, 531 CardEmulation.CATEGORY_PAYMENT); 532 } 533 } else { 534 if (DBG) { 535 Log.d(TAG, "verifyDefaults: Current default: " + defaultPaymentService 536 + " for user:" + userIdDefaultPaymentService); 537 } 538 } 539 if (defaultPaymentService == null) { 540 // A payment service may have been removed, leaving only one; 541 // in that case, automatically set that app as default. 542 int numPaymentServices = 0; 543 ComponentName lastFoundPaymentService = null; 544 PackageManager pm; 545 try { 546 pm = mContext.createPackageContextAsUser("android", /*flags=*/0, 547 UserHandle.of(userId)).getPackageManager(); 548 } catch (NameNotFoundException e) { 549 Log.e(TAG, "verifyDefaults: Could not create user package context"); 550 return; 551 } 552 553 for (ApduServiceInfo service : services) { 554 if (service.hasCategory(CardEmulation.CATEGORY_PAYMENT) 555 && wasServicePreInstalled(pm, service.getComponent())) { 556 numPaymentServices++; 557 lastFoundPaymentService = service.getComponent(); 558 } 559 } 560 if (numPaymentServices > 1) { 561 // More than one service left, leave default unset 562 if (DBG) Log.d(TAG, "verifyDefaults: No default set, more than one service left."); 563 setDefaultServiceForCategoryChecked(userId, null, CardEmulation.CATEGORY_PAYMENT); 564 } else if (numPaymentServices == 1) { 565 // Make single found payment service the default 566 if (DBG) { 567 Log.d(TAG, 568 "verifyDefaults: No default set, " + "making single service default."); 569 } 570 setDefaultServiceForCategoryChecked(userId, lastFoundPaymentService, 571 CardEmulation.CATEGORY_PAYMENT); 572 } else { 573 // No payment services left, leave default at null 574 if (DBG) { 575 Log.d(TAG, 576 "verifyDefaults: No default set, " + "last payment service removed."); 577 } 578 setDefaultServiceForCategoryChecked(userId, null, CardEmulation.CATEGORY_PAYMENT); 579 } 580 } 581 } 582 wasServicePreInstalled(PackageManager packageManager, ComponentName service)583 boolean wasServicePreInstalled(PackageManager packageManager, ComponentName service) { 584 try { 585 ApplicationInfo ai = packageManager 586 .getApplicationInfo(service.getPackageName(), /*flags=*/0); 587 if ((ApplicationInfo.FLAG_SYSTEM & ai.flags) != 0) { 588 if (DBG) { 589 Log.d(TAG, 590 "wasServicePreInstalled: Service was " + "pre-installed on the device"); 591 } 592 return true; 593 } 594 } catch (NameNotFoundException e) { 595 Log.e(TAG, "wasServicePreInstalled: Service is not currently " 596 + "installed on the device."); 597 return false; 598 } 599 if (DBG) { 600 Log.d(TAG, "wasServicePreInstalled: Service was not pre-installed on the device"); 601 } 602 return false; 603 } 604 getDefaultServiceForCategory(int userId, String category, boolean validateInstalled)605 ComponentName getDefaultServiceForCategory(int userId, String category, 606 boolean validateInstalled) { 607 if (!CardEmulation.CATEGORY_PAYMENT.equals(category)) { 608 Log.e(TAG, 609 "getDefaultServiceForCategory: Not allowing defaults for category " + category); 610 return null; 611 } 612 // Load current payment default from settings 613 String name = Settings.Secure.getString( 614 mContext.createContextAsUser(UserHandle.of(userId), 0).getContentResolver(), 615 Constants.SETTINGS_SECURE_NFC_PAYMENT_DEFAULT_COMPONENT); 616 if (name != null) { 617 ComponentName service = ComponentName.unflattenFromString(name); 618 if (!validateInstalled || service == null) { 619 return service; 620 } else { 621 return mServiceCache.hasService(userId, service) ? service : null; 622 } 623 } else { 624 return null; 625 } 626 } 627 setDefaultServiceForCategoryChecked(int userId, ComponentName service, String category)628 boolean setDefaultServiceForCategoryChecked(int userId, ComponentName service, 629 String category) { 630 if (!CardEmulation.CATEGORY_PAYMENT.equals(category)) { 631 Log.e(TAG, "setDefaultServiceForCategoryChecked: Not allowing defaults for category " 632 + category); 633 return false; 634 } 635 // TODO Not really nice to be writing to Settings.Secure here... 636 // ideally we overlay our local changes over whatever is in 637 // Settings.Secure 638 if (service == null || mServiceCache.hasService(userId, service)) { 639 Settings.Secure.putString(mContext 640 .createContextAsUser(UserHandle.of(userId), 0).getContentResolver(), 641 Constants.SETTINGS_SECURE_NFC_PAYMENT_DEFAULT_COMPONENT, 642 service != null ? service.flattenToString() : null); 643 } else { 644 Log.e(TAG, 645 "setDefaultServiceForCategoryChecked: Could not find default " 646 + "service to make default: " 647 + service); 648 } 649 return true; 650 } 651 isServiceRegistered(int userId, ComponentName service)652 boolean isServiceRegistered(int userId, ComponentName service) { 653 boolean serviceFound = mServiceCache.hasService(userId, service); 654 if (!serviceFound) { 655 // If we don't know about this service yet, it may have just been enabled 656 // using PackageManager.setComponentEnabledSetting(). The PackageManager 657 // broadcasts are delayed by 10 seconds in that scenario, which causes 658 // calls to our APIs referencing that service to fail. 659 // Hence, update the cache in case we don't know about the service. 660 if (DBG) { 661 Log.d(TAG, "isServiceRegistered: Didn't find passed in service, " 662 + "invalidating cache"); 663 } 664 mServiceCache.invalidateCache(userId, true); 665 } 666 return mServiceCache.hasService(userId, service); 667 } 668 isNfcFServiceInstalled(int userId, ComponentName service)669 boolean isNfcFServiceInstalled(int userId, ComponentName service) { 670 boolean serviceFound = mNfcFServicesCache.hasService(userId, service); 671 if (!serviceFound) { 672 // If we don't know about this service yet, it may have just been enabled 673 // using PackageManager.setComponentEnabledSetting(). The PackageManager 674 // broadcasts are delayed by 10 seconds in that scenario, which causes 675 // calls to our APIs referencing that service to fail. 676 // Hence, update the cache in case we don't know about the service. 677 if (DBG) { 678 Log.d(TAG, 679 "isNfcFServiceInstalled: Didn't find passed in service, " 680 + "invalidating cache"); 681 } 682 mNfcFServicesCache.invalidateCache(userId); 683 } 684 return mNfcFServicesCache.hasService(userId, service); 685 } 686 687 /** 688 * Returns true if it's not selecting NDEF AIDs 689 * It's used to skip userActivity if it only selects NDEF AIDs 690 */ isSkipAid(byte[] data)691 boolean isSkipAid(byte[] data) { 692 if (mNotSkipAid || data == null 693 || data.length < SELECT_APDU_HDR_LENGTH + MINIMUM_AID_LENGTH 694 || !Arrays.equals(SELECT_AID_HDR, 0, SELECT_AID_HDR.length, 695 data, 0, SELECT_AID_HDR.length)) { 696 return false; 697 } 698 int aidLength = Byte.toUnsignedInt(data[SELECT_APDU_HDR_LENGTH - 1]); 699 if (data.length >= SELECT_APDU_HDR_LENGTH + NDEF_AID_LENGTH 700 && aidLength == NDEF_AID_LENGTH) { 701 if (Arrays.equals(data, SELECT_APDU_HDR_LENGTH, 702 SELECT_APDU_HDR_LENGTH + NDEF_AID_LENGTH, 703 NDEF_AID_V1, 0, NDEF_AID_LENGTH)) { 704 if (DBG) Log.d(TAG, "isSkipAid: Skip for NDEF_V1"); 705 return true; 706 } else if (Arrays.equals(data, SELECT_APDU_HDR_LENGTH, 707 SELECT_APDU_HDR_LENGTH + NDEF_AID_LENGTH, 708 NDEF_AID_V2, 0, NDEF_AID_LENGTH)) { 709 if (DBG) Log.d(TAG, "isSkipAid: Skip for NDEF_V2"); 710 return true; 711 } 712 } 713 // The data payload is not selecting the skip AID. 714 mNotSkipAid = true; 715 return false; 716 } 717 718 /** 719 * Returns whether a service in this package is preferred, 720 * either because it's the default payment app or it's running 721 * in the foreground. 722 */ packageHasPreferredService(String packageName)723 public boolean packageHasPreferredService(String packageName) { 724 return mPreferredServices.packageHasPreferredService(packageName); 725 } 726 727 @Override onPreferredSubscriptionChanged(int subscriptionId, boolean isActive)728 public void onPreferredSubscriptionChanged(int subscriptionId, boolean isActive) { 729 int simType = isActive ? getSimTypeById(subscriptionId) : TelephonyUtils.SIM_TYPE_UNKNOWN; 730 Log.i(TAG, "onPreferredSubscriptionChanged: subscription_" + subscriptionId + "is active(" 731 + isActive + ")" 732 + ", type(" + simType + ")"); 733 mRoutingOptionManager.onPreferredSimChanged(simType); 734 if (simType != TelephonyUtils.SIM_TYPE_UNKNOWN) { 735 updateRouteBasedOnPreferredSim(); 736 } 737 else { 738 Log.i(TAG, "onPreferredSubscriptionChanged: SIM is Invalid type"); 739 } 740 mAidCache.onPreferredSimChanged(simType); 741 // try to nfc turned off and on to swp initialize 742 NfcService.getInstance().onPreferredSimChanged(); 743 } 744 updateRouteBasedOnPreferredSim()745 private void updateRouteBasedOnPreferredSim() { 746 boolean changed = false; 747 changed |= updateRouteToPreferredSim(()->mRoutingOptionManager.getDefaultRoute(), 748 route->mRoutingOptionManager.overrideDefaultRoute(route)); 749 changed |= updateRouteToPreferredSim(()->mRoutingOptionManager.getDefaultIsoDepRoute(), 750 route->mRoutingOptionManager.overrideDefaultIsoDepRoute(route)); 751 changed |= updateRouteToPreferredSim(()->mRoutingOptionManager.getDefaultOffHostRoute(), 752 route->mRoutingOptionManager.overrideDefaultOffHostRoute(route)); 753 if (changed) { 754 mRoutingOptionManager.overwriteRoutingTable(); 755 } 756 } updateRouteToPreferredSim(Supplier<Integer> getter, Consumer<Integer> setter)757 private boolean updateRouteToPreferredSim(Supplier<Integer> getter, Consumer<Integer> setter) { 758 String se = mRoutingOptionManager.getSecureElementForRoute(getter.get()); 759 if (se.startsWith(RoutingOptionManager.SE_PREFIX_SIM)) { 760 int route = mRoutingOptionManager.getRouteForSecureElement( 761 mRoutingOptionManager.getPreferredSim()); 762 setter.accept(route); 763 return true; 764 } 765 else { 766 Log.d(TAG, "updateRouteToPreferredSim: ignore"); 767 } 768 return false; 769 } 770 771 /** 772 * This class implements the application-facing APIs and are called 773 * from binder. All calls must be permission-checked. 774 */ 775 final class CardEmulationInterface extends INfcCardEmulation.Stub { 776 @Override isDefaultServiceForCategory(int userId, ComponentName service, String category)777 public boolean isDefaultServiceForCategory(int userId, ComponentName service, 778 String category) { 779 NfcPermissions.enforceUserPermissions(mContext); 780 NfcPermissions.validateUserId(userId); 781 if (!isServiceRegistered(userId, service)) { 782 return false; 783 } 784 if (mWalletRoleObserver.isWalletRoleFeatureEnabled()) { 785 PackageAndUser holder = 786 mWalletRoleObserver.getDefaultWalletRoleHolder(userId); 787 if (holder.getPackage() == null) { 788 return false; 789 } 790 return service.getPackageName().equals( 791 holder.getPackage()) && userId == holder.getUserId(); 792 } 793 ComponentName defaultService = 794 getDefaultServiceForCategory(userId, category, true); 795 return (defaultService != null && defaultService.equals(service)); 796 } 797 798 @Override isDefaultServiceForAid(int userId, ComponentName service, String aid)799 public boolean isDefaultServiceForAid(int userId, 800 ComponentName service, String aid) throws RemoteException { 801 NfcPermissions.validateUserId(userId); 802 NfcPermissions.enforceUserPermissions(mContext); 803 if (!isServiceRegistered(userId, service)) { 804 return false; 805 } 806 return mAidCache.isDefaultServiceForAid(userId, service, aid); 807 } 808 809 @Override setDefaultServiceForCategory(int userId, ComponentName service, String category)810 public boolean setDefaultServiceForCategory(int userId, 811 ComponentName service, String category) throws RemoteException { 812 NfcPermissions.validateUserId(userId); 813 NfcPermissions.enforceAdminPermissions(mContext); 814 if (!isServiceRegistered(userId, service)) { 815 return false; 816 } 817 return setDefaultServiceForCategoryChecked(userId, service, category); 818 } 819 820 @Override setDefaultForNextTap(int userId, ComponentName service)821 public boolean setDefaultForNextTap(int userId, ComponentName service) 822 throws RemoteException { 823 NfcPermissions.validateProfileId(mContext, userId); 824 NfcPermissions.enforceAdminPermissions(mContext); 825 if (service != null && !isServiceRegistered(userId, service)) { 826 return false; 827 } 828 return mPreferredServices.setDefaultForNextTap(userId, service); 829 } 830 831 @Override setShouldDefaultToObserveModeForService(int userId, ComponentName service, boolean enable)832 public boolean setShouldDefaultToObserveModeForService(int userId, 833 ComponentName service, boolean enable) { 834 NfcPermissions.validateUserId(userId); 835 NfcPermissions.enforceUserPermissions(mContext); 836 if (!isServiceRegistered(userId, service)) { 837 return false; 838 } 839 Log.d(TAG, "setShouldDefaultToObserveModeForService: (" + service + ") to " 840 + enable); 841 boolean currentStatus = mServiceCache.doesServiceShouldDefaultToObserveMode(userId, 842 service); 843 844 if (currentStatus != enable) { 845 if (!mServiceCache.setShouldDefaultToObserveModeForService(userId, 846 Binder.getCallingUid(), service, enable)) { 847 return false; 848 } 849 updateForShouldDefaultToObserveMode(userId); 850 } 851 return true; 852 } 853 854 @Override registerAidGroupForService(int userId, ComponentName service, AidGroup aidGroup)855 public boolean registerAidGroupForService(int userId, 856 ComponentName service, AidGroup aidGroup) throws RemoteException { 857 NfcPermissions.validateUserId(userId); 858 NfcPermissions.enforceUserPermissions(mContext); 859 if (!isServiceRegistered(userId, service)) { 860 Log.e(TAG, "registerAidGroupForService: service (" + service 861 + ") isn't registered for user " + userId); 862 return false; 863 } 864 if (!mServiceCache.registerAidGroupForService(userId, Binder.getCallingUid(), service, 865 aidGroup)) { 866 return false; 867 } 868 NfcService.getInstance().onPreferredPaymentChanged( 869 NfcAdapter.PREFERRED_PAYMENT_UPDATED); 870 mNfcEventLog.logEvent( 871 NfcEventProto.EventType.newBuilder() 872 .setAidRegistration(NfcEventProto.NfcAidRegistration.newBuilder() 873 .setAppInfo(NfcEventProto.NfcAppInfo.newBuilder() 874 .setUid(Binder.getCallingUid()) 875 .build()) 876 .setComponentInfo( 877 NfcEventProto.NfcComponentInfo.newBuilder() 878 .setPackageName( 879 service.getPackageName()) 880 .setClassName( 881 service.getClassName()) 882 .build()) 883 .setIsRegistration(true) 884 .addAllAids(aidGroup.getAids()) 885 .build()) 886 .build()); 887 return true; 888 } 889 890 @Override registerPollingLoopFilterForService(int userId, ComponentName service, String pollingLoopFilter, boolean autoTransact)891 public boolean registerPollingLoopFilterForService(int userId, ComponentName service, 892 String pollingLoopFilter, boolean autoTransact) throws RemoteException { 893 NfcPermissions.validateUserId(userId); 894 NfcPermissions.enforceUserPermissions(mContext); 895 if (!isServiceRegistered(userId, service)) { 896 Log.e(TAG, "registerPollingLoopFilterForService: service (" + service 897 + ") isn't registered for user " + userId); 898 return false; 899 } 900 if (!mServiceCache.registerPollingLoopFilterForService(userId, Binder.getCallingUid(), 901 service, pollingLoopFilter, autoTransact)) { 902 return false; 903 } 904 mNfcEventLog.logEvent( 905 NfcEventProto.EventType.newBuilder() 906 .setPollingLoopRegistration(NfcEventProto.NfcPollingLoopRegistration 907 .newBuilder() 908 .setAppInfo(NfcEventProto.NfcAppInfo.newBuilder() 909 .setUid(Binder.getCallingUid()) 910 .build()) 911 .setComponentInfo( 912 NfcEventProto.NfcComponentInfo.newBuilder() 913 .setPackageName( 914 service.getPackageName()) 915 .setClassName( 916 service.getClassName()) 917 .build()) 918 .setIsRegistration(true) 919 .setPollingLoopFilter(pollingLoopFilter) 920 .build()) 921 .build()); 922 return true; 923 } 924 925 @Override removePollingLoopFilterForService(int userId, ComponentName service, String pollingLoopFilter)926 public boolean removePollingLoopFilterForService(int userId, ComponentName service, 927 String pollingLoopFilter) throws RemoteException { 928 NfcPermissions.validateUserId(userId); 929 NfcPermissions.enforceUserPermissions(mContext); 930 if (!isServiceRegistered(userId, service)) { 931 Log.e(TAG, "removePollingLoopFilterForService: service (" + service 932 + ") isn't registered for user " + userId); 933 return false; 934 } 935 if (!mServiceCache.removePollingLoopFilterForService(userId, Binder.getCallingUid(), 936 service, pollingLoopFilter)) { 937 return false; 938 } 939 mNfcEventLog.logEvent( 940 NfcEventProto.EventType.newBuilder() 941 .setPollingLoopRegistration(NfcEventProto.NfcPollingLoopRegistration 942 .newBuilder() 943 .setAppInfo(NfcEventProto.NfcAppInfo.newBuilder() 944 .setUid(Binder.getCallingUid()) 945 .build()) 946 .setComponentInfo( 947 NfcEventProto.NfcComponentInfo.newBuilder() 948 .setPackageName( 949 service.getPackageName()) 950 .setClassName( 951 service.getClassName()) 952 .build()) 953 .setIsRegistration(false) 954 .setPollingLoopFilter(pollingLoopFilter) 955 .build()) 956 .build()); 957 return true; 958 } 959 960 @Override registerPollingLoopPatternFilterForService(int userId, ComponentName service, String pollingLoopPatternFilter, boolean autoTransact)961 public boolean registerPollingLoopPatternFilterForService(int userId, ComponentName service, 962 String pollingLoopPatternFilter, boolean autoTransact) throws RemoteException { 963 NfcPermissions.validateUserId(userId); 964 NfcPermissions.enforceUserPermissions(mContext); 965 if (!isServiceRegistered(userId, service)) { 966 Log.e(TAG, "registerPollingLoopPatternFilterForService: service (" + service 967 + ") isn't registed for user " + userId); 968 return false; 969 } 970 if (!mServiceCache.registerPollingLoopPatternFilterForService(userId, 971 Binder.getCallingUid(), service, pollingLoopPatternFilter, autoTransact)) { 972 return false; 973 } 974 mNfcEventLog.logEvent( 975 NfcEventProto.EventType.newBuilder() 976 .setPollingLoopRegistration(NfcEventProto.NfcPollingLoopRegistration 977 .newBuilder() 978 .setAppInfo(NfcEventProto.NfcAppInfo.newBuilder() 979 .setUid(Binder.getCallingUid()) 980 .build()) 981 .setComponentInfo( 982 NfcEventProto.NfcComponentInfo.newBuilder() 983 .setPackageName( 984 service.getPackageName()) 985 .setClassName( 986 service.getClassName()) 987 .build()) 988 .setIsRegistration(true) 989 .setPollingLoopFilter(pollingLoopPatternFilter) 990 .build()) 991 .build()); 992 return true; 993 } 994 995 @Override removePollingLoopPatternFilterForService(int userId, ComponentName service, String pollingLoopPatternFilter)996 public boolean removePollingLoopPatternFilterForService(int userId, ComponentName service, 997 String pollingLoopPatternFilter) throws RemoteException { 998 NfcPermissions.validateUserId(userId); 999 NfcPermissions.enforceUserPermissions(mContext); 1000 if (!isServiceRegistered(userId, service)) { 1001 Log.e(TAG, "removePollingLoopPatternFilterForService: service (" + service 1002 + ") isn't registed for user " + userId); 1003 return false; 1004 } 1005 if (!mServiceCache.removePollingLoopPatternFilterForService(userId, 1006 Binder.getCallingUid(), service, pollingLoopPatternFilter)) { 1007 return false; 1008 } 1009 mNfcEventLog.logEvent( 1010 NfcEventProto.EventType.newBuilder() 1011 .setPollingLoopRegistration(NfcEventProto.NfcPollingLoopRegistration 1012 .newBuilder() 1013 .setAppInfo(NfcEventProto.NfcAppInfo.newBuilder() 1014 .setUid(Binder.getCallingUid()) 1015 .build()) 1016 .setComponentInfo( 1017 NfcEventProto.NfcComponentInfo.newBuilder() 1018 .setPackageName( 1019 service.getPackageName()) 1020 .setClassName( 1021 service.getClassName()) 1022 .build()) 1023 .setIsRegistration(false) 1024 .setPollingLoopFilter(pollingLoopPatternFilter) 1025 .build()) 1026 .build()); 1027 return true; 1028 } 1029 1030 @Override setOffHostForService(int userId, ComponentName service, String offHostSE)1031 public boolean setOffHostForService(int userId, ComponentName service, String offHostSE) { 1032 NfcPermissions.validateUserId(userId); 1033 NfcPermissions.enforceUserPermissions(mContext); 1034 if (!isServiceRegistered(userId, service)) { 1035 return false; 1036 } 1037 if (!mServiceCache.setOffHostSecureElement(userId, Binder.getCallingUid(), service, 1038 offHostSE)) { 1039 return false; 1040 } 1041 NfcService.getInstance().onPreferredPaymentChanged( 1042 NfcAdapter.PREFERRED_PAYMENT_UPDATED); 1043 return true; 1044 } 1045 1046 @Override unsetOffHostForService(int userId, ComponentName service)1047 public boolean unsetOffHostForService(int userId, ComponentName service) { 1048 NfcPermissions.validateUserId(userId); 1049 NfcPermissions.enforceUserPermissions(mContext); 1050 if (!isServiceRegistered(userId, service)) { 1051 return false; 1052 } 1053 if (!mServiceCache.resetOffHostSecureElement(userId, Binder.getCallingUid(), service)) { 1054 return false; 1055 } 1056 NfcService.getInstance().onPreferredPaymentChanged( 1057 NfcAdapter.PREFERRED_PAYMENT_UPDATED); 1058 return true; 1059 } 1060 1061 @Override getAidGroupForService(int userId, ComponentName service, String category)1062 public AidGroup getAidGroupForService(int userId, 1063 ComponentName service, String category) throws RemoteException { 1064 NfcPermissions.validateUserId(userId); 1065 NfcPermissions.enforceUserPermissions(mContext); 1066 if (!isServiceRegistered(userId, service)) { 1067 return null; 1068 } 1069 return mServiceCache.getAidGroupForService(userId, Binder.getCallingUid(), service, 1070 category); 1071 } 1072 1073 @Override removeAidGroupForService(int userId, ComponentName service, String category)1074 public boolean removeAidGroupForService(int userId, 1075 ComponentName service, String category) throws RemoteException { 1076 NfcPermissions.validateUserId(userId); 1077 NfcPermissions.enforceUserPermissions(mContext); 1078 if (!isServiceRegistered(userId, service)) { 1079 return false; 1080 } 1081 if (!mServiceCache.removeAidGroupForService(userId, Binder.getCallingUid(), service, 1082 category)) { 1083 return false; 1084 } 1085 NfcService.getInstance().onPreferredPaymentChanged( 1086 NfcAdapter.PREFERRED_PAYMENT_UPDATED); 1087 mNfcEventLog.logEvent( 1088 NfcEventProto.EventType.newBuilder() 1089 .setAidRegistration(NfcEventProto.NfcAidRegistration.newBuilder() 1090 .setAppInfo(NfcEventProto.NfcAppInfo.newBuilder() 1091 .setUid(Binder.getCallingUid()) 1092 .build()) 1093 .setComponentInfo( 1094 NfcEventProto.NfcComponentInfo.newBuilder() 1095 .setPackageName( 1096 service.getPackageName()) 1097 .setClassName( 1098 service.getClassName()) 1099 .build()) 1100 .setIsRegistration(false) 1101 .build()) 1102 .build()); 1103 return true; 1104 } 1105 1106 @Override getServices(int userId, String category)1107 public List<ApduServiceInfo> getServices(int userId, String category) 1108 throws RemoteException { 1109 NfcPermissions.validateProfileId(mContext, userId); 1110 NfcPermissions.enforceAdminPermissions(mContext); 1111 return mServiceCache.getServicesForCategory(userId, category); 1112 } 1113 1114 @Override setPreferredService(ComponentName service)1115 public boolean setPreferredService(ComponentName service) 1116 throws RemoteException { 1117 NfcPermissions.enforceUserPermissions(mContext); 1118 if (!isServiceRegistered( UserHandle.getUserHandleForUid( 1119 Binder.getCallingUid()).getIdentifier(), service)) { 1120 Log.e(TAG, "setPreferredService: unknown component"); 1121 return false; 1122 } 1123 return mPreferredServices.registerPreferredForegroundService(service, 1124 Binder.getCallingUid()); 1125 } 1126 1127 @Override unsetPreferredService()1128 public boolean unsetPreferredService() throws RemoteException { 1129 NfcPermissions.enforceUserPermissions(mContext); 1130 return mPreferredServices.unregisteredPreferredForegroundService( 1131 Binder.getCallingUid()); 1132 } 1133 1134 @Override supportsAidPrefixRegistration()1135 public boolean supportsAidPrefixRegistration() throws RemoteException { 1136 return mAidCache.supportsAidPrefixRegistration(); 1137 } 1138 1139 @Override getPreferredPaymentService(int userId)1140 public ApduServiceInfo getPreferredPaymentService(int userId) throws RemoteException { 1141 NfcPermissions.validateUserId(userId); 1142 NfcPermissions.enforceUserPermissions(mContext); 1143 NfcPermissions.enforcePreferredPaymentInfoPermissions(mContext); 1144 return mServiceCache.getService(userId, 1145 mAidCache.getPreferredService().getComponentName()); 1146 } 1147 1148 @Override setServiceEnabledForCategoryOther(int userId, ComponentName app, boolean status)1149 public int setServiceEnabledForCategoryOther(int userId, 1150 ComponentName app, boolean status) throws RemoteException { 1151 if (!mDeviceConfigFacade.getEnableServiceOther()) 1152 return SET_SERVICE_ENABLED_STATUS_FAILURE_FEATURE_UNSUPPORTED; 1153 NfcPermissions.enforceUserPermissions(mContext); 1154 1155 return mServiceCache.registerOtherForService(userId, app, status); 1156 } 1157 1158 @Override isDefaultPaymentRegistered()1159 public boolean isDefaultPaymentRegistered() throws RemoteException { 1160 if (mWalletRoleObserver.isWalletRoleFeatureEnabled()) { 1161 int callingUserId = Binder.getCallingUserHandle().getIdentifier(); 1162 return mWalletRoleObserver.getDefaultWalletRoleHolder( 1163 callingUserId).getPackage() != null; 1164 } 1165 String defaultComponent = Settings.Secure.getString(mContext.getContentResolver(), 1166 Constants.SETTINGS_SECURE_NFC_PAYMENT_DEFAULT_COMPONENT); 1167 return defaultComponent != null ? true : false; 1168 } 1169 1170 @Override overrideRoutingTable(int userHandle, String protocol, String technology, String pkg)1171 public void overrideRoutingTable(int userHandle, String protocol, String technology, 1172 String pkg) { 1173 Log.d(TAG, "overrideRoutingTable: userHandle " + userHandle + ", protocol " + protocol 1174 + ", technology " + technology); 1175 1176 NfcPermissions.enforceAdminPermissions(mContext); 1177 1178 if ((protocol != null && protocol.equals("default")) 1179 || (technology != null && technology.equals("default"))) { 1180 Log.e(TAG, "overrideRoutingTable: override value cannot be set to default"); 1181 throw new IllegalArgumentException("default value is not allowed."); 1182 } 1183 1184 int callingUid = Binder.getCallingUid(); 1185 if (android.nfc.Flags.nfcOverrideRecoverRoutingTable()) { 1186 if (!isPreferredServicePackageNameForUser(pkg, 1187 UserHandle.getUserHandleForUid(callingUid).getIdentifier()) 1188 && !mNfcInjector.isSignedWithPlatformKey(callingUid)) { 1189 Log.e(TAG, "overrideRoutingTable: Caller not preferred NFC service."); 1190 throw new SecurityException("Caller not preferred NFC service"); 1191 } 1192 } 1193 if (!mForegroundUtils 1194 .registerUidToBackgroundCallback(mForegroundCallback, callingUid)) { 1195 Log.e(TAG, "overrideRoutingTable: Caller is not in foreground."); 1196 throw new IllegalArgumentException("Caller is not in foreground."); 1197 } 1198 mForegroundUid = callingUid; 1199 1200 int protocolRoute = getRouteForSecureElement(protocol); 1201 int technologyRoute = getRouteForSecureElement(technology); 1202 if (DBG) { 1203 Log.d(TAG, "overrideRoutingTable: protocolRoute " + protocolRoute 1204 + ", technologyRoute " + technologyRoute); 1205 } 1206 1207 // mRoutingOptionManager.overrideDefaultRoute(protocolRoute); 1208 mRoutingOptionManager.overrideDefaultIsoDepRoute(protocolRoute); 1209 mRoutingOptionManager.overrideDefaultOffHostRoute(technologyRoute); 1210 int result = mAidCache.onRoutingOverridedOrRecovered(); 1211 switch (result) { 1212 case AidRoutingManager.CONFIGURE_ROUTING_SUCCESS: 1213 break; 1214 case AidRoutingManager.CONFIGURE_ROUTING_FAILURE_TABLE_FULL: 1215 throw new IllegalArgumentException("CONFIGURE_ROUTING_FAILURE_TABLE_FULL"); 1216 case AidRoutingManager.CONFIGURE_ROUTING_FAILURE_UNKNOWN: 1217 throw new IllegalArgumentException("CONFIGURE_ROUTING_FAILURE_UNKNOWN"); 1218 } 1219 } 1220 1221 @Override recoverRoutingTable(int userHandle)1222 public void recoverRoutingTable(int userHandle) { 1223 Log.d(TAG, "recoverRoutingTable: userHandle " + userHandle); 1224 1225 NfcPermissions.enforceAdminPermissions(mContext); 1226 1227 if (!mForegroundUtils.isInForeground(Binder.getCallingUid())) { 1228 if (DBG) Log.d(TAG, "recoverRoutingTable : not in foreground."); 1229 throw new IllegalArgumentException("Caller is not in foreground."); 1230 } 1231 mForegroundUid = Process.INVALID_UID; 1232 1233 mRoutingOptionManager.recoverOverridedRoutingTable(); 1234 if (mAidCache.onRoutingOverridedOrRecovered() 1235 != AidRoutingManager.CONFIGURE_ROUTING_SUCCESS) { 1236 throw new IllegalArgumentException( 1237 "recoverRoutingTable: " + "onRoutingOverridedOrRecovered() failed"); 1238 } 1239 } 1240 1241 @Override overwriteRoutingTable(int userHandle, String aids, String protocol, String technology, String sc)1242 public void overwriteRoutingTable(int userHandle, String aids, 1243 String protocol, String technology, String sc) { 1244 Log.d(TAG, "overwriteRoutingTable(): userHandle: " + userHandle 1245 + ", emptyAid: " + aids + ", protocol: " + protocol 1246 + ", technology: " + technology + ", systemCode: " + sc); 1247 1248 NfcPermissions.enforceAdminPermissions(mContext); 1249 1250 int aidRoute = getRouteForSecureElement(aids); 1251 int protocolRoute = getRouteForSecureElement(protocol); 1252 int technologyRoute = getRouteForSecureElement(technology); 1253 int scRoute = getRouteForSecureElement(sc); 1254 1255 if (DBG) { 1256 Log.d(TAG, "overwriteRoutingTable(): aidRoute: " + Integer.toHexString(aidRoute) 1257 + ", protocolRoute: " + Integer.toHexString(protocolRoute) 1258 + ", technologyRoute: " + Integer.toHexString(technologyRoute) 1259 + ", scRoute: " + Integer.toHexString(scRoute)); 1260 } 1261 if (aids != null) { 1262 mRoutingOptionManager.overrideDefaultRoute(aidRoute); 1263 } 1264 if (protocol != null) { 1265 mRoutingOptionManager.overrideDefaultIsoDepRoute(protocolRoute); 1266 } 1267 if (technology != null) { 1268 mRoutingOptionManager.overrideDefaultOffHostRoute(technologyRoute); 1269 } 1270 if (sc != null) { 1271 mRoutingOptionManager.overrideDefaultScRoute(scRoute); 1272 } 1273 if (aids != null || protocol != null || technology != null || sc != null) { 1274 mRoutingOptionManager.overwriteRoutingTable(); 1275 } 1276 if (mAidCache.onRoutingOverridedOrRecovered() 1277 != AidRoutingManager.CONFIGURE_ROUTING_SUCCESS) { 1278 throw new IllegalArgumentException("onRoutingOverridedOrRecovered() failed"); 1279 } 1280 } 1281 1282 @Override getRoutingStatus()1283 public List<String> getRoutingStatus() { 1284 NfcPermissions.enforceAdminPermissions(mContext); 1285 List<Integer> routingList = new ArrayList<>(); 1286 1287 if (mRoutingOptionManager.isRoutingTableOverrided()) { 1288 routingList.add(mRoutingOptionManager.getOverrideDefaultRoute()); 1289 routingList.add(mRoutingOptionManager.getOverrideDefaultIsoDepRoute()); 1290 routingList.add(mRoutingOptionManager.getOverrideDefaultOffHostRoute()); 1291 } 1292 else { 1293 routingList.add(mRoutingOptionManager.getDefaultRoute()); 1294 routingList.add(mRoutingOptionManager.getDefaultIsoDepRoute()); 1295 routingList.add(mRoutingOptionManager.getDefaultOffHostRoute()); 1296 } 1297 1298 return routingList.stream() 1299 .map(route->mRoutingOptionManager.getSecureElementForRoute(route)) 1300 .collect(Collectors.toList()); 1301 } 1302 1303 @Override setAutoChangeStatus(boolean state)1304 public void setAutoChangeStatus(boolean state) { 1305 NfcPermissions.enforceAdminPermissions(mContext); 1306 mRoutingOptionManager.setAutoChangeStatus(state); 1307 } 1308 1309 @Override isAutoChangeEnabled()1310 public boolean isAutoChangeEnabled() { 1311 NfcPermissions.enforceAdminPermissions(mContext); 1312 return mRoutingOptionManager.isAutoChangeEnabled(); 1313 } 1314 1315 @Override isEuiccSupported()1316 public boolean isEuiccSupported() { 1317 NfcPermissions.enforceUserPermissions(mContext); 1318 return mContext.getResources().getBoolean(R.bool.enable_euicc_support) 1319 && NfcInjector.NfcProperties.isEuiccSupported(); 1320 } 1321 1322 /** 1323 * Make sure the device has required telephony feature 1324 * 1325 * @throws UnsupportedOperationException if the device does not have required telephony feature 1326 */ enforceTelephonySubscriptionFeatureWithException( String callingPackage, String methodName)1327 private void enforceTelephonySubscriptionFeatureWithException( 1328 String callingPackage, String methodName) { 1329 if (callingPackage == null) return; 1330 if (mVendorApiLevel < Build.VERSION_CODES.VANILLA_ICE_CREAM) { 1331 // Skip to check associated telephony feature, 1332 // if compatibility change is not enabled for the current process or 1333 // the SDK version of vendor partition is less than Android V. 1334 return; 1335 } 1336 if (!mContext.getPackageManager().hasSystemFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) { 1337 throw new UnsupportedOperationException( 1338 methodName + " is unsupported without " + FEATURE_TELEPHONY_SUBSCRIPTION); 1339 } 1340 } 1341 1342 @Override setDefaultNfcSubscriptionId(int subscriptionId, String pkgName)1343 public int setDefaultNfcSubscriptionId(int subscriptionId, String pkgName) { 1344 NfcPermissions.enforceAdminPermissions(mContext); 1345 if (!android.nfc.Flags.enableCardEmulationEuicc()) { 1346 Log.d(TAG, "setDefaultNfcSubscriptionId: Euicc CardEmulation isn't enabled"); 1347 return CardEmulation.SET_SUBSCRIPTION_ID_STATUS_FAILED_NOT_SUPPORTED; 1348 } 1349 enforceTelephonySubscriptionFeatureWithException(pkgName, "setDefaultNfcSubscriptionId"); 1350 mPreferredSubscriptionService.setPreferredSubscriptionId(subscriptionId, true); 1351 // TODO(b/321314635): Write to NFC persistent setting. 1352 return CardEmulation.SET_SUBSCRIPTION_ID_STATUS_SUCCESS; 1353 } 1354 1355 @Override getDefaultNfcSubscriptionId(String pkgName)1356 public int getDefaultNfcSubscriptionId(String pkgName) { 1357 NfcPermissions.enforceUserPermissions(mContext); 1358 enforceTelephonySubscriptionFeatureWithException(pkgName, "getDefaultNfcSubscriptionId"); 1359 // TODO(b/321314635): Read NFC persistent setting. 1360 return mPreferredSubscriptionService.getPreferredSubscriptionId(); 1361 } 1362 1363 @Override registerNfcEventCallback(INfcEventCallback listener)1364 public void registerNfcEventCallback(INfcEventCallback listener) { 1365 if (!android.nfc.Flags.nfcEventListener()) { 1366 return; 1367 } 1368 mNfcEventCallbacks.register(listener); 1369 } 1370 1371 @Override unregisterNfcEventCallback( INfcEventCallback listener)1372 public void unregisterNfcEventCallback( 1373 INfcEventCallback listener) { 1374 if (!android.nfc.Flags.nfcEventListener()) { 1375 return; 1376 } 1377 mNfcEventCallbacks.unregister(listener); 1378 } 1379 } 1380 1381 final RemoteCallbackList<INfcEventCallback> mNfcEventCallbacks = new RemoteCallbackList<>(); 1382 1383 private interface ListenerCall { invoke(INfcEventCallback listener)1384 void invoke(INfcEventCallback listener) throws RemoteException; 1385 } 1386 callNfcEventCallbacks(ListenerCall call)1387 private void callNfcEventCallbacks(ListenerCall call) { 1388 synchronized (mNfcEventCallbacks) { 1389 int numListeners = mNfcEventCallbacks.beginBroadcast(); 1390 try { 1391 IntStream.range(0, numListeners).forEach(i -> { 1392 try { 1393 call.invoke(mNfcEventCallbacks.getBroadcastItem(i)); 1394 } catch (RemoteException re) { 1395 Log.i(TAG, "callNfcEventCallbacks: Service died", re); 1396 } 1397 }); 1398 1399 } finally { 1400 mNfcEventCallbacks.finishBroadcast(); 1401 } 1402 } 1403 } 1404 notifyPreferredServiceListeners(ComponentNameAndUser preferredService)1405 void notifyPreferredServiceListeners(ComponentNameAndUser preferredService) { 1406 if (!android.nfc.Flags.nfcEventListener()) { 1407 return; 1408 } 1409 callNfcEventCallbacks(listener -> listener.onPreferredServiceChanged(preferredService)); 1410 } 1411 1412 @Override onAidConflict(@onNull String aid)1413 public void onAidConflict(@NonNull String aid) { 1414 if (android.nfc.Flags.nfcEventListener()) { 1415 callNfcEventCallbacks(listener -> listener.onAidConflictOccurred(aid)); 1416 } 1417 } 1418 1419 @Override onAidNotRouted(@onNull String aid)1420 public void onAidNotRouted(@NonNull String aid) { 1421 if (android.nfc.Flags.nfcEventListener()) { 1422 callNfcEventCallbacks(listener -> listener.onAidNotRouted(aid)); 1423 } 1424 } 1425 onNfcStateChanged(int state)1426 public void onNfcStateChanged(int state) { 1427 if (android.nfc.Flags.nfcEventListener()) { 1428 callNfcEventCallbacks(listener -> listener.onNfcStateChanged(state)); 1429 } 1430 } 1431 onRemoteFieldChanged(boolean isDetected)1432 public void onRemoteFieldChanged(boolean isDetected) { 1433 if (android.nfc.Flags.nfcEventListener()) { 1434 callNfcEventCallbacks(listener -> listener.onRemoteFieldChanged(isDetected)); 1435 } 1436 } 1437 onInternalErrorReported(@ardEmulation.NfcInternalErrorType int errorType)1438 public void onInternalErrorReported(@CardEmulation.NfcInternalErrorType int errorType) { 1439 if (android.nfc.Flags.nfcEventListener()) { 1440 callNfcEventCallbacks(listener -> listener.onInternalErrorReported(errorType)); 1441 } 1442 } 1443 1444 final ForegroundUtils.Callback mForegroundCallback = new ForegroundCallbackImpl(); 1445 1446 class ForegroundCallbackImpl implements ForegroundUtils.Callback { 1447 @Override onUidToBackground(int uid)1448 public void onUidToBackground(int uid) { 1449 synchronized (CardEmulationManager.this) { 1450 if (mForegroundUid == uid) { 1451 if (DBG) { 1452 Log.d(TAG, "onUidToBackground: Uid " + uid + " switch to background"); 1453 } 1454 mForegroundUid = Process.INVALID_UID; 1455 mRoutingOptionManager.recoverOverridedRoutingTable(); 1456 } 1457 } 1458 } 1459 } 1460 getRouteForSecureElement(String se)1461 private int getRouteForSecureElement(String se) { 1462 String route = se; 1463 if (route == null) { 1464 return -1; 1465 } 1466 1467 if (route.equals("DH")) { 1468 return 0; 1469 } 1470 1471 if (route.length() == 3) { 1472 route = route + '1'; 1473 } 1474 return mRoutingOptionManager.getRouteForSecureElement(route); 1475 } 1476 1477 /** 1478 * This class implements the application-facing APIs and are called 1479 * from binder. All calls must be permission-checked. 1480 */ 1481 final class NfcFCardEmulationInterface extends INfcFCardEmulation.Stub { 1482 @Override getSystemCodeForService(int userId, ComponentName service)1483 public String getSystemCodeForService(int userId, ComponentName service) 1484 throws RemoteException { 1485 NfcPermissions.validateUserId(userId); 1486 NfcPermissions.enforceUserPermissions(mContext); 1487 if (!isNfcFServiceInstalled(userId, service)) { 1488 return null; 1489 } 1490 return mNfcFServicesCache.getSystemCodeForService( 1491 userId, Binder.getCallingUid(), service); 1492 } 1493 1494 @Override registerSystemCodeForService(int userId, ComponentName service, String systemCode)1495 public boolean registerSystemCodeForService(int userId, ComponentName service, 1496 String systemCode) 1497 throws RemoteException { 1498 NfcPermissions.validateUserId(userId); 1499 NfcPermissions.enforceUserPermissions(mContext); 1500 if (!isNfcFServiceInstalled(userId, service)) { 1501 return false; 1502 } 1503 return mNfcFServicesCache.registerSystemCodeForService( 1504 userId, Binder.getCallingUid(), service, systemCode); 1505 } 1506 1507 @Override removeSystemCodeForService(int userId, ComponentName service)1508 public boolean removeSystemCodeForService(int userId, ComponentName service) 1509 throws RemoteException { 1510 NfcPermissions.validateUserId(userId); 1511 NfcPermissions.enforceUserPermissions(mContext); 1512 if (!isNfcFServiceInstalled(userId, service)) { 1513 return false; 1514 } 1515 return mNfcFServicesCache.removeSystemCodeForService( 1516 userId, Binder.getCallingUid(), service); 1517 } 1518 1519 @Override getNfcid2ForService(int userId, ComponentName service)1520 public String getNfcid2ForService(int userId, ComponentName service) 1521 throws RemoteException { 1522 NfcPermissions.validateUserId(userId); 1523 NfcPermissions.enforceUserPermissions(mContext); 1524 if (!isNfcFServiceInstalled(userId, service)) { 1525 return null; 1526 } 1527 return mNfcFServicesCache.getNfcid2ForService( 1528 userId, Binder.getCallingUid(), service); 1529 } 1530 1531 @Override setNfcid2ForService(int userId, ComponentName service, String nfcid2)1532 public boolean setNfcid2ForService(int userId, 1533 ComponentName service, String nfcid2) throws RemoteException { 1534 NfcPermissions.validateUserId(userId); 1535 NfcPermissions.enforceUserPermissions(mContext); 1536 if (!isNfcFServiceInstalled(userId, service)) { 1537 return false; 1538 } 1539 return mNfcFServicesCache.setNfcid2ForService( 1540 userId, Binder.getCallingUid(), service, nfcid2); 1541 } 1542 1543 @Override enableNfcFForegroundService(ComponentName service)1544 public boolean enableNfcFForegroundService(ComponentName service) 1545 throws RemoteException { 1546 NfcPermissions.enforceUserPermissions(mContext); 1547 if (isNfcFServiceInstalled(UserHandle.getUserHandleForUid( 1548 Binder.getCallingUid()).getIdentifier(), service)) { 1549 return mEnabledNfcFServices.registerEnabledForegroundService(service, 1550 Binder.getCallingUid()); 1551 } 1552 return false; 1553 } 1554 1555 @Override disableNfcFForegroundService()1556 public boolean disableNfcFForegroundService() throws RemoteException { 1557 NfcPermissions.enforceUserPermissions(mContext); 1558 return mEnabledNfcFServices.unregisteredEnabledForegroundService( 1559 Binder.getCallingUid()); 1560 } 1561 1562 @Override getNfcFServices(int userId)1563 public List<NfcFServiceInfo> getNfcFServices(int userId) 1564 throws RemoteException { 1565 NfcPermissions.validateProfileId(mContext, userId); 1566 NfcPermissions.enforceUserPermissions(mContext); 1567 return mNfcFServicesCache.getServices(userId); 1568 } 1569 1570 @Override getMaxNumOfRegisterableSystemCodes()1571 public int getMaxNumOfRegisterableSystemCodes() 1572 throws RemoteException { 1573 NfcPermissions.enforceUserPermissions(mContext); 1574 return NfcService.getInstance().getLfT3tMax(); 1575 } 1576 } 1577 1578 @Override onPreferredPaymentServiceChanged(ComponentNameAndUser service)1579 public void onPreferredPaymentServiceChanged(ComponentNameAndUser service) { 1580 Log.i(TAG, "onPreferredPaymentServiceChanged"); 1581 ComponentNameAndUser oldPreferredService = mAidCache.getPreferredService(); 1582 mAidCache.onPreferredPaymentServiceChanged(service); 1583 mHostEmulationManager.onPreferredPaymentServiceChanged(service); 1584 ComponentNameAndUser newPreferredService = mAidCache.getPreferredService(); 1585 1586 NfcService.getInstance().onPreferredPaymentChanged( 1587 NfcAdapter.PREFERRED_PAYMENT_CHANGED); 1588 if (!Objects.equals(oldPreferredService, newPreferredService)) { 1589 updateForShouldDefaultToObserveMode(newPreferredService.getUserId()); 1590 notifyPreferredServiceListeners(newPreferredService); 1591 } 1592 } 1593 1594 @Override onPreferredForegroundServiceChanged(ComponentNameAndUser service)1595 public void onPreferredForegroundServiceChanged(ComponentNameAndUser service) { 1596 Log.i(TAG, "onPreferredForegroundServiceChanged"); 1597 ComponentNameAndUser oldPreferredService = mAidCache.getPreferredService(); 1598 mHostEmulationManager.onPreferredForegroundServiceChanged(service); 1599 ComponentNameAndUser newPreferredService = mAidCache.getPreferredService(); 1600 1601 NfcService.getInstance().onPreferredPaymentChanged( 1602 NfcAdapter.PREFERRED_PAYMENT_CHANGED); 1603 if (!Objects.equals(oldPreferredService, newPreferredService)) { 1604 updateForShouldDefaultToObserveMode(newPreferredService.getUserId()); 1605 notifyPreferredServiceListeners(newPreferredService); 1606 } 1607 } 1608 updateForDefaultSwpToEuicc()1609 public void updateForDefaultSwpToEuicc() { 1610 if (!android.nfc.Flags.enableCardEmulationEuicc()) { 1611 Log.d(TAG, "updateForDefaultSwpToEuicc: Euicc CardEmulation isn't enabled"); 1612 return; 1613 } 1614 1615 if (!mContext.getResources().getBoolean(R.bool.enable_euicc_support) 1616 || !NfcInjector.NfcProperties.isEuiccSupported()) { 1617 Log.d(TAG, "updateForDefaultSwpToEuicc: Euicc CardEmulation is not support"); 1618 return; 1619 } 1620 1621 if (DBG) Log.d(TAG, "updateForDefaultSwpToEuicc: Assign SWP for eSIM before NFC turned on"); 1622 1623 int preferredSubscriptionId = mPreferredSubscriptionService.getPreferredSubscriptionId(); 1624 String response = mTelephonyUtils 1625 .updateSwpStatusForEuicc(getSimTypeById(preferredSubscriptionId)); 1626 Log.d(TAG, "updateForDefaultSwpToEuicc: response: " + response); 1627 if (response.length() >= 4) { 1628 String statusWord = response.substring(response.length() - 4); 1629 if (!TextUtils.equals(statusWord, "9000")) { 1630 Log.e(TAG, "updateForDefaultSwpToEuicc: ASSIGN_SWP(LSE) Command is fail: " 1631 + statusWord); 1632 } 1633 } else { 1634 Log.e(TAG, "updateForDefaultSwpToEuicc: response.length() is wrong length : " 1635 + response.length()); 1636 } 1637 } 1638 getSimTypeById(int subscriptionId)1639 private int getSimTypeById(int subscriptionId) { 1640 Optional<SubscriptionInfo> optionalInfo = 1641 mTelephonyUtils.getActiveSubscriptionInfoById(subscriptionId); 1642 if (optionalInfo.isPresent()) { 1643 SubscriptionInfo info = optionalInfo.get(); 1644 if (info.isEmbedded()) { 1645 return info.getPortIndex() == 0 1646 ? TelephonyUtils.SIM_TYPE_EUICC_1 : TelephonyUtils.SIM_TYPE_EUICC_2; 1647 } 1648 else { 1649 return TelephonyUtils.SIM_TYPE_UICC; 1650 } 1651 } 1652 1653 return TelephonyUtils.SIM_TYPE_UNKNOWN; 1654 } 1655 updateForShouldDefaultToObserveMode(int userId)1656 public void updateForShouldDefaultToObserveMode(int userId) { 1657 long token = Binder.clearCallingIdentity(); 1658 try { 1659 NfcAdapter adapter = NfcAdapter.getDefaultAdapter(mContext); 1660 if (adapter == null) { 1661 Log.e(TAG, "updateForShouldDefaultToObserveMode: adapter is null, returning"); 1662 return; 1663 } 1664 ComponentNameAndUser preferredServiceAndUser = mAidCache.getPreferredService(); 1665 if (preferredServiceAndUser == null) { 1666 return; 1667 } 1668 ComponentName preferredService = preferredServiceAndUser.getComponentName(); 1669 boolean enableObserveMode = mServiceCache.doesServiceShouldDefaultToObserveMode(userId, 1670 preferredService); 1671 mHostEmulationManager.updateForShouldDefaultToObserveMode(enableObserveMode); 1672 } finally { 1673 Binder.restoreCallingIdentity(token); 1674 } 1675 } 1676 updateFirmwareExitFramesForWalletRole(int userId)1677 public void updateFirmwareExitFramesForWalletRole(int userId) { 1678 if (!Flags.exitFrames()) { 1679 return; 1680 } 1681 1682 NfcService nfcService = NfcService.getInstance(); 1683 if (!nfcService.isFirmwareExitFramesSupported() 1684 || nfcService.getNumberOfFirmwareExitFramesSupported() <= 0) { 1685 return; 1686 } 1687 1688 // Get all services then find those associated with role holder 1689 Stream<ApduServiceInfo> roleServices = mServiceCache.getServices(userId).stream().filter( 1690 serviceInfo -> mAidCache.isDefaultOrAssociatedWalletService(serviceInfo, userId)); 1691 1692 // Not every pattern filter is a valid exit frame, so this function catches 1693 // exceptions that could be thrown creating an ExitFrame object from a pattern. 1694 Function<String, ExitFrame> toExitFrameOrNull = (s) -> { 1695 try { 1696 return new ExitFrame(s); 1697 } catch (Exception e) { 1698 return null; 1699 } 1700 }; 1701 // Combine filters and pattern filters, slice to size of supported, build list of exit 1702 // frames 1703 List<ExitFrame> exitFrames = roleServices.flatMap(serviceInfo -> 1704 Stream.concat( 1705 serviceInfo.getPollingLoopFilters().stream(), 1706 serviceInfo.getPollingLoopPatternFilters() 1707 .stream().map(Pattern::toString) 1708 ) 1709 .filter( 1710 serviceInfo::getShouldAutoTransact)) 1711 .distinct() 1712 .map(toExitFrameOrNull) 1713 .filter(Objects::nonNull) 1714 .limit(nfcService.getNumberOfFirmwareExitFramesSupported()) 1715 .collect(Collectors.toList()); 1716 Log.d(TAG, "updateFirmwareExitFramesForWalletRole: " + exitFrames.size() + " frames"); 1717 nfcService.setFirmwareExitFrameTable(exitFrames, FIRMWARE_EXIT_FRAME_TIMEOUT_MS); 1718 } 1719 onObserveModeStateChange(boolean enabled)1720 public void onObserveModeStateChange(boolean enabled) { 1721 mHostEmulationManager.onObserveModeStateChange(enabled); 1722 if (android.nfc.Flags.nfcEventListener()) { 1723 callNfcEventCallbacks(listener -> listener.onObserveModeStateChanged(enabled)); 1724 } 1725 } 1726 onObserveModeDisabledInFirmware(PollingFrame exitFrame)1727 public void onObserveModeDisabledInFirmware(PollingFrame exitFrame) { 1728 if (android.nfc.Flags.nfcEventListener()) { 1729 callNfcEventCallbacks(listener -> listener.onObserveModeDisabledInFirmware(exitFrame)); 1730 } 1731 mHostEmulationManager.onObserveModeDisabledInFirmware(exitFrame); 1732 1733 if (mStatsdUtils != null) { 1734 mStatsdUtils.logAutoTransactReported(StatsdUtils.PROCESSOR_NFCC, exitFrame.getData()); 1735 } 1736 } 1737 1738 @Override onWalletRoleHolderChanged(String holder, int userId)1739 public void onWalletRoleHolderChanged(String holder, int userId) { 1740 mPreferredServices.onWalletRoleHolderChanged(holder, userId); 1741 mAidCache.onWalletRoleHolderChanged(holder, userId); 1742 if (Flags.exitFrames()) { 1743 updateFirmwareExitFramesForWalletRole(userId); 1744 } 1745 } 1746 1747 @Override onEnabledForegroundNfcFServiceChanged(int userId, ComponentName service)1748 public void onEnabledForegroundNfcFServiceChanged(int userId, ComponentName service) { 1749 mT3tIdentifiersCache.onEnabledForegroundNfcFServiceChanged(userId, service); 1750 mHostNfcFEmulationManager.onEnabledForegroundNfcFServiceChanged(userId, service); 1751 } 1752 getRegisteredAidCategory(String aid)1753 public String getRegisteredAidCategory(String aid) { 1754 RegisteredAidCache.AidResolveInfo resolvedInfo = mAidCache.resolveAid(aid); 1755 if (resolvedInfo != null) { 1756 return resolvedInfo.getCategory(); 1757 } 1758 return ""; 1759 } 1760 isRequiresScreenOnServiceExist()1761 public boolean isRequiresScreenOnServiceExist() { 1762 return mAidCache.isRequiresScreenOnServiceExist(); 1763 } 1764 isPreferredServicePackageNameForUser(String packageName, int userId)1765 public boolean isPreferredServicePackageNameForUser(String packageName, int userId) { 1766 return mAidCache.isPreferredServicePackageNameForUser(packageName, userId); 1767 } 1768 isHostCardEmulationActivated()1769 public boolean isHostCardEmulationActivated() { 1770 return mHostEmulationManager.isHostCardEmulationActivated(); 1771 } 1772 } 1773