diff options
| author | 2024-11-19 04:56:08 +0000 | |
|---|---|---|
| committer | 2024-11-19 04:56:08 +0000 | |
| commit | 203e424b5d45e8fc08d88ccf15f6bca5633eccdf (patch) | |
| tree | 78668379fc4386e90c0e4d697db2668229b43512 | |
| parent | ff6d5624fae77177f32776f5b895de052189e409 (diff) | |
| parent | bed2d455b554451daeb103cfaab890a70722ced0 (diff) | |
Merge "Add callbacks to NFC Event Listener" into main am: 9a644bdcac am: bed2d455b5
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/3318993
Change-Id: I97180171e199c7d0bc2057262cc9e4908245c892
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
| -rw-r--r-- | nfc/api/current.txt | 9 | ||||
| -rw-r--r-- | nfc/java/android/nfc/INfcEventListener.aidl | 5 | ||||
| -rw-r--r-- | nfc/java/android/nfc/cardemulation/CardEmulation.java | 143 |
3 files changed, 146 insertions, 11 deletions
diff --git a/nfc/api/current.txt b/nfc/api/current.txt index 9a7a39f213ee..7ae2eafaf461 100644 --- a/nfc/api/current.txt +++ b/nfc/api/current.txt @@ -228,6 +228,10 @@ package android.nfc.cardemulation { field public static final String CATEGORY_PAYMENT = "payment"; field public static final String EXTRA_CATEGORY = "category"; field public static final String EXTRA_SERVICE_COMPONENT = "component"; + field @FlaggedApi("android.nfc.nfc_event_listener") public static final int NFC_INTERNAL_ERROR_COMMAND_TIMEOUT = 3; // 0x3 + field @FlaggedApi("android.nfc.nfc_event_listener") public static final int NFC_INTERNAL_ERROR_NFC_CRASH_RESTART = 1; // 0x1 + field @FlaggedApi("android.nfc.nfc_event_listener") public static final int NFC_INTERNAL_ERROR_NFC_HARDWARE_ERROR = 2; // 0x2 + field @FlaggedApi("android.nfc.nfc_event_listener") public static final int NFC_INTERNAL_ERROR_UNKNOWN = 0; // 0x0 field @FlaggedApi("android.nfc.nfc_override_recover_routing_table") public static final int PROTOCOL_AND_TECHNOLOGY_ROUTE_DEFAULT = 3; // 0x3 field @FlaggedApi("android.nfc.nfc_override_recover_routing_table") public static final int PROTOCOL_AND_TECHNOLOGY_ROUTE_DH = 0; // 0x0 field @FlaggedApi("android.nfc.nfc_override_recover_routing_table") public static final int PROTOCOL_AND_TECHNOLOGY_ROUTE_ESE = 1; // 0x1 @@ -239,8 +243,13 @@ package android.nfc.cardemulation { } @FlaggedApi("android.nfc.nfc_event_listener") public static interface CardEmulation.NfcEventListener { + method @FlaggedApi("android.nfc.nfc_event_listener") public default void onAidConflictOccurred(@NonNull String); + method @FlaggedApi("android.nfc.nfc_event_listener") public default void onAidNotRouted(@NonNull String); + method @FlaggedApi("android.nfc.nfc_event_listener") public default void onInternalErrorReported(int); + method @FlaggedApi("android.nfc.nfc_event_listener") public default void onNfcStateChanged(int); method @FlaggedApi("android.nfc.nfc_event_listener") public default void onObserveModeStateChanged(boolean); method @FlaggedApi("android.nfc.nfc_event_listener") public default void onPreferredServiceChanged(boolean); + method @FlaggedApi("android.nfc.nfc_event_listener") public default void onRemoteFieldChanged(boolean); } public abstract class HostApduService extends android.app.Service { diff --git a/nfc/java/android/nfc/INfcEventListener.aidl b/nfc/java/android/nfc/INfcEventListener.aidl index 5162c26ac536..774d8f875192 100644 --- a/nfc/java/android/nfc/INfcEventListener.aidl +++ b/nfc/java/android/nfc/INfcEventListener.aidl @@ -8,4 +8,9 @@ import android.nfc.ComponentNameAndUser; oneway interface INfcEventListener { void onPreferredServiceChanged(in ComponentNameAndUser ComponentNameAndUser); void onObserveModeStateChanged(boolean isEnabled); + void onAidConflictOccurred(in String aid); + void onAidNotRouted(in String aid); + void onNfcStateChanged(in int nfcState); + void onRemoteFieldChanged(boolean isDetected); + void onInternalErrorReported(in int errorType); }
\ No newline at end of file diff --git a/nfc/java/android/nfc/cardemulation/CardEmulation.java b/nfc/java/android/nfc/cardemulation/CardEmulation.java index 891752475824..e9ec7215e4d0 100644 --- a/nfc/java/android/nfc/cardemulation/CardEmulation.java +++ b/nfc/java/android/nfc/cardemulation/CardEmulation.java @@ -1144,6 +1144,40 @@ public final class CardEmulation { }; } + @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER) + public static final int NFC_INTERNAL_ERROR_UNKNOWN = 0; + + /** + * This error is reported when the NFC command watchdog restarts the NFC stack. + */ + @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER) + public static final int NFC_INTERNAL_ERROR_NFC_CRASH_RESTART = 1; + + /** + * This error is reported when the NFC controller does not respond or there's an NCI transport + * error. + */ + @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER) + public static final int NFC_INTERNAL_ERROR_NFC_HARDWARE_ERROR = 2; + + /** + * This error is reported when the NFC stack times out while waiting for a response to a command + * sent to the NFC hardware. + */ + @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER) + public static final int NFC_INTERNAL_ERROR_COMMAND_TIMEOUT = 3; + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER) + @IntDef(prefix = "NFC_INTERNAL_ERROR_", value = { + NFC_INTERNAL_ERROR_UNKNOWN, + NFC_INTERNAL_ERROR_NFC_CRASH_RESTART, + NFC_INTERNAL_ERROR_NFC_HARDWARE_ERROR, + NFC_INTERNAL_ERROR_COMMAND_TIMEOUT, + }) + public @interface NfcInternalErrorType {} + /** Listener for preferred service state changes. */ @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER) public interface NfcEventListener { @@ -1166,6 +1200,57 @@ public final class CardEmulation { */ @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER) default void onObserveModeStateChanged(boolean isEnabled) {} + + /** + * This method is called when an AID conflict is detected during an NFC transaction. This + * can happen when multiple services are registered for the same AID. + * + * @param aid The AID that is in conflict + */ + @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER) + default void onAidConflictOccurred(@NonNull String aid) {} + + /** + * This method is called when an AID is not routed to any service during an NFC + * transaction. This can happen when no service is registered for the given AID. + * + * @param aid the AID that was not routed + */ + @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER) + default void onAidNotRouted(@NonNull String aid) {} + + /** + * This method is called when the NFC state changes. + * + * @see NfcAdapter#getAdapterState() + * + * @param state The new NFC state + */ + @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER) + default void onNfcStateChanged(@NfcAdapter.AdapterState int state) {} + /** + * This method is called when the NFC controller is in card emulation mode and an NFC + * reader's field is either detected or lost. + * + * @param isDetected true if an NFC reader is detected, false if it is lost + */ + @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER) + default void onRemoteFieldChanged(boolean isDetected) {} + + /** + * This method is called when an internal error is reported by the NFC stack. + * + * No action is required in response to these events as the NFC stack will automatically + * attempt to recover. These errors are reported for informational purposes only. + * + * Note that these errors can be reported when performing various internal NFC operations + * (such as during device shutdown) and cannot always be explicitly correlated with NFC + * transaction failures. + * + * @param errorType The type of the internal error + */ + @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER) + default void onInternalErrorReported(@NfcInternalErrorType int errorType) {} } private final ArrayMap<NfcEventListener, Executor> mNfcEventListeners = new ArrayMap<>(); @@ -1185,25 +1270,61 @@ public final class CardEmulation { mContext.getPackageName(), componentNameAndUser.getComponentName() .getPackageName()); - synchronized (mNfcEventListeners) { - mNfcEventListeners.forEach( - (listener, executor) -> { - executor.execute( - () -> listener.onPreferredServiceChanged(isPreferred)); - }); - } + callListeners(listener -> listener.onPreferredServiceChanged(isPreferred)); } public void onObserveModeStateChanged(boolean isEnabled) { if (!android.nfc.Flags.nfcEventListener()) { return; } + callListeners(listener -> listener.onObserveModeStateChanged(isEnabled)); + } + + public void onAidConflictOccurred(String aid) { + if (!android.nfc.Flags.nfcEventListener()) { + return; + } + callListeners(listener -> listener.onAidConflictOccurred(aid)); + } + + public void onAidNotRouted(String aid) { + if (!android.nfc.Flags.nfcEventListener()) { + return; + } + callListeners(listener -> listener.onAidNotRouted(aid)); + } + + public void onNfcStateChanged(int state) { + if (!android.nfc.Flags.nfcEventListener()) { + return; + } + callListeners(listener -> listener.onNfcStateChanged(state)); + } + + public void onRemoteFieldChanged(boolean isDetected) { + if (!android.nfc.Flags.nfcEventListener()) { + return; + } + callListeners(listener -> listener.onRemoteFieldChanged(isDetected)); + } + + public void onInternalErrorReported(@NfcInternalErrorType int errorType) { + if (!android.nfc.Flags.nfcEventListener()) { + return; + } + callListeners(listener -> listener.onInternalErrorReported(errorType)); + } + + interface ListenerCall { + void invoke(NfcEventListener listener); + } + + private void callListeners(ListenerCall listenerCall) { synchronized (mNfcEventListeners) { mNfcEventListeners.forEach( - (listener, executor) -> { - executor.execute( - () -> listener.onObserveModeStateChanged(isEnabled)); - }); + (listener, executor) -> { + executor.execute(() -> listenerCall.invoke(listener)); + }); } } }; |