Merge "[Nfc framework] API to include/exclude Other category service component" into main am: 8c7eea4061
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/2803133
Change-Id: Id1a59849765e22203414b6cc9be843a1c7c9823c
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/core/java/android/nfc/INfcCardEmulation.aidl b/core/java/android/nfc/INfcCardEmulation.aidl
index 53843fe..c7b3b2c 100644
--- a/core/java/android/nfc/INfcCardEmulation.aidl
+++ b/core/java/android/nfc/INfcCardEmulation.aidl
@@ -40,5 +40,6 @@
boolean unsetPreferredService();
boolean supportsAidPrefixRegistration();
ApduServiceInfo getPreferredPaymentService(int userHandle);
+ boolean setServiceEnabledForCategoryOther(int userHandle, in ComponentName app, boolean status);
boolean isDefaultPaymentRegistered();
}
diff --git a/core/java/android/nfc/cardemulation/ApduServiceInfo.java b/core/java/android/nfc/cardemulation/ApduServiceInfo.java
index 665b753..9cf8c4d 100644
--- a/core/java/android/nfc/cardemulation/ApduServiceInfo.java
+++ b/core/java/android/nfc/cardemulation/ApduServiceInfo.java
@@ -127,6 +127,11 @@
private final String mSettingsActivityName;
/**
+ * State of the service for CATEGORY_OTHER selection
+ */
+ private boolean mOtherServiceSelectionState;
+
+ /**
* @hide
*/
public ApduServiceInfo(ResolveInfo info, boolean onHost, String description,
@@ -134,8 +139,21 @@
boolean requiresUnlock, int bannerResource, int uid,
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,
requiresUnlock, onHost ? true : false, bannerResource, uid,
- settingsActivityName, offHost, staticOffHost);
+ settingsActivityName, offHost, staticOffHost, isSelected);
}
/**
@@ -144,7 +162,7 @@
public ApduServiceInfo(ResolveInfo info, boolean onHost, String description,
List<AidGroup> staticAidGroups, List<AidGroup> dynamicAidGroups,
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.mDescription = description;
this.mStaticAidGroups = new HashMap<String, AidGroup>();
@@ -163,6 +181,8 @@
this.mBannerResourceId = bannerResource;
this.mUid = uid;
this.mSettingsActivityName = settingsActivityName;
+ this.mOtherServiceSelectionState = isSelected;
+
}
/**
@@ -351,6 +371,9 @@
}
// Set uid
mUid = si.applicationInfo.uid;
+
+ mOtherServiceSelectionState = false; // support other category
+
}
/**
@@ -720,43 +743,47 @@
dest.writeInt(mBannerResourceId);
dest.writeInt(mUid);
dest.writeString(mSettingsActivityName);
+
+ dest.writeInt(mOtherServiceSelectionState ? 1 : 0);
};
@FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
public static final @NonNull Parcelable.Creator<ApduServiceInfo> CREATOR =
new Parcelable.Creator<ApduServiceInfo>() {
- @Override
- public ApduServiceInfo createFromParcel(Parcel source) {
- ResolveInfo info = ResolveInfo.CREATOR.createFromParcel(source);
- String description = source.readString();
- boolean onHost = source.readInt() != 0;
- String offHostName = source.readString();
- String staticOffHostName = source.readString();
- ArrayList<AidGroup> staticAidGroups = new ArrayList<AidGroup>();
- int numStaticGroups = source.readInt();
- if (numStaticGroups > 0) {
- source.readTypedList(staticAidGroups, AidGroup.CREATOR);
- }
- ArrayList<AidGroup> dynamicAidGroups = new ArrayList<AidGroup>();
- int numDynamicGroups = source.readInt();
- if (numDynamicGroups > 0) {
- source.readTypedList(dynamicAidGroups, AidGroup.CREATOR);
- }
- boolean requiresUnlock = source.readInt() != 0;
- boolean requiresScreenOn = source.readInt() != 0;
- int bannerResource = source.readInt();
- int uid = source.readInt();
- String settingsActivityName = source.readString();
- return new ApduServiceInfo(info, onHost, description, staticAidGroups,
- dynamicAidGroups, requiresUnlock, requiresScreenOn, bannerResource, uid,
- settingsActivityName, offHostName, staticOffHostName);
- }
+ @Override
+ public ApduServiceInfo createFromParcel(Parcel source) {
+ ResolveInfo info = ResolveInfo.CREATOR.createFromParcel(source);
+ String description = source.readString();
+ boolean onHost = source.readInt() != 0;
+ String offHostName = source.readString();
+ String staticOffHostName = source.readString();
+ ArrayList<AidGroup> staticAidGroups = new ArrayList<AidGroup>();
+ int numStaticGroups = source.readInt();
+ if (numStaticGroups > 0) {
+ source.readTypedList(staticAidGroups, AidGroup.CREATOR);
+ }
+ ArrayList<AidGroup> dynamicAidGroups = new ArrayList<AidGroup>();
+ int numDynamicGroups = source.readInt();
+ if (numDynamicGroups > 0) {
+ source.readTypedList(dynamicAidGroups, AidGroup.CREATOR);
+ }
+ boolean requiresUnlock = source.readInt() != 0;
+ boolean requiresScreenOn = source.readInt() != 0;
+ int bannerResource = source.readInt();
+ int uid = source.readInt();
+ String settingsActivityName = source.readString();
+ boolean isSelected = source.readInt() != 0;
+ return new ApduServiceInfo(info, onHost, description, staticAidGroups,
+ dynamicAidGroups, requiresUnlock, requiresScreenOn, bannerResource, uid,
+ settingsActivityName, offHostName, staticOffHostName,
+ isSelected);
+ }
- @Override
- public ApduServiceInfo[] newArray(int size) {
- return new ApduServiceInfo[size];
- }
- };
+ @Override
+ public ApduServiceInfo[] newArray(int size) {
+ return new ApduServiceInfo[size];
+ }
+ };
/**
* Dump contents for debugging.
@@ -779,14 +806,16 @@
}
pw.println(" Static AID groups:");
for (AidGroup group : mStaticAidGroups.values()) {
- pw.println(" Category: " + group.getCategory());
+ pw.println(" Category: " + group.getCategory()
+ + "(selected: " + mOtherServiceSelectionState + ")");
for (String aid : group.getAids()) {
pw.println(" AID: " + aid);
}
}
pw.println(" Dynamic AID groups:");
for (AidGroup group : mDynamicAidGroups.values()) {
- pw.println(" Category: " + group.getCategory());
+ pw.println(" Category: " + group.getCategory()
+ + "(selected: " + mOtherServiceSelectionState + ")");
for (String aid : group.getAids()) {
pw.println(" AID: " + aid);
}
@@ -796,6 +825,22 @@
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.
*
diff --git a/core/java/android/nfc/cardemulation/CardEmulation.java b/core/java/android/nfc/cardemulation/CardEmulation.java
index d3b3a78..d048b59 100644
--- a/core/java/android/nfc/cardemulation/CardEmulation.java
+++ b/core/java/android/nfc/cardemulation/CardEmulation.java
@@ -947,6 +947,39 @@
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() {
NfcAdapter adapter = NfcAdapter.getDefaultAdapter(mContext);
sService = adapter.getCardEmulationService();