Merge "Add NFC TagIntentAppPreference System API" am: ab5d84cf41

Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/2337344

Change-Id: I5d79ad211ce3b26ee91bff699fadf9b9268f05a1
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Treehugger Robot
2023-01-18 22:33:04 +00:00
committed by Automerger Merge Worker
3 changed files with 187 additions and 0 deletions

View File

@@ -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 {

View File

@@ -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);
}

View File

@@ -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;
}
}
}