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

Commit a0de319f authored by Alisher Alikhodjaev's avatar Alisher Alikhodjaev
Browse files

Implementation of Dedicated card mode APIs changes

(Discovery tech and Change Routing)

Bug: 300351519
Test: n/a
Change-Id: If664910d00fc673c0329e0cd4489174260eb4f1e
(cherry picked from commit 04a371696f7d882f151d1b0ae4dd262fda9e4452)
parent 2d1d2cce
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -28823,6 +28823,8 @@ package android.nfc {
    method public boolean isSecureNfcEnabled();
    method public boolean isSecureNfcSupported();
    method @FlaggedApi("android.nfc.enable_nfc_charging") public boolean isWlcEnabled();
    method @FlaggedApi("android.nfc.enable_nfc_set_discovery_tech") public void resetDiscoveryTechnology(@NonNull android.app.Activity);
    method @FlaggedApi("android.nfc.enable_nfc_set_discovery_tech") public void setDiscoveryTechnology(@NonNull android.app.Activity, int, int);
    field public static final String ACTION_ADAPTER_STATE_CHANGED = "android.nfc.action.ADAPTER_STATE_CHANGED";
    field public static final String ACTION_NDEF_DISCOVERED = "android.nfc.action.NDEF_DISCOVERED";
    field @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) public static final String ACTION_PREFERRED_PAYMENT_CHANGED = "android.nfc.action.PREFERRED_PAYMENT_CHANGED";
@@ -28838,6 +28840,13 @@ package android.nfc {
    field public static final String EXTRA_READER_PRESENCE_CHECK_DELAY = "presence";
    field public static final String EXTRA_SECURE_ELEMENT_NAME = "android.nfc.extra.SECURE_ELEMENT_NAME";
    field public static final String EXTRA_TAG = "android.nfc.extra.TAG";
    field @FlaggedApi("android.nfc.enable_nfc_set_discovery_tech") public static final int FLAG_LISTEN_DISABLE = 0; // 0x0
    field @FlaggedApi("android.nfc.enable_nfc_set_discovery_tech") public static final int FLAG_LISTEN_KEEP = -1; // 0xffffffff
    field @FlaggedApi("android.nfc.enable_nfc_set_discovery_tech") public static final int FLAG_LISTEN_NFC_PASSIVE_A = 1; // 0x1
    field @FlaggedApi("android.nfc.enable_nfc_set_discovery_tech") public static final int FLAG_LISTEN_NFC_PASSIVE_B = 2; // 0x2
    field @FlaggedApi("android.nfc.enable_nfc_set_discovery_tech") public static final int FLAG_LISTEN_NFC_PASSIVE_F = 4; // 0x4
    field @FlaggedApi("android.nfc.enable_nfc_set_discovery_tech") public static final int FLAG_READER_DISABLE = 0; // 0x0
    field @FlaggedApi("android.nfc.enable_nfc_set_discovery_tech") public static final int FLAG_READER_KEEP = -1; // 0xffffffff
    field public static final int FLAG_READER_NFC_A = 1; // 0x1
    field public static final int FLAG_READER_NFC_B = 2; // 0x2
    field public static final int FLAG_READER_NFC_BARCODE = 16; // 0x10
+2 −0
Original line number Diff line number Diff line
@@ -95,4 +95,6 @@ interface INfcAdapter
    void registerWlcStateListener(in INfcWlcStateListener listener);
    void unregisterWlcStateListener(in INfcWlcStateListener listener);
    WlcLDeviceInfo getWlcLDeviceInfo();

    void updateDiscoveryTechnology(IBinder b, int pollFlags, int listenFlags);
}
+3 −0
Original line number Diff line number Diff line
@@ -43,4 +43,7 @@ interface INfcCardEmulation
    ApduServiceInfo getPreferredPaymentService(int userHandle);
    boolean setServiceEnabledForCategoryOther(int userHandle, in ComponentName app, boolean status);
    boolean isDefaultPaymentRegistered();

    boolean overrideRoutingTable(int userHandle, String protocol, String technology);
    boolean recoverRoutingTable(int userHandle);
}
+74 −0
Original line number Diff line number Diff line
@@ -112,6 +112,9 @@ public final class NfcActivityManager extends IAppCallback.Stub
        Bundle readerModeExtras = null;
        Binder token;

        int mPollTech = NfcAdapter.FLAG_USE_ALL_TECH;
        int mListenTech = NfcAdapter.FLAG_USE_ALL_TECH;

        public NfcActivityState(Activity activity) {
            if (activity.isDestroyed()) {
                throw new IllegalStateException("activity is already destroyed");
@@ -132,6 +135,9 @@ public final class NfcActivityManager extends IAppCallback.Stub
            readerModeFlags = 0;
            readerModeExtras = null;
            token = null;

            mPollTech = NfcAdapter.FLAG_USE_ALL_TECH;
            mListenTech = NfcAdapter.FLAG_USE_ALL_TECH;
        }
        @Override
        public String toString() {
@@ -278,6 +284,9 @@ public final class NfcActivityManager extends IAppCallback.Stub
        int readerModeFlags = 0;
        Bundle readerModeExtras = null;
        Binder token;
        int pollTech;
        int listenTech;

        synchronized (NfcActivityManager.this) {
            NfcActivityState state = findActivityState(activity);
            if (DBG) Log.d(TAG, "onResume() for " + activity + " " + state);
@@ -286,9 +295,15 @@ public final class NfcActivityManager extends IAppCallback.Stub
            token = state.token;
            readerModeFlags = state.readerModeFlags;
            readerModeExtras = state.readerModeExtras;

            pollTech = state.mPollTech;
            listenTech = state.mListenTech;
        }
        if (readerModeFlags != 0) {
            setReaderMode(token, readerModeFlags, readerModeExtras);
        } else if (listenTech != NfcAdapter.FLAG_USE_ALL_TECH
                || pollTech != NfcAdapter.FLAG_USE_ALL_TECH) {
            changeDiscoveryTech(token, pollTech, listenTech);
        }
        requestNfcServiceCallback();
    }
@@ -298,6 +313,9 @@ public final class NfcActivityManager extends IAppCallback.Stub
    public void onActivityPaused(Activity activity) {
        boolean readerModeFlagsSet;
        Binder token;
        int pollTech;
        int listenTech;

        synchronized (NfcActivityManager.this) {
            NfcActivityState state = findActivityState(activity);
            if (DBG) Log.d(TAG, "onPause() for " + activity + " " + state);
@@ -305,10 +323,17 @@ public final class NfcActivityManager extends IAppCallback.Stub
            state.resumed = false;
            token = state.token;
            readerModeFlagsSet = state.readerModeFlags != 0;

            pollTech = state.mPollTech;
            listenTech = state.mListenTech;
        }
        if (readerModeFlagsSet) {
            // Restore default p2p modes
            setReaderMode(token, 0, null);
        } else if (listenTech != NfcAdapter.FLAG_USE_ALL_TECH
                || pollTech != NfcAdapter.FLAG_USE_ALL_TECH) {
            changeDiscoveryTech(token,
                    NfcAdapter.FLAG_USE_ALL_TECH, NfcAdapter.FLAG_USE_ALL_TECH);
        }
    }

@@ -333,4 +358,53 @@ public final class NfcActivityManager extends IAppCallback.Stub
        }
    }

    /** setDiscoveryTechnology() implementation */
    public void setDiscoveryTech(Activity activity, int pollTech, int listenTech) {
        boolean isResumed;
        Binder token;
        boolean readerModeFlagsSet;
        synchronized (NfcActivityManager.this) {
            NfcActivityState state = getActivityState(activity);
            readerModeFlagsSet = state.readerModeFlags != 0;
            state.mListenTech = listenTech;
            state.mPollTech = pollTech;
            token = state.token;
            isResumed = state.resumed;
        }
        if (!readerModeFlagsSet && isResumed) {
            changeDiscoveryTech(token, pollTech, listenTech);
        } else if (readerModeFlagsSet) {
            throw new IllegalStateException("Cannot be used when the Reader Mode is enabled");
        }
    }

    /** resetDiscoveryTechnology() implementation */
    public void resetDiscoveryTech(Activity activity) {
        boolean isResumed;
        Binder token;
        boolean readerModeFlagsSet;
        synchronized (NfcActivityManager.this) {
            NfcActivityState state = getActivityState(activity);
            readerModeFlagsSet = state.readerModeFlags != 0;
            state.mListenTech = NfcAdapter.FLAG_USE_ALL_TECH;
            state.mPollTech = NfcAdapter.FLAG_USE_ALL_TECH;
            token = state.token;
            isResumed = state.resumed;
        }
        if (readerModeFlagsSet) {
            disableReaderMode(activity);
        } else if (isResumed) {
            changeDiscoveryTech(token, NfcAdapter.FLAG_USE_ALL_TECH, NfcAdapter.FLAG_USE_ALL_TECH);
        }

    }

    private void changeDiscoveryTech(Binder token, int pollTech, int listenTech) {
        try {
            NfcAdapter.sService.updateDiscoveryTechnology(token, pollTech, listenTech);
        } catch (RemoteException e) {
            mAdapter.attemptDeadServiceRecovery(e);
        }
    }

}
+177 −18
Original line number Diff line number Diff line
@@ -333,6 +333,19 @@ public final class NfcAdapter {
     */
    public static final int FLAG_READER_NFC_BARCODE = 0x10;

    /** @hide */
    @IntDef(flag = true, prefix = {"FLAG_READER_"}, value = {
        FLAG_READER_KEEP,
        FLAG_READER_DISABLE,
        FLAG_READER_NFC_A,
        FLAG_READER_NFC_B,
        FLAG_READER_NFC_F,
        FLAG_READER_NFC_V,
        FLAG_READER_NFC_BARCODE
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface PollTechnology {}

    /**
     * Flag for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}.
     * <p>
@@ -359,6 +372,76 @@ public final class NfcAdapter {
     */
    public static final String EXTRA_READER_PRESENCE_CHECK_DELAY = "presence";

    /**
     * Flag for use with {@link #setDiscoveryTechnology(Activity, int, int)}.
     * <p>
     * Setting this flag enables listening for Nfc-A technology.
     */
    @FlaggedApi(Flags.FLAG_ENABLE_NFC_SET_DISCOVERY_TECH)
    public static final int FLAG_LISTEN_NFC_PASSIVE_A = 0x1;

    /**
     * Flag for use with {@link #setDiscoveryTechnology(Activity, int, int)}.
     * <p>
     * Setting this flag enables listening for Nfc-B technology.
     */
    @FlaggedApi(Flags.FLAG_ENABLE_NFC_SET_DISCOVERY_TECH)
    public static final int FLAG_LISTEN_NFC_PASSIVE_B = 1 << 1;

    /**
     * Flag for use with {@link #setDiscoveryTechnology(Activity, int, int)}.
     * <p>
     * Setting this flag enables listening for Nfc-F technology.
     */
    @FlaggedApi(Flags.FLAG_ENABLE_NFC_SET_DISCOVERY_TECH)
    public static final int FLAG_LISTEN_NFC_PASSIVE_F = 1 << 2;

    /**
     * Flags for use with {@link #setDiscoveryTechnology(Activity, int, int)}.
     * <p>
     * Setting this flag disables listening.
     */
    @FlaggedApi(Flags.FLAG_ENABLE_NFC_SET_DISCOVERY_TECH)
    public static final int FLAG_LISTEN_DISABLE = 0x0;

    /**
     * Flags for use with {@link #setDiscoveryTechnology(Activity, int, int)}.
     * <p>
     * Setting this flag disables polling.
     */
    @FlaggedApi(Flags.FLAG_ENABLE_NFC_SET_DISCOVERY_TECH)
    public static final int FLAG_READER_DISABLE = 0x0;

    /**
     * Flags for use with {@link #setDiscoveryTechnology(Activity, int, int)}.
     * <p>
     * Setting this flag makes listening to use current flags.
     */
    @FlaggedApi(Flags.FLAG_ENABLE_NFC_SET_DISCOVERY_TECH)
    public static final int FLAG_LISTEN_KEEP = -1;

    /**
     * Flags for use with {@link #setDiscoveryTechnology(Activity, int, int)}.
     * <p>
     * Setting this flag makes polling to use current flags.
     */
    @FlaggedApi(Flags.FLAG_ENABLE_NFC_SET_DISCOVERY_TECH)
    public static final int FLAG_READER_KEEP = -1;

    /** @hide */
    public static final int FLAG_USE_ALL_TECH = 0xff;

    /** @hide */
    @IntDef(flag = true, prefix = {"FLAG_LISTEN_"}, value = {
        FLAG_LISTEN_KEEP,
        FLAG_LISTEN_DISABLE,
        FLAG_LISTEN_NFC_PASSIVE_A,
        FLAG_LISTEN_NFC_PASSIVE_B,
        FLAG_LISTEN_NFC_PASSIVE_F
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface ListenTechnology {}

    /**
     * @hide
     * @removed
@@ -437,12 +520,14 @@ public final class NfcAdapter {
    @Retention(RetentionPolicy.SOURCE)
    public @interface TagIntentAppPreferenceResult {}

    // Guarded by NfcAdapter.class
    // Guarded by sLock
    static boolean sIsInitialized = false;
    static boolean sHasNfcFeature;
    static boolean sHasCeFeature;
    static boolean sHasNfcWlcFeature;

    static Object sLock = new Object();

    // Final after first constructor, except for
    // attemptDeadServiceRecovery() when NFC crashes - we accept a best effort
    // recovery
@@ -1235,7 +1320,7 @@ public final class NfcAdapter {
    @java.lang.Deprecated
    @UnsupportedAppUsage
    public void setBeamPushUris(Uri[] uris, Activity activity) {
        synchronized (NfcAdapter.class) {
        synchronized (sLock) {
            if (!sHasNfcFeature) {
                throw new UnsupportedOperationException();
            }
@@ -1305,7 +1390,7 @@ public final class NfcAdapter {
    @java.lang.Deprecated
    @UnsupportedAppUsage
    public void setBeamPushUrisCallback(CreateBeamUrisCallback callback, Activity activity) {
        synchronized (NfcAdapter.class) {
        synchronized (sLock) {
            if (!sHasNfcFeature) {
                throw new UnsupportedOperationException();
            }
@@ -1390,7 +1475,7 @@ public final class NfcAdapter {
    @UnsupportedAppUsage
    public void setNdefPushMessage(NdefMessage message, Activity activity,
            Activity ... activities) {
        synchronized (NfcAdapter.class) {
        synchronized (sLock) {
            if (!sHasNfcFeature) {
                throw new UnsupportedOperationException();
            }
@@ -1404,7 +1489,7 @@ public final class NfcAdapter {
    @SystemApi
    @UnsupportedAppUsage
    public void setNdefPushMessage(NdefMessage message, Activity activity, int flags) {
        synchronized (NfcAdapter.class) {
        synchronized (sLock) {
            if (!sHasNfcFeature) {
                throw new UnsupportedOperationException();
            }
@@ -1483,7 +1568,7 @@ public final class NfcAdapter {
    @UnsupportedAppUsage
    public void setNdefPushMessageCallback(CreateNdefMessageCallback callback, Activity activity,
            Activity ... activities) {
        synchronized (NfcAdapter.class) {
        synchronized (sLock) {
            if (!sHasNfcFeature) {
                throw new UnsupportedOperationException();
            }
@@ -1534,7 +1619,7 @@ public final class NfcAdapter {
    @UnsupportedAppUsage
    public void setOnNdefPushCompleteCallback(OnNdefPushCompleteCallback callback,
            Activity activity, Activity ... activities) {
        synchronized (NfcAdapter.class) {
        synchronized (sLock) {
            if (!sHasNfcFeature) {
                throw new UnsupportedOperationException();
            }
@@ -1577,7 +1662,7 @@ public final class NfcAdapter {
     */
    public void enableForegroundDispatch(Activity activity, PendingIntent intent,
            IntentFilter[] filters, String[][] techLists) {
        synchronized (NfcAdapter.class) {
        synchronized (sLock) {
            if (!sHasNfcFeature) {
                throw new UnsupportedOperationException();
            }
@@ -1612,7 +1697,7 @@ public final class NfcAdapter {
     * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
     */
    public void disableForegroundDispatch(Activity activity) {
        synchronized (NfcAdapter.class) {
        synchronized (sLock) {
            if (!sHasNfcFeature) {
                throw new UnsupportedOperationException();
            }
@@ -1648,7 +1733,7 @@ public final class NfcAdapter {
     */
    public void enableReaderMode(Activity activity, ReaderCallback callback, int flags,
            Bundle extras) {
        synchronized (NfcAdapter.class) {
        synchronized (sLock) {
            if (!sHasNfcFeature) {
                throw new UnsupportedOperationException();
            }
@@ -1665,7 +1750,7 @@ public final class NfcAdapter {
     * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
     */
    public void disableReaderMode(Activity activity) {
        synchronized (NfcAdapter.class) {
        synchronized (sLock) {
            if (!sHasNfcFeature) {
                throw new UnsupportedOperationException();
            }
@@ -1693,7 +1778,7 @@ public final class NfcAdapter {
    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
    @SuppressLint("VisiblySynchronized")
    public void setReaderMode(boolean enablePolling) {
        synchronized (NfcAdapter.class) {
        synchronized (sLock) {
            if (!sHasNfcFeature) {
                throw new UnsupportedOperationException();
            }
@@ -1707,6 +1792,80 @@ public final class NfcAdapter {
        }
    }

    /**
     * Set the NFC controller to enable specific poll/listen technologies,
     * as specified in parameters, while this Activity is in the foreground.
     *
     * Use {@link #FLAG_READER_KEEP} to keep current polling technology.
     * Use {@link #FLAG_LISTEN_KEEP} to keep current listenig technology.
     * Use {@link #FLAG_READER_DISABLE} to disable polling.
     * Use {@link #FLAG_LISTEN_DISABLE} to disable listening.
     * Also refer to {@link #resetDiscoveryTechnology(Activity)} to restore these changes.
     * </p>
     * The pollTech, listenTech parameters can be one or several of below list.
     * <pre>
     *                    Poll                    Listen
     *  Passive A         0x01   (NFC_A)           0x01  (NFC_PASSIVE_A)
     *  Passive B         0x02   (NFC_B)           0x02  (NFC_PASSIVE_B)
     *  Passive F         0x04   (NFC_F)           0x04  (NFC_PASSIVE_F)
     *  ISO 15693         0x08   (NFC_V)             -
     *  Kovio             0x10   (NFC_BARCODE)       -
     * </pre>
     * <p>Example usage in an Activity that requires to disable poll,
     * keep current listen technologies:
     * <pre>
     * protected void onResume() {
     *     mNfcAdapter = NfcAdapter.getDefaultAdapter(getApplicationContext());
     *     mNfcAdapter.setDiscoveryTechnology(this,
     *         NfcAdapter.FLAG_READER_DISABLE, NfcAdapter.FLAG_LISTEN_KEEP);
     * }</pre></p>
     * @param activity The Activity that requests NFC controller to enable specific technologies.
     * @param pollTech Flags indicating poll technologies.
     * @param listenTech Flags indicating listen technologies.
     * @throws UnsupportedOperationException if FEATURE_NFC,
     * FEATURE_NFC_HOST_CARD_EMULATION, FEATURE_NFC_HOST_CARD_EMULATION_NFCF are unavailable.
     */

    @FlaggedApi(Flags.FLAG_ENABLE_NFC_SET_DISCOVERY_TECH)
    public void setDiscoveryTechnology(@NonNull Activity activity,
            @PollTechnology int pollTech, @ListenTechnology int listenTech) {
        if (listenTech == FLAG_LISTEN_DISABLE) {
            synchronized (sLock) {
                if (!sHasNfcFeature) {
                    throw new UnsupportedOperationException();
                }
            }
            mNfcActivityManager.enableReaderMode(activity, null, pollTech, null);
            return;
        }
        if (pollTech == FLAG_READER_DISABLE) {
            synchronized (sLock) {
                if (!sHasCeFeature) {
                    throw new UnsupportedOperationException();
                }
            }
        } else {
            synchronized (sLock) {
                if (!sHasNfcFeature || !sHasCeFeature) {
                    throw new UnsupportedOperationException();
                }
            }
        }
        mNfcActivityManager.setDiscoveryTech(activity, pollTech, listenTech);
    }

    /**
     * Restore the poll/listen technologies of NFC controller,
     * which were changed by {@link #setDiscoveryTechnology(Activity , int , int)}
     *
     * @param activity The Activity that requests to changed technologies.
     */

    @FlaggedApi(Flags.FLAG_ENABLE_NFC_SET_DISCOVERY_TECH)
    public void resetDiscoveryTechnology(@NonNull Activity activity) {
        mNfcActivityManager.resetDiscoveryTech(activity);
    }

    /**
     * Manually invoke Android Beam to share data.
     *
@@ -1737,7 +1896,7 @@ public final class NfcAdapter {
    @java.lang.Deprecated
    @UnsupportedAppUsage
    public boolean invokeBeam(Activity activity) {
        synchronized (NfcAdapter.class) {
        synchronized (sLock) {
            if (!sHasNfcFeature) {
                throw new UnsupportedOperationException();
            }
@@ -1775,7 +1934,7 @@ public final class NfcAdapter {
    @Deprecated
    @UnsupportedAppUsage
    public void enableForegroundNdefPush(Activity activity, NdefMessage message) {
        synchronized (NfcAdapter.class) {
        synchronized (sLock) {
            if (!sHasNfcFeature) {
                throw new UnsupportedOperationException();
            }
@@ -1805,7 +1964,7 @@ public final class NfcAdapter {
    @Deprecated
    @UnsupportedAppUsage
    public void disableForegroundNdefPush(Activity activity) {
        synchronized (NfcAdapter.class) {
        synchronized (sLock) {
            if (!sHasNfcFeature) {
                throw new UnsupportedOperationException();
            }
@@ -2085,7 +2244,7 @@ public final class NfcAdapter {
    @java.lang.Deprecated
    @UnsupportedAppUsage
    public boolean isNdefPushEnabled() {
        synchronized (NfcAdapter.class) {
        synchronized (sLock) {
            if (!sHasNfcFeature) {
                throw new UnsupportedOperationException();
            }
@@ -2199,7 +2358,7 @@ public final class NfcAdapter {
    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
    public boolean addNfcUnlockHandler(final NfcUnlockHandler unlockHandler,
                                       String[] tagTechnologies) {
        synchronized (NfcAdapter.class) {
        synchronized (sLock) {
            if (!sHasNfcFeature) {
                throw new UnsupportedOperationException();
            }
@@ -2248,7 +2407,7 @@ public final class NfcAdapter {
    @SystemApi
    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
    public boolean removeNfcUnlockHandler(NfcUnlockHandler unlockHandler) {
        synchronized (NfcAdapter.class) {
        synchronized (sLock) {
            if (!sHasNfcFeature) {
                throw new UnsupportedOperationException();
            }
Loading