diff options
| author | 2023-10-19 10:34:28 -0700 | |
|---|---|---|
| committer | 2023-10-19 13:13:46 -0700 | |
| commit | 5ed8f129a5b6c0580ae3175b7e1e921b31f67f9f (patch) | |
| tree | e2653888d8d504f1a210ce42f84ea360f87d359c | |
| parent | 6fff31bf3fc3e9d2c9cb94a0c64e0447b1e801e0 (diff) | |
nfc(api): Create privileged setReaderMode API
Since NFC is becoming a mainline module, the existing CameraServiceProxy
usage of raw INfcAdapter aidl interface will not be mainline compatible.
So, create a system api to formalize this API usage. This has also been
requested by the DCK team previously.
Also, preserve the existing INfcAdapter usage behind the flag by
including INfcAdapter file directly inside services/core.
Bug: 303286040
Bug: 290843937
Test: atest CtsNfcTestCases
Change-Id: I09b9bc58bd4f7cea705a0a17268448dde2bfef0a
| -rw-r--r-- | core/api/system-current.txt | 1 | ||||
| -rw-r--r-- | core/java/Android.bp | 9 | ||||
| -rw-r--r-- | core/java/android/nfc/NfcAdapter.java | 36 | ||||
| -rw-r--r-- | services/core/Android.bp | 2 | ||||
| -rw-r--r-- | services/core/java/com/android/server/camera/CameraServiceProxy.java | 35 |
5 files changed, 76 insertions, 7 deletions
diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 64734f4dc762..64ea1ab0c826 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -10251,6 +10251,7 @@ package android.nfc { 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 @FlaggedApi("android.nfc.enable_nfc_mainline") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void setReaderMode(boolean); 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 TAG_INTENT_APP_PREF_RESULT_PACKAGE_NOT_FOUND = -1; // 0xffffffff diff --git a/core/java/Android.bp b/core/java/Android.bp index 70864d532986..26b758189996 100644 --- a/core/java/Android.bp +++ b/core/java/Android.bp @@ -14,6 +14,15 @@ aidl_library { hdrs: ["android/hardware/HardwareBuffer.aidl"], } +// TODO (b/303286040): Remove this once |ENABLE_NFC_MAINLINE_FLAG| is rolled out +filegroup { + name: "framework-core-nfc-infcadapter-sources", + srcs: [ + "android/nfc/INfcAdapter.aidl", + ], + visibility: ["//frameworks/base/services/core"], +} + filegroup { name: "framework-core-sources", srcs: [ diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java index 46586308e3cf..4a7bd3f29458 100644 --- a/core/java/android/nfc/NfcAdapter.java +++ b/core/java/android/nfc/NfcAdapter.java @@ -24,6 +24,7 @@ import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; +import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.annotation.UserIdInt; import android.app.Activity; @@ -37,6 +38,7 @@ import android.nfc.tech.MifareClassic; import android.nfc.tech.Ndef; import android.nfc.tech.NfcA; import android.nfc.tech.NfcF; +import android.os.Binder; import android.os.Build; import android.os.Bundle; import android.os.Handler; @@ -1594,6 +1596,40 @@ public final class NfcAdapter { mNfcActivityManager.disableReaderMode(activity); } + // Flags arguments to NFC adapter to enable/disable NFC + private static final int DISABLE_POLLING_FLAGS = 0x1000; + private static final int ENABLE_POLLING_FLAGS = 0x0000; + + /** + * Privileged API to enable disable reader polling. + * Note: Use with caution! The app is responsible for ensuring that the polling state is + * returned to normal. + * + * @see #enableReaderMode(Activity, ReaderCallback, int, Bundle) for more detailed + * documentation. + * + * @param enablePolling whether to enable or disable polling. + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) + @SuppressLint("VisiblySynchronized") + public void setReaderMode(boolean enablePolling) { + synchronized (NfcAdapter.class) { + if (!sHasNfcFeature) { + throw new UnsupportedOperationException(); + } + } + Binder token = new Binder(); + int flags = enablePolling ? ENABLE_POLLING_FLAGS : DISABLE_POLLING_FLAGS; + try { + NfcAdapter.sService.setReaderMode(token, null, flags, null); + } catch (RemoteException e) { + attemptDeadServiceRecovery(e); + } + } + /** * Manually invoke Android Beam to share data. * diff --git a/services/core/Android.bp b/services/core/Android.bp index 9ac30f334d0b..189ab19763ac 100644 --- a/services/core/Android.bp +++ b/services/core/Android.bp @@ -118,6 +118,7 @@ java_library_static { ":display-device-config", ":display-layout-config", ":device-state-config", + ":framework-core-nfc-infcadapter-sources", "java/com/android/server/EventLogTags.logtags", "java/com/android/server/am/EventLogTags.logtags", "java/com/android/server/wm/EventLogTags.logtags", @@ -178,6 +179,7 @@ java_library_static { "android.hardware.power.stats-V2-java", "android.hardware.power-V4-java", "android.hidl.manager-V1.2-java", + "android.nfc.flags-aconfig-java", "cbor-java", "icu4j_calendar_astronomer", "android.security.aaid_aidl-java", diff --git a/services/core/java/com/android/server/camera/CameraServiceProxy.java b/services/core/java/com/android/server/camera/CameraServiceProxy.java index f8f0088ac047..3c885a145315 100644 --- a/services/core/java/com/android/server/camera/CameraServiceProxy.java +++ b/services/core/java/com/android/server/camera/CameraServiceProxy.java @@ -53,6 +53,8 @@ import android.hardware.usb.UsbDevice; import android.hardware.usb.UsbManager; import android.media.AudioManager; import android.nfc.INfcAdapter; +import android.nfc.NfcAdapter; +import android.nfc.NfcManager; import android.os.Binder; import android.os.Handler; import android.os.HandlerExecutor; @@ -162,10 +164,6 @@ public class CameraServiceProxy extends SystemService * SCALER_ROTATE_AND_CROP_NONE -> Always return CaptureRequest.SCALER_ROTATE_AND_CROP_NONE */ - // Flags arguments to NFC adapter to enable/disable NFC - public static final int DISABLE_POLLING_FLAGS = 0x1000; - public static final int ENABLE_POLLING_FLAGS = 0x0000; - // Handler message codes private static final int MSG_SWITCH_USER = 1; private static final int MSG_NOTIFY_DEVICE_STATE = 2; @@ -215,7 +213,6 @@ public class CameraServiceProxy extends SystemService private final List<CameraUsageEvent> mCameraUsageHistory = new ArrayList<>(); private static final String NFC_NOTIFICATION_PROP = "ro.camera.notify_nfc"; - private static final String NFC_SERVICE_BINDER_NAME = "nfc"; private static final IBinder nfcInterfaceToken = new Binder(); private final boolean mNotifyNfc; @@ -1255,8 +1252,13 @@ public class CameraServiceProxy extends SystemService } } - private void notifyNfcService(boolean enablePolling) { - + // TODO(b/303286040): Remove the raw INfcAdapter usage once |ENABLE_NFC_MAINLINE_FLAG| is + // rolled out. + private static final String NFC_SERVICE_BINDER_NAME = "nfc"; + // Flags arguments to NFC adapter to enable/disable NFC + public static final int DISABLE_POLLING_FLAGS = 0x1000; + public static final int ENABLE_POLLING_FLAGS = 0x0000; + private void setNfcReaderModeUsingINfcAdapter(boolean enablePolling) { IBinder nfcServiceBinder = getBinderService(NFC_SERVICE_BINDER_NAME); if (nfcServiceBinder == null) { Slog.w(TAG, "Could not connect to NFC service to notify it of camera state"); @@ -1272,6 +1274,25 @@ public class CameraServiceProxy extends SystemService } } + private void notifyNfcService(boolean enablePolling) { + if (android.nfc.Flags.enableNfcMainline()) { + NfcManager nfcManager = mContext.getSystemService(NfcManager.class); + if (nfcManager == null) { + Slog.w(TAG, "Could not connect to NFC service to notify it of camera state"); + return; + } + NfcAdapter nfcAdapter = nfcManager.getDefaultAdapter(); + if (nfcAdapter == null) { + Slog.w(TAG, "Could not connect to NFC service to notify it of camera state"); + return; + } + if (DEBUG) Slog.v(TAG, "Setting NFC reader mode. enablePolling: " + enablePolling); + nfcAdapter.setReaderMode(enablePolling); + } else { + setNfcReaderModeUsingINfcAdapter(enablePolling); + } + } + private static int[] toArray(Collection<Integer> c) { int len = c.size(); int[] ret = new int[len]; |