summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTreehugger Robot <treehugger-gerrit@google.com>2023-01-18 22:08:06 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2023-01-18 22:08:06 +0000
commitab5d84cf410abdb5c850166ce72cf3c873484876 (patch)
tree47d9a4b53bf6a5e56de036a153579f30310e0eeb
parent49d070c4e578ec24e550d506f582018d1d58c480 (diff)
parentba43e33ca5838914e4d9975527a68057efec3274 (diff)
downloadbase-ab5d84cf410abdb5c850166ce72cf3c873484876.tar.gz
Merge "Add NFC TagIntentAppPreference System API"
-rw-r--r--core/api/system-current.txt6
-rw-r--r--core/java/android/nfc/INfcAdapter.aidl6
-rw-r--r--core/java/android/nfc/NfcAdapter.java175
3 files changed, 187 insertions, 0 deletions
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 6eddc3c097c6..49a5aa76a6ac 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -9120,14 +9120,20 @@ package android.nfc {
method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enable();
method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enableNdefPush();
method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enableSecureNfc(boolean);
+ method @NonNull @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public java.util.Map<java.lang.String,java.lang.Boolean> getTagIntentAppPreferenceForUser(int);
method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public boolean isControllerAlwaysOn();
method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public boolean isControllerAlwaysOnSupported();
+ method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean isTagIntentAppPreferenceSupported();
method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public void registerControllerAlwaysOnListener(@NonNull java.util.concurrent.Executor, @NonNull android.nfc.NfcAdapter.ControllerAlwaysOnListener);
method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean removeNfcUnlockHandler(android.nfc.NfcAdapter.NfcUnlockHandler);
method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public boolean setControllerAlwaysOn(boolean);
method public void setNdefPushMessage(android.nfc.NdefMessage, android.app.Activity, int);
+ method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int setTagIntentAppPreferenceForUser(int, @NonNull String, boolean);
method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public void unregisterControllerAlwaysOnListener(@NonNull android.nfc.NfcAdapter.ControllerAlwaysOnListener);
field public static final int FLAG_NDEF_PUSH_NO_CONFIRM = 1; // 0x1
+ field public static final int TAG_INTENT_APP_PREF_RESULT_PACKAGE_NOT_FOUND = -1; // 0xffffffff
+ field public static final int TAG_INTENT_APP_PREF_RESULT_SUCCESS = 0; // 0x0
+ field public static final int TAG_INTENT_APP_PREF_RESULT_UNAVAILABLE = -2; // 0xfffffffe
}
public static interface NfcAdapter.ControllerAlwaysOnListener {
diff --git a/core/java/android/nfc/INfcAdapter.aidl b/core/java/android/nfc/INfcAdapter.aidl
index de107a2c7c70..8a30ef4c2121 100644
--- a/core/java/android/nfc/INfcAdapter.aidl
+++ b/core/java/android/nfc/INfcAdapter.aidl
@@ -80,4 +80,10 @@ interface INfcAdapter
boolean isControllerAlwaysOnSupported();
void registerControllerAlwaysOnListener(in INfcControllerAlwaysOnListener listener);
void unregisterControllerAlwaysOnListener(in INfcControllerAlwaysOnListener listener);
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)")
+ boolean isTagIntentAppPreferenceSupported();
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)")
+ Map getTagIntentAppPreferenceForUser(int userId);
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)")
+ int setTagIntentAppPreferenceForUser(int userId, String pkg, boolean allow);
}
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index 0c7f52999513..a980158a2e5e 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -17,12 +17,14 @@
package android.nfc;
import android.annotation.CallbackExecutor;
+import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SystemApi;
+import android.annotation.UserIdInt;
import android.app.Activity;
import android.app.ActivityThread;
import android.app.OnActivityPausedListener;
@@ -46,9 +48,14 @@ import android.os.ServiceManager;
import android.util.Log;
import java.io.IOException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
+import java.util.Map;
+import java.util.Objects;
import java.util.concurrent.Executor;
/**
@@ -371,6 +378,45 @@ public final class NfcAdapter {
public static final String ACTION_REQUIRE_UNLOCK_FOR_NFC =
"android.nfc.action.REQUIRE_UNLOCK_FOR_NFC";
+ /**
+ * The requested app is correctly added to the Tag intent app preference.
+ *
+ * @see #setTagIntentAppPreferenceForUser(int userId, String pkg, boolean allow)
+ * @hide
+ */
+ @SystemApi
+ public static final int TAG_INTENT_APP_PREF_RESULT_SUCCESS = 0;
+
+ /**
+ * The requested app is not installed on the device.
+ *
+ * @see #setTagIntentAppPreferenceForUser(int userId, String pkg, boolean allow)
+ * @hide
+ */
+ @SystemApi
+ public static final int TAG_INTENT_APP_PREF_RESULT_PACKAGE_NOT_FOUND = -1;
+
+ /**
+ * The NfcService is not available.
+ *
+ * @see #setTagIntentAppPreferenceForUser(int userId, String pkg, boolean allow)
+ * @hide
+ */
+ @SystemApi
+ public static final int TAG_INTENT_APP_PREF_RESULT_UNAVAILABLE = -2;
+
+ /**
+ * Possible response codes from {@link #setTagIntentAppPreferenceForUser}.
+ *
+ * @hide
+ */
+ @IntDef(prefix = { "TAG_INTENT_APP_PREF_RESULT" }, value = {
+ TAG_INTENT_APP_PREF_RESULT_SUCCESS,
+ TAG_INTENT_APP_PREF_RESULT_PACKAGE_NOT_FOUND,
+ TAG_INTENT_APP_PREF_RESULT_UNAVAILABLE})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface TagIntentAppPreferenceResult {}
+
// Guarded by NfcAdapter.class
static boolean sIsInitialized = false;
static boolean sHasNfcFeature;
@@ -2408,4 +2454,133 @@ public final class NfcAdapter {
@NonNull ControllerAlwaysOnListener listener) {
mControllerAlwaysOnListener.unregister(listener);
}
+
+
+ /**
+ * Sets whether we dispatch NFC Tag intents to the package.
+ *
+ * <p>{@link #ACTION_NDEF_DISCOVERED}, {@link #ACTION_TECH_DISCOVERED} or
+ * {@link #ACTION_TAG_DISCOVERED} will not be dispatched to an Activity if its package is
+ * disallowed.
+ * <p>An app is added to the preference list with the allowed flag set to {@code true}
+ * when a Tag intent is dispatched to the package for the first time. This API is called
+ * by settings to note that the user wants to change this default preference.
+ *
+ * @param userId the user to whom this package name will belong to
+ * @param pkg the full name (i.e. com.google.android.tag) of the package that will be added to
+ * the preference list
+ * @param allow {@code true} to allow dispatching Tag intents to the package's activity,
+ * {@code false} otherwise
+ * @return the {@link #TagIntentAppPreferenceResult} value
+ * @throws UnsupportedOperationException if {@link isTagIntentAppPreferenceSupported} returns
+ * {@code false}
+ *
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
+ @TagIntentAppPreferenceResult
+ public int setTagIntentAppPreferenceForUser(@UserIdInt int userId,
+ @NonNull String pkg, boolean allow) {
+ Objects.requireNonNull(pkg, "pkg cannot be null");
+ if (!isTagIntentAppPreferenceSupported()) {
+ Log.e(TAG, "TagIntentAppPreference is not supported");
+ throw new UnsupportedOperationException();
+ }
+ try {
+ return sService.setTagIntentAppPreferenceForUser(userId, pkg, allow);
+ } catch (RemoteException e) {
+ attemptDeadServiceRecovery(e);
+ // Try one more time
+ if (sService == null) {
+ Log.e(TAG, "Failed to recover NFC Service.");
+ }
+ try {
+ return sService.setTagIntentAppPreferenceForUser(userId, pkg, allow);
+ } catch (RemoteException ee) {
+ Log.e(TAG, "Failed to recover NFC Service.");
+ }
+ return TAG_INTENT_APP_PREF_RESULT_UNAVAILABLE;
+ }
+ }
+
+
+ /**
+ * Get the Tag dispatch preference list of the UserId.
+ *
+ * <p>This returns a mapping of package names for this user id to whether we dispatch Tag
+ * intents to the package. {@link #ACTION_NDEF_DISCOVERED}, {@link #ACTION_TECH_DISCOVERED} or
+ * {@link #ACTION_TAG_DISCOVERED} will not be dispatched to an Activity if its package is
+ * disallowed.
+ *
+ * @param userId the user to whom this preference list will belong to
+ * @return a map of the UserId which indicates the mapping from package name to
+ * boolean(allow status), otherwise return an empty map
+ * @throws UnsupportedOperationException if {@link isTagIntentAppPreferenceSupported} returns
+ * {@code false}
+ *
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
+ @NonNull
+ public Map<String, Boolean> getTagIntentAppPreferenceForUser(@UserIdInt int userId) {
+ if (!isTagIntentAppPreferenceSupported()) {
+ Log.e(TAG, "TagIntentAppPreference is not supported");
+ throw new UnsupportedOperationException();
+ }
+ try {
+ Map<String, Boolean> result = (Map<String, Boolean>) sService
+ .getTagIntentAppPreferenceForUser(userId);
+ return result;
+ } catch (RemoteException e) {
+ attemptDeadServiceRecovery(e);
+ // Try one more time
+ if (sService == null) {
+ Log.e(TAG, "Failed to recover NFC Service.");
+ return Collections.emptyMap();
+ }
+ try {
+ Map<String, Boolean> result = (Map<String, Boolean>) sService
+ .getTagIntentAppPreferenceForUser(userId);
+ return result;
+ } catch (RemoteException ee) {
+ Log.e(TAG, "Failed to recover NFC Service.");
+ }
+ return Collections.emptyMap();
+ }
+ }
+
+ /**
+ * Checks if the device supports Tag application preference.
+ *
+ * @return {@code true} if the device supports Tag application preference, {@code false}
+ * otherwise
+ * @throws UnsupportedOperationException if FEATURE_NFC is unavailable
+ *
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
+ public boolean isTagIntentAppPreferenceSupported() {
+ if (!sHasNfcFeature) {
+ throw new UnsupportedOperationException();
+ }
+ try {
+ return sService.isTagIntentAppPreferenceSupported();
+ } catch (RemoteException e) {
+ attemptDeadServiceRecovery(e);
+ // Try one more time
+ if (sService == null) {
+ Log.e(TAG, "Failed to recover NFC Service.");
+ return false;
+ }
+ try {
+ return sService.isTagIntentAppPreferenceSupported();
+ } catch (RemoteException ee) {
+ Log.e(TAG, "Failed to recover NFC Service.");
+ }
+ return false;
+ }
+ }
}