Loading core/java/android/nfc/INfcCardEmulation.aidl +1 −0 Original line number Original line Diff line number Diff line Loading @@ -40,5 +40,6 @@ interface INfcCardEmulation boolean unsetPreferredService(); boolean unsetPreferredService(); boolean supportsAidPrefixRegistration(); boolean supportsAidPrefixRegistration(); ApduServiceInfo getPreferredPaymentService(int userHandle); ApduServiceInfo getPreferredPaymentService(int userHandle); boolean setServiceEnabledForCategoryOther(int userHandle, in ComponentName app, boolean status); boolean isDefaultPaymentRegistered(); boolean isDefaultPaymentRegistered(); } } core/java/android/nfc/cardemulation/ApduServiceInfo.java +80 −35 Original line number Original line Diff line number Diff line Loading @@ -126,6 +126,11 @@ public final class ApduServiceInfo implements Parcelable { */ */ private final String mSettingsActivityName; private final String mSettingsActivityName; /** * State of the service for CATEGORY_OTHER selection */ private boolean mOtherServiceSelectionState; /** /** * @hide * @hide */ */ Loading @@ -133,9 +138,22 @@ public final class ApduServiceInfo implements Parcelable { List<AidGroup> staticAidGroups, List<AidGroup> dynamicAidGroups, List<AidGroup> staticAidGroups, List<AidGroup> dynamicAidGroups, boolean requiresUnlock, int bannerResource, int uid, boolean requiresUnlock, int bannerResource, int uid, String settingsActivityName, String offHost, String staticOffHost) { String settingsActivityName, String offHost, String staticOffHost) { this(info, onHost, description, staticAidGroups, dynamicAidGroups, requiresUnlock, bannerResource, uid, settingsActivityName, offHost, staticOffHost, false); } /** * @hide */ public ApduServiceInfo(ResolveInfo info, boolean onHost, String description, List<AidGroup> staticAidGroups, List<AidGroup> dynamicAidGroups, boolean requiresUnlock, int bannerResource, int uid, String settingsActivityName, String offHost, String staticOffHost, boolean isSelected) { this(info, onHost, description, staticAidGroups, dynamicAidGroups, this(info, onHost, description, staticAidGroups, dynamicAidGroups, requiresUnlock, onHost ? true : false, bannerResource, uid, requiresUnlock, onHost ? true : false, bannerResource, uid, settingsActivityName, offHost, staticOffHost); settingsActivityName, offHost, staticOffHost, isSelected); } } /** /** Loading @@ -144,7 +162,7 @@ public final class ApduServiceInfo implements Parcelable { public ApduServiceInfo(ResolveInfo info, boolean onHost, String description, public ApduServiceInfo(ResolveInfo info, boolean onHost, String description, List<AidGroup> staticAidGroups, List<AidGroup> dynamicAidGroups, List<AidGroup> staticAidGroups, List<AidGroup> dynamicAidGroups, boolean requiresUnlock, boolean requiresScreenOn, int bannerResource, int uid, boolean requiresUnlock, boolean requiresScreenOn, int bannerResource, int uid, String settingsActivityName, String offHost, String staticOffHost) { String settingsActivityName, String offHost, String staticOffHost, boolean isSelected) { this.mService = info; this.mService = info; this.mDescription = description; this.mDescription = description; this.mStaticAidGroups = new HashMap<String, AidGroup>(); this.mStaticAidGroups = new HashMap<String, AidGroup>(); Loading @@ -163,6 +181,8 @@ public final class ApduServiceInfo implements Parcelable { this.mBannerResourceId = bannerResource; this.mBannerResourceId = bannerResource; this.mUid = uid; this.mUid = uid; this.mSettingsActivityName = settingsActivityName; this.mSettingsActivityName = settingsActivityName; this.mOtherServiceSelectionState = isSelected; } } /** /** Loading Loading @@ -351,6 +371,9 @@ public final class ApduServiceInfo implements Parcelable { } } // Set uid // Set uid mUid = si.applicationInfo.uid; mUid = si.applicationInfo.uid; mOtherServiceSelectionState = false; // support other category } } /** /** Loading Loading @@ -720,6 +743,8 @@ public final class ApduServiceInfo implements Parcelable { dest.writeInt(mBannerResourceId); dest.writeInt(mBannerResourceId); dest.writeInt(mUid); dest.writeInt(mUid); dest.writeString(mSettingsActivityName); dest.writeString(mSettingsActivityName); dest.writeInt(mOtherServiceSelectionState ? 1 : 0); }; }; @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) Loading Loading @@ -747,9 +772,11 @@ public final class ApduServiceInfo implements Parcelable { int bannerResource = source.readInt(); int bannerResource = source.readInt(); int uid = source.readInt(); int uid = source.readInt(); String settingsActivityName = source.readString(); String settingsActivityName = source.readString(); boolean isSelected = source.readInt() != 0; return new ApduServiceInfo(info, onHost, description, staticAidGroups, return new ApduServiceInfo(info, onHost, description, staticAidGroups, dynamicAidGroups, requiresUnlock, requiresScreenOn, bannerResource, uid, dynamicAidGroups, requiresUnlock, requiresScreenOn, bannerResource, uid, settingsActivityName, offHostName, staticOffHostName); settingsActivityName, offHostName, staticOffHostName, isSelected); } } @Override @Override Loading Loading @@ -779,14 +806,16 @@ public final class ApduServiceInfo implements Parcelable { } } pw.println(" Static AID groups:"); pw.println(" Static AID groups:"); for (AidGroup group : mStaticAidGroups.values()) { for (AidGroup group : mStaticAidGroups.values()) { pw.println(" Category: " + group.getCategory()); pw.println(" Category: " + group.getCategory() + "(selected: " + mOtherServiceSelectionState + ")"); for (String aid : group.getAids()) { for (String aid : group.getAids()) { pw.println(" AID: " + aid); pw.println(" AID: " + aid); } } } } pw.println(" Dynamic AID groups:"); pw.println(" Dynamic AID groups:"); for (AidGroup group : mDynamicAidGroups.values()) { for (AidGroup group : mDynamicAidGroups.values()) { pw.println(" Category: " + group.getCategory()); pw.println(" Category: " + group.getCategory() + "(selected: " + mOtherServiceSelectionState + ")"); for (String aid : group.getAids()) { for (String aid : group.getAids()) { pw.println(" AID: " + aid); pw.println(" AID: " + aid); } } Loading @@ -796,6 +825,22 @@ public final class ApduServiceInfo implements Parcelable { pw.println(" Requires Device ScreenOn: " + mRequiresDeviceScreenOn); pw.println(" Requires Device ScreenOn: " + mRequiresDeviceScreenOn); } } /** * @hide */ public void setOtherServiceState(boolean selected) { mOtherServiceSelectionState = selected; } /** * @hide */ public boolean isSelectedOtherService() { return mOtherServiceSelectionState; } /** /** * Dump debugging info as ApduServiceInfoProto. * Dump debugging info as ApduServiceInfoProto. * * Loading core/java/android/nfc/cardemulation/CardEmulation.java +33 −0 Original line number Original line Diff line number Diff line Loading @@ -947,6 +947,39 @@ public final class CardEmulation { return true; return true; } } /** * Allows to set or unset preferred service (category other) to avoid AID Collision. * * @param service The ComponentName of the service * @param status true to enable, false to disable * @return set service for the category and true if service is already set return false. * * @hide */ public boolean setServiceEnabledForCategoryOther(ComponentName service, boolean status) { if (service == null) { throw new NullPointerException("activity or service or category is null"); } int userId = mContext.getUser().getIdentifier(); try { return sService.setServiceEnabledForCategoryOther(userId, service, status); } catch (RemoteException e) { // Try one more time recoverService(); if (sService == null) { Log.e(TAG, "Failed to recover CardEmulationService."); return false; } try { return sService.setServiceEnabledForCategoryOther(userId, service, status); } catch (RemoteException ee) { Log.e(TAG, "Failed to reach CardEmulationService."); return false; } } } void recoverService() { void recoverService() { NfcAdapter adapter = NfcAdapter.getDefaultAdapter(mContext); NfcAdapter adapter = NfcAdapter.getDefaultAdapter(mContext); sService = adapter.getCardEmulationService(); sService = adapter.getCardEmulationService(); Loading Loading
core/java/android/nfc/INfcCardEmulation.aidl +1 −0 Original line number Original line Diff line number Diff line Loading @@ -40,5 +40,6 @@ interface INfcCardEmulation boolean unsetPreferredService(); boolean unsetPreferredService(); boolean supportsAidPrefixRegistration(); boolean supportsAidPrefixRegistration(); ApduServiceInfo getPreferredPaymentService(int userHandle); ApduServiceInfo getPreferredPaymentService(int userHandle); boolean setServiceEnabledForCategoryOther(int userHandle, in ComponentName app, boolean status); boolean isDefaultPaymentRegistered(); boolean isDefaultPaymentRegistered(); } }
core/java/android/nfc/cardemulation/ApduServiceInfo.java +80 −35 Original line number Original line Diff line number Diff line Loading @@ -126,6 +126,11 @@ public final class ApduServiceInfo implements Parcelable { */ */ private final String mSettingsActivityName; private final String mSettingsActivityName; /** * State of the service for CATEGORY_OTHER selection */ private boolean mOtherServiceSelectionState; /** /** * @hide * @hide */ */ Loading @@ -133,9 +138,22 @@ public final class ApduServiceInfo implements Parcelable { List<AidGroup> staticAidGroups, List<AidGroup> dynamicAidGroups, List<AidGroup> staticAidGroups, List<AidGroup> dynamicAidGroups, boolean requiresUnlock, int bannerResource, int uid, boolean requiresUnlock, int bannerResource, int uid, String settingsActivityName, String offHost, String staticOffHost) { String settingsActivityName, String offHost, String staticOffHost) { this(info, onHost, description, staticAidGroups, dynamicAidGroups, requiresUnlock, bannerResource, uid, settingsActivityName, offHost, staticOffHost, false); } /** * @hide */ public ApduServiceInfo(ResolveInfo info, boolean onHost, String description, List<AidGroup> staticAidGroups, List<AidGroup> dynamicAidGroups, boolean requiresUnlock, int bannerResource, int uid, String settingsActivityName, String offHost, String staticOffHost, boolean isSelected) { this(info, onHost, description, staticAidGroups, dynamicAidGroups, this(info, onHost, description, staticAidGroups, dynamicAidGroups, requiresUnlock, onHost ? true : false, bannerResource, uid, requiresUnlock, onHost ? true : false, bannerResource, uid, settingsActivityName, offHost, staticOffHost); settingsActivityName, offHost, staticOffHost, isSelected); } } /** /** Loading @@ -144,7 +162,7 @@ public final class ApduServiceInfo implements Parcelable { public ApduServiceInfo(ResolveInfo info, boolean onHost, String description, public ApduServiceInfo(ResolveInfo info, boolean onHost, String description, List<AidGroup> staticAidGroups, List<AidGroup> dynamicAidGroups, List<AidGroup> staticAidGroups, List<AidGroup> dynamicAidGroups, boolean requiresUnlock, boolean requiresScreenOn, int bannerResource, int uid, boolean requiresUnlock, boolean requiresScreenOn, int bannerResource, int uid, String settingsActivityName, String offHost, String staticOffHost) { String settingsActivityName, String offHost, String staticOffHost, boolean isSelected) { this.mService = info; this.mService = info; this.mDescription = description; this.mDescription = description; this.mStaticAidGroups = new HashMap<String, AidGroup>(); this.mStaticAidGroups = new HashMap<String, AidGroup>(); Loading @@ -163,6 +181,8 @@ public final class ApduServiceInfo implements Parcelable { this.mBannerResourceId = bannerResource; this.mBannerResourceId = bannerResource; this.mUid = uid; this.mUid = uid; this.mSettingsActivityName = settingsActivityName; this.mSettingsActivityName = settingsActivityName; this.mOtherServiceSelectionState = isSelected; } } /** /** Loading Loading @@ -351,6 +371,9 @@ public final class ApduServiceInfo implements Parcelable { } } // Set uid // Set uid mUid = si.applicationInfo.uid; mUid = si.applicationInfo.uid; mOtherServiceSelectionState = false; // support other category } } /** /** Loading Loading @@ -720,6 +743,8 @@ public final class ApduServiceInfo implements Parcelable { dest.writeInt(mBannerResourceId); dest.writeInt(mBannerResourceId); dest.writeInt(mUid); dest.writeInt(mUid); dest.writeString(mSettingsActivityName); dest.writeString(mSettingsActivityName); dest.writeInt(mOtherServiceSelectionState ? 1 : 0); }; }; @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) Loading Loading @@ -747,9 +772,11 @@ public final class ApduServiceInfo implements Parcelable { int bannerResource = source.readInt(); int bannerResource = source.readInt(); int uid = source.readInt(); int uid = source.readInt(); String settingsActivityName = source.readString(); String settingsActivityName = source.readString(); boolean isSelected = source.readInt() != 0; return new ApduServiceInfo(info, onHost, description, staticAidGroups, return new ApduServiceInfo(info, onHost, description, staticAidGroups, dynamicAidGroups, requiresUnlock, requiresScreenOn, bannerResource, uid, dynamicAidGroups, requiresUnlock, requiresScreenOn, bannerResource, uid, settingsActivityName, offHostName, staticOffHostName); settingsActivityName, offHostName, staticOffHostName, isSelected); } } @Override @Override Loading Loading @@ -779,14 +806,16 @@ public final class ApduServiceInfo implements Parcelable { } } pw.println(" Static AID groups:"); pw.println(" Static AID groups:"); for (AidGroup group : mStaticAidGroups.values()) { for (AidGroup group : mStaticAidGroups.values()) { pw.println(" Category: " + group.getCategory()); pw.println(" Category: " + group.getCategory() + "(selected: " + mOtherServiceSelectionState + ")"); for (String aid : group.getAids()) { for (String aid : group.getAids()) { pw.println(" AID: " + aid); pw.println(" AID: " + aid); } } } } pw.println(" Dynamic AID groups:"); pw.println(" Dynamic AID groups:"); for (AidGroup group : mDynamicAidGroups.values()) { for (AidGroup group : mDynamicAidGroups.values()) { pw.println(" Category: " + group.getCategory()); pw.println(" Category: " + group.getCategory() + "(selected: " + mOtherServiceSelectionState + ")"); for (String aid : group.getAids()) { for (String aid : group.getAids()) { pw.println(" AID: " + aid); pw.println(" AID: " + aid); } } Loading @@ -796,6 +825,22 @@ public final class ApduServiceInfo implements Parcelable { pw.println(" Requires Device ScreenOn: " + mRequiresDeviceScreenOn); pw.println(" Requires Device ScreenOn: " + mRequiresDeviceScreenOn); } } /** * @hide */ public void setOtherServiceState(boolean selected) { mOtherServiceSelectionState = selected; } /** * @hide */ public boolean isSelectedOtherService() { return mOtherServiceSelectionState; } /** /** * Dump debugging info as ApduServiceInfoProto. * Dump debugging info as ApduServiceInfoProto. * * Loading
core/java/android/nfc/cardemulation/CardEmulation.java +33 −0 Original line number Original line Diff line number Diff line Loading @@ -947,6 +947,39 @@ public final class CardEmulation { return true; return true; } } /** * Allows to set or unset preferred service (category other) to avoid AID Collision. * * @param service The ComponentName of the service * @param status true to enable, false to disable * @return set service for the category and true if service is already set return false. * * @hide */ public boolean setServiceEnabledForCategoryOther(ComponentName service, boolean status) { if (service == null) { throw new NullPointerException("activity or service or category is null"); } int userId = mContext.getUser().getIdentifier(); try { return sService.setServiceEnabledForCategoryOther(userId, service, status); } catch (RemoteException e) { // Try one more time recoverService(); if (sService == null) { Log.e(TAG, "Failed to recover CardEmulationService."); return false; } try { return sService.setServiceEnabledForCategoryOther(userId, service, status); } catch (RemoteException ee) { Log.e(TAG, "Failed to reach CardEmulationService."); return false; } } } void recoverService() { void recoverService() { NfcAdapter adapter = NfcAdapter.getDefaultAdapter(mContext); NfcAdapter adapter = NfcAdapter.getDefaultAdapter(mContext); sService = adapter.getCardEmulationService(); sService = adapter.getCardEmulationService(); Loading