Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5ed8f129 authored by Roshan Pius's avatar Roshan Pius
Browse files

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
parent 6fff31bf
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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
+9 −0
Original line number Diff line number Diff line
@@ -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: [
+36 −0
Original line number Diff line number Diff line
@@ -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.
     *
+2 −0
Original line number Diff line number Diff line
@@ -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",
+28 −7
Original line number Diff line number Diff line
@@ -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];