summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Treehugger Robot <android-test-infra-autosubmit@system.gserviceaccount.com> 2024-02-24 04:43:16 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2024-02-24 04:43:16 +0000
commitec6ff848c3ac88fb7e4223f99c488fe0dea3412c (patch)
treef877f722119f70087efcb92e0e28fcf232ba5483
parent1d41776dcf6eaf7f9c550ca0578d564a418171d7 (diff)
parentc44d59d7dcf478c33218f308adf260a9c2972012 (diff)
Merge changes from topics "dynamic_autotransct", "throw_for_invalid_plf" into main
* changes: Update javadoc to make it clear that polling loop filter needs at least one byte and the implementation to throw if the filter isn't valid. Add boolean autoTransact flag to registerPollingLoopForService()
-rw-r--r--core/api/system-current.txt3
-rw-r--r--nfc/api/current.txt2
-rw-r--r--nfc/java/android/nfc/INfcCardEmulation.aidl2
-rw-r--r--nfc/java/android/nfc/cardemulation/ApduServiceInfo.java26
-rw-r--r--nfc/java/android/nfc/cardemulation/CardEmulation.java39
5 files changed, 31 insertions, 41 deletions
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 062bdaad9f7f..d9b5d56544d6 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -10421,8 +10421,7 @@ package android.nfc.cardemulation {
@FlaggedApi("android.nfc.enable_nfc_mainline") public final class ApduServiceInfo implements android.os.Parcelable {
ctor @FlaggedApi("android.nfc.enable_nfc_mainline") public ApduServiceInfo(@NonNull android.content.pm.PackageManager, @NonNull android.content.pm.ResolveInfo, boolean) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
- method @FlaggedApi("android.nfc.nfc_read_polling_loop") public void addPollingLoopFilter(@NonNull String);
- method @FlaggedApi("android.nfc.nfc_read_polling_loop") public void addPollingLoopFilterToAutoTransact(@NonNull String);
+ method @FlaggedApi("android.nfc.nfc_read_polling_loop") public void addPollingLoopFilter(@NonNull String, boolean);
method @FlaggedApi("android.nfc.nfc_observe_mode") public boolean defaultToObserveMode();
method @FlaggedApi("android.nfc.enable_nfc_mainline") public int describeContents();
method @FlaggedApi("android.nfc.enable_nfc_mainline") public void dump(@NonNull android.os.ParcelFileDescriptor, @NonNull java.io.PrintWriter, @NonNull String[]);
diff --git a/nfc/api/current.txt b/nfc/api/current.txt
index 7b53ca6ea7e9..0fb7c95e3680 100644
--- a/nfc/api/current.txt
+++ b/nfc/api/current.txt
@@ -204,7 +204,7 @@ package android.nfc.cardemulation {
method public boolean isDefaultServiceForAid(android.content.ComponentName, String);
method public boolean isDefaultServiceForCategory(android.content.ComponentName, String);
method public boolean registerAidsForService(android.content.ComponentName, String, java.util.List<java.lang.String>);
- method @FlaggedApi("android.nfc.nfc_read_polling_loop") public boolean registerPollingLoopFilterForService(@NonNull android.content.ComponentName, @NonNull String);
+ method @FlaggedApi("android.nfc.nfc_read_polling_loop") public boolean registerPollingLoopFilterForService(@NonNull android.content.ComponentName, @NonNull String, boolean);
method public boolean removeAidsForService(android.content.ComponentName, String);
method @FlaggedApi("android.nfc.nfc_observe_mode") public boolean setDefaultToObserveModeForService(@NonNull android.content.ComponentName, boolean);
method @NonNull @RequiresPermission(android.Manifest.permission.NFC) public boolean setOffHostForService(@NonNull android.content.ComponentName, @NonNull String);
diff --git a/nfc/java/android/nfc/INfcCardEmulation.aidl b/nfc/java/android/nfc/INfcCardEmulation.aidl
index 65d0625f251e..64f7fa44c12f 100644
--- a/nfc/java/android/nfc/INfcCardEmulation.aidl
+++ b/nfc/java/android/nfc/INfcCardEmulation.aidl
@@ -32,7 +32,7 @@ interface INfcCardEmulation
boolean setDefaultForNextTap(int userHandle, in ComponentName service);
boolean setDefaultToObserveModeForService(int userId, in android.content.ComponentName service, boolean enable);
boolean registerAidGroupForService(int userHandle, in ComponentName service, in AidGroup aidGroup);
- boolean registerPollingLoopFilterForService(int userHandle, in ComponentName service, in String pollingLoopFilter);
+ boolean registerPollingLoopFilterForService(int userHandle, in ComponentName service, in String pollingLoopFilter, boolean autoTransact);
boolean setOffHostForService(int userHandle, in ComponentName service, in String offHostSecureElement);
boolean unsetOffHostForService(int userHandle, in ComponentName service);
AidGroup getAidGroupForService(int userHandle, in ComponentName service, String category);
diff --git a/nfc/java/android/nfc/cardemulation/ApduServiceInfo.java b/nfc/java/android/nfc/cardemulation/ApduServiceInfo.java
index c81b95b7c81b..e62e37bd4ca0 100644
--- a/nfc/java/android/nfc/cardemulation/ApduServiceInfo.java
+++ b/nfc/java/android/nfc/cardemulation/ApduServiceInfo.java
@@ -681,34 +681,18 @@ public final class ApduServiceInfo implements Parcelable {
/**
* Add a Polling Loop Filter. Custom NFC polling frames that match this filter will be
- * delivered to {@link HostApduService#processPollingFrames(List)}. Adding a key with this or
- * {@link ApduServiceInfo#addPollingLoopFilterToAutoTransact(String)} multiple times will
- * cause the value to be overwritten each time.
+ * delivered to {@link HostApduService#processPollingFrames(List)}. Adding a key with this
+ * multiple times will cause the value to be overwritten each time.
* @param pollingLoopFilter the polling loop filter to add, must be a valide hexadecimal string
*/
@FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP)
- public void addPollingLoopFilter(@NonNull String pollingLoopFilter) {
- mAutoTransact.put(pollingLoopFilter.toUpperCase(Locale.ROOT), false);
+ public void addPollingLoopFilter(@NonNull String pollingLoopFilter,
+ boolean autoTransact) {
+ mAutoTransact.put(pollingLoopFilter, autoTransact);
}
/**
- * Add a Polling Loop Filter. Custom NFC polling frames that match this filter will cause the
- * device to exit observe mode, just as if
- * {@link android.nfc.NfcAdapter#setObserveModeEnabled(boolean)} had been called with true,
- * allowing transactions to proceed. The matching frame will also be delivered to
- * {@link HostApduService#processPollingFrames(List)}. Adding a key with this or
- * {@link ApduServiceInfo#addPollingLoopFilter(String)} multiple times will
- * cause the value to be overwritten each time.
- *
- * @param pollingLoopFilter the polling loop filter to add, must be a valide hexadecimal string
- */
- @FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP)
- public void addPollingLoopFilterToAutoTransact(@NonNull String pollingLoopFilter) {
- mAutoTransact.put(pollingLoopFilter.toUpperCase(Locale.ROOT), true);
- }
-
- /**
* Remove a Polling Loop Filter. Custom NFC polling frames that match this filter will no
* longer be delivered to {@link HostApduService#processPollingFrames(List)}.
* @param pollingLoopFilter this polling loop filter to add.
diff --git a/nfc/java/android/nfc/cardemulation/CardEmulation.java b/nfc/java/android/nfc/cardemulation/CardEmulation.java
index e681a8568300..47ddd9de224f 100644
--- a/nfc/java/android/nfc/cardemulation/CardEmulation.java
+++ b/nfc/java/android/nfc/cardemulation/CardEmulation.java
@@ -42,6 +42,7 @@ import android.provider.Settings.SettingNotFoundException;
import android.util.Log;
import java.util.HashMap;
+import java.util.HexFormat;
import java.util.List;
import java.util.regex.Pattern;
@@ -59,7 +60,6 @@ import java.util.regex.Pattern;
*/
public final class CardEmulation {
private static final Pattern AID_PATTERN = Pattern.compile("[0-9A-Fa-f]{10,32}\\*?\\#?");
- private static final Pattern PLF_PATTERN = Pattern.compile("[0-9A-Fa-f]{1,32}");
static final String TAG = "CardEmulation";
@@ -360,21 +360,28 @@ public final class CardEmulation {
}
/**
- * Register a polling loop filter (PLF) for a HostApduService. The PLF can be sequence of an
- * even number of hexadecimal numbers (0-9, A-F or a-f). When non-standard polling loop frame
- * matches this sequence exactly, it may be delivered to
- * {@link HostApduService#processPollingFrames(List)} if this service is currently
- * preferred or there are no other services registered for this filter.
+ * Register a polling loop filter (PLF) for a HostApduService and indicate whether it should
+ * auto-transact or not. The PLF can be sequence of an
+ * even number of at least 2 hexadecimal numbers (0-9, A-F or a-f), representing a series of
+ * bytes. When non-standard polling loop frame matches this sequence exactly, it may be
+ * delivered to {@link HostApduService#processPollingFrames(List)}. If auto-transact is set to
+ * true, then observe mode will also be disabled. if this service is currently preferred or
+ * there are no other services registered for this filter.
* @param service The HostApduService to register the filter for
* @param pollingLoopFilter The filter to register
+ * @param autoTransact true to have the NFC stack automatically disable observe mode and allow
+ * transactions to proceed when this filter matches, false otherwise
* @return true if the filter was registered, false otherwise
+ * @throws IllegalArgumentException if the passed in string doesn't parse to at least one byte
*/
@FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP)
public boolean registerPollingLoopFilterForService(@NonNull ComponentName service,
- @NonNull String pollingLoopFilter) {
+ @NonNull String pollingLoopFilter, boolean autoTransact) {
+ pollingLoopFilter = validatePollingLoopFilter(pollingLoopFilter);
+
try {
return sService.registerPollingLoopFilterForService(mContext.getUser().getIdentifier(),
- service, pollingLoopFilter);
+ service, pollingLoopFilter, autoTransact);
} catch (RemoteException e) {
// Try one more time
recoverService();
@@ -384,7 +391,8 @@ public final class CardEmulation {
}
try {
return sService.registerPollingLoopFilterForService(
- mContext.getUser().getIdentifier(), service, pollingLoopFilter);
+ mContext.getUser().getIdentifier(), service,
+ pollingLoopFilter, autoTransact);
} catch (RemoteException ee) {
Log.e(TAG, "Failed to reach CardEmulationService.");
return false;
@@ -979,15 +987,14 @@ public final class CardEmulation {
* @hide
*/
@FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP)
- public static boolean isValidPollingLoopFilter(@NonNull String pollingLoopFilter) {
+ public static @NonNull String validatePollingLoopFilter(@NonNull String pollingLoopFilter) {
// Verify hex characters
- if (!PLF_PATTERN.matcher(pollingLoopFilter).matches()) {
- Log.e(TAG, "Polling Loop Filter " + pollingLoopFilter
- + " is not a valid Polling Loop Filter.");
- return false;
+ byte[] plfBytes = HexFormat.of().parseHex(pollingLoopFilter);
+ if (plfBytes.length == 0) {
+ throw new IllegalArgumentException(
+ "Polling loop filter must contain at least one byte.");
}
-
- return true;
+ return HexFormat.of().withUpperCase().formatHex(plfBytes);
}
/**