diff --git a/core/java/android/security/net/config/NetworkSecurityTrustManager.java b/core/java/android/security/net/config/NetworkSecurityTrustManager.java
index d9cc82a..029b674 100644
--- a/core/java/android/security/net/config/NetworkSecurityTrustManager.java
+++ b/core/java/android/security/net/config/NetworkSecurityTrustManager.java
@@ -16,16 +16,17 @@
 
 package android.security.net.config;
 
+import android.util.ArrayMap;
+
 import com.android.org.conscrypt.TrustManagerImpl;
 
-import android.util.ArrayMap;
 import java.io.IOException;
 import java.net.Socket;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
 import java.security.GeneralSecurityException;
 import java.security.KeyStore;
 import java.security.MessageDigest;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -105,7 +106,7 @@
 
     /**
      * Hostname aware version of {@link #checkServerTrusted(X509Certificate[], String)}.
-     * This interface is used by conscrypt and android.net.http.X509TrustManagerExtensions do not
+     * This interface is used by Conscrypt and android.net.http.X509TrustManagerExtensions do not
      * modify without modifying those callers.
      */
     public List<X509Certificate> checkServerTrusted(X509Certificate[] certs, String authType,
@@ -115,6 +116,19 @@
         return trustedChain;
     }
 
+    /**
+     * This interface is used by Conscrypt and android.net.http.X509TrustManagerExtensions do not
+     * modify without modifying those callers.
+     */
+    public List<X509Certificate> checkServerTrusted(X509Certificate[] certs,
+            byte[] ocspData, byte[] tlsSctData, String authType,
+            String host) throws CertificateException {
+        List<X509Certificate> trustedChain = mDelegate.checkServerTrusted(
+                certs, ocspData, tlsSctData, authType, host);
+        checkPins(trustedChain);
+        return trustedChain;
+    }
+
     private void checkPins(List<X509Certificate> chain) throws CertificateException {
         PinSet pinSet = mNetworkSecurityConfig.getPins();
         if (pinSet.pins.isEmpty()
diff --git a/core/java/android/security/net/config/RootTrustManager.java b/core/java/android/security/net/config/RootTrustManager.java
index 58dc4ba..a1bdec5 100644
--- a/core/java/android/security/net/config/RootTrustManager.java
+++ b/core/java/android/security/net/config/RootTrustManager.java
@@ -120,7 +120,7 @@
 
     /**
      * Hostname aware version of {@link #checkServerTrusted(X509Certificate[], String)}.
-     * This interface is used by conscrypt and android.net.http.X509TrustManagerExtensions do not
+     * This interface is used by Conscrypt and android.net.http.X509TrustManagerExtensions do not
      * modify without modifying those callers.
      */
     @UnsupportedAppUsage
@@ -134,6 +134,22 @@
         return config.getTrustManager().checkServerTrusted(certs, authType, hostname);
     }
 
+    /**
+     * This interface is used by Conscrypt and android.net.http.X509TrustManagerExtensions do not
+     * modify without modifying those callers.
+     */
+    public List<X509Certificate> checkServerTrusted(X509Certificate[] certs,
+            byte[] ocspData, byte[] tlsSctData, String authType,
+            String hostname) throws CertificateException {
+        if (hostname == null && mConfig.hasPerDomainConfigs()) {
+            throw new CertificateException(
+                    "Domain specific configurations require that the hostname be provided");
+        }
+        NetworkSecurityConfig config = mConfig.getConfigForHostname(hostname);
+        return config.getTrustManager().checkServerTrusted(
+                certs, ocspData, tlsSctData, authType, hostname);
+    }
+
     @Override
     public X509Certificate[] getAcceptedIssuers() {
         // getAcceptedIssuers is meant to be used to determine which trust anchors the server will
diff --git a/core/tests/coretests/src/android/net/http/OWNERS b/core/tests/coretests/src/android/net/http/OWNERS
new file mode 100644
index 0000000..c93a419
--- /dev/null
+++ b/core/tests/coretests/src/android/net/http/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/net/http/OWNERS
diff --git a/native/android/OWNERS b/native/android/OWNERS
index 1fde7d2..3ea2d35 100644
--- a/native/android/OWNERS
+++ b/native/android/OWNERS
@@ -29,6 +29,7 @@
 # Input
 per-file input.cpp = file:/INPUT_OWNERS
 
-# PerformanceHint
+# ADPF
 per-file performance_hint.cpp = file:/ADPF_OWNERS
+per-file system_health.cpp = file:/ADPF_OWNERS
 per-file thermal.cpp = file:/ADPF_OWNERS
diff --git a/nfc/Android.bp b/nfc/Android.bp
deleted file mode 100644
index 0fdb3bd..0000000
--- a/nfc/Android.bp
+++ /dev/null
@@ -1,79 +0,0 @@
-package {
-    default_team: "trendy_team_fwk_nfc",
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "frameworks_base_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["frameworks_base_license"],
-}
-
-filegroup {
-    name: "framework-nfc-updatable-sources",
-    path: "java",
-    srcs: [
-        "java/**/*.java",
-        "java/**/*.aidl",
-    ],
-    visibility: [
-        "//frameworks/base:__subpackages__",
-        "//packages/apps/Nfc:__subpackages__",
-        "//packages/modules/Nfc:__subpackages__",
-    ],
-}
-
-java_sdk_library {
-    name: "framework-nfc",
-    libs: [
-        "androidx.annotation_annotation",
-        "unsupportedappusage", // for android.compat.annotation.UnsupportedAppUsage
-        "framework-permission-s.stubs.module_lib",
-        "framework-permission.stubs.module_lib",
-    ],
-    stub_only_libs: [
-        // Needed for javadoc references.
-        "framework-permission-s.stubs.module_lib",
-    ],
-    static_libs: [
-        "android.nfc.flags-aconfig-java",
-        "android.permission.flags-aconfig-java",
-    ],
-    srcs: [
-        ":framework-nfc-updatable-sources",
-        ":framework-nfc-javastream-protos",
-    ],
-    defaults: ["framework-module-defaults"],
-    sdk_version: "module_current",
-    min_sdk_version: "35", // Make it 36 once available.
-    installable: true,
-    optimize: {
-        enabled: false,
-    },
-    hostdex: true, // for hiddenapi check
-    permitted_packages: [
-        "android.nfc",
-        "com.android.nfc",
-    ],
-    impl_library_visibility: [
-        "//frameworks/base:__subpackages__",
-        "//cts:__subpackages__",
-        "//packages/apps/Nfc:__subpackages__",
-        "//packages/modules/Nfc:__subpackages__",
-    ],
-    jarjar_rules: ":nfc-jarjar-rules",
-    lint: {
-        baseline_filename: "lint-baseline.xml",
-    },
-    apex_available: [
-        "//apex_available:platform",
-        "com.android.nfcservices",
-    ],
-    aconfig_declarations: [
-        "android.nfc.flags-aconfig",
-    ],
-}
-
-filegroup {
-    name: "nfc-jarjar-rules",
-    srcs: ["jarjar-rules.txt"],
-}
diff --git a/nfc/OWNERS b/nfc/OWNERS
deleted file mode 100644
index f46dccd..0000000
--- a/nfc/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 48448
-include platform/packages/apps/Nfc:/OWNERS
\ No newline at end of file
diff --git a/nfc/TEST_MAPPING b/nfc/TEST_MAPPING
deleted file mode 100644
index 49c778d..0000000
--- a/nfc/TEST_MAPPING
+++ /dev/null
@@ -1,13 +0,0 @@
-{
-  "presubmit": [
-    {
-      "name": "NfcManagerTests"
-    },
-    {
-      "name": "CtsNfcTestCases"
-    },
-    {
-      "name": "CtsNdefTestCases"
-    }
-  ]
-}
diff --git a/nfc/api/current.txt b/nfc/api/current.txt
deleted file mode 100644
index c8c479a..0000000
--- a/nfc/api/current.txt
+++ /dev/null
@@ -1,495 +0,0 @@
-// Signature format: 2.0
-package android.nfc {
-
-  public final class AvailableNfcAntenna implements android.os.Parcelable {
-    ctor public AvailableNfcAntenna(int, int);
-    method public int describeContents();
-    method public int getLocationX();
-    method public int getLocationY();
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.nfc.AvailableNfcAntenna> CREATOR;
-  }
-
-  public class FormatException extends java.lang.Exception {
-    ctor public FormatException();
-    ctor public FormatException(String);
-    ctor public FormatException(String, Throwable);
-  }
-
-  public final class NdefMessage implements android.os.Parcelable {
-    ctor public NdefMessage(byte[]) throws android.nfc.FormatException;
-    ctor public NdefMessage(android.nfc.NdefRecord, android.nfc.NdefRecord...);
-    ctor public NdefMessage(android.nfc.NdefRecord[]);
-    method public int describeContents();
-    method public int getByteArrayLength();
-    method public android.nfc.NdefRecord[] getRecords();
-    method public byte[] toByteArray();
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.nfc.NdefMessage> CREATOR;
-  }
-
-  public final class NdefRecord implements android.os.Parcelable {
-    ctor public NdefRecord(short, byte[], byte[], byte[]);
-    ctor @Deprecated public NdefRecord(byte[]) throws android.nfc.FormatException;
-    method public static android.nfc.NdefRecord createApplicationRecord(String);
-    method public static android.nfc.NdefRecord createExternal(String, String, byte[]);
-    method public static android.nfc.NdefRecord createMime(String, byte[]);
-    method public static android.nfc.NdefRecord createTextRecord(String, String);
-    method public static android.nfc.NdefRecord createUri(android.net.Uri);
-    method public static android.nfc.NdefRecord createUri(String);
-    method public int describeContents();
-    method public byte[] getId();
-    method public byte[] getPayload();
-    method public short getTnf();
-    method public byte[] getType();
-    method @Deprecated public byte[] toByteArray();
-    method public String toMimeType();
-    method public android.net.Uri toUri();
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.nfc.NdefRecord> CREATOR;
-    field public static final byte[] RTD_ALTERNATIVE_CARRIER;
-    field public static final byte[] RTD_HANDOVER_CARRIER;
-    field public static final byte[] RTD_HANDOVER_REQUEST;
-    field public static final byte[] RTD_HANDOVER_SELECT;
-    field public static final byte[] RTD_SMART_POSTER;
-    field public static final byte[] RTD_TEXT;
-    field public static final byte[] RTD_URI;
-    field public static final short TNF_ABSOLUTE_URI = 3; // 0x3
-    field public static final short TNF_EMPTY = 0; // 0x0
-    field public static final short TNF_EXTERNAL_TYPE = 4; // 0x4
-    field public static final short TNF_MIME_MEDIA = 2; // 0x2
-    field public static final short TNF_UNCHANGED = 6; // 0x6
-    field public static final short TNF_UNKNOWN = 5; // 0x5
-    field public static final short TNF_WELL_KNOWN = 1; // 0x1
-  }
-
-  public final class NfcAdapter {
-    method @FlaggedApi("android.nfc.nfc_state_change") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean disable();
-    method public void disableForegroundDispatch(android.app.Activity);
-    method public void disableReaderMode(android.app.Activity);
-    method @FlaggedApi("android.nfc.nfc_state_change") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enable();
-    method public void enableForegroundDispatch(android.app.Activity, android.app.PendingIntent, android.content.IntentFilter[], String[][]);
-    method public void enableReaderMode(android.app.Activity, android.nfc.NfcAdapter.ReaderCallback, int, android.os.Bundle);
-    method public static android.nfc.NfcAdapter getDefaultAdapter(android.content.Context);
-    method @Nullable public android.nfc.NfcAntennaInfo getNfcAntennaInfo();
-    method @FlaggedApi("android.nfc.enable_nfc_charging") @Nullable public android.nfc.WlcListenerDeviceInfo getWlcListenerDeviceInfo();
-    method public boolean ignore(android.nfc.Tag, int, android.nfc.NfcAdapter.OnTagRemovedListener, android.os.Handler);
-    method public boolean isEnabled();
-    method @FlaggedApi("android.nfc.nfc_observe_mode") public boolean isObserveModeEnabled();
-    method @FlaggedApi("android.nfc.nfc_observe_mode") public boolean isObserveModeSupported();
-    method @FlaggedApi("android.nfc.enable_nfc_reader_option") public boolean isReaderOptionEnabled();
-    method @FlaggedApi("android.nfc.enable_nfc_reader_option") public boolean isReaderOptionSupported();
-    method public boolean isSecureNfcEnabled();
-    method public boolean isSecureNfcSupported();
-    method @FlaggedApi("android.nfc.nfc_check_tag_intent_preference") public boolean isTagIntentAllowed();
-    method @FlaggedApi("android.nfc.nfc_check_tag_intent_preference") public boolean isTagIntentAppPreferenceSupported();
-    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);
-    method @FlaggedApi("android.nfc.nfc_observe_mode") public boolean setObserveModeEnabled(boolean);
-    field public static final String ACTION_ADAPTER_STATE_CHANGED = "android.nfc.action.ADAPTER_STATE_CHANGED";
-    field @FlaggedApi("android.nfc.nfc_check_tag_intent_preference") public static final String ACTION_CHANGE_TAG_INTENT_PREFERENCE = "android.nfc.action.CHANGE_TAG_INTENT_PREFERENCE";
-    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";
-    field public static final String ACTION_TAG_DISCOVERED = "android.nfc.action.TAG_DISCOVERED";
-    field public static final String ACTION_TECH_DISCOVERED = "android.nfc.action.TECH_DISCOVERED";
-    field @RequiresPermission(android.Manifest.permission.NFC_TRANSACTION_EVENT) public static final String ACTION_TRANSACTION_DETECTED = "android.nfc.action.TRANSACTION_DETECTED";
-    field public static final String EXTRA_ADAPTER_STATE = "android.nfc.extra.ADAPTER_STATE";
-    field public static final String EXTRA_AID = "android.nfc.extra.AID";
-    field public static final String EXTRA_DATA = "android.nfc.extra.DATA";
-    field public static final String EXTRA_ID = "android.nfc.extra.ID";
-    field public static final String EXTRA_NDEF_MESSAGES = "android.nfc.extra.NDEF_MESSAGES";
-    field public static final String EXTRA_PREFERRED_PAYMENT_CHANGED_REASON = "android.nfc.extra.PREFERRED_PAYMENT_CHANGED_REASON";
-    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 = -2147483648; // 0x80000000
-    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 = -2147483648; // 0x80000000
-    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
-    field public static final int FLAG_READER_NFC_F = 4; // 0x4
-    field public static final int FLAG_READER_NFC_V = 8; // 0x8
-    field public static final int FLAG_READER_NO_PLATFORM_SOUNDS = 256; // 0x100
-    field public static final int FLAG_READER_SKIP_NDEF_CHECK = 128; // 0x80
-    field public static final int PREFERRED_PAYMENT_CHANGED = 2; // 0x2
-    field public static final int PREFERRED_PAYMENT_LOADED = 1; // 0x1
-    field public static final int PREFERRED_PAYMENT_UPDATED = 3; // 0x3
-    field public static final int STATE_OFF = 1; // 0x1
-    field public static final int STATE_ON = 3; // 0x3
-    field public static final int STATE_TURNING_OFF = 4; // 0x4
-    field public static final int STATE_TURNING_ON = 2; // 0x2
-  }
-
-  @Deprecated public static interface NfcAdapter.CreateBeamUrisCallback {
-    method @Deprecated public android.net.Uri[] createBeamUris(android.nfc.NfcEvent);
-  }
-
-  @Deprecated public static interface NfcAdapter.CreateNdefMessageCallback {
-    method @Deprecated public android.nfc.NdefMessage createNdefMessage(android.nfc.NfcEvent);
-  }
-
-  @Deprecated public static interface NfcAdapter.OnNdefPushCompleteCallback {
-    method @Deprecated public void onNdefPushComplete(android.nfc.NfcEvent);
-  }
-
-  public static interface NfcAdapter.OnTagRemovedListener {
-    method public void onTagRemoved();
-  }
-
-  public static interface NfcAdapter.ReaderCallback {
-    method public void onTagDiscovered(android.nfc.Tag);
-  }
-
-  public final class NfcAntennaInfo implements android.os.Parcelable {
-    ctor public NfcAntennaInfo(int, int, boolean, @NonNull java.util.List<android.nfc.AvailableNfcAntenna>);
-    method public int describeContents();
-    method @NonNull public java.util.List<android.nfc.AvailableNfcAntenna> getAvailableNfcAntennas();
-    method public int getDeviceHeight();
-    method public int getDeviceWidth();
-    method public boolean isDeviceFoldable();
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.nfc.NfcAntennaInfo> CREATOR;
-  }
-
-  public final class NfcEvent {
-    field public final android.nfc.NfcAdapter nfcAdapter;
-    field public final int peerLlcpMajorVersion;
-    field public final int peerLlcpMinorVersion;
-  }
-
-  public final class NfcManager {
-    method public android.nfc.NfcAdapter getDefaultAdapter();
-  }
-
-  public final class Tag implements android.os.Parcelable {
-    method public int describeContents();
-    method public byte[] getId();
-    method public String[] getTechList();
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.nfc.Tag> CREATOR;
-  }
-
-  public class TagLostException extends java.io.IOException {
-    ctor public TagLostException();
-    ctor public TagLostException(String);
-  }
-
-  @FlaggedApi("android.nfc.enable_nfc_charging") public final class WlcListenerDeviceInfo implements android.os.Parcelable {
-    ctor public WlcListenerDeviceInfo(int, double, double, int);
-    method public int describeContents();
-    method @FloatRange(from=0.0, to=100.0) public double getBatteryLevel();
-    method public int getProductId();
-    method public int getState();
-    method public double getTemperature();
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.nfc.WlcListenerDeviceInfo> CREATOR;
-    field public static final int STATE_CONNECTED_CHARGING = 2; // 0x2
-    field public static final int STATE_CONNECTED_DISCHARGING = 3; // 0x3
-    field public static final int STATE_DISCONNECTED = 1; // 0x1
-  }
-
-}
-
-package android.nfc.cardemulation {
-
-  public final class CardEmulation {
-    method public boolean categoryAllowsForegroundPreference(String);
-    method @Nullable @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) public java.util.List<java.lang.String> getAidsForPreferredPaymentService();
-    method public java.util.List<java.lang.String> getAidsForService(android.content.ComponentName, String);
-    method @FlaggedApi("android.nfc.enable_card_emulation_euicc") public int getDefaultNfcSubscriptionId();
-    method @Nullable @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) public CharSequence getDescriptionForPreferredPaymentService();
-    method public static android.nfc.cardemulation.CardEmulation getInstance(android.nfc.NfcAdapter);
-    method @Nullable @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) public String getRouteDestinationForPreferredPaymentService();
-    method public int getSelectionModeForCategory(String);
-    method public boolean isDefaultServiceForAid(android.content.ComponentName, String);
-    method public boolean isDefaultServiceForCategory(android.content.ComponentName, String);
-    method @FlaggedApi("android.nfc.enable_card_emulation_euicc") public boolean isEuiccSupported();
-    method public boolean registerAidsForService(android.content.ComponentName, String, java.util.List<java.lang.String>);
-    method @FlaggedApi("android.nfc.nfc_event_listener") public void registerNfcEventCallback(@NonNull java.util.concurrent.Executor, @NonNull android.nfc.cardemulation.CardEmulation.NfcEventCallback);
-    method @FlaggedApi("android.nfc.nfc_read_polling_loop") public boolean registerPollingLoopFilterForService(@NonNull android.content.ComponentName, @NonNull String, boolean);
-    method @FlaggedApi("android.nfc.nfc_read_polling_loop") public boolean registerPollingLoopPatternFilterForService(@NonNull android.content.ComponentName, @NonNull String, boolean);
-    method public boolean removeAidsForService(android.content.ComponentName, String);
-    method @FlaggedApi("android.nfc.nfc_read_polling_loop") public boolean removePollingLoopFilterForService(@NonNull android.content.ComponentName, @NonNull String);
-    method @FlaggedApi("android.nfc.nfc_read_polling_loop") public boolean removePollingLoopPatternFilterForService(@NonNull android.content.ComponentName, @NonNull String);
-    method @NonNull @RequiresPermission(android.Manifest.permission.NFC) public boolean setOffHostForService(@NonNull android.content.ComponentName, @NonNull String);
-    method public boolean setPreferredService(android.app.Activity, android.content.ComponentName);
-    method @FlaggedApi("android.nfc.nfc_observe_mode") public boolean setShouldDefaultToObserveModeForService(@NonNull android.content.ComponentName, boolean);
-    method public boolean supportsAidPrefixRegistration();
-    method @FlaggedApi("android.nfc.nfc_event_listener") public void unregisterNfcEventCallback(@NonNull android.nfc.cardemulation.CardEmulation.NfcEventCallback);
-    method @NonNull @RequiresPermission(android.Manifest.permission.NFC) public boolean unsetOffHostForService(@NonNull android.content.ComponentName);
-    method public boolean unsetPreferredService(android.app.Activity);
-    field @Deprecated public static final String ACTION_CHANGE_DEFAULT = "android.nfc.cardemulation.action.ACTION_CHANGE_DEFAULT";
-    field public static final String CATEGORY_OTHER = "other";
-    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_associated_role_services") public static final String PROPERTY_ALLOW_SHARED_ROLE_PRIORITY = "android.nfc.cardemulation.PROPERTY_ALLOW_SHARED_ROLE_PRIORITY";
-    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
-    field @FlaggedApi("android.nfc.nfc_override_recover_routing_table") public static final int PROTOCOL_AND_TECHNOLOGY_ROUTE_UICC = 2; // 0x2
-    field @FlaggedApi("android.nfc.nfc_override_recover_routing_table") public static final int PROTOCOL_AND_TECHNOLOGY_ROUTE_UNSET = -1; // 0xffffffff
-    field public static final int SELECTION_MODE_ALWAYS_ASK = 1; // 0x1
-    field public static final int SELECTION_MODE_ASK_IF_CONFLICT = 2; // 0x2
-    field public static final int SELECTION_MODE_PREFER_DEFAULT = 0; // 0x0
-  }
-
-  @FlaggedApi("android.nfc.nfc_event_listener") public static interface CardEmulation.NfcEventCallback {
-    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 {
-    ctor public HostApduService();
-    method public final void notifyUnhandled();
-    method public final android.os.IBinder onBind(android.content.Intent);
-    method public abstract void onDeactivated(int);
-    method public abstract byte[] processCommandApdu(byte[], android.os.Bundle);
-    method @FlaggedApi("android.nfc.nfc_read_polling_loop") public void processPollingFrames(@NonNull java.util.List<android.nfc.cardemulation.PollingFrame>);
-    method public final void sendResponseApdu(byte[]);
-    field public static final int DEACTIVATION_DESELECTED = 1; // 0x1
-    field public static final int DEACTIVATION_LINK_LOSS = 0; // 0x0
-    field public static final String SERVICE_INTERFACE = "android.nfc.cardemulation.action.HOST_APDU_SERVICE";
-    field public static final String SERVICE_META_DATA = "android.nfc.cardemulation.host_apdu_service";
-  }
-
-  public abstract class HostNfcFService extends android.app.Service {
-    ctor public HostNfcFService();
-    method public final android.os.IBinder onBind(android.content.Intent);
-    method public abstract void onDeactivated(int);
-    method public abstract byte[] processNfcFPacket(byte[], android.os.Bundle);
-    method public final void sendResponsePacket(byte[]);
-    field public static final int DEACTIVATION_LINK_LOSS = 0; // 0x0
-    field public static final String SERVICE_INTERFACE = "android.nfc.cardemulation.action.HOST_NFCF_SERVICE";
-    field public static final String SERVICE_META_DATA = "android.nfc.cardemulation.host_nfcf_service";
-  }
-
-  public final class NfcFCardEmulation {
-    method public boolean disableService(android.app.Activity) throws java.lang.RuntimeException;
-    method public boolean enableService(android.app.Activity, android.content.ComponentName) throws java.lang.RuntimeException;
-    method public static android.nfc.cardemulation.NfcFCardEmulation getInstance(android.nfc.NfcAdapter);
-    method public String getNfcid2ForService(android.content.ComponentName) throws java.lang.RuntimeException;
-    method public String getSystemCodeForService(android.content.ComponentName) throws java.lang.RuntimeException;
-    method public boolean registerSystemCodeForService(android.content.ComponentName, String) throws java.lang.RuntimeException;
-    method public boolean setNfcid2ForService(android.content.ComponentName, String) throws java.lang.RuntimeException;
-    method public boolean unregisterSystemCodeForService(android.content.ComponentName) throws java.lang.RuntimeException;
-  }
-
-  public abstract class OffHostApduService extends android.app.Service {
-    ctor public OffHostApduService();
-    field public static final String SERVICE_INTERFACE = "android.nfc.cardemulation.action.OFF_HOST_APDU_SERVICE";
-    field public static final String SERVICE_META_DATA = "android.nfc.cardemulation.off_host_apdu_service";
-  }
-
-  @FlaggedApi("android.nfc.nfc_read_polling_loop") public final class PollingFrame implements android.os.Parcelable {
-    method public int describeContents();
-    method @NonNull public byte[] getData();
-    method public long getTimestamp();
-    method public boolean getTriggeredAutoTransact();
-    method public int getType();
-    method public int getVendorSpecificGain();
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.nfc.cardemulation.PollingFrame> CREATOR;
-    field @FlaggedApi("android.nfc.nfc_read_polling_loop") public static final int POLLING_LOOP_TYPE_A = 65; // 0x41
-    field @FlaggedApi("android.nfc.nfc_read_polling_loop") public static final int POLLING_LOOP_TYPE_B = 66; // 0x42
-    field @FlaggedApi("android.nfc.nfc_read_polling_loop") public static final int POLLING_LOOP_TYPE_F = 70; // 0x46
-    field @FlaggedApi("android.nfc.nfc_read_polling_loop") public static final int POLLING_LOOP_TYPE_OFF = 88; // 0x58
-    field @FlaggedApi("android.nfc.nfc_read_polling_loop") public static final int POLLING_LOOP_TYPE_ON = 79; // 0x4f
-    field @FlaggedApi("android.nfc.nfc_read_polling_loop") public static final int POLLING_LOOP_TYPE_UNKNOWN = 85; // 0x55
-  }
-
-}
-
-package android.nfc.tech {
-
-  public final class IsoDep implements android.nfc.tech.TagTechnology {
-    method public void close() throws java.io.IOException;
-    method public void connect() throws java.io.IOException;
-    method public static android.nfc.tech.IsoDep get(android.nfc.Tag);
-    method public byte[] getHiLayerResponse();
-    method public byte[] getHistoricalBytes();
-    method public int getMaxTransceiveLength();
-    method public android.nfc.Tag getTag();
-    method public int getTimeout();
-    method public boolean isConnected();
-    method public boolean isExtendedLengthApduSupported();
-    method public void setTimeout(int);
-    method public byte[] transceive(byte[]) throws java.io.IOException;
-  }
-
-  public final class MifareClassic implements android.nfc.tech.TagTechnology {
-    method public boolean authenticateSectorWithKeyA(int, byte[]) throws java.io.IOException;
-    method public boolean authenticateSectorWithKeyB(int, byte[]) throws java.io.IOException;
-    method public int blockToSector(int);
-    method public void close() throws java.io.IOException;
-    method public void connect() throws java.io.IOException;
-    method public void decrement(int, int) throws java.io.IOException;
-    method public static android.nfc.tech.MifareClassic get(android.nfc.Tag);
-    method public int getBlockCount();
-    method public int getBlockCountInSector(int);
-    method public int getMaxTransceiveLength();
-    method public int getSectorCount();
-    method public int getSize();
-    method public android.nfc.Tag getTag();
-    method public int getTimeout();
-    method public int getType();
-    method public void increment(int, int) throws java.io.IOException;
-    method public boolean isConnected();
-    method public byte[] readBlock(int) throws java.io.IOException;
-    method public void restore(int) throws java.io.IOException;
-    method public int sectorToBlock(int);
-    method public void setTimeout(int);
-    method public byte[] transceive(byte[]) throws java.io.IOException;
-    method public void transfer(int) throws java.io.IOException;
-    method public void writeBlock(int, byte[]) throws java.io.IOException;
-    field public static final int BLOCK_SIZE = 16; // 0x10
-    field public static final byte[] KEY_DEFAULT;
-    field public static final byte[] KEY_MIFARE_APPLICATION_DIRECTORY;
-    field public static final byte[] KEY_NFC_FORUM;
-    field public static final int SIZE_1K = 1024; // 0x400
-    field public static final int SIZE_2K = 2048; // 0x800
-    field public static final int SIZE_4K = 4096; // 0x1000
-    field public static final int SIZE_MINI = 320; // 0x140
-    field public static final int TYPE_CLASSIC = 0; // 0x0
-    field public static final int TYPE_PLUS = 1; // 0x1
-    field public static final int TYPE_PRO = 2; // 0x2
-    field public static final int TYPE_UNKNOWN = -1; // 0xffffffff
-  }
-
-  public final class MifareUltralight implements android.nfc.tech.TagTechnology {
-    method public void close() throws java.io.IOException;
-    method public void connect() throws java.io.IOException;
-    method public static android.nfc.tech.MifareUltralight get(android.nfc.Tag);
-    method public int getMaxTransceiveLength();
-    method public android.nfc.Tag getTag();
-    method public int getTimeout();
-    method public int getType();
-    method public boolean isConnected();
-    method public byte[] readPages(int) throws java.io.IOException;
-    method public void setTimeout(int);
-    method public byte[] transceive(byte[]) throws java.io.IOException;
-    method public void writePage(int, byte[]) throws java.io.IOException;
-    field public static final int PAGE_SIZE = 4; // 0x4
-    field public static final int TYPE_ULTRALIGHT = 1; // 0x1
-    field public static final int TYPE_ULTRALIGHT_C = 2; // 0x2
-    field public static final int TYPE_UNKNOWN = -1; // 0xffffffff
-  }
-
-  public final class Ndef implements android.nfc.tech.TagTechnology {
-    method public boolean canMakeReadOnly();
-    method public void close() throws java.io.IOException;
-    method public void connect() throws java.io.IOException;
-    method public static android.nfc.tech.Ndef get(android.nfc.Tag);
-    method public android.nfc.NdefMessage getCachedNdefMessage();
-    method public int getMaxSize();
-    method public android.nfc.NdefMessage getNdefMessage() throws android.nfc.FormatException, java.io.IOException;
-    method public android.nfc.Tag getTag();
-    method public String getType();
-    method public boolean isConnected();
-    method public boolean isWritable();
-    method public boolean makeReadOnly() throws java.io.IOException;
-    method public void writeNdefMessage(android.nfc.NdefMessage) throws android.nfc.FormatException, java.io.IOException;
-    field public static final String MIFARE_CLASSIC = "com.nxp.ndef.mifareclassic";
-    field public static final String NFC_FORUM_TYPE_1 = "org.nfcforum.ndef.type1";
-    field public static final String NFC_FORUM_TYPE_2 = "org.nfcforum.ndef.type2";
-    field public static final String NFC_FORUM_TYPE_3 = "org.nfcforum.ndef.type3";
-    field public static final String NFC_FORUM_TYPE_4 = "org.nfcforum.ndef.type4";
-  }
-
-  public final class NdefFormatable implements android.nfc.tech.TagTechnology {
-    method public void close() throws java.io.IOException;
-    method public void connect() throws java.io.IOException;
-    method public void format(android.nfc.NdefMessage) throws android.nfc.FormatException, java.io.IOException;
-    method public void formatReadOnly(android.nfc.NdefMessage) throws android.nfc.FormatException, java.io.IOException;
-    method public static android.nfc.tech.NdefFormatable get(android.nfc.Tag);
-    method public android.nfc.Tag getTag();
-    method public boolean isConnected();
-  }
-
-  public final class NfcA implements android.nfc.tech.TagTechnology {
-    method public void close() throws java.io.IOException;
-    method public void connect() throws java.io.IOException;
-    method public static android.nfc.tech.NfcA get(android.nfc.Tag);
-    method public byte[] getAtqa();
-    method public int getMaxTransceiveLength();
-    method public short getSak();
-    method public android.nfc.Tag getTag();
-    method public int getTimeout();
-    method public boolean isConnected();
-    method public void setTimeout(int);
-    method public byte[] transceive(byte[]) throws java.io.IOException;
-  }
-
-  public final class NfcB implements android.nfc.tech.TagTechnology {
-    method public void close() throws java.io.IOException;
-    method public void connect() throws java.io.IOException;
-    method public static android.nfc.tech.NfcB get(android.nfc.Tag);
-    method public byte[] getApplicationData();
-    method public int getMaxTransceiveLength();
-    method public byte[] getProtocolInfo();
-    method public android.nfc.Tag getTag();
-    method public boolean isConnected();
-    method public byte[] transceive(byte[]) throws java.io.IOException;
-  }
-
-  public final class NfcBarcode implements android.nfc.tech.TagTechnology {
-    method public void close() throws java.io.IOException;
-    method public void connect() throws java.io.IOException;
-    method public static android.nfc.tech.NfcBarcode get(android.nfc.Tag);
-    method public byte[] getBarcode();
-    method public android.nfc.Tag getTag();
-    method public int getType();
-    method public boolean isConnected();
-    field public static final int TYPE_KOVIO = 1; // 0x1
-    field public static final int TYPE_UNKNOWN = -1; // 0xffffffff
-  }
-
-  public final class NfcF implements android.nfc.tech.TagTechnology {
-    method public void close() throws java.io.IOException;
-    method public void connect() throws java.io.IOException;
-    method public static android.nfc.tech.NfcF get(android.nfc.Tag);
-    method public byte[] getManufacturer();
-    method public int getMaxTransceiveLength();
-    method public byte[] getSystemCode();
-    method public android.nfc.Tag getTag();
-    method public int getTimeout();
-    method public boolean isConnected();
-    method public void setTimeout(int);
-    method public byte[] transceive(byte[]) throws java.io.IOException;
-  }
-
-  public final class NfcV implements android.nfc.tech.TagTechnology {
-    method public void close() throws java.io.IOException;
-    method public void connect() throws java.io.IOException;
-    method public static android.nfc.tech.NfcV get(android.nfc.Tag);
-    method public byte getDsfId();
-    method public int getMaxTransceiveLength();
-    method public byte getResponseFlags();
-    method public android.nfc.Tag getTag();
-    method public boolean isConnected();
-    method public byte[] transceive(byte[]) throws java.io.IOException;
-  }
-
-  public interface TagTechnology extends java.io.Closeable {
-    method public void connect() throws java.io.IOException;
-    method public android.nfc.Tag getTag();
-    method public boolean isConnected();
-  }
-
-}
-
diff --git a/nfc/api/lint-baseline.txt b/nfc/api/lint-baseline.txt
deleted file mode 100644
index ef9aab6..0000000
--- a/nfc/api/lint-baseline.txt
+++ /dev/null
@@ -1,95 +0,0 @@
-// Baseline format: 1.0
-BroadcastBehavior: android.nfc.NfcAdapter#ACTION_ADAPTER_STATE_CHANGED:
-    Field 'ACTION_ADAPTER_STATE_CHANGED' is missing @BroadcastBehavior
-BroadcastBehavior: android.nfc.NfcAdapter#ACTION_PREFERRED_PAYMENT_CHANGED:
-    Field 'ACTION_PREFERRED_PAYMENT_CHANGED' is missing @BroadcastBehavior
-BroadcastBehavior: android.nfc.NfcAdapter#ACTION_TRANSACTION_DETECTED:
-    Field 'ACTION_TRANSACTION_DETECTED' is missing @BroadcastBehavior
-
-
-MissingNullability: android.nfc.cardemulation.OffHostApduService#onBind(android.content.Intent):
-    Missing nullability on method `onBind` return
-MissingNullability: android.nfc.cardemulation.OffHostApduService#onBind(android.content.Intent) parameter #0:
-    Missing nullability on parameter `intent` in method `onBind`
-
-
-RequiresPermission: android.nfc.NfcAdapter#disableForegroundDispatch(android.app.Activity):
-    Method 'disableForegroundDispatch' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.NfcAdapter#enableForegroundDispatch(android.app.Activity, android.app.PendingIntent, android.content.IntentFilter[], String[][]):
-    Method 'enableForegroundDispatch' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.cardemulation.CardEmulation#isDefaultServiceForAid(android.content.ComponentName, String):
-    Method 'isDefaultServiceForAid' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.cardemulation.CardEmulation#isDefaultServiceForCategory(android.content.ComponentName, String):
-    Method 'isDefaultServiceForCategory' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.cardemulation.CardEmulation#setOffHostForService(android.content.ComponentName, String):
-    Method 'setOffHostForService' documentation mentions permissions already declared by @RequiresPermission
-RequiresPermission: android.nfc.tech.IsoDep#getTimeout():
-    Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.IsoDep#setTimeout(int):
-    Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.IsoDep#transceive(byte[]):
-    Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#authenticateSectorWithKeyA(int, byte[]):
-    Method 'authenticateSectorWithKeyA' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#authenticateSectorWithKeyB(int, byte[]):
-    Method 'authenticateSectorWithKeyB' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#decrement(int, int):
-    Method 'decrement' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#getTimeout():
-    Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#increment(int, int):
-    Method 'increment' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#readBlock(int):
-    Method 'readBlock' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#restore(int):
-    Method 'restore' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#setTimeout(int):
-    Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#transceive(byte[]):
-    Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#transfer(int):
-    Method 'transfer' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#writeBlock(int, byte[]):
-    Method 'writeBlock' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareUltralight#getTimeout():
-    Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareUltralight#readPages(int):
-    Method 'readPages' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareUltralight#setTimeout(int):
-    Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareUltralight#transceive(byte[]):
-    Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareUltralight#writePage(int, byte[]):
-    Method 'writePage' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.Ndef#getNdefMessage():
-    Method 'getNdefMessage' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.Ndef#isWritable():
-    Method 'isWritable' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.Ndef#makeReadOnly():
-    Method 'makeReadOnly' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.Ndef#writeNdefMessage(android.nfc.NdefMessage):
-    Method 'writeNdefMessage' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NdefFormatable#format(android.nfc.NdefMessage):
-    Method 'format' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NdefFormatable#formatReadOnly(android.nfc.NdefMessage):
-    Method 'formatReadOnly' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcA#getTimeout():
-    Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcA#setTimeout(int):
-    Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcA#transceive(byte[]):
-    Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcB#transceive(byte[]):
-    Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcF#getTimeout():
-    Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcF#setTimeout(int):
-    Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcF#transceive(byte[]):
-    Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcV#transceive(byte[]):
-    Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.TagTechnology#close():
-    Method 'close' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.TagTechnology#connect():
-    Method 'connect' documentation mentions permissions without declaring @RequiresPermission
diff --git a/nfc/api/module-lib-current.txt b/nfc/api/module-lib-current.txt
deleted file mode 100644
index 5ebe911..0000000
--- a/nfc/api/module-lib-current.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-// Signature format: 2.0
-package android.nfc {
-
-  public class NfcFrameworkInitializer {
-    method public static void registerServiceWrappers();
-    method public static void setNfcServiceManager(@NonNull android.nfc.NfcServiceManager);
-  }
-
-}
-
diff --git a/nfc/api/module-lib-lint-baseline.txt b/nfc/api/module-lib-lint-baseline.txt
deleted file mode 100644
index f7f8ee3..0000000
--- a/nfc/api/module-lib-lint-baseline.txt
+++ /dev/null
@@ -1,93 +0,0 @@
-// Baseline format: 1.0
-BroadcastBehavior: android.nfc.NfcAdapter#ACTION_ADAPTER_STATE_CHANGED:
-    Field 'ACTION_ADAPTER_STATE_CHANGED' is missing @BroadcastBehavior
-BroadcastBehavior: android.nfc.NfcAdapter#ACTION_PREFERRED_PAYMENT_CHANGED:
-    Field 'ACTION_PREFERRED_PAYMENT_CHANGED' is missing @BroadcastBehavior
-BroadcastBehavior: android.nfc.NfcAdapter#ACTION_REQUIRE_UNLOCK_FOR_NFC:
-    Field 'ACTION_REQUIRE_UNLOCK_FOR_NFC' is missing @BroadcastBehavior
-BroadcastBehavior: android.nfc.NfcAdapter#ACTION_TRANSACTION_DETECTED:
-    Field 'ACTION_TRANSACTION_DETECTED' is missing @BroadcastBehavior
-
-RequiresPermission: android.nfc.NfcAdapter#disableForegroundDispatch(android.app.Activity):
-    Method 'disableForegroundDispatch' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.NfcAdapter#enableForegroundDispatch(android.app.Activity, android.app.PendingIntent, android.content.IntentFilter[], String[][]):
-    Method 'enableForegroundDispatch' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.cardemulation.CardEmulation#isDefaultServiceForAid(android.content.ComponentName, String):
-    Method 'isDefaultServiceForAid' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.cardemulation.CardEmulation#isDefaultServiceForCategory(android.content.ComponentName, String):
-    Method 'isDefaultServiceForCategory' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.cardemulation.CardEmulation#setOffHostForService(android.content.ComponentName, String):
-    Method 'setOffHostForService' documentation mentions permissions already declared by @RequiresPermission
-RequiresPermission: android.nfc.tech.IsoDep#getTimeout():
-    Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.IsoDep#setTimeout(int):
-    Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.IsoDep#transceive(byte[]):
-    Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#authenticateSectorWithKeyA(int, byte[]):
-    Method 'authenticateSectorWithKeyA' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#authenticateSectorWithKeyB(int, byte[]):
-    Method 'authenticateSectorWithKeyB' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#decrement(int, int):
-    Method 'decrement' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#getTimeout():
-    Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#increment(int, int):
-    Method 'increment' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#readBlock(int):
-    Method 'readBlock' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#restore(int):
-    Method 'restore' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#setTimeout(int):
-    Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#transceive(byte[]):
-    Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#transfer(int):
-    Method 'transfer' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#writeBlock(int, byte[]):
-    Method 'writeBlock' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareUltralight#getTimeout():
-    Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareUltralight#readPages(int):
-    Method 'readPages' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareUltralight#setTimeout(int):
-    Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareUltralight#transceive(byte[]):
-    Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareUltralight#writePage(int, byte[]):
-    Method 'writePage' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.Ndef#getNdefMessage():
-    Method 'getNdefMessage' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.Ndef#isWritable():
-    Method 'isWritable' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.Ndef#makeReadOnly():
-    Method 'makeReadOnly' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.Ndef#writeNdefMessage(android.nfc.NdefMessage):
-    Method 'writeNdefMessage' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NdefFormatable#format(android.nfc.NdefMessage):
-    Method 'format' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NdefFormatable#formatReadOnly(android.nfc.NdefMessage):
-    Method 'formatReadOnly' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcA#getTimeout():
-    Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcA#setTimeout(int):
-    Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcA#transceive(byte[]):
-    Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcB#transceive(byte[]):
-    Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcF#getTimeout():
-    Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcF#setTimeout(int):
-    Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcF#transceive(byte[]):
-    Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcV#transceive(byte[]):
-    Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.TagTechnology#close():
-    Method 'close' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.TagTechnology#connect():
-    Method 'connect' documentation mentions permissions without declaring @RequiresPermission
-
-SdkConstant: android.nfc.NfcAdapter#ACTION_REQUIRE_UNLOCK_FOR_NFC:
-    Field 'ACTION_REQUIRE_UNLOCK_FOR_NFC' is missing @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
diff --git a/nfc/api/module-lib-removed.txt b/nfc/api/module-lib-removed.txt
deleted file mode 100644
index d802177..0000000
--- a/nfc/api/module-lib-removed.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/nfc/api/removed.txt b/nfc/api/removed.txt
deleted file mode 100644
index fb82b5d..0000000
--- a/nfc/api/removed.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-// Signature format: 2.0
-package android.nfc {
-
-  public final class NfcAdapter {
-    method @Deprecated @android.compat.annotation.UnsupportedAppUsage public void disableForegroundNdefPush(android.app.Activity);
-    method @Deprecated @android.compat.annotation.UnsupportedAppUsage public void enableForegroundNdefPush(android.app.Activity, android.nfc.NdefMessage);
-    method @Deprecated @android.compat.annotation.UnsupportedAppUsage public boolean invokeBeam(android.app.Activity);
-    method @Deprecated @android.compat.annotation.UnsupportedAppUsage public boolean isNdefPushEnabled();
-    method @Deprecated @android.compat.annotation.UnsupportedAppUsage public void setBeamPushUris(android.net.Uri[], android.app.Activity);
-    method @Deprecated @android.compat.annotation.UnsupportedAppUsage public void setBeamPushUrisCallback(android.nfc.NfcAdapter.CreateBeamUrisCallback, android.app.Activity);
-    method @Deprecated @android.compat.annotation.UnsupportedAppUsage public void setNdefPushMessage(android.nfc.NdefMessage, android.app.Activity, android.app.Activity...);
-    method @Deprecated @android.compat.annotation.UnsupportedAppUsage public void setNdefPushMessageCallback(android.nfc.NfcAdapter.CreateNdefMessageCallback, android.app.Activity, android.app.Activity...);
-    method @Deprecated @android.compat.annotation.UnsupportedAppUsage public void setOnNdefPushCompleteCallback(android.nfc.NfcAdapter.OnNdefPushCompleteCallback, android.app.Activity, android.app.Activity...);
-  }
-
-}
-
diff --git a/nfc/api/system-current.txt b/nfc/api/system-current.txt
deleted file mode 100644
index 6bd6072..0000000
--- a/nfc/api/system-current.txt
+++ /dev/null
@@ -1,256 +0,0 @@
-// Signature format: 2.0
-package android.nfc {
-
-  public final class NfcAdapter {
-    method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean addNfcUnlockHandler(android.nfc.NfcAdapter.NfcUnlockHandler, String[]);
-    method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean disable(boolean);
-    method @FlaggedApi("android.nfc.enable_nfc_reader_option") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enableReaderOption(boolean);
-    method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enableSecureNfc(boolean);
-    method @FlaggedApi("android.nfc.enable_nfc_mainline") public int getAdapterState();
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @NonNull public android.nfc.NfcOemExtension getNfcOemExtension();
-    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.NFC_SET_CONTROLLER_ALWAYS_ON) public void registerControllerAlwaysOnListener(@NonNull java.util.concurrent.Executor, @NonNull android.nfc.NfcAdapter.ControllerAlwaysOnListener);
-    method @FlaggedApi("android.nfc.nfc_vendor_cmd") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void registerNfcVendorNciCallback(@NonNull java.util.concurrent.Executor, @NonNull android.nfc.NfcAdapter.NfcVendorNciCallback);
-    method @FlaggedApi("android.nfc.enable_nfc_charging") public void registerWlcStateListener(@NonNull java.util.concurrent.Executor, @NonNull android.nfc.NfcAdapter.WlcStateListener);
-    method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean removeNfcUnlockHandler(android.nfc.NfcAdapter.NfcUnlockHandler);
-    method @FlaggedApi("android.nfc.nfc_vendor_cmd") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int sendVendorNciMessage(int, @IntRange(from=0, to=15) int, @IntRange(from=0) int, @NonNull byte[]);
-    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 setReaderModePollingEnabled(boolean);
-    method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int setTagIntentAppPreferenceForUser(int, @NonNull String, boolean);
-    method @FlaggedApi("android.nfc.enable_nfc_charging") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean setWlcEnabled(boolean);
-    method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public void unregisterControllerAlwaysOnListener(@NonNull android.nfc.NfcAdapter.ControllerAlwaysOnListener);
-    method @FlaggedApi("android.nfc.nfc_vendor_cmd") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void unregisterNfcVendorNciCallback(@NonNull android.nfc.NfcAdapter.NfcVendorNciCallback);
-    method @FlaggedApi("android.nfc.enable_nfc_charging") public void unregisterWlcStateListener(@NonNull android.nfc.NfcAdapter.WlcStateListener);
-    field @FlaggedApi("android.nfc.enable_nfc_mainline") public static final String ACTION_REQUIRE_UNLOCK_FOR_NFC = "android.nfc.action.REQUIRE_UNLOCK_FOR_NFC";
-    field @FlaggedApi("android.nfc.enable_nfc_mainline") @RequiresPermission(android.Manifest.permission.SHOW_CUSTOMIZED_RESOLVER) public static final String ACTION_SHOW_NFC_RESOLVER = "android.nfc.action.SHOW_NFC_RESOLVER";
-    field @FlaggedApi("android.nfc.enable_nfc_mainline") public static final String EXTRA_RESOLVE_INFOS = "android.nfc.extra.RESOLVE_INFOS";
-    field @FlaggedApi("android.nfc.nfc_set_default_disc_tech") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public static final int FLAG_SET_DEFAULT_TECH = 1073741824; // 0x40000000
-    field @FlaggedApi("android.nfc.nfc_vendor_cmd") public static final int MESSAGE_TYPE_COMMAND = 1; // 0x1
-    field @FlaggedApi("android.nfc.nfc_vendor_cmd") public static final int SEND_VENDOR_NCI_STATUS_FAILED = 3; // 0x3
-    field @FlaggedApi("android.nfc.nfc_vendor_cmd") public static final int SEND_VENDOR_NCI_STATUS_MESSAGE_CORRUPTED = 2; // 0x2
-    field @FlaggedApi("android.nfc.nfc_vendor_cmd") public static final int SEND_VENDOR_NCI_STATUS_REJECTED = 1; // 0x1
-    field @FlaggedApi("android.nfc.nfc_vendor_cmd") public static final int SEND_VENDOR_NCI_STATUS_SUCCESS = 0; // 0x0
-    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 {
-    method public void onControllerAlwaysOnChanged(boolean);
-  }
-
-  public static interface NfcAdapter.NfcUnlockHandler {
-    method public boolean onUnlockAttempted(android.nfc.Tag);
-  }
-
-  @FlaggedApi("android.nfc.nfc_vendor_cmd") public static interface NfcAdapter.NfcVendorNciCallback {
-    method @FlaggedApi("android.nfc.nfc_vendor_cmd") public void onVendorNciNotification(@IntRange(from=9, to=15) int, int, @NonNull byte[]);
-    method @FlaggedApi("android.nfc.nfc_vendor_cmd") public void onVendorNciResponse(@IntRange(from=0, to=15) int, int, @NonNull byte[]);
-  }
-
-  @FlaggedApi("android.nfc.enable_nfc_charging") public static interface NfcAdapter.WlcStateListener {
-    method public void onWlcStateChanged(@NonNull android.nfc.WlcListenerDeviceInfo);
-  }
-
-  @FlaggedApi("android.nfc.nfc_oem_extension") public final class NfcOemExtension {
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void clearPreference();
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int forceRoutingTableCommit();
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @NonNull public java.util.Map<java.lang.String,java.lang.Integer> getActiveNfceeList();
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public long getMaxPausePollingTimeoutMills();
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @NonNull @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public android.nfc.RoutingStatus getRoutingStatus();
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @NonNull @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public java.util.List<android.nfc.NfcRoutingTableEntry> getRoutingTable();
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @NonNull public android.nfc.T4tNdefNfcee getT4tNdefNfcee();
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean hasUserEnabledNfc();
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean isAutoChangeEnabled();
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean isTagPresent();
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void maybeTriggerFirmwareUpdate();
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void overwriteRoutingTable(int, int, int, int);
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int pausePolling(long);
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void registerCallback(@NonNull java.util.concurrent.Executor, @NonNull android.nfc.NfcOemExtension.Callback);
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int resumePolling();
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void setAutoChangeEnabled(boolean);
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public void setControllerAlwaysOnMode(int);
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void synchronizeScreenState();
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void triggerInitialization();
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void unregisterCallback(@NonNull android.nfc.NfcOemExtension.Callback);
-    field public static final int COMMIT_ROUTING_STATUS_FAILED = 3; // 0x3
-    field public static final int COMMIT_ROUTING_STATUS_FAILED_UPDATE_IN_PROGRESS = 6; // 0x6
-    field public static final int COMMIT_ROUTING_STATUS_OK = 0; // 0x0
-    field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int DISABLE = 0; // 0x0
-    field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int ENABLE_DEFAULT = 1; // 0x1
-    field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int ENABLE_EE = 3; // 0x3
-    field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int ENABLE_TRANSPARENT = 2; // 0x2
-    field public static final int HCE_ACTIVATE = 1; // 0x1
-    field public static final int HCE_DATA_TRANSFERRED = 2; // 0x2
-    field public static final int HCE_DEACTIVATE = 3; // 0x3
-    field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int NFCEE_TECH_A = 1; // 0x1
-    field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int NFCEE_TECH_B = 2; // 0x2
-    field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int NFCEE_TECH_F = 4; // 0x4
-    field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int NFCEE_TECH_NONE = 0; // 0x0
-    field public static final int POLLING_STATE_CHANGE_ALREADY_IN_REQUESTED_STATE = 2; // 0x2
-    field public static final int POLLING_STATE_CHANGE_SUCCEEDED = 1; // 0x1
-    field public static final int STATUS_OK = 0; // 0x0
-    field public static final int STATUS_UNKNOWN_ERROR = 1; // 0x1
-  }
-
-  public static interface NfcOemExtension.Callback {
-    method public void onApplyRouting(@NonNull java.util.function.Consumer<java.lang.Boolean>);
-    method public void onBootFinished(int);
-    method public void onBootStarted();
-    method public void onCardEmulationActivated(boolean);
-    method public void onDisableFinished(int);
-    method public void onDisableRequested(@NonNull java.util.function.Consumer<java.lang.Boolean>);
-    method public void onDisableStarted();
-    method public void onEeListenActivated(boolean);
-    method public void onEeUpdated();
-    method public void onEnableFinished(int);
-    method public void onEnableRequested(@NonNull java.util.function.Consumer<java.lang.Boolean>);
-    method public void onEnableStarted();
-    method public void onExtractOemPackages(@NonNull android.nfc.NdefMessage, @NonNull java.util.function.Consumer<java.util.List<java.lang.String>>);
-    method public void onGetOemAppSearchIntent(@NonNull java.util.List<java.lang.String>, @NonNull java.util.function.Consumer<android.content.Intent>);
-    method public void onHceEventReceived(int);
-    method public void onLaunchHceAppChooserActivity(@NonNull String, @NonNull java.util.List<android.nfc.cardemulation.ApduServiceInfo>, @NonNull android.content.ComponentName, @NonNull String);
-    method public void onLaunchHceTapAgainDialog(@NonNull android.nfc.cardemulation.ApduServiceInfo, @NonNull String);
-    method public void onLogEventNotified(@NonNull android.nfc.OemLogItems);
-    method public void onNdefMessage(@NonNull android.nfc.Tag, @NonNull android.nfc.NdefMessage, @NonNull java.util.function.Consumer<java.lang.Boolean>);
-    method public void onNdefRead(@NonNull java.util.function.Consumer<java.lang.Boolean>);
-    method public void onReaderOptionChanged(boolean);
-    method public void onRfDiscoveryStarted(boolean);
-    method public void onRfFieldActivated(boolean);
-    method public void onRoutingChanged(@NonNull java.util.function.Consumer<java.lang.Boolean>);
-    method public void onRoutingTableFull();
-    method public void onStateUpdated(int);
-    method public void onTagConnected(boolean);
-    method public void onTagDispatch(@NonNull java.util.function.Consumer<java.lang.Boolean>);
-  }
-
-  @FlaggedApi("android.nfc.nfc_oem_extension") public abstract class NfcRoutingTableEntry {
-    method public int getNfceeId();
-    method public int getRouteType();
-    method public int getType();
-    field public static final int TYPE_AID = 0; // 0x0
-    field public static final int TYPE_PROTOCOL = 1; // 0x1
-    field public static final int TYPE_SYSTEM_CODE = 3; // 0x3
-    field public static final int TYPE_TECHNOLOGY = 2; // 0x2
-  }
-
-  @FlaggedApi("android.nfc.nfc_oem_extension") public final class OemLogItems implements android.os.Parcelable {
-    method public int describeContents();
-    method public int getAction();
-    method public int getCallingPid();
-    method @Nullable public byte[] getCommandApdu();
-    method public int getEvent();
-    method @Nullable public byte[] getResponseApdu();
-    method @Nullable public java.time.Instant getRfFieldEventTimeMillis();
-    method @Nullable public android.nfc.Tag getTag();
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.nfc.OemLogItems> CREATOR;
-    field public static final int EVENT_DISABLE = 2; // 0x2
-    field public static final int EVENT_ENABLE = 1; // 0x1
-    field public static final int EVENT_UNSET = 0; // 0x0
-    field public static final int LOG_ACTION_HCE_DATA = 516; // 0x204
-    field public static final int LOG_ACTION_NFC_TOGGLE = 513; // 0x201
-    field public static final int LOG_ACTION_RF_FIELD_STATE_CHANGED = 1; // 0x1
-    field public static final int LOG_ACTION_SCREEN_STATE_CHANGED = 518; // 0x206
-    field public static final int LOG_ACTION_TAG_DETECTED = 3; // 0x3
-  }
-
-  @FlaggedApi("android.nfc.nfc_oem_extension") public class RoutingStatus {
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int getDefaultIsoDepRoute();
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int getDefaultOffHostRoute();
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int getDefaultRoute();
-  }
-
-  @FlaggedApi("android.nfc.nfc_oem_extension") public class RoutingTableAidEntry extends android.nfc.NfcRoutingTableEntry {
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @NonNull public String getAid();
-  }
-
-  @FlaggedApi("android.nfc.nfc_oem_extension") public class RoutingTableProtocolEntry extends android.nfc.NfcRoutingTableEntry {
-    method @FlaggedApi("android.nfc.nfc_oem_extension") public int getProtocol();
-    field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int PROTOCOL_ISO_DEP = 4; // 0x4
-    field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int PROTOCOL_NDEF = 7; // 0x7
-    field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int PROTOCOL_NFC_DEP = 5; // 0x5
-    field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int PROTOCOL_T1T = 1; // 0x1
-    field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int PROTOCOL_T2T = 2; // 0x2
-    field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int PROTOCOL_T3T = 3; // 0x3
-    field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int PROTOCOL_T5T = 6; // 0x6
-    field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int PROTOCOL_UNDETERMINED = 0; // 0x0
-    field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int PROTOCOL_UNSUPPORTED = -1; // 0xffffffff
-  }
-
-  @FlaggedApi("android.nfc.nfc_oem_extension") public class RoutingTableSystemCodeEntry extends android.nfc.NfcRoutingTableEntry {
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @NonNull public byte[] getSystemCode();
-  }
-
-  @FlaggedApi("android.nfc.nfc_oem_extension") public class RoutingTableTechnologyEntry extends android.nfc.NfcRoutingTableEntry {
-    method @FlaggedApi("android.nfc.nfc_oem_extension") public int getTechnology();
-    field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int TECHNOLOGY_A = 0; // 0x0
-    field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int TECHNOLOGY_B = 1; // 0x1
-    field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int TECHNOLOGY_F = 2; // 0x2
-    field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int TECHNOLOGY_UNSUPPORTED = -1; // 0xffffffff
-    field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int TECHNOLOGY_V = 3; // 0x3
-  }
-
-  @FlaggedApi("android.nfc.nfc_oem_extension") public final class T4tNdefNfcee {
-    method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) @WorkerThread public int clearData();
-    method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean isOperationOngoing();
-    method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean isSupported();
-    method @Nullable @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) @WorkerThread public android.nfc.T4tNdefNfceeCcFileInfo readCcfile();
-    method @NonNull @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) @WorkerThread public byte[] readData(@IntRange(from=0, to=65535) int);
-    method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) @WorkerThread public int writeData(@IntRange(from=0, to=65535) int, @NonNull byte[]);
-    field public static final int CLEAR_DATA_FAILED_DEVICE_BUSY = -1; // 0xffffffff
-    field public static final int CLEAR_DATA_FAILED_INTERNAL = 0; // 0x0
-    field public static final int CLEAR_DATA_SUCCESS = 1; // 0x1
-    field public static final int WRITE_DATA_ERROR_CONNECTION_FAILED = -6; // 0xfffffffa
-    field public static final int WRITE_DATA_ERROR_DEVICE_BUSY = -9; // 0xfffffff7
-    field public static final int WRITE_DATA_ERROR_EMPTY_PAYLOAD = -7; // 0xfffffff9
-    field public static final int WRITE_DATA_ERROR_INTERNAL = -1; // 0xffffffff
-    field public static final int WRITE_DATA_ERROR_INVALID_FILE_ID = -4; // 0xfffffffc
-    field public static final int WRITE_DATA_ERROR_INVALID_LENGTH = -5; // 0xfffffffb
-    field public static final int WRITE_DATA_ERROR_NDEF_VALIDATION_FAILED = -8; // 0xfffffff8
-    field public static final int WRITE_DATA_ERROR_NFC_NOT_ON = -3; // 0xfffffffd
-    field public static final int WRITE_DATA_ERROR_RF_ACTIVATED = -2; // 0xfffffffe
-    field public static final int WRITE_DATA_SUCCESS = 0; // 0x0
-  }
-
-  @FlaggedApi("android.nfc.nfc_oem_extension") public final class T4tNdefNfceeCcFileInfo implements android.os.Parcelable {
-    method public int describeContents();
-    method @IntRange(from=15, to=32767) public int getCcFileLength();
-    method @IntRange(from=0xffffffff, to=65535) public int getFileId();
-    method @IntRange(from=5, to=32767) public int getMaxSize();
-    method public int getVersion();
-    method public boolean isReadAllowed();
-    method public boolean isWriteAllowed();
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.nfc.T4tNdefNfceeCcFileInfo> CREATOR;
-    field public static final int VERSION_2_0 = 32; // 0x20
-    field public static final int VERSION_3_0 = 48; // 0x30
-  }
-
-}
-
-package android.nfc.cardemulation {
-
-  public final class CardEmulation {
-    method @FlaggedApi("android.permission.flags.wallet_role_enabled") @Nullable @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) public static android.content.ComponentName getPreferredPaymentService(@NonNull android.content.Context);
-    method @FlaggedApi("android.nfc.enable_nfc_mainline") @NonNull public java.util.List<android.nfc.cardemulation.ApduServiceInfo> getServices(@NonNull String, int);
-    method @FlaggedApi("android.nfc.nfc_override_recover_routing_table") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void overrideRoutingTable(@NonNull android.app.Activity, int, int);
-    method @FlaggedApi("android.nfc.nfc_override_recover_routing_table") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void recoverRoutingTable(@NonNull android.app.Activity);
-    method @FlaggedApi("android.nfc.enable_card_emulation_euicc") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int setDefaultNfcSubscriptionId(int);
-    method @FlaggedApi("android.nfc.nfc_set_service_enabled_for_category_other") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int setServiceEnabledForCategoryOther(@NonNull android.content.ComponentName, boolean);
-    field @FlaggedApi("android.nfc.nfc_set_service_enabled_for_category_other") public static final int SET_SERVICE_ENABLED_STATUS_FAILURE_ALREADY_SET = 3; // 0x3
-    field @FlaggedApi("android.nfc.nfc_set_service_enabled_for_category_other") public static final int SET_SERVICE_ENABLED_STATUS_FAILURE_FEATURE_UNSUPPORTED = 1; // 0x1
-    field @FlaggedApi("android.nfc.nfc_set_service_enabled_for_category_other") public static final int SET_SERVICE_ENABLED_STATUS_FAILURE_INVALID_SERVICE = 2; // 0x2
-    field @FlaggedApi("android.nfc.nfc_set_service_enabled_for_category_other") public static final int SET_SERVICE_ENABLED_STATUS_FAILURE_UNKNOWN_ERROR = 4; // 0x4
-    field @FlaggedApi("android.nfc.nfc_set_service_enabled_for_category_other") public static final int SET_SERVICE_ENABLED_STATUS_OK = 0; // 0x0
-    field @FlaggedApi("android.nfc.enable_card_emulation_euicc") public static final int SET_SUBSCRIPTION_ID_STATUS_FAILED_INTERNAL_ERROR = 2; // 0x2
-    field @FlaggedApi("android.nfc.enable_card_emulation_euicc") public static final int SET_SUBSCRIPTION_ID_STATUS_FAILED_INVALID_SUBSCRIPTION_ID = 1; // 0x1
-    field @FlaggedApi("android.nfc.enable_card_emulation_euicc") public static final int SET_SUBSCRIPTION_ID_STATUS_FAILED_NOT_SUPPORTED = 3; // 0x3
-    field @FlaggedApi("android.nfc.enable_card_emulation_euicc") public static final int SET_SUBSCRIPTION_ID_STATUS_SUCCESS = 0; // 0x0
-    field @FlaggedApi("android.nfc.enable_card_emulation_euicc") public static final int SET_SUBSCRIPTION_ID_STATUS_UNKNOWN = -1; // 0xffffffff
-  }
-
-}
-
diff --git a/nfc/api/system-lint-baseline.txt b/nfc/api/system-lint-baseline.txt
deleted file mode 100644
index c7a6181..0000000
--- a/nfc/api/system-lint-baseline.txt
+++ /dev/null
@@ -1,119 +0,0 @@
-// Baseline format: 1.0
-BroadcastBehavior: android.nfc.NfcAdapter#ACTION_ADAPTER_STATE_CHANGED:
-    Field 'ACTION_ADAPTER_STATE_CHANGED' is missing @BroadcastBehavior
-BroadcastBehavior: android.nfc.NfcAdapter#ACTION_PREFERRED_PAYMENT_CHANGED:
-    Field 'ACTION_PREFERRED_PAYMENT_CHANGED' is missing @BroadcastBehavior
-BroadcastBehavior: android.nfc.NfcAdapter#ACTION_REQUIRE_UNLOCK_FOR_NFC:
-    Field 'ACTION_REQUIRE_UNLOCK_FOR_NFC' is missing @BroadcastBehavior
-BroadcastBehavior: android.nfc.NfcAdapter#ACTION_TRANSACTION_DETECTED:
-    Field 'ACTION_TRANSACTION_DETECTED' is missing @BroadcastBehavior
-
-
-CallbackMethodName: android.nfc.NfcOemExtension.Callback#shouldSkipRoutingChange():
-    Callback method names must follow the on<Something> style: shouldSkipRoutingChange
-
-
-MethodNameTense: android.nfc.NfcOemExtension.Callback#onEnable():
-    Unexpected tense; probably meant `enabled`, was `onEnable`
-
-
-MissingNullability: android.nfc.cardemulation.CardEmulation#overrideRoutingTable(android.app.Activity, String, String) parameter #1:
-    Missing nullability on parameter `protocol` in method `overrideRoutingTable`
-MissingNullability: android.nfc.cardemulation.CardEmulation#overrideRoutingTable(android.app.Activity, String, String) parameter #2:
-    Missing nullability on parameter `technology` in method `overrideRoutingTable`
-MissingNullability: android.nfc.cardemulation.OffHostApduService#onBind(android.content.Intent):
-    Missing nullability on method `onBind` return
-MissingNullability: android.nfc.cardemulation.OffHostApduService#onBind(android.content.Intent) parameter #0:
-    Missing nullability on parameter `intent` in method `onBind`
-
-
-RequiresPermission: android.nfc.NfcAdapter#disableForegroundDispatch(android.app.Activity):
-    Method 'disableForegroundDispatch' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.NfcAdapter#enableForegroundDispatch(android.app.Activity, android.app.PendingIntent, android.content.IntentFilter[], String[][]):
-    Method 'enableForegroundDispatch' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.cardemulation.CardEmulation#isDefaultServiceForAid(android.content.ComponentName, String):
-    Method 'isDefaultServiceForAid' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.cardemulation.CardEmulation#isDefaultServiceForCategory(android.content.ComponentName, String):
-    Method 'isDefaultServiceForCategory' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.cardemulation.CardEmulation#setOffHostForService(android.content.ComponentName, String):
-    Method 'setOffHostForService' documentation mentions permissions already declared by @RequiresPermission
-RequiresPermission: android.nfc.tech.IsoDep#getTimeout():
-    Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.IsoDep#setTimeout(int):
-    Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.IsoDep#transceive(byte[]):
-    Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#authenticateSectorWithKeyA(int, byte[]):
-    Method 'authenticateSectorWithKeyA' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#authenticateSectorWithKeyB(int, byte[]):
-    Method 'authenticateSectorWithKeyB' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#decrement(int, int):
-    Method 'decrement' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#getTimeout():
-    Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#increment(int, int):
-    Method 'increment' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#readBlock(int):
-    Method 'readBlock' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#restore(int):
-    Method 'restore' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#setTimeout(int):
-    Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#transceive(byte[]):
-    Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#transfer(int):
-    Method 'transfer' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#writeBlock(int, byte[]):
-    Method 'writeBlock' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareUltralight#getTimeout():
-    Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareUltralight#readPages(int):
-    Method 'readPages' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareUltralight#setTimeout(int):
-    Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareUltralight#transceive(byte[]):
-    Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareUltralight#writePage(int, byte[]):
-    Method 'writePage' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.Ndef#getNdefMessage():
-    Method 'getNdefMessage' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.Ndef#isWritable():
-    Method 'isWritable' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.Ndef#makeReadOnly():
-    Method 'makeReadOnly' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.Ndef#writeNdefMessage(android.nfc.NdefMessage):
-    Method 'writeNdefMessage' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NdefFormatable#format(android.nfc.NdefMessage):
-    Method 'format' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NdefFormatable#formatReadOnly(android.nfc.NdefMessage):
-    Method 'formatReadOnly' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcA#getTimeout():
-    Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcA#setTimeout(int):
-    Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcA#transceive(byte[]):
-    Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcB#transceive(byte[]):
-    Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcF#getTimeout():
-    Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcF#setTimeout(int):
-    Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcF#transceive(byte[]):
-    Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcV#transceive(byte[]):
-    Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.TagTechnology#close():
-    Method 'close' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.TagTechnology#connect():
-    Method 'connect' documentation mentions permissions without declaring @RequiresPermission
-
-
-SamShouldBeLast: android.nfc.NfcAdapter#enableReaderMode(android.app.Activity, android.nfc.NfcAdapter.ReaderCallback, int, android.os.Bundle):
-    SAM-compatible parameters (such as parameter 2, "callback", in android.nfc.NfcAdapter.enableReaderMode) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
-SamShouldBeLast: android.nfc.NfcAdapter#ignore(android.nfc.Tag, int, android.nfc.NfcAdapter.OnTagRemovedListener, android.os.Handler):
-    SAM-compatible parameters (such as parameter 3, "tagRemovedListener", in android.nfc.NfcAdapter.ignore) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
-
-
-SdkConstant: android.nfc.NfcAdapter#ACTION_REQUIRE_UNLOCK_FOR_NFC:
-    Field 'ACTION_REQUIRE_UNLOCK_FOR_NFC' is missing @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
diff --git a/nfc/api/system-removed.txt b/nfc/api/system-removed.txt
deleted file mode 100644
index c6eaa57..0000000
--- a/nfc/api/system-removed.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-// Signature format: 2.0
-package android.nfc {
-
-  public final class NfcAdapter {
-    method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean disableNdefPush();
-    method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enableNdefPush();
-    method public void setNdefPushMessage(android.nfc.NdefMessage, android.app.Activity, int);
-    field public static final int FLAG_NDEF_PUSH_NO_CONFIRM = 1; // 0x1
-  }
-
-}
-
diff --git a/nfc/api/test-current.txt b/nfc/api/test-current.txt
deleted file mode 100644
index d802177..0000000
--- a/nfc/api/test-current.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/nfc/api/test-removed.txt b/nfc/api/test-removed.txt
deleted file mode 100644
index d802177..0000000
--- a/nfc/api/test-removed.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/nfc/jarjar-rules.txt b/nfc/jarjar-rules.txt
deleted file mode 100644
index 63a6a58..0000000
--- a/nfc/jarjar-rules.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-# Used by framework-nfc for proto debug dumping
-rule android.app.PendingIntentProto* com.android.nfc.x.@0
-rule android.content.ComponentNameProto* com.android.nfc.x.@0
-rule android.content.IntentProto* com.android.nfc.x.@0
-rule android.content.IntentFilterProto* com.android.nfc.x.@0
-rule android.content.AuthorityEntryProto* com.android.nfc.x.@0
-rule android.content.UriRelativeFilter* com.android.nfc.x.@0
-rule android.nfc.cardemulation.AidGroupProto* com.android.nfc.x.@0
-rule android.nfc.cardemulation.ApduServiceInfoProto* com.android.nfc.x.@0
-rule android.nfc.cardemulation.NfcFServiceInfoProto* com.android.nfc.x.@0
-rule android.nfc.NdefMessageProto* com.android.nfc.x.@0
-rule android.nfc.NdefRecordProto* com.android.nfc.x.@0
-rule com.android.nfc.cardemulation.CardEmulationManagerProto* com.android.nfc.x.@0
-rule com.android.nfc.cardemulation.RegisteredServicesCacheProto* com.android.nfc.x.@0
-rule com.android.nfc.cardemulation.RegisteredNfcFServicesCacheProto* com.android.nfc.x.@0
-rule com.android.nfc.cardemulation.PreferredServicesProto* com.android.nfc.x.@0
-rule com.android.nfc.cardemulation.EnabledNfcFServicesProto* com.android.nfc.x.@0
-rule com.android.nfc.cardemulation.RegisteredAidCacheProto* com.android.nfc.x.@0
-rule com.android.nfc.cardemulation.AidRoutingManagerProto* com.android.nfc.x.@0
-rule com.android.nfc.cardemulation.RegisteredT3tIdentifiersCacheProto* com.android.nfc.x.@0
-rule com.android.nfc.cardemulation.SystemCodeRoutingManagerProto* com.android.nfc.x.@0
-rule com.android.nfc.cardemulation.HostEmulationManagerProto* com.android.nfc.x.@0
-rule com.android.nfc.cardemulation.HostNfcFEmulationManagerProto* com.android.nfc.x.@0
-rule com.android.nfc.NfcServiceDumpProto* com.android.nfc.x.@0
-rule com.android.nfc.DiscoveryParamsProto* com.android.nfc.x.@0
-rule com.android.nfc.NfcDispatcherProto* com.android.nfc.x.@0
-rule android.os.PersistableBundleProto* com.android.nfc.x.@0
-
-# Used by framework-nfc for reading trunk stable flags
-rule android.nfc.*Flags* com.android.nfc.x.@0
-rule android.nfc.Flags com.android.nfc.x.@0
-rule android.permission.flags.** com.android.nfc.x.@0
-
-# Used by framework-nfc for misc utilities
-rule android.os.PatternMatcher* com.android.nfc.x.@0
-
-rule com.android.incident.Privacy* com.android.nfc.x.@0
-rule com.android.incident.PrivacyFlags* com.android.nfc.x.@0
diff --git a/nfc/java/android/nfc/ApduList.aidl b/nfc/java/android/nfc/ApduList.aidl
deleted file mode 100644
index f6236b2..0000000
--- a/nfc/java/android/nfc/ApduList.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-parcelable ApduList;
\ No newline at end of file
diff --git a/nfc/java/android/nfc/ApduList.java b/nfc/java/android/nfc/ApduList.java
deleted file mode 100644
index 027141d..0000000
--- a/nfc/java/android/nfc/ApduList.java
+++ /dev/null
@@ -1,68 +0,0 @@
-package android.nfc;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * @hide
- */
-public class ApduList implements Parcelable {
-
-    private ArrayList<byte[]> commands = new ArrayList<byte[]>();
-
-    public ApduList() {
-    }
-
-    public void add(byte[] command) {
-        commands.add(command);
-    }
-
-    public List<byte[]> get() {
-        return commands;
-    }
-
-    public static final @android.annotation.NonNull Parcelable.Creator<ApduList> CREATOR =
-        new Parcelable.Creator<ApduList>() {
-        @Override
-        public ApduList createFromParcel(Parcel in) {
-            return new ApduList(in);
-        }
-
-        @Override
-        public ApduList[] newArray(int size) {
-            return new ApduList[size];
-        }
-    };
-
-    private ApduList(Parcel in) {
-        int count = in.readInt();
-
-        for (int i = 0 ; i < count ; i++) {
-
-            int length = in.readInt();
-            byte[] cmd = new byte[length];
-            in.readByteArray(cmd);
-            commands.add(cmd);
-        }
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(commands.size());
-
-        for (byte[] cmd : commands) {
-            dest.writeInt(cmd.length);
-            dest.writeByteArray(cmd);
-        }
-    }
-}
-
-
diff --git a/nfc/java/android/nfc/AvailableNfcAntenna.aidl b/nfc/java/android/nfc/AvailableNfcAntenna.aidl
deleted file mode 100644
index 9d06e2d..0000000
--- a/nfc/java/android/nfc/AvailableNfcAntenna.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-parcelable AvailableNfcAntenna;
diff --git a/nfc/java/android/nfc/AvailableNfcAntenna.java b/nfc/java/android/nfc/AvailableNfcAntenna.java
deleted file mode 100644
index e76aeb0..0000000
--- a/nfc/java/android/nfc/AvailableNfcAntenna.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Represents a single available Nfc antenna
- * on an Android device.
- */
-public final class AvailableNfcAntenna implements Parcelable {
-    /**
-     * Location of the antenna on the Y axis in millimeters.
-     * 0 is the top-left when the user is facing the screen
-     * and the device orientation is Portrait.
-     */
-    private final int mLocationX;
-    /**
-     * Location of the antenna on the Y axis in millimeters.
-     * 0 is the top-left when the user is facing the screen
-     * and the device orientation is Portrait.
-     */
-    private final int mLocationY;
-
-    public AvailableNfcAntenna(int locationX, int locationY) {
-        this.mLocationX = locationX;
-        this.mLocationY = locationY;
-    }
-
-    /**
-     * Location of the antenna on the X axis in millimeters.
-     * 0 is the top-left when the user is facing the screen
-     * and the device orientation is Portrait.
-     */
-    public int getLocationX() {
-        return mLocationX;
-    }
-
-    /**
-     * Location of the antenna on the Y axis in millimeters.
-     * 0 is the top-left when the user is facing the screen
-     * and the device orientation is Portrait.
-     */
-    public int getLocationY() {
-        return mLocationY;
-    }
-
-    private AvailableNfcAntenna(Parcel in) {
-        this.mLocationX = in.readInt();
-        this.mLocationY = in.readInt();
-    }
-
-    public static final @android.annotation.NonNull Parcelable.Creator<AvailableNfcAntenna>
-            CREATOR = new Parcelable.Creator<AvailableNfcAntenna>() {
-                @Override
-                public AvailableNfcAntenna createFromParcel(Parcel in) {
-                    return new AvailableNfcAntenna(in);
-                }
-
-                @Override
-                public AvailableNfcAntenna[] newArray(int size) {
-                    return new AvailableNfcAntenna[size];
-                }
-            };
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(@NonNull Parcel dest, int flags) {
-        dest.writeInt(mLocationX);
-        dest.writeInt(mLocationY);
-    }
-
-    @Override
-    public int hashCode() {
-        final int prime = 31;
-        int result = 1;
-        result = prime * result + mLocationX;
-        result = prime * result + mLocationY;
-        return result;
-    }
-
-    /**
-     * Returns true if the specified AvailableNfcAntenna contains
-     * identical specifications.
-     */
-    @Override
-    public boolean equals(@Nullable Object obj) {
-        if (this == obj) return true;
-        if (obj == null) return false;
-        if (getClass() != obj.getClass()) return false;
-        AvailableNfcAntenna other = (AvailableNfcAntenna) obj;
-        if (this.mLocationX != other.mLocationX) return false;
-        return this.mLocationY == other.mLocationY;
-    }
-
-    @Override
-    public String toString() {
-        return "AvailableNfcAntenna " + "x: " + mLocationX + " y: " + mLocationY;
-    }
-}
diff --git a/nfc/java/android/nfc/ComponentNameAndUser.aidl b/nfc/java/android/nfc/ComponentNameAndUser.aidl
deleted file mode 100644
index e677998..0000000
--- a/nfc/java/android/nfc/ComponentNameAndUser.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-parcelable ComponentNameAndUser;
\ No newline at end of file
diff --git a/nfc/java/android/nfc/ComponentNameAndUser.java b/nfc/java/android/nfc/ComponentNameAndUser.java
deleted file mode 100644
index 59e6c62..0000000
--- a/nfc/java/android/nfc/ComponentNameAndUser.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import android.annotation.UserIdInt;
-import android.content.ComponentName;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.Objects;
-
-/**
- * @hide
- */
-public class ComponentNameAndUser implements Parcelable {
-    @UserIdInt private final int mUserId;
-    private ComponentName mComponentName;
-
-    public ComponentNameAndUser(@UserIdInt int userId, ComponentName componentName) {
-        mUserId = userId;
-        mComponentName = componentName;
-    }
-
-    /**
-     * @hide
-     */
-    public int describeContents() {
-        return 0;
-    }
-
-    /**
-     * @hide
-     */
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeInt(mUserId);
-        out.writeParcelable(mComponentName, flags);
-    }
-
-    public static final Parcelable.Creator<ComponentNameAndUser> CREATOR =
-            new Parcelable.Creator<ComponentNameAndUser>() {
-                public ComponentNameAndUser createFromParcel(Parcel in) {
-                    return new ComponentNameAndUser(in);
-                }
-
-                public ComponentNameAndUser[] newArray(int size) {
-                    return new ComponentNameAndUser[size];
-                }
-            };
-
-    private ComponentNameAndUser(Parcel in) {
-        mUserId = in.readInt();
-        mComponentName = in.readParcelable(null, ComponentName.class);
-    }
-
-    @UserIdInt
-    public int getUserId() {
-        return mUserId;
-    }
-
-    public ComponentName getComponentName() {
-        return mComponentName;
-    }
-
-    @Override
-    public String toString() {
-        return mComponentName + " for user id: " + mUserId;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (obj != null && obj instanceof ComponentNameAndUser) {
-            ComponentNameAndUser other = (ComponentNameAndUser) obj;
-            return other.getUserId() == mUserId
-                    && Objects.equals(other.getComponentName(), mComponentName);
-        }
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        if (mComponentName == null) {
-            return mUserId;
-        }
-        return mComponentName.hashCode() + mUserId;
-    }
-}
diff --git a/nfc/java/android/nfc/Constants.java b/nfc/java/android/nfc/Constants.java
deleted file mode 100644
index 9b11e2d..0000000
--- a/nfc/java/android/nfc/Constants.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import android.provider.Settings;
-
-/**
- * @hide
- * TODO(b/303286040): Holds @hide API constants. Formalize these APIs.
- */
-public final class Constants {
-    private Constants() { }
-
-    public static final String SETTINGS_SECURE_NFC_PAYMENT_FOREGROUND = "nfc_payment_foreground";
-    public static final String SETTINGS_SECURE_NFC_PAYMENT_DEFAULT_COMPONENT = "nfc_payment_default_component";
-    public static final String FEATURE_NFC_ANY = "android.hardware.nfc.any";
-
-    /**
-     * @hide constant copied from {@link Settings.Global}
-     * TODO(b/274636414): Migrate to official API in Android V.
-     */
-    public static final String SETTINGS_SATELLITE_MODE_RADIOS = "satellite_mode_radios";
-    /**
-     * @hide constant copied from {@link Settings.Global}
-     * TODO(b/274636414): Migrate to official API in Android V.
-     */
-    public static final String SETTINGS_SATELLITE_MODE_ENABLED = "satellite_mode_enabled";
-}
diff --git a/nfc/java/android/nfc/Entry.aidl b/nfc/java/android/nfc/Entry.aidl
deleted file mode 100644
index 148c4ec..0000000
--- a/nfc/java/android/nfc/Entry.aidl
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.nfc;
-
-parcelable Entry;
\ No newline at end of file
diff --git a/nfc/java/android/nfc/Entry.java b/nfc/java/android/nfc/Entry.java
deleted file mode 100644
index aa5ba58..0000000
--- a/nfc/java/android/nfc/Entry.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.nfc;
-
-import android.annotation.NonNull;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-
-/** @hide */
-public final class Entry implements Parcelable {
-    private final byte mType;
-    private final byte mNfceeId;
-    private final String mEntry;
-    private final String mRoutingType;
-
-    public Entry(String entry, byte type, byte nfceeId, String routingType) {
-        mEntry = entry;
-        mType = type;
-        mNfceeId = nfceeId;
-        mRoutingType = routingType;
-    }
-
-    public byte getType() {
-        return mType;
-    }
-
-    public byte getNfceeId() {
-        return mNfceeId;
-    }
-
-    public String getEntry() {
-        return mEntry;
-    }
-
-    public String getRoutingType() {
-        return mRoutingType;
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    private Entry(Parcel in) {
-        this.mEntry = in.readString();
-        this.mNfceeId = in.readByte();
-        this.mType = in.readByte();
-        this.mRoutingType = in.readString();
-    }
-
-    public static final @NonNull Parcelable.Creator<Entry> CREATOR =
-            new Parcelable.Creator<Entry>() {
-                @Override
-                public Entry createFromParcel(Parcel in) {
-                    return new Entry(in);
-                }
-
-                @Override
-                public Entry[] newArray(int size) {
-                    return new Entry[size];
-                }
-            };
-
-    @Override
-    public void writeToParcel(@NonNull Parcel dest, int flags) {
-        dest.writeString(mEntry);
-        dest.writeByte(mNfceeId);
-        dest.writeByte(mType);
-        dest.writeString(mRoutingType);
-    }
-}
diff --git a/nfc/java/android/nfc/ErrorCodes.java b/nfc/java/android/nfc/ErrorCodes.java
deleted file mode 100644
index d2c81cd..0000000
--- a/nfc/java/android/nfc/ErrorCodes.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2010, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import android.compat.annotation.UnsupportedAppUsage;
-
-/**
- * This class defines all the error codes that can be returned by the service
- * and producing an exception on the application level. These are needed since
- * binders does not support exceptions.
- *
- * @hide
- */
-public class ErrorCodes {
-
-    @UnsupportedAppUsage
-    public static boolean isError(int code) {
-        if (code < 0) {
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    public static String asString(int code) {
-        switch (code) {
-            case SUCCESS: return "SUCCESS";
-            case ERROR_IO: return "IO";
-            case ERROR_CANCELLED: return "CANCELLED";
-            case ERROR_TIMEOUT: return "TIMEOUT";
-            case ERROR_BUSY: return "BUSY";
-            case ERROR_CONNECT: return "CONNECT/DISCONNECT";
-//            case ERROR_DISCONNECT: return "DISCONNECT";
-            case ERROR_READ: return "READ";
-            case ERROR_WRITE: return "WRITE";
-            case ERROR_INVALID_PARAM: return "INVALID_PARAM";
-            case ERROR_INSUFFICIENT_RESOURCES: return "INSUFFICIENT_RESOURCES";
-            case ERROR_SOCKET_CREATION: return "SOCKET_CREATION";
-            case ERROR_SOCKET_NOT_CONNECTED: return "SOCKET_NOT_CONNECTED";
-            case ERROR_BUFFER_TO_SMALL: return "BUFFER_TO_SMALL";
-            case ERROR_SAP_USED: return "SAP_USED";
-            case ERROR_SERVICE_NAME_USED: return "SERVICE_NAME_USED";
-            case ERROR_SOCKET_OPTIONS: return "SOCKET_OPTIONS";
-            case ERROR_NFC_ON: return "NFC_ON";
-            case ERROR_NOT_INITIALIZED: return "NOT_INITIALIZED";
-            case ERROR_SE_ALREADY_SELECTED: return "SE_ALREADY_SELECTED";
-            case ERROR_SE_CONNECTED: return "SE_CONNECTED";
-            case ERROR_NO_SE_CONNECTED: return "NO_SE_CONNECTED";
-            case ERROR_NOT_SUPPORTED: return "NOT_SUPPORTED";
-            default: return "UNKNOWN ERROR";
-        }
-    }
-
-    public static final int SUCCESS = 0;
-
-    public static final int ERROR_IO = -1;
-
-    public static final int ERROR_CANCELLED = -2;
-
-    public static final int ERROR_TIMEOUT = -3;
-
-    public static final int ERROR_BUSY = -4;
-
-    public static final int ERROR_CONNECT = -5;
-
-    public static final int ERROR_DISCONNECT = -5;
-
-    public static final int ERROR_READ = -6;
-
-    public static final int ERROR_WRITE = -7;
-
-    public static final int ERROR_INVALID_PARAM = -8;
-
-    public static final int ERROR_INSUFFICIENT_RESOURCES = -9;
-
-    public static final int ERROR_SOCKET_CREATION = -10;
-
-    public static final int ERROR_SOCKET_NOT_CONNECTED = -11;
-
-    public static final int ERROR_BUFFER_TO_SMALL = -12;
-
-    public static final int ERROR_SAP_USED = -13;
-
-    public static final int ERROR_SERVICE_NAME_USED = -14;
-
-    public static final int ERROR_SOCKET_OPTIONS = -15;
-
-    public static final int ERROR_NFC_ON = -16;
-
-    public static final int ERROR_NOT_INITIALIZED = -17;
-
-    public static final int ERROR_SE_ALREADY_SELECTED = -18;
-
-    public static final int ERROR_SE_CONNECTED = -19;
-
-    public static final int ERROR_NO_SE_CONNECTED = -20;
-
-    public static final int ERROR_NOT_SUPPORTED = -21;
-
-}
diff --git a/nfc/java/android/nfc/FormatException.java b/nfc/java/android/nfc/FormatException.java
deleted file mode 100644
index a57de1e..0000000
--- a/nfc/java/android/nfc/FormatException.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2010, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-public class FormatException extends Exception {
-    public FormatException() {
-        super();
-    }
-
-    public FormatException(String message) {
-        super(message);
-    }
-
-    public FormatException(String message, Throwable e) {
-        super(message, e);
-    }
-}
diff --git a/nfc/java/android/nfc/IAppCallback.aidl b/nfc/java/android/nfc/IAppCallback.aidl
deleted file mode 100644
index b06bf06..0000000
--- a/nfc/java/android/nfc/IAppCallback.aidl
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import android.nfc.Tag;
-
-/**
- * @hide
- */
-interface IAppCallback
-{
-    oneway void onTagDiscovered(in Tag tag);
-}
diff --git a/nfc/java/android/nfc/INfcAdapter.aidl b/nfc/java/android/nfc/INfcAdapter.aidl
deleted file mode 100644
index ac0a5aa..0000000
--- a/nfc/java/android/nfc/INfcAdapter.aidl
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import android.app.PendingIntent;
-import android.content.IntentFilter;
-import android.nfc.Entry;
-import android.nfc.NdefMessage;
-import android.nfc.Tag;
-import android.nfc.TechListParcel;
-import android.nfc.IAppCallback;
-import android.nfc.INfcAdapterExtras;
-import android.nfc.INfcControllerAlwaysOnListener;
-import android.nfc.INfcVendorNciCallback;
-import android.nfc.INfcTag;
-import android.nfc.INfcCardEmulation;
-import android.nfc.INfcFCardEmulation;
-import android.nfc.INfcOemExtensionCallback;
-import android.nfc.INfcUnlockHandler;
-import android.nfc.IT4tNdefNfcee;
-import android.nfc.ITagRemovedCallback;
-import android.nfc.INfcDta;
-import android.nfc.INfcWlcStateListener;
-import android.nfc.NfcAntennaInfo;
-import android.nfc.WlcListenerDeviceInfo;
-import android.nfc.cardemulation.PollingFrame;
-import android.os.Bundle;
-
-/**
- * @hide
- */
-interface INfcAdapter
-{
-    INfcTag getNfcTagInterface();
-    INfcCardEmulation getNfcCardEmulationInterface();
-    INfcFCardEmulation getNfcFCardEmulationInterface();
-    INfcAdapterExtras getNfcAdapterExtrasInterface(in String pkg);
-    INfcDta getNfcDtaInterface(in String pkg);
-    int getState();
-    boolean disable(boolean saveState, in String pkg);
-    boolean enable(in String pkg);
-    int pausePolling(long timeoutInMs);
-    int resumePolling();
-
-    void setForegroundDispatch(in PendingIntent intent,
-            in IntentFilter[] filters, in TechListParcel techLists);
-    void setAppCallback(in IAppCallback callback);
-
-    boolean ignore(int nativeHandle, int debounceMs, ITagRemovedCallback callback);
-
-    void dispatch(in Tag tag);
-
-    void setReaderMode (IBinder b, IAppCallback callback, int flags, in Bundle extras, String pkg);
-
-    void addNfcUnlockHandler(INfcUnlockHandler unlockHandler, in int[] techList);
-    void removeNfcUnlockHandler(INfcUnlockHandler unlockHandler);
-
-    void verifyNfcPermission();
-    boolean isNfcSecureEnabled();
-    boolean deviceSupportsNfcSecure();
-    boolean setNfcSecure(boolean enable);
-    NfcAntennaInfo getNfcAntennaInfo();
-
-    void setControllerAlwaysOn(int mode);
-    boolean isControllerAlwaysOn();
-    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);
-
-    boolean isReaderOptionEnabled();
-    boolean isReaderOptionSupported();
-    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)")
-    boolean enableReaderOption(boolean enable, in String pkg);
-    boolean isObserveModeSupported();
-    boolean isObserveModeEnabled();
-    boolean setObserveMode(boolean enabled, String pkg);
-
-    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)")
-    boolean setWlcEnabled(boolean enable);
-    boolean isWlcEnabled();
-    void registerWlcStateListener(in INfcWlcStateListener listener);
-    void unregisterWlcStateListener(in INfcWlcStateListener listener);
-    WlcListenerDeviceInfo getWlcListenerDeviceInfo();
-
-    void updateDiscoveryTechnology(IBinder b, int pollFlags, int listenFlags, String pkg);
-
-    void notifyPollingLoop(in PollingFrame frame);
-    void notifyHceDeactivated();
-    void notifyTestHceData(in int technology, in byte[] data);
-    int sendVendorNciMessage(int mt, int gid, int oid, in byte[] payload);
-    void registerVendorExtensionCallback(in INfcVendorNciCallback callbacks);
-    void unregisterVendorExtensionCallback(in INfcVendorNciCallback callbacks);
-    void registerOemExtensionCallback(INfcOemExtensionCallback callbacks);
-    void unregisterOemExtensionCallback(INfcOemExtensionCallback callbacks);
-    void clearPreference();
-    void setScreenState();
-    void checkFirmware();
-    Map fetchActiveNfceeList();
-    void triggerInitialization();
-    boolean getSettingStatus();
-    boolean isTagPresent();
-    List<Entry> getRoutingTableEntryList();
-    void indicateDataMigration(boolean inProgress, String pkg);
-    int commitRouting();
-    boolean isTagIntentAllowed(in String pkg, in int Userid);
-    IT4tNdefNfcee getT4tNdefNfceeInterface();
-    long getMaxPausePollingTimeoutMs();
-}
diff --git a/nfc/java/android/nfc/INfcAdapterExtras.aidl b/nfc/java/android/nfc/INfcAdapterExtras.aidl
deleted file mode 100644
index cde57c5..0000000
--- a/nfc/java/android/nfc/INfcAdapterExtras.aidl
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import android.os.Bundle;
-
-
-/**
- * {@hide}
- */
-interface INfcAdapterExtras {
-    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
-    Bundle open(in String pkg, IBinder b);
-    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
-    Bundle close(in String pkg, IBinder b);
-    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
-    Bundle transceive(in String pkg, in byte[] data_in);
-    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
-    int getCardEmulationRoute(in String pkg);
-    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
-    void setCardEmulationRoute(in String pkg, int route);
-    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
-    void authenticate(in String pkg, in byte[] token);
-    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
-    String getDriverName(in String pkg);
-}
diff --git a/nfc/java/android/nfc/INfcCardEmulation.aidl b/nfc/java/android/nfc/INfcCardEmulation.aidl
deleted file mode 100644
index 00ceaa9..0000000
--- a/nfc/java/android/nfc/INfcCardEmulation.aidl
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import android.content.ComponentName;
-import android.nfc.INfcEventCallback;
-
-import android.nfc.cardemulation.AidGroup;
-import android.nfc.cardemulation.ApduServiceInfo;
-import android.os.RemoteCallback;
-
-/**
- * @hide
- */
-interface INfcCardEmulation
-{
-    boolean isDefaultServiceForCategory(int userHandle, in ComponentName service, String category);
-    boolean isDefaultServiceForAid(int userHandle, in ComponentName service, String aid);
-    boolean setDefaultServiceForCategory(int userHandle, in ComponentName service, String category);
-    boolean setDefaultForNextTap(int userHandle, in ComponentName service);
-    boolean setShouldDefaultToObserveModeForService(int userId, in android.content.ComponentName service, boolean enable);
-    boolean registerAidGroupForService(int userHandle, in ComponentName service, in AidGroup aidGroup);
-    boolean registerPollingLoopFilterForService(int userHandle, in ComponentName service, in String pollingLoopFilter, boolean autoTransact);
-    boolean registerPollingLoopPatternFilterForService(int userHandle, in ComponentName service, in String pollingLoopPatternFilter, boolean autoTransact);
-    boolean setOffHostForService(int userHandle, in ComponentName service, in String offHostSecureElement);
-    boolean unsetOffHostForService(int userHandle, in ComponentName service);
-    AidGroup getAidGroupForService(int userHandle, in ComponentName service, String category);
-    boolean removeAidGroupForService(int userHandle, in ComponentName service, String category);
-    boolean removePollingLoopFilterForService(int userHandle, in ComponentName service, in String pollingLoopFilter);
-    boolean removePollingLoopPatternFilterForService(int userHandle, in ComponentName service, in String pollingLoopPatternFilter);
-    List<ApduServiceInfo> getServices(int userHandle, in String category);
-    boolean setPreferredService(in ComponentName service);
-    boolean unsetPreferredService();
-    boolean supportsAidPrefixRegistration();
-    ApduServiceInfo getPreferredPaymentService(int userHandle);
-    int setServiceEnabledForCategoryOther(int userHandle, in ComponentName app, boolean status);
-    boolean isDefaultPaymentRegistered();
-
-    void overrideRoutingTable(int userHandle, String protocol, String technology, in String pkg);
-    void recoverRoutingTable(int userHandle);
-    boolean isEuiccSupported();
-    int getDefaultNfcSubscriptionId(in String pkg);
-    int setDefaultNfcSubscriptionId(int subscriptionId, in String pkg);
-    void setAutoChangeStatus(boolean state);
-    boolean isAutoChangeEnabled();
-    List<String> getRoutingStatus();
-    void overwriteRoutingTable(int userHandle, String emptyAid, String protocol, String tech, String sc);
-
-    void registerNfcEventCallback(in INfcEventCallback listener);
-    void unregisterNfcEventCallback(in INfcEventCallback listener);
-}
diff --git a/nfc/java/android/nfc/INfcControllerAlwaysOnListener.aidl b/nfc/java/android/nfc/INfcControllerAlwaysOnListener.aidl
deleted file mode 100644
index 1bb7680..0000000
--- a/nfc/java/android/nfc/INfcControllerAlwaysOnListener.aidl
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-/**
- * @hide
- */
-oneway interface INfcControllerAlwaysOnListener {
-  /**
-   * Called whenever the controller always on state changes
-   *
-   * @param isEnabled true if the state is enabled, false otherwise
-   */
-  void onControllerAlwaysOnChanged(boolean isEnabled);
-}
diff --git a/nfc/java/android/nfc/INfcDta.aidl b/nfc/java/android/nfc/INfcDta.aidl
deleted file mode 100644
index 4cc5927..0000000
--- a/nfc/java/android/nfc/INfcDta.aidl
+++ /dev/null
@@ -1,34 +0,0 @@
- /*
-  * Copyright (C) 2017 NXP Semiconductors
-  *
-  * Licensed under the Apache License, Version 2.0 (the "License");
-  * you may not use this file except in compliance with the License.
-  * You may obtain a copy of the License at
-  *
-  *      http://www.apache.org/licenses/LICENSE-2.0
-  *
-  * Unless required by applicable law or agreed to in writing, software
-  * distributed under the License is distributed on an "AS IS" BASIS,
-  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  * See the License for the specific language governing permissions and
-  * limitations under the License.
-  */
-package android.nfc;
-
-import android.os.Bundle;
-
-/**
- * {@hide}
- */
-interface INfcDta {
-
-    void enableDta();
-    void disableDta();
-    boolean enableServer(String serviceName, int serviceSap, int miu,
-            int rwSize,int testCaseId);
-    void disableServer();
-    boolean enableClient(String serviceName, int miu, int rwSize,
-            int testCaseId);
-    void disableClient();
-    boolean registerMessageService(String msgServiceName);
-}
diff --git a/nfc/java/android/nfc/INfcEventCallback.aidl b/nfc/java/android/nfc/INfcEventCallback.aidl
deleted file mode 100644
index af1fa2fb..0000000
--- a/nfc/java/android/nfc/INfcEventCallback.aidl
+++ /dev/null
@@ -1,16 +0,0 @@
-package android.nfc;
-
-import android.nfc.ComponentNameAndUser;
-
-/**
- * @hide
- */
-oneway interface INfcEventCallback {
-    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/INfcFCardEmulation.aidl b/nfc/java/android/nfc/INfcFCardEmulation.aidl
deleted file mode 100644
index 124bfac..0000000
--- a/nfc/java/android/nfc/INfcFCardEmulation.aidl
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import android.content.ComponentName;
-import android.nfc.cardemulation.NfcFServiceInfo;
-
-/**
- * @hide
- */
-interface INfcFCardEmulation
-{
-    String getSystemCodeForService(int userHandle, in ComponentName service);
-    boolean registerSystemCodeForService(int userHandle, in ComponentName service, String systemCode);
-    boolean removeSystemCodeForService(int userHandle, in ComponentName service);
-    String getNfcid2ForService(int userHandle, in ComponentName service);
-    boolean setNfcid2ForService(int userHandle, in ComponentName service, String nfcid2);
-    boolean enableNfcFForegroundService(in ComponentName service);
-    boolean disableNfcFForegroundService();
-    List<NfcFServiceInfo> getNfcFServices(int userHandle);
-    int getMaxNumOfRegisterableSystemCodes();
-}
diff --git a/nfc/java/android/nfc/INfcOemExtensionCallback.aidl b/nfc/java/android/nfc/INfcOemExtensionCallback.aidl
deleted file mode 100644
index e5eac0b..0000000
--- a/nfc/java/android/nfc/INfcOemExtensionCallback.aidl
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.nfc;
-
-import android.content.ComponentName;
-import android.nfc.cardemulation.ApduServiceInfo;
-import android.nfc.NdefMessage;
-import android.nfc.OemLogItems;
-import android.nfc.Tag;
-import android.os.ResultReceiver;
-
-import java.util.List;
-
-/**
- * @hide
- */
-interface INfcOemExtensionCallback {
-   void onTagConnected(boolean connected);
-   void onStateUpdated(int state);
-   void onApplyRouting(in ResultReceiver isSkipped);
-   void onNdefRead(in ResultReceiver isSkipped);
-   void onEnable(in ResultReceiver isAllowed);
-   void onDisable(in ResultReceiver isAllowed);
-   void onBootStarted();
-   void onEnableStarted();
-   void onDisableStarted();
-   void onBootFinished(int status);
-   void onEnableFinished(int status);
-   void onDisableFinished(int status);
-   void onTagDispatch(in ResultReceiver isSkipped);
-   void onRoutingChanged(in ResultReceiver isSkipped);
-   void onHceEventReceived(int action);
-   void onReaderOptionChanged(boolean enabled);
-   void onCardEmulationActivated(boolean isActivated);
-   void onRfFieldActivated(boolean isActivated);
-   void onRfDiscoveryStarted(boolean isDiscoveryStarted);
-   void onEeListenActivated(boolean isActivated);
-   void onEeUpdated();
-   void onGetOemAppSearchIntent(in List<String> firstPackage, in ResultReceiver intentConsumer);
-   void onNdefMessage(in Tag tag, in NdefMessage message, in ResultReceiver hasOemExecutableContent);
-   void onLaunchHceAppChooserActivity(in String selectedAid, in List<ApduServiceInfo> services, in ComponentName failedComponent, in String category);
-   void onLaunchHceTapAgainActivity(in ApduServiceInfo service, in String category);
-   void onRoutingTableFull();
-   void onLogEventNotified(in OemLogItems item);
-   void onExtractOemPackages(in NdefMessage message, in ResultReceiver packageReceiver);
-}
diff --git a/nfc/java/android/nfc/INfcTag.aidl b/nfc/java/android/nfc/INfcTag.aidl
deleted file mode 100644
index 170df71..0000000
--- a/nfc/java/android/nfc/INfcTag.aidl
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import android.nfc.NdefMessage;
-import android.nfc.Tag;
-import android.nfc.TransceiveResult;
-
-/**
- * @hide
- */
-interface INfcTag
-{
-    int connect(int nativeHandle, int technology);
-    int reconnect(int nativeHandle);
-    int[] getTechList(int nativeHandle);
-    boolean isNdef(int nativeHandle);
-    boolean isPresent(int nativeHandle);
-    TransceiveResult transceive(int nativeHandle, in byte[] data, boolean raw);
-
-    NdefMessage ndefRead(int nativeHandle);
-    int ndefWrite(int nativeHandle, in NdefMessage msg);
-    int ndefMakeReadOnly(int nativeHandle);
-    boolean ndefIsWritable(int nativeHandle);
-    int formatNdef(int nativeHandle, in byte[] key);
-    Tag rediscover(int nativehandle);
-
-    int setTimeout(int technology, int timeout);
-    int getTimeout(int technology);
-    void resetTimeouts();
-    boolean canMakeReadOnly(int ndefType);
-    int getMaxTransceiveLength(int technology);
-    boolean getExtendedLengthApdusSupported();
-
-    boolean isTagUpToDate(long cookie);
-}
diff --git a/nfc/java/android/nfc/INfcUnlockHandler.aidl b/nfc/java/android/nfc/INfcUnlockHandler.aidl
deleted file mode 100644
index e1cace9..0000000
--- a/nfc/java/android/nfc/INfcUnlockHandler.aidl
+++ /dev/null
@@ -1,12 +0,0 @@
-package android.nfc;
-
-import android.nfc.Tag;
-
-/**
- * @hide
- */
-interface INfcUnlockHandler {
-
-    boolean onUnlockAttempted(in Tag tag);
-
-}
diff --git a/nfc/java/android/nfc/INfcVendorNciCallback.aidl b/nfc/java/android/nfc/INfcVendorNciCallback.aidl
deleted file mode 100644
index 821dc6f..0000000
--- a/nfc/java/android/nfc/INfcVendorNciCallback.aidl
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.nfc;
-
-/**
- * @hide
- */
-oneway interface INfcVendorNciCallback {
-    void onVendorResponseReceived(int gid, int oid, in byte[] payload);
-    void onVendorNotificationReceived(int gid, int oid, in byte[] payload);
-}
diff --git a/nfc/java/android/nfc/INfcWlcStateListener.aidl b/nfc/java/android/nfc/INfcWlcStateListener.aidl
deleted file mode 100644
index 584eb9a..0000000
--- a/nfc/java/android/nfc/INfcWlcStateListener.aidl
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import android.nfc.WlcListenerDeviceInfo;
-/**
- * @hide
- */
-oneway interface INfcWlcStateListener {
-  /**
-   * Called whenever NFC WLC state changes
-   *
-   * @param wlcListenerDeviceInfo NFC wlc listener information
-   */
-  void onWlcStateChanged(in WlcListenerDeviceInfo wlcListenerDeviceInfo);
-}
diff --git a/nfc/java/android/nfc/IT4tNdefNfcee.aidl b/nfc/java/android/nfc/IT4tNdefNfcee.aidl
deleted file mode 100644
index b4cda5b..0000000
--- a/nfc/java/android/nfc/IT4tNdefNfcee.aidl
+++ /dev/null
@@ -1,33 +0,0 @@
-/******************************************************************************
- *
- *  Copyright (C) 2024 The Android Open Source Project.
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at:
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
-
-package android.nfc;
-
-import android.nfc.T4tNdefNfceeCcFileInfo;
-
-/**
- * @hide
- */
-interface IT4tNdefNfcee {
-    int writeData(in int fileId, in byte[] data);
-    byte[] readData(in int fileId);
-    int clearNdefData();
-    boolean isNdefOperationOngoing();
-    boolean isNdefNfceeEmulationSupported();
-    T4tNdefNfceeCcFileInfo readCcfile();
-}
diff --git a/nfc/java/android/nfc/ITagRemovedCallback.aidl b/nfc/java/android/nfc/ITagRemovedCallback.aidl
deleted file mode 100644
index 2a06ff3..0000000
--- a/nfc/java/android/nfc/ITagRemovedCallback.aidl
+++ /dev/null
@@ -1,8 +0,0 @@
-package android.nfc;
-
-/**
- * @hide
- */
-oneway interface ITagRemovedCallback {
-    void onTagRemoved();
-}
diff --git a/nfc/java/android/nfc/NdefMessage.aidl b/nfc/java/android/nfc/NdefMessage.aidl
deleted file mode 100644
index 378b9d0..0000000
--- a/nfc/java/android/nfc/NdefMessage.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-parcelable NdefMessage;
diff --git a/nfc/java/android/nfc/NdefMessage.java b/nfc/java/android/nfc/NdefMessage.java
deleted file mode 100644
index 553f6c0..0000000
--- a/nfc/java/android/nfc/NdefMessage.java
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import android.annotation.Nullable;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.proto.ProtoOutputStream;
-
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-
-/**
- * Represents an immutable NDEF Message.
- * <p>
- * NDEF (NFC Data Exchange Format) is a light-weight binary format,
- * used to encapsulate typed data. It is specified by the NFC Forum,
- * for transmission and storage with NFC, however it is transport agnostic.
- * <p>
- * NDEF defines messages and records. An NDEF Record contains
- * typed data, such as MIME-type media, a URI, or a custom
- * application payload. An NDEF Message is a container for
- * one or more NDEF Records.
- * <p>
- * When an Android device receives an NDEF Message
- * (for example by reading an NFC tag) it processes it through
- * a dispatch mechanism to determine an activity to launch.
- * The type of the <em>first</em> record in the message has
- * special importance for message dispatch, so design this record
- * carefully.
- * <p>
- * Use {@link #NdefMessage(byte[])} to construct an NDEF Message from
- * binary data, or {@link #NdefMessage(NdefRecord[])} to
- * construct from one or more {@link NdefRecord}s.
- * <p class="note">
- * {@link NdefMessage} and {@link NdefRecord} implementations are
- * always available, even on Android devices that do not have NFC hardware.
- * <p class="note">
- * {@link NdefRecord}s are intended to be immutable (and thread-safe),
- * however they may contain mutable fields. So take care not to modify
- * mutable fields passed into constructors, or modify mutable fields
- * obtained by getter methods, unless such modification is explicitly
- * marked as safe.
- *
- * @see NfcAdapter#ACTION_NDEF_DISCOVERED
- * @see NdefRecord
- */
-public final class NdefMessage implements Parcelable {
-    private final NdefRecord[] mRecords;
-
-    /**
-     * Construct an NDEF Message by parsing raw bytes.<p>
-     * Strict validation of the NDEF binary structure is performed:
-     * there must be at least one record, every record flag must
-     * be correct, and the total length of the message must match
-     * the length of the input data.<p>
-     * This parser can handle chunked records, and converts them
-     * into logical {@link NdefRecord}s within the message.<p>
-     * Once the input data has been parsed to one or more logical
-     * records, basic validation of the tnf, type, id, and payload fields
-     * of each record is performed, as per the documentation on
-     * on {@link NdefRecord#NdefRecord(short, byte[], byte[], byte[])}<p>
-     * If either strict validation of the binary format fails, or
-     * basic validation during record construction fails, a
-     * {@link FormatException} is thrown<p>
-     * Deep inspection of the type, id and payload fields of
-     * each record is not performed, so it is possible to parse input
-     * that has a valid binary format and confirms to the basic
-     * validation requirements of
-     * {@link NdefRecord#NdefRecord(short, byte[], byte[], byte[])},
-     * but fails more strict requirements as specified by the
-     * NFC Forum.
-     *
-     * <p class="note">
-     * It is safe to re-use the data byte array after construction:
-     * this constructor will make an internal copy of all necessary fields.
-     *
-     * @param data raw bytes to parse
-     * @throws FormatException if the data cannot be parsed
-     */
-    public NdefMessage(byte[] data) throws FormatException {
-        if (data == null) throw new NullPointerException("data is null");
-        ByteBuffer buffer = ByteBuffer.wrap(data);
-
-        mRecords = NdefRecord.parse(buffer, false);
-
-        if (buffer.remaining() > 0) {
-            throw new FormatException("trailing data");
-        }
-    }
-
-    /**
-     * Construct an NDEF Message from one or more NDEF Records.
-     *
-     * @param record first record (mandatory)
-     * @param records additional records (optional)
-     */
-    public NdefMessage(NdefRecord record, NdefRecord ... records) {
-        // validate
-        if (record == null) throw new NullPointerException("record cannot be null");
-
-        for (NdefRecord r : records) {
-            if (r == null) {
-                throw new NullPointerException("record cannot be null");
-            }
-        }
-
-        mRecords = new NdefRecord[1 + records.length];
-        mRecords[0] = record;
-        System.arraycopy(records, 0, mRecords, 1, records.length);
-    }
-
-    /**
-     * Construct an NDEF Message from one or more NDEF Records.
-     *
-     * @param records one or more records
-     */
-    public NdefMessage(NdefRecord[] records) {
-        // validate
-        if (records.length < 1) {
-            throw new IllegalArgumentException("must have at least one record");
-        }
-        for (NdefRecord r : records) {
-            if (r == null) {
-                throw new NullPointerException("records cannot contain null");
-            }
-        }
-
-        mRecords = records;
-    }
-
-    /**
-     * Get the NDEF Records inside this NDEF Message.<p>
-     * An {@link NdefMessage} always has one or more NDEF Records: so the
-     * following code to retrieve the first record is always safe
-     * (no need to check for null or array length >= 1):
-     * <pre>
-     * NdefRecord firstRecord = ndefMessage.getRecords()[0];
-     * </pre>
-     *
-     * @return array of one or more NDEF records.
-     */
-    public NdefRecord[] getRecords() {
-        return mRecords;
-    }
-
-    /**
-     * Return the length of this NDEF Message if it is written to a byte array
-     * with {@link #toByteArray}.<p>
-     * An NDEF Message can be formatted to bytes in different ways
-     * depending on chunking, SR, and ID flags, so the length returned
-     * by this method may not be equal to the length of the original
-     * byte array used to construct this NDEF Message. However it will
-     * always be equal to the length of the byte array produced by
-     * {@link #toByteArray}.
-     *
-     * @return length of this NDEF Message when written to bytes with {@link #toByteArray}
-     * @see #toByteArray
-     */
-    public int getByteArrayLength() {
-        int length = 0;
-        for (NdefRecord r : mRecords) {
-            length += r.getByteLength();
-        }
-        return length;
-    }
-
-    /**
-     * Return this NDEF Message as raw bytes.<p>
-     * The NDEF Message is formatted as per the NDEF 1.0 specification,
-     * and the byte array is suitable for network transmission or storage
-     * in an NFC Forum NDEF compatible tag.<p>
-     * This method will not chunk any records, and will always use the
-     * short record (SR) format and omit the identifier field when possible.
-     *
-     * @return NDEF Message in binary format
-     * @see #getByteArrayLength()
-     */
-    public byte[] toByteArray() {
-        int length = getByteArrayLength();
-        ByteBuffer buffer = ByteBuffer.allocate(length);
-
-        for (int i=0; i<mRecords.length; i++) {
-            boolean mb = (i == 0);  // first record
-            boolean me = (i == mRecords.length - 1);  // last record
-            mRecords[i].writeToByteBuffer(buffer, mb, me);
-        }
-
-        return buffer.array();
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(mRecords.length);
-        dest.writeTypedArray(mRecords, flags);
-    }
-
-    public static final @android.annotation.NonNull Parcelable.Creator<NdefMessage> CREATOR =
-            new Parcelable.Creator<NdefMessage>() {
-        @Override
-        public NdefMessage createFromParcel(Parcel in) {
-            int recordsLength = in.readInt();
-            NdefRecord[] records = new NdefRecord[recordsLength];
-            in.readTypedArray(records, NdefRecord.CREATOR);
-            return new NdefMessage(records);
-        }
-        @Override
-        public NdefMessage[] newArray(int size) {
-            return new NdefMessage[size];
-        }
-    };
-
-    @Override
-    public int hashCode() {
-        return Arrays.hashCode(mRecords);
-    }
-
-    /**
-     * Returns true if the specified NDEF Message contains
-     * identical NDEF Records.
-     */
-    @Override
-    public boolean equals(@Nullable Object obj) {
-        if (this == obj) return true;
-        if (obj == null) return false;
-        if (getClass() != obj.getClass()) return false;
-        NdefMessage other = (NdefMessage) obj;
-        return Arrays.equals(mRecords, other.mRecords);
-    }
-
-    @Override
-    public String toString() {
-        return "NdefMessage " + Arrays.toString(mRecords);
-    }
-
-    /**
-     * Dump debugging information as a NdefMessageProto
-     * @hide
-     *
-     * Note:
-     * See proto definition in frameworks/base/core/proto/android/nfc/ndef.proto
-     * When writing a nested message, must call {@link ProtoOutputStream#start(long)} before and
-     * {@link ProtoOutputStream#end(long)} after.
-     * Never reuse a proto field number. When removing a field, mark it as reserved.
-     */
-    public void dumpDebug(ProtoOutputStream proto) {
-        for (NdefRecord record : mRecords) {
-            long token = proto.start(NdefMessageProto.NDEF_RECORDS);
-            record.dumpDebug(proto);
-            proto.end(token);
-        }
-    }
-}
\ No newline at end of file
diff --git a/nfc/java/android/nfc/NdefRecord.aidl b/nfc/java/android/nfc/NdefRecord.aidl
deleted file mode 100644
index 10f89d0..0000000
--- a/nfc/java/android/nfc/NdefRecord.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-parcelable NdefRecord;
\ No newline at end of file
diff --git a/nfc/java/android/nfc/NdefRecord.java b/nfc/java/android/nfc/NdefRecord.java
deleted file mode 100644
index 7bf4355..0000000
--- a/nfc/java/android/nfc/NdefRecord.java
+++ /dev/null
@@ -1,1080 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import android.annotation.Nullable;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Build;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.proto.ProtoOutputStream;
-
-import java.nio.BufferUnderflowException;
-import java.nio.ByteBuffer;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Locale;
-
-/**
- * Represents an immutable NDEF Record.
- * <p>
- * NDEF (NFC Data Exchange Format) is a light-weight binary format,
- * used to encapsulate typed data. It is specified by the NFC Forum,
- * for transmission and storage with NFC, however it is transport agnostic.
- * <p>
- * NDEF defines messages and records. An NDEF Record contains
- * typed data, such as MIME-type media, a URI, or a custom
- * application payload. An NDEF Message is a container for
- * one or more NDEF Records.
- * <p>
- * This class represents logical (complete) NDEF Records, and can not be
- * used to represent chunked (partial) NDEF Records. However
- * {@link NdefMessage#NdefMessage(byte[])} can be used to parse a message
- * containing chunked records, and will return a message with unchunked
- * (complete) records.
- * <p>
- * A logical NDEF Record always contains a 3-bit TNF (Type Name Field)
- * that provides high level typing for the rest of the record. The
- * remaining fields are variable length and not always present:
- * <ul>
- * <li><em>type</em>: detailed typing for the payload</li>
- * <li><em>id</em>: identifier meta-data, not commonly used</li>
- * <li><em>payload</em>: the actual payload</li>
- * </ul>
- * <p>
- * Helpers such as {@link NdefRecord#createUri}, {@link NdefRecord#createMime}
- * and {@link NdefRecord#createExternal} are included to create well-formatted
- * NDEF Records with correctly set tnf, type, id and payload fields, please
- * use these helpers whenever possible.
- * <p>
- * Use the constructor {@link #NdefRecord(short, byte[], byte[], byte[])}
- * if you know what you are doing and what to set the fields individually.
- * Only basic validation is performed with this constructor, so it is possible
- * to create records that do not confirm to the strict NFC Forum
- * specifications.
- * <p>
- * The binary representation of an NDEF Record includes additional flags to
- * indicate location with an NDEF message, provide support for chunking of
- * NDEF records, and to pack optional fields. This class does not expose
- * those details. To write an NDEF Record as binary you must first put it
- * into an {@link NdefMessage}, then call {@link NdefMessage#toByteArray()}.
- * <p class="note">
- * {@link NdefMessage} and {@link NdefRecord} implementations are
- * always available, even on Android devices that do not have NFC hardware.
- * <p class="note">
- * {@link NdefRecord}s are intended to be immutable (and thread-safe),
- * however they may contain mutable fields. So take care not to modify
- * mutable fields passed into constructors, or modify mutable fields
- * obtained by getter methods, unless such modification is explicitly
- * marked as safe.
- *
- * @see NfcAdapter#ACTION_NDEF_DISCOVERED
- * @see NdefMessage
- */
-public final class NdefRecord implements Parcelable {
-    /**
-     * Indicates the record is empty.<p>
-     * Type, id and payload fields are empty in a {@literal TNF_EMPTY} record.
-     */
-    public static final short TNF_EMPTY = 0x00;
-
-    /**
-     * Indicates the type field contains a well-known RTD type name.<p>
-     * Use this tnf with RTD types such as {@link #RTD_TEXT}, {@link #RTD_URI}.
-     * <p>
-     * The RTD type name format is specified in NFCForum-TS-RTD_1.0.
-     *
-     * @see #RTD_URI
-     * @see #RTD_TEXT
-     * @see #RTD_SMART_POSTER
-     * @see #createUri
-     */
-    public static final short TNF_WELL_KNOWN = 0x01;
-
-    /**
-     * Indicates the type field contains a media-type BNF
-     * construct, defined by RFC 2046.<p>
-     * Use this with MIME type names such as {@literal "image/jpeg"}, or
-     * using the helper {@link #createMime}.
-     *
-     * @see #createMime
-     */
-    public static final short TNF_MIME_MEDIA = 0x02;
-
-    /**
-     * Indicates the type field contains an absolute-URI
-     * BNF construct defined by RFC 3986.<p>
-     * When creating new records prefer {@link #createUri},
-     * since it offers more compact URI encoding
-     * ({@literal #RTD_URI} allows compression of common URI prefixes).
-     *
-     * @see #createUri
-     */
-    public static final short TNF_ABSOLUTE_URI = 0x03;
-
-    /**
-     * Indicates the type field contains an external type name.<p>
-     * Used to encode custom payloads. When creating new records
-     * use the helper {@link #createExternal}.<p>
-     * The external-type RTD format is specified in NFCForum-TS-RTD_1.0.<p>
-     * <p>
-     * Note this TNF should not be used with RTD_TEXT or RTD_URI constants.
-     * Those are well known RTD constants, not external RTD constants.
-     *
-     * @see #createExternal
-     */
-    public static final short TNF_EXTERNAL_TYPE = 0x04;
-
-    /**
-     * Indicates the payload type is unknown.<p>
-     * NFC Forum explains this should be treated similarly to the
-     * "application/octet-stream" MIME type. The payload
-     * type is not explicitly encoded within the record.
-     * <p>
-     * The type field is empty in an {@literal TNF_UNKNOWN} record.
-     */
-    public static final short TNF_UNKNOWN = 0x05;
-
-    /**
-     * Indicates the payload is an intermediate or final chunk of a chunked
-     * NDEF Record.<p>
-     * {@literal TNF_UNCHANGED} can not be used with this class
-     * since all {@link NdefRecord}s are already unchunked, however they
-     * may appear in the binary format.
-     */
-    public static final short TNF_UNCHANGED = 0x06;
-
-    /**
-     * Reserved TNF type.
-     * <p>
-     * The NFC Forum NDEF Specification v1.0 suggests for NDEF parsers to treat this
-     * value like TNF_UNKNOWN.
-     * @hide
-     */
-    public static final short TNF_RESERVED = 0x07;
-
-    /**
-     * RTD Text type. For use with {@literal TNF_WELL_KNOWN}.
-     * @see #TNF_WELL_KNOWN
-     */
-    public static final byte[] RTD_TEXT = {0x54};  // "T"
-
-    /**
-     * RTD URI type. For use with {@literal TNF_WELL_KNOWN}.
-     * @see #TNF_WELL_KNOWN
-     */
-    public static final byte[] RTD_URI = {0x55};   // "U"
-
-    /**
-     * RTD Smart Poster type. For use with {@literal TNF_WELL_KNOWN}.
-     * @see #TNF_WELL_KNOWN
-     */
-    public static final byte[] RTD_SMART_POSTER = {0x53, 0x70};  // "Sp"
-
-    /**
-     * RTD Alternative Carrier type. For use with {@literal TNF_WELL_KNOWN}.
-     * @see #TNF_WELL_KNOWN
-     */
-    public static final byte[] RTD_ALTERNATIVE_CARRIER = {0x61, 0x63};  // "ac"
-
-    /**
-     * RTD Handover Carrier type. For use with {@literal TNF_WELL_KNOWN}.
-     * @see #TNF_WELL_KNOWN
-     */
-    public static final byte[] RTD_HANDOVER_CARRIER = {0x48, 0x63};  // "Hc"
-
-    /**
-     * RTD Handover Request type. For use with {@literal TNF_WELL_KNOWN}.
-     * @see #TNF_WELL_KNOWN
-     */
-    public static final byte[] RTD_HANDOVER_REQUEST = {0x48, 0x72};  // "Hr"
-
-    /**
-     * RTD Handover Select type. For use with {@literal TNF_WELL_KNOWN}.
-     * @see #TNF_WELL_KNOWN
-     */
-    public static final byte[] RTD_HANDOVER_SELECT = {0x48, 0x73}; // "Hs"
-
-    /**
-     * RTD Android app type. For use with {@literal TNF_EXTERNAL}.
-     * <p>
-     * The payload of a record with type RTD_ANDROID_APP
-     * should be the package name identifying an application.
-     * Multiple RTD_ANDROID_APP records may be included
-     * in a single {@link NdefMessage}.
-     * <p>
-     * Use {@link #createApplicationRecord(String)} to create
-     * RTD_ANDROID_APP records.
-     * @hide
-     */
-    public static final byte[] RTD_ANDROID_APP = "android.com:pkg".getBytes();
-
-    private static final byte FLAG_MB = (byte) 0x80;
-    private static final byte FLAG_ME = (byte) 0x40;
-    private static final byte FLAG_CF = (byte) 0x20;
-    private static final byte FLAG_SR = (byte) 0x10;
-    private static final byte FLAG_IL = (byte) 0x08;
-
-    /**
-     * NFC Forum "URI Record Type Definition"<p>
-     * This is a mapping of "URI Identifier Codes" to URI string prefixes,
-     * per section 3.2.2 of the NFC Forum URI Record Type Definition document.
-     */
-    private static final String[] URI_PREFIX_MAP = new String[] {
-            "", // 0x00
-            "http://www.", // 0x01
-            "https://www.", // 0x02
-            "http://", // 0x03
-            "https://", // 0x04
-            "tel:", // 0x05
-            "mailto:", // 0x06
-            "ftp://anonymous:anonymous@", // 0x07
-            "ftp://ftp.", // 0x08
-            "ftps://", // 0x09
-            "sftp://", // 0x0A
-            "smb://", // 0x0B
-            "nfs://", // 0x0C
-            "ftp://", // 0x0D
-            "dav://", // 0x0E
-            "news:", // 0x0F
-            "telnet://", // 0x10
-            "imap:", // 0x11
-            "rtsp://", // 0x12
-            "urn:", // 0x13
-            "pop:", // 0x14
-            "sip:", // 0x15
-            "sips:", // 0x16
-            "tftp:", // 0x17
-            "btspp://", // 0x18
-            "btl2cap://", // 0x19
-            "btgoep://", // 0x1A
-            "tcpobex://", // 0x1B
-            "irdaobex://", // 0x1C
-            "file://", // 0x1D
-            "urn:epc:id:", // 0x1E
-            "urn:epc:tag:", // 0x1F
-            "urn:epc:pat:", // 0x20
-            "urn:epc:raw:", // 0x21
-            "urn:epc:", // 0x22
-            "urn:nfc:", // 0x23
-    };
-
-    private static final int MAX_PAYLOAD_SIZE = 10 * (1 << 20);  // 10 MB payload limit
-
-    private static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
-
-    private final short mTnf;
-    private final byte[] mType;
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    private final byte[] mId;
-    private final byte[] mPayload;
-
-    /**
-     * Create a new Android Application Record (AAR).
-     * <p>
-     * This record indicates to other Android devices the package
-     * that should be used to handle the entire NDEF message.
-     * You can embed this record anywhere into your message
-     * to ensure that the intended package receives the message.
-     * <p>
-     * When an Android device dispatches an {@link NdefMessage}
-     * containing one or more Android application records,
-     * the applications contained in those records will be the
-     * preferred target for the {@link NfcAdapter#ACTION_NDEF_DISCOVERED}
-     * intent, in the order in which they appear in the message.
-     * This dispatch behavior was first added to Android in
-     * Ice Cream Sandwich.
-     * <p>
-     * If none of the applications have a are installed on the device,
-     * a Market link will be opened to the first application.
-     * <p>
-     * Note that Android application records do not overrule
-     * applications that have called
-     * {@link NfcAdapter#enableForegroundDispatch}.
-     *
-     * @param packageName Android package name
-     * @return Android application NDEF record
-     */
-    public static NdefRecord createApplicationRecord(String packageName) {
-        if (packageName == null) throw new NullPointerException("packageName is null");
-        if (packageName.length() == 0) throw new IllegalArgumentException("packageName is empty");
-
-        return new NdefRecord(TNF_EXTERNAL_TYPE, RTD_ANDROID_APP, null,
-                packageName.getBytes(StandardCharsets.UTF_8));
-    }
-
-    /**
-     * Create a new NDEF Record containing a URI.<p>
-     * Use this method to encode a URI (or URL) into an NDEF Record.<p>
-     * Uses the well known URI type representation: {@link #TNF_WELL_KNOWN}
-     * and {@link #RTD_URI}. This is the most efficient encoding
-     * of a URI into NDEF.<p>
-     * The uri parameter will be normalized with
-     * {@link Uri#normalizeScheme} to set the scheme to lower case to
-     * follow Android best practices for intent filtering.
-     * However the unchecked exception
-     * {@link IllegalArgumentException} may be thrown if the uri
-     * parameter has serious problems, for example if it is empty, so always
-     * catch this exception if you are passing user-generated data into this
-     * method.<p>
-     *
-     * Reference specification: NFCForum-TS-RTD_URI_1.0
-     *
-     * @param uri URI to encode.
-     * @return an NDEF Record containing the URI
-     * @throws IllegalArugmentException if the uri is empty or invalid
-     */
-    public static NdefRecord createUri(Uri uri) {
-        if (uri == null) throw new NullPointerException("uri is null");
-
-        uri = uri.normalizeScheme();
-        String uriString = uri.toString();
-        if (uriString.length() == 0) throw new IllegalArgumentException("uri is empty");
-
-        byte prefix = 0;
-        for (int i = 1; i < URI_PREFIX_MAP.length; i++) {
-            if (uriString.startsWith(URI_PREFIX_MAP[i])) {
-                prefix = (byte) i;
-                uriString = uriString.substring(URI_PREFIX_MAP[i].length());
-                break;
-            }
-        }
-        byte[] uriBytes = uriString.getBytes(StandardCharsets.UTF_8);
-        byte[] recordBytes = new byte[uriBytes.length + 1];
-        recordBytes[0] = prefix;
-        System.arraycopy(uriBytes, 0, recordBytes, 1, uriBytes.length);
-        return new NdefRecord(TNF_WELL_KNOWN, RTD_URI, null, recordBytes);
-    }
-
-    /**
-     * Create a new NDEF Record containing a URI.<p>
-     * Use this method to encode a URI (or URL) into an NDEF Record.<p>
-     * Uses the well known URI type representation: {@link #TNF_WELL_KNOWN}
-     * and {@link #RTD_URI}. This is the most efficient encoding
-     * of a URI into NDEF.<p>
-      * The uriString parameter will be normalized with
-     * {@link Uri#normalizeScheme} to set the scheme to lower case to
-     * follow Android best practices for intent filtering.
-     * However the unchecked exception
-     * {@link IllegalArgumentException} may be thrown if the uriString
-     * parameter has serious problems, for example if it is empty, so always
-     * catch this exception if you are passing user-generated data into this
-     * method.<p>
-     *
-     * Reference specification: NFCForum-TS-RTD_URI_1.0
-     *
-     * @param uriString string URI to encode.
-     * @return an NDEF Record containing the URI
-     * @throws IllegalArugmentException if the uriString is empty or invalid
-     */
-    public static NdefRecord createUri(String uriString) {
-        return createUri(Uri.parse(uriString));
-    }
-
-    /**
-     * Create a new NDEF Record containing MIME data.<p>
-     * Use this method to encode MIME-typed data into an NDEF Record,
-     * such as "text/plain", or "image/jpeg".<p>
-     * The mimeType parameter will be normalized with
-     * {@link Intent#normalizeMimeType} to follow Android best
-     * practices for intent filtering, for example to force lower-case.
-     * However the unchecked exception
-     * {@link IllegalArgumentException} may be thrown
-     * if the mimeType parameter has serious problems,
-     * for example if it is empty, so always catch this
-     * exception if you are passing user-generated data into this method.
-     * <p>
-     * For efficiency, This method might not make an internal copy of the
-     * mimeData byte array, so take care not
-     * to modify the mimeData byte array while still using the returned
-     * NdefRecord.
-     *
-     * @param mimeType a valid MIME type
-     * @param mimeData MIME data as bytes
-     * @return an NDEF Record containing the MIME-typed data
-     * @throws IllegalArugmentException if the mimeType is empty or invalid
-     *
-     */
-    public static NdefRecord createMime(String mimeType, byte[] mimeData) {
-        if (mimeType == null) throw new NullPointerException("mimeType is null");
-
-        // We only do basic MIME type validation: trying to follow the
-        // RFCs strictly only ends in tears, since there are lots of MIME
-        // types in common use that are not strictly valid as per RFC rules
-        mimeType = Intent.normalizeMimeType(mimeType);
-        if (mimeType.length() == 0) throw new IllegalArgumentException("mimeType is empty");
-        int slashIndex = mimeType.indexOf('/');
-        if (slashIndex == 0) throw new IllegalArgumentException("mimeType must have major type");
-        if (slashIndex == mimeType.length() - 1) {
-            throw new IllegalArgumentException("mimeType must have minor type");
-        }
-        // missing '/' is allowed
-
-        // MIME RFCs suggest ASCII encoding for content-type
-        byte[] typeBytes = mimeType.getBytes(StandardCharsets.US_ASCII);
-        return new NdefRecord(TNF_MIME_MEDIA, typeBytes, null, mimeData);
-    }
-
-    /**
-     * Create a new NDEF Record containing external (application-specific) data.<p>
-     * Use this method to encode application specific data into an NDEF Record.
-     * The data is typed by a domain name (usually your Android package name) and
-     * a domain-specific type. This data is packaged into a "NFC Forum External
-     * Type" NDEF Record.<p>
-     * NFC Forum requires that the domain and type used in an external record
-     * are treated as case insensitive, however Android intent filtering is
-     * always case sensitive. So this method will force the domain and type to
-     * lower-case before creating the NDEF Record.<p>
-     * The unchecked exception {@link IllegalArgumentException} will be thrown
-     * if the domain and type have serious problems, for example if either field
-     * is empty, so always catch this
-     * exception if you are passing user-generated data into this method.<p>
-     * There are no such restrictions on the payload data.<p>
-     * For efficiency, This method might not make an internal copy of the
-     * data byte array, so take care not
-     * to modify the data byte array while still using the returned
-     * NdefRecord.
-     *
-     * Reference specification: NFCForum-TS-RTD_1.0
-     * @param domain domain-name of issuing organization
-     * @param type domain-specific type of data
-     * @param data payload as bytes
-     * @throws IllegalArugmentException if either domain or type are empty or invalid
-     */
-    public static NdefRecord createExternal(String domain, String type, byte[] data) {
-        if (domain == null) throw new NullPointerException("domain is null");
-        if (type == null) throw new NullPointerException("type is null");
-
-        domain = domain.trim().toLowerCase(Locale.ROOT);
-        type = type.trim().toLowerCase(Locale.ROOT);
-
-        if (domain.length() == 0) throw new IllegalArgumentException("domain is empty");
-        if (type.length() == 0) throw new IllegalArgumentException("type is empty");
-
-        byte[] byteDomain = domain.getBytes(StandardCharsets.UTF_8);
-        byte[] byteType = type.getBytes(StandardCharsets.UTF_8);
-        byte[] b = new byte[byteDomain.length + 1 + byteType.length];
-        System.arraycopy(byteDomain, 0, b, 0, byteDomain.length);
-        b[byteDomain.length] = ':';
-        System.arraycopy(byteType, 0, b, byteDomain.length + 1, byteType.length);
-
-        return new NdefRecord(TNF_EXTERNAL_TYPE, b, null, data);
-    }
-
-    /**
-     * Create a new NDEF record containing UTF-8 text data.<p>
-     *
-     * The caller can either specify the language code for the provided text,
-     * or otherwise the language code corresponding to the current default
-     * locale will be used.
-     *
-     * Reference specification: NFCForum-TS-RTD_Text_1.0
-     * @param languageCode The languageCode for the record. If locale is empty or null,
-     *                     the language code of the current default locale will be used.
-     * @param text   The text to be encoded in the record. Will be represented in UTF-8 format.
-     * @throws IllegalArgumentException if text is null
-     */
-    public static NdefRecord createTextRecord(String languageCode, String text) {
-        if (text == null) throw new NullPointerException("text is null");
-
-        byte[] textBytes = text.getBytes(StandardCharsets.UTF_8);
-
-        byte[] languageCodeBytes = null;
-        if (languageCode != null && !languageCode.isEmpty()) {
-            languageCodeBytes = languageCode.getBytes(StandardCharsets.US_ASCII);
-        } else {
-            languageCodeBytes = Locale.getDefault().getLanguage().
-                    getBytes(StandardCharsets.US_ASCII);
-        }
-        // We only have 6 bits to indicate ISO/IANA language code.
-        if (languageCodeBytes.length >= 64) {
-            throw new IllegalArgumentException("language code is too long, must be <64 bytes.");
-        }
-        ByteBuffer buffer = ByteBuffer.allocate(1 + languageCodeBytes.length + textBytes.length);
-
-        byte status = (byte) (languageCodeBytes.length & 0xFF);
-        buffer.put(status);
-        buffer.put(languageCodeBytes);
-        buffer.put(textBytes);
-
-        return new NdefRecord(TNF_WELL_KNOWN, RTD_TEXT, null, buffer.array());
-    }
-
-    /**
-     * Construct an NDEF Record from its component fields.<p>
-     * Recommend to use helpers such as {#createUri} or
-     * {{@link #createExternal} where possible, since they perform
-     * stricter validation that the record is correctly formatted
-     * as per NDEF specifications. However if you know what you are
-     * doing then this constructor offers the most flexibility.<p>
-     * An {@link NdefRecord} represents a logical (complete)
-     * record, and cannot represent NDEF Record chunks.<p>
-     * Basic validation of the tnf, type, id and payload is performed
-     * as per the following rules:
-     * <ul>
-     * <li>The tnf paramter must be a 3-bit value.</li>
-     * <li>Records with a tnf of {@link #TNF_EMPTY} cannot have a type,
-     * id or payload.</li>
-     * <li>Records with a tnf of {@link #TNF_UNKNOWN} or {@literal 0x07}
-     * cannot have a type.</li>
-     * <li>Records with a tnf of {@link #TNF_UNCHANGED} are not allowed
-     * since this class only represents complete (unchunked) records.</li>
-     * </ul>
-     * This minimal validation is specified by
-     * NFCForum-TS-NDEF_1.0 section 3.2.6 (Type Name Format).<p>
-     * If any of the above validation
-     * steps fail then {@link IllegalArgumentException} is thrown.<p>
-     * Deep inspection of the type, id and payload fields is not
-     * performed, so it is possible to create NDEF Records
-     * that conform to section 3.2.6
-     * but fail other more strict NDEF specification requirements. For
-     * example, the payload may be invalid given the tnf and type.
-     * <p>
-     * To omit a type, id or payload field, set the parameter to an
-     * empty byte array or null.
-     *
-     * @param tnf  a 3-bit TNF constant
-     * @param type byte array, containing zero to 255 bytes, or null
-     * @param id   byte array, containing zero to 255 bytes, or null
-     * @param payload byte array, containing zero to (2 ** 32 - 1) bytes,
-     *                or null
-     * @throws IllegalArugmentException if a valid record cannot be created
-     */
-    public NdefRecord(short tnf, byte[] type, byte[] id, byte[] payload) {
-        /* convert nulls */
-        if (type == null) type = EMPTY_BYTE_ARRAY;
-        if (id == null) id = EMPTY_BYTE_ARRAY;
-        if (payload == null) payload = EMPTY_BYTE_ARRAY;
-
-        String message = validateTnf(tnf, type, id, payload);
-        if (message != null) {
-            throw new IllegalArgumentException(message);
-        }
-
-        mTnf = tnf;
-        mType = type;
-        mId = id;
-        mPayload = payload;
-    }
-
-    /**
-     * Construct an NDEF Record from raw bytes.<p>
-     * This method is deprecated, use {@link NdefMessage#NdefMessage(byte[])}
-     * instead. This is because it does not make sense to parse a record:
-     * the NDEF binary format is only defined for a message, and the
-     * record flags MB and ME do not make sense outside of the context of
-     * an entire message.<p>
-     * This implementation will attempt to parse a single record by ignoring
-     * the MB and ME flags, and otherwise following the rules of
-     * {@link NdefMessage#NdefMessage(byte[])}.<p>
-     *
-     * @param data raw bytes to parse
-     * @throws FormatException if the data cannot be parsed into a valid record
-     * @deprecated use {@link NdefMessage#NdefMessage(byte[])} instead.
-     */
-    @Deprecated
-    public NdefRecord(byte[] data) throws FormatException {
-        ByteBuffer buffer = ByteBuffer.wrap(data);
-        NdefRecord[] rs = parse(buffer, true);
-
-        if (buffer.remaining() > 0) {
-            throw new FormatException("data too long");
-        }
-
-        mTnf = rs[0].mTnf;
-        mType = rs[0].mType;
-        mId = rs[0].mId;
-        mPayload = rs[0].mPayload;
-    }
-
-    /**
-     * Returns the 3-bit TNF.
-     * <p>
-     * TNF is the top-level type.
-     */
-    public short getTnf() {
-        return mTnf;
-    }
-
-    /**
-     * Returns the variable length Type field.
-     * <p>
-     * This should be used in conjunction with the TNF field to determine the
-     * payload format.
-     * <p>
-     * Returns an empty byte array if this record
-     * does not have a type field.
-     */
-    public byte[] getType() {
-        return mType.clone();
-    }
-
-    /**
-     * Returns the variable length ID.
-     * <p>
-     * Returns an empty byte array if this record
-     * does not have an id field.
-     */
-    public byte[] getId() {
-        return mId.clone();
-    }
-
-    /**
-     * Returns the variable length payload.
-     * <p>
-     * Returns an empty byte array if this record
-     * does not have a payload field.
-     */
-    public byte[] getPayload() {
-        return mPayload.clone();
-    }
-
-    /**
-     * Return this NDEF Record as a byte array.<p>
-     * This method is deprecated, use {@link NdefMessage#toByteArray}
-     * instead. This is because the NDEF binary format is not defined for
-     * a record outside of the context of a message: the MB and ME flags
-     * cannot be set without knowing the location inside a message.<p>
-     * This implementation will attempt to serialize a single record by
-     * always setting the MB and ME flags (in other words, assume this
-     * is a single-record NDEF Message).<p>
-     *
-     * @deprecated use {@link NdefMessage#toByteArray()} instead
-     */
-    @Deprecated
-    public byte[] toByteArray() {
-        ByteBuffer buffer = ByteBuffer.allocate(getByteLength());
-        writeToByteBuffer(buffer, true, true);
-        return buffer.array();
-    }
-
-    /**
-     * Map this record to a MIME type, or return null if it cannot be mapped.<p>
-     * Currently this method considers all {@link #TNF_MIME_MEDIA} records to
-     * be MIME records, as well as some {@link #TNF_WELL_KNOWN} records such as
-     * {@link #RTD_TEXT}. If this is a MIME record then the MIME type as string
-     * is returned, otherwise null is returned.<p>
-     * This method does not perform validation that the MIME type is
-     * actually valid. It always attempts to
-     * return a string containing the type if this is a MIME record.<p>
-     * The returned MIME type will by normalized to lower-case using
-     * {@link Intent#normalizeMimeType}.<p>
-     * The MIME payload can be obtained using {@link #getPayload}.
-     *
-     * @return MIME type as a string, or null if this is not a MIME record
-     */
-    public String toMimeType() {
-        switch (mTnf) {
-            case NdefRecord.TNF_WELL_KNOWN:
-                if (Arrays.equals(mType, NdefRecord.RTD_TEXT)) {
-                    return "text/plain";
-                }
-                break;
-            case NdefRecord.TNF_MIME_MEDIA:
-                String mimeType = new String(mType, StandardCharsets.US_ASCII);
-                return Intent.normalizeMimeType(mimeType);
-        }
-        return null;
-    }
-
-    /**
-     * Map this record to a URI, or return null if it cannot be mapped.<p>
-     * Currently this method considers the following to be URI records:
-     * <ul>
-     * <li>{@link #TNF_ABSOLUTE_URI} records.</li>
-     * <li>{@link #TNF_WELL_KNOWN} with a type of {@link #RTD_URI}.</li>
-     * <li>{@link #TNF_WELL_KNOWN} with a type of {@link #RTD_SMART_POSTER}
-     * and containing a URI record in the NDEF message nested in the payload.
-     * </li>
-     * <li>{@link #TNF_EXTERNAL_TYPE} records.</li>
-     * </ul>
-     * If this is not a URI record by the above rules, then null is returned.<p>
-     * This method does not perform validation that the URI is
-     * actually valid: it always attempts to create and return a URI if
-     * this record appears to be a URI record by the above rules.<p>
-     * The returned URI will be normalized to have a lower case scheme
-     * using {@link Uri#normalizeScheme}.<p>
-     *
-     * @return URI, or null if this is not a URI record
-     */
-    public Uri toUri() {
-        return toUri(false);
-    }
-
-    private Uri toUri(boolean inSmartPoster) {
-        switch (mTnf) {
-            case TNF_WELL_KNOWN:
-                if (Arrays.equals(mType, RTD_SMART_POSTER) && !inSmartPoster) {
-                    try {
-                        // check payload for a nested NDEF Message containing a URI
-                        NdefMessage nestedMessage = new NdefMessage(mPayload);
-                        for (NdefRecord nestedRecord : nestedMessage.getRecords()) {
-                            Uri uri = nestedRecord.toUri(true);
-                            if (uri != null) {
-                                return uri;
-                            }
-                        }
-                    } catch (FormatException e) {  }
-                } else if (Arrays.equals(mType, RTD_URI)) {
-                    Uri wktUri = parseWktUri();
-                    return (wktUri != null ? wktUri.normalizeScheme() : null);
-                }
-                break;
-
-            case TNF_ABSOLUTE_URI:
-                Uri uri = Uri.parse(new String(mType, StandardCharsets.UTF_8));
-                return uri.normalizeScheme();
-
-            case TNF_EXTERNAL_TYPE:
-                if (inSmartPoster) {
-                    break;
-                }
-                return Uri.parse("vnd.android.nfc://ext/" + new String(mType, StandardCharsets.US_ASCII));
-        }
-        return null;
-    }
-
-    /**
-     * Return complete URI of {@link #TNF_WELL_KNOWN}, {@link #RTD_URI} records.
-     * @return complete URI, or null if invalid
-     */
-    private Uri parseWktUri() {
-        if (mPayload.length < 2) {
-            return null;
-        }
-
-        // payload[0] contains the URI Identifier Code, as per
-        // NFC Forum "URI Record Type Definition" section 3.2.2.
-        int prefixIndex = (mPayload[0] & (byte)0xFF);
-        if (prefixIndex < 0 || prefixIndex >= URI_PREFIX_MAP.length) {
-            return null;
-        }
-        String prefix = URI_PREFIX_MAP[prefixIndex];
-        String suffix = new String(Arrays.copyOfRange(mPayload, 1, mPayload.length),
-                StandardCharsets.UTF_8);
-        return Uri.parse(prefix + suffix);
-    }
-
-    /**
-     * Main record parsing method.<p>
-     * Expects NdefMessage to begin immediately, allows trailing data.<p>
-     * Currently has strict validation of all fields as per NDEF 1.0
-     * specification section 2.5. We will attempt to keep this as strict as
-     * possible to encourage well-formatted NDEF.<p>
-     * Always returns 1 or more NdefRecord's, or throws FormatException.
-     *
-     * @param buffer ByteBuffer to read from
-     * @param ignoreMbMe ignore MB and ME flags, and read only 1 complete record
-     * @return one or more records
-     * @throws FormatException on any parsing error
-     */
-    static NdefRecord[] parse(ByteBuffer buffer, boolean ignoreMbMe) throws FormatException {
-        List<NdefRecord> records = new ArrayList<NdefRecord>();
-
-        try {
-            byte[] type = null;
-            byte[] id = null;
-            byte[] payload = null;
-            ArrayList<byte[]> chunks = new ArrayList<byte[]>();
-            boolean inChunk = false;
-            short chunkTnf = -1;
-            boolean me = false;
-
-            while (!me) {
-                byte flag = buffer.get();
-
-                boolean mb = (flag & NdefRecord.FLAG_MB) != 0;
-                me = (flag & NdefRecord.FLAG_ME) != 0;
-                boolean cf = (flag & NdefRecord.FLAG_CF) != 0;
-                boolean sr = (flag & NdefRecord.FLAG_SR) != 0;
-                boolean il = (flag & NdefRecord.FLAG_IL) != 0;
-                short tnf = (short)(flag & 0x07);
-
-                if (!mb && records.size() == 0 && !inChunk && !ignoreMbMe) {
-                    throw new FormatException("expected MB flag");
-                } else if (mb && (records.size() != 0 || inChunk) && !ignoreMbMe) {
-                    throw new FormatException("unexpected MB flag");
-                } else if (inChunk && il) {
-                    throw new FormatException("unexpected IL flag in non-leading chunk");
-                } else if (cf && me) {
-                    throw new FormatException("unexpected ME flag in non-trailing chunk");
-                } else if (inChunk && tnf != NdefRecord.TNF_UNCHANGED) {
-                    throw new FormatException("expected TNF_UNCHANGED in non-leading chunk");
-                } else if (!inChunk && tnf == NdefRecord.TNF_UNCHANGED) {
-                    throw new FormatException("" +
-                            "unexpected TNF_UNCHANGED in first chunk or unchunked record");
-                }
-
-                int typeLength = buffer.get() & 0xFF;
-                long payloadLength = sr ? (buffer.get() & 0xFF) : (buffer.getInt() & 0xFFFFFFFFL);
-                int idLength = il ? (buffer.get() & 0xFF) : 0;
-
-                if (inChunk && typeLength != 0) {
-                    throw new FormatException("expected zero-length type in non-leading chunk");
-                }
-
-                if (!inChunk) {
-                    type = (typeLength > 0 ? new byte[typeLength] : EMPTY_BYTE_ARRAY);
-                    id = (idLength > 0 ? new byte[idLength] : EMPTY_BYTE_ARRAY);
-                    buffer.get(type);
-                    buffer.get(id);
-                }
-
-                ensureSanePayloadSize(payloadLength);
-                payload = (payloadLength > 0 ? new byte[(int)payloadLength] : EMPTY_BYTE_ARRAY);
-                buffer.get(payload);
-
-                if (cf && !inChunk) {
-                    // first chunk
-                    if (typeLength == 0 && tnf != NdefRecord.TNF_UNKNOWN) {
-                        throw new FormatException("expected non-zero type length in first chunk");
-                    }
-                    chunks.clear();
-                    chunkTnf = tnf;
-                }
-                if (cf || inChunk) {
-                    // any chunk
-                    chunks.add(payload);
-                }
-                if (!cf && inChunk) {
-                    // last chunk, flatten the payload
-                    payloadLength = 0;
-                    for (byte[] p : chunks) {
-                        payloadLength += p.length;
-                    }
-                    ensureSanePayloadSize(payloadLength);
-                    payload = new byte[(int)payloadLength];
-                    int i = 0;
-                    for (byte[] p : chunks) {
-                        System.arraycopy(p, 0, payload, i, p.length);
-                        i += p.length;
-                    }
-                    tnf = chunkTnf;
-                }
-                if (cf) {
-                    // more chunks to come
-                    inChunk = true;
-                    continue;
-                } else {
-                    inChunk = false;
-                }
-
-                String error = validateTnf(tnf, type, id, payload);
-                if (error != null) {
-                    throw new FormatException(error);
-                }
-                records.add(new NdefRecord(tnf, type, id, payload));
-                if (ignoreMbMe) {  // for parsing a single NdefRecord
-                    break;
-                }
-            }
-        } catch (BufferUnderflowException e) {
-            throw new FormatException("expected more data", e);
-        }
-        return records.toArray(new NdefRecord[records.size()]);
-    }
-
-    private static void ensureSanePayloadSize(long size) throws FormatException {
-        if (size > MAX_PAYLOAD_SIZE) {
-            throw new FormatException(
-                    "payload above max limit: " + size + " > " + MAX_PAYLOAD_SIZE);
-        }
-    }
-
-    /**
-     * Perform simple validation that the tnf is valid.<p>
-     * Validates the requirements of NFCForum-TS-NDEF_1.0 section
-     * 3.2.6 (Type Name Format). This just validates that the tnf
-     * is valid, and that the relevant type, id and payload
-     * fields are present (or empty) for this tnf. It does not
-     * perform any deep inspection of the type, id and payload fields.<p>
-     * Also does not allow TNF_UNCHANGED since this class is only used
-     * to present logical (unchunked) records.
-     *
-     * @return null if valid, or a string error if invalid.
-     */
-    static String validateTnf(short tnf, byte[] type, byte[] id, byte[] payload) {
-        switch (tnf) {
-            case TNF_EMPTY:
-                if (type.length != 0 || id.length != 0 || payload.length != 0) {
-                    return "unexpected data in TNF_EMPTY record";
-                }
-                return null;
-            case TNF_WELL_KNOWN:
-            case TNF_MIME_MEDIA:
-            case TNF_ABSOLUTE_URI:
-            case TNF_EXTERNAL_TYPE:
-                return null;
-            case TNF_UNKNOWN:
-            case TNF_RESERVED:
-                if (type.length != 0) {
-                    return "unexpected type field in TNF_UNKNOWN or TNF_RESERVEd record";
-                }
-                return null;
-            case TNF_UNCHANGED:
-                return "unexpected TNF_UNCHANGED in first chunk or logical record";
-            default:
-                return String.format("unexpected tnf value: 0x%02x", tnf);
-        }
-    }
-
-    /**
-     * Serialize record for network transmission.<p>
-     * Uses specified MB and ME flags.<p>
-     * Does not chunk records.
-     */
-    void writeToByteBuffer(ByteBuffer buffer, boolean mb, boolean me) {
-        boolean sr = mPayload.length < 256;
-        boolean il = mTnf == TNF_EMPTY ? true : mId.length > 0;
-
-        byte flags = (byte)((mb ? FLAG_MB : 0) | (me ? FLAG_ME : 0) |
-                (sr ? FLAG_SR : 0) | (il ? FLAG_IL : 0) | mTnf);
-        buffer.put(flags);
-
-        buffer.put((byte)mType.length);
-        if (sr) {
-            buffer.put((byte)mPayload.length);
-        } else {
-            buffer.putInt(mPayload.length);
-        }
-        if (il) {
-            buffer.put((byte)mId.length);
-        }
-
-        buffer.put(mType);
-        buffer.put(mId);
-        buffer.put(mPayload);
-    }
-
-    /**
-     * Get byte length of serialized record.
-     */
-    int getByteLength() {
-        int length = 3 + mType.length + mId.length + mPayload.length;
-
-        boolean sr = mPayload.length < 256;
-        boolean il = mTnf == TNF_EMPTY ? true : mId.length > 0;
-
-        if (!sr) length += 3;
-        if (il) length += 1;
-
-        return length;
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(mTnf);
-        dest.writeInt(mType.length);
-        dest.writeByteArray(mType);
-        dest.writeInt(mId.length);
-        dest.writeByteArray(mId);
-        dest.writeInt(mPayload.length);
-        dest.writeByteArray(mPayload);
-    }
-
-    public static final @android.annotation.NonNull Parcelable.Creator<NdefRecord> CREATOR =
-            new Parcelable.Creator<NdefRecord>() {
-        @Override
-        public NdefRecord createFromParcel(Parcel in) {
-            short tnf = (short)in.readInt();
-            int typeLength = in.readInt();
-            byte[] type = new byte[typeLength];
-            in.readByteArray(type);
-            int idLength = in.readInt();
-            byte[] id = new byte[idLength];
-            in.readByteArray(id);
-            int payloadLength = in.readInt();
-            byte[] payload = new byte[payloadLength];
-            in.readByteArray(payload);
-
-            return new NdefRecord(tnf, type, id, payload);
-        }
-        @Override
-        public NdefRecord[] newArray(int size) {
-            return new NdefRecord[size];
-        }
-    };
-
-    @Override
-    public int hashCode() {
-        final int prime = 31;
-        int result = 1;
-        result = prime * result + Arrays.hashCode(mId);
-        result = prime * result + Arrays.hashCode(mPayload);
-        result = prime * result + mTnf;
-        result = prime * result + Arrays.hashCode(mType);
-        return result;
-    }
-
-    /**
-     * Returns true if the specified NDEF Record contains
-     * identical tnf, type, id and payload fields.
-     */
-    @Override
-    public boolean equals(@Nullable Object obj) {
-        if (this == obj) return true;
-        if (obj == null) return false;
-        if (getClass() != obj.getClass()) return false;
-        NdefRecord other = (NdefRecord) obj;
-        if (!Arrays.equals(mId, other.mId)) return false;
-        if (!Arrays.equals(mPayload, other.mPayload)) return false;
-        if (mTnf != other.mTnf) return false;
-        return Arrays.equals(mType, other.mType);
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder b = new StringBuilder(String.format("NdefRecord tnf=%X", mTnf));
-        if (mType.length > 0) b.append(" type=").append(bytesToString(mType));
-        if (mId.length > 0) b.append(" id=").append(bytesToString(mId));
-        if (mPayload.length > 0) b.append(" payload=").append(bytesToString(mPayload));
-        return b.toString();
-    }
-
-    /**
-     * Dump debugging information as a NdefRecordProto
-     * @hide
-     *
-     * Note:
-     * See proto definition in frameworks/base/core/proto/android/nfc/ndef.proto
-     * When writing a nested message, must call {@link ProtoOutputStream#start(long)} before and
-     * {@link ProtoOutputStream#end(long)} after.
-     * Never reuse a proto field number. When removing a field, mark it as reserved.
-     */
-    public void dumpDebug(ProtoOutputStream proto) {
-        proto.write(NdefRecordProto.TYPE, mType);
-        proto.write(NdefRecordProto.ID, mId);
-        proto.write(NdefRecordProto.PAYLOAD_BYTES, mPayload.length);
-    }
-
-    private static StringBuilder bytesToString(byte[] bs) {
-        StringBuilder s = new StringBuilder();
-        for (byte b : bs) {
-            s.append(String.format("%02X", b));
-        }
-        return s;
-    }
-}
diff --git a/nfc/java/android/nfc/NfcActivityManager.java b/nfc/java/android/nfc/NfcActivityManager.java
deleted file mode 100644
index 909eca7..0000000
--- a/nfc/java/android/nfc/NfcActivityManager.java
+++ /dev/null
@@ -1,403 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import android.app.Activity;
-import android.app.Application;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.nfc.NfcAdapter.ReaderCallback;
-import android.os.Binder;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- * Manages NFC API's that are coupled to the life-cycle of an Activity.
- *
- * <p>Uses {@link Application#registerActivityLifecycleCallbacks} to hook
- * into activity life-cycle events such as onPause() and onResume().
- *
- * @hide
- */
-public final class NfcActivityManager extends IAppCallback.Stub
-        implements Application.ActivityLifecycleCallbacks {
-    static final String TAG = NfcAdapter.TAG;
-    static final Boolean DBG = false;
-
-    @UnsupportedAppUsage
-    final NfcAdapter mAdapter;
-
-    // All objects in the lists are protected by this
-    final List<NfcApplicationState> mApps;  // Application(s) that have NFC state. Usually one
-    final List<NfcActivityState> mActivities;  // Activities that have NFC state
-
-    /**
-     * NFC State associated with an {@link Application}.
-     */
-    class NfcApplicationState {
-        int refCount = 0;
-        final Application app;
-        public NfcApplicationState(Application app) {
-            this.app = app;
-        }
-        public void register() {
-            refCount++;
-            if (refCount == 1) {
-                this.app.registerActivityLifecycleCallbacks(NfcActivityManager.this);
-            }
-        }
-        public void unregister() {
-            refCount--;
-            if (refCount == 0) {
-                this.app.unregisterActivityLifecycleCallbacks(NfcActivityManager.this);
-            } else if (refCount < 0) {
-                Log.e(TAG, "-ve refcount for " + app);
-            }
-        }
-    }
-
-    NfcApplicationState findAppState(Application app) {
-        for (NfcApplicationState appState : mApps) {
-            if (appState.app == app) {
-                return appState;
-            }
-        }
-        return null;
-    }
-
-    void registerApplication(Application app) {
-        NfcApplicationState appState = findAppState(app);
-        if (appState == null) {
-            appState = new NfcApplicationState(app);
-            mApps.add(appState);
-        }
-        appState.register();
-    }
-
-    void unregisterApplication(Application app) {
-        NfcApplicationState appState = findAppState(app);
-        if (appState == null) {
-            Log.e(TAG, "app was not registered " + app);
-            return;
-        }
-        appState.unregister();
-    }
-
-    /**
-     * NFC state associated with an {@link Activity}
-     */
-    class NfcActivityState {
-        boolean resumed = false;
-        Activity activity;
-        NfcAdapter.ReaderCallback readerCallback = null;
-        int readerModeFlags = 0;
-        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");
-            }
-            // Check if activity is resumed right now, as we will not
-            // immediately get a callback for that.
-            resumed = activity.isResumed();
-
-            this.activity = activity;
-            this.token = new Binder();
-            registerApplication(activity.getApplication());
-        }
-        public void destroy() {
-            unregisterApplication(activity.getApplication());
-            resumed = false;
-            activity = null;
-            readerCallback = null;
-            readerModeFlags = 0;
-            readerModeExtras = null;
-            token = null;
-
-            mPollTech = NfcAdapter.FLAG_USE_ALL_TECH;
-            mListenTech = NfcAdapter.FLAG_USE_ALL_TECH;
-        }
-        @Override
-        public String toString() {
-            StringBuilder s = new StringBuilder("[");
-            s.append(readerCallback);
-            s.append("]");
-            return s.toString();
-        }
-    }
-
-    /** find activity state from mActivities */
-    synchronized NfcActivityState findActivityState(Activity activity) {
-        for (NfcActivityState state : mActivities) {
-            if (state.activity == activity) {
-                return state;
-            }
-        }
-        return null;
-    }
-
-    /** find or create activity state from mActivities */
-    synchronized NfcActivityState getActivityState(Activity activity) {
-        NfcActivityState state = findActivityState(activity);
-        if (state == null) {
-            state = new NfcActivityState(activity);
-            mActivities.add(state);
-        }
-        return state;
-    }
-
-    synchronized NfcActivityState findResumedActivityState() {
-        for (NfcActivityState state : mActivities) {
-            if (state.resumed) {
-                return state;
-            }
-        }
-        return null;
-    }
-
-    synchronized void destroyActivityState(Activity activity) {
-        NfcActivityState activityState = findActivityState(activity);
-        if (activityState != null) {
-            activityState.destroy();
-            mActivities.remove(activityState);
-        }
-    }
-
-    public NfcActivityManager(NfcAdapter adapter) {
-        mAdapter = adapter;
-        mActivities = new LinkedList<NfcActivityState>();
-        mApps = new ArrayList<NfcApplicationState>(1);  // Android VM usually has 1 app
-    }
-
-    public void enableReaderMode(Activity activity, ReaderCallback callback, int flags,
-            Bundle extras) {
-        boolean isResumed;
-        Binder token;
-        int pollTech, listenTech;
-        synchronized (NfcActivityManager.this) {
-            NfcActivityState state = getActivityState(activity);
-            state.readerCallback = callback;
-            state.readerModeFlags = flags;
-            state.readerModeExtras = extras;
-            pollTech = state.mPollTech;
-            listenTech = state.mListenTech;
-            token = state.token;
-            isResumed = state.resumed;
-        }
-        if (isResumed) {
-            if (listenTech != NfcAdapter.FLAG_USE_ALL_TECH
-                    || pollTech != NfcAdapter.FLAG_USE_ALL_TECH) {
-                throw new IllegalStateException(
-                    "Cannot be used when alternative DiscoveryTechnology is set");
-            } else {
-                setReaderMode(token, flags, extras);
-            }
-        }
-    }
-
-    public void disableReaderMode(Activity activity) {
-        boolean isResumed;
-        Binder token;
-        synchronized (NfcActivityManager.this) {
-            NfcActivityState state = getActivityState(activity);
-            state.readerCallback = null;
-            state.readerModeFlags = 0;
-            state.readerModeExtras = null;
-            token = state.token;
-            isResumed = state.resumed;
-        }
-        if (isResumed) {
-            setReaderMode(token, 0, null);
-        }
-
-    }
-
-    public void setReaderMode(Binder token, int flags, Bundle extras) {
-        if (DBG) Log.d(TAG, "Setting reader mode");
-        NfcAdapter.callService(() -> NfcAdapter.sService.setReaderMode(
-                token, this, flags, extras, mAdapter.getContext().getPackageName()));
-    }
-
-    /**
-     * Request or unrequest NFC service callbacks.
-     * Makes IPC call - do not hold lock.
-     */
-    void requestNfcServiceCallback() {
-        NfcAdapter.callService(() -> NfcAdapter.sService.setAppCallback(this));
-    }
-
-    void verifyNfcPermission() {
-        NfcAdapter.callService(() -> NfcAdapter.sService.verifyNfcPermission());
-    }
-
-    @Override
-    public void onTagDiscovered(Tag tag) throws RemoteException {
-        NfcAdapter.ReaderCallback callback;
-        synchronized (NfcActivityManager.this) {
-            NfcActivityState state = findResumedActivityState();
-            if (state == null) return;
-
-            callback = state.readerCallback;
-        }
-
-        // Make callback without lock
-        if (callback != null) {
-            callback.onTagDiscovered(tag);
-        }
-
-    }
-    /** Callback from Activity life-cycle, on main thread */
-    @Override
-    public void onActivityCreated(Activity activity, Bundle savedInstanceState) { /* NO-OP */ }
-
-    /** Callback from Activity life-cycle, on main thread */
-    @Override
-    public void onActivityStarted(Activity activity) { /* NO-OP */ }
-
-    /** Callback from Activity life-cycle, on main thread */
-    @Override
-    public void onActivityResumed(Activity activity) {
-        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);
-            if (state == null) return;
-            state.resumed = true;
-            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();
-    }
-
-    /** Callback from Activity life-cycle, on main thread */
-    @Override
-    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);
-            if (state == null) return;
-            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);
-        }
-    }
-
-    /** Callback from Activity life-cycle, on main thread */
-    @Override
-    public void onActivityStopped(Activity activity) { /* NO-OP */ }
-
-    /** Callback from Activity life-cycle, on main thread */
-    @Override
-    public void onActivitySaveInstanceState(Activity activity, Bundle outState) { /* NO-OP */ }
-
-    /** Callback from Activity life-cycle, on main thread */
-    @Override
-    public void onActivityDestroyed(Activity activity) {
-        synchronized (NfcActivityManager.this) {
-            NfcActivityState state = findActivityState(activity);
-            if (DBG) Log.d(TAG, "onDestroy() for " + activity + " " + state);
-            if (state != null) {
-                // release all associated references
-                destroyActivityState(activity);
-            }
-        }
-    }
-
-    /** 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);
-            state.mListenTech = NfcAdapter.FLAG_USE_ALL_TECH;
-            state.mPollTech = NfcAdapter.FLAG_USE_ALL_TECH;
-            token = state.token;
-            isResumed = state.resumed;
-        }
-        if (isResumed) {
-            changeDiscoveryTech(token, NfcAdapter.FLAG_USE_ALL_TECH, NfcAdapter.FLAG_USE_ALL_TECH);
-        }
-
-    }
-
-    private void changeDiscoveryTech(Binder token, int pollTech, int listenTech) {
-        NfcAdapter.callService(
-                () -> NfcAdapter.sService.updateDiscoveryTechnology(
-                        token, pollTech, listenTech, mAdapter.getContext().getPackageName()));
-    }
-
-}
diff --git a/nfc/java/android/nfc/NfcAdapter.java b/nfc/java/android/nfc/NfcAdapter.java
deleted file mode 100644
index 63397c2..0000000
--- a/nfc/java/android/nfc/NfcAdapter.java
+++ /dev/null
@@ -1,2949 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import android.Manifest;
-import android.annotation.CallbackExecutor;
-import android.annotation.FlaggedApi;
-import android.annotation.IntDef;
-import android.annotation.IntRange;
-import android.annotation.NonNull;
-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.TestApi;
-import android.annotation.UserIdInt;
-import android.app.Activity;
-import android.app.PendingIntent;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.content.Context;
-import android.content.IntentFilter;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.net.Uri;
-import android.nfc.cardemulation.PollingFrame;
-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;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.os.UserHandle;
-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;
-
-/**
- * Represents the local NFC adapter.
- * <p>
- * Use the helper {@link #getDefaultAdapter(Context)} to get the default NFC
- * adapter for this Android device.
- *
- * <div class="special reference">
- * <h3>Developer Guides</h3>
- * <p>For more information about using NFC, read the
- * <a href="{@docRoot}guide/topics/nfc/index.html">Near Field Communication</a> developer guide.</p>
- * <p>To perform basic file sharing between devices, read
- * <a href="{@docRoot}training/beam-files/index.html">Sharing Files with NFC</a>.
- * </div>
- */
-public final class NfcAdapter {
-    static final String TAG = "NFC";
-
-    private final NfcControllerAlwaysOnListener mControllerAlwaysOnListener;
-    private final NfcWlcStateListener mNfcWlcStateListener;
-    private final NfcVendorNciCallbackListener mNfcVendorNciCallbackListener;
-
-    /**
-     * Intent to start an activity when a tag with NDEF payload is discovered.
-     *
-     * <p>The system inspects the first {@link NdefRecord} in the first {@link NdefMessage} and
-     * looks for a URI, SmartPoster, or MIME record. If a URI or SmartPoster record is found the
-     * intent will contain the URI in its data field. If a MIME record is found the intent will
-     * contain the MIME type in its type field. This allows activities to register
-     * {@link IntentFilter}s targeting specific content on tags. Activities should register the
-     * most specific intent filters possible to avoid the activity chooser dialog, which can
-     * disrupt the interaction with the tag as the user interacts with the screen.
-     *
-     * <p>If the tag has an NDEF payload this intent is started before
-     * {@link #ACTION_TECH_DISCOVERED}. If any activities respond to this intent neither
-     * {@link #ACTION_TECH_DISCOVERED} or {@link #ACTION_TAG_DISCOVERED} will be started.
-     *
-     * <p>The MIME type or data URI of this intent are normalized before dispatch -
-     * so that MIME, URI scheme and URI host are always lower-case.
-     */
-    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
-    public static final String ACTION_NDEF_DISCOVERED = "android.nfc.action.NDEF_DISCOVERED";
-
-    /**
-     * Intent to start an activity when a tag is discovered and activities are registered for the
-     * specific technologies on the tag.
-     *
-     * <p>To receive this intent an activity must include an intent filter
-     * for this action and specify the desired tech types in a
-     * manifest <code>meta-data</code> entry. Here is an example manfiest entry:
-     * <pre>
-     * &lt;activity android:name=".nfc.TechFilter" android:label="NFC/TechFilter"&gt;
-     *     &lt;!-- Add a technology filter --&gt;
-     *     &lt;intent-filter&gt;
-     *         &lt;action android:name="android.nfc.action.TECH_DISCOVERED" /&gt;
-     *     &lt;/intent-filter&gt;
-     *
-     *     &lt;meta-data android:name="android.nfc.action.TECH_DISCOVERED"
-     *         android:resource="@xml/filter_nfc"
-     *     /&gt;
-     * &lt;/activity&gt;</pre>
-     *
-     * <p>The meta-data XML file should contain one or more <code>tech-list</code> entries
-     * each consisting or one or more <code>tech</code> entries. The <code>tech</code> entries refer
-     * to the qualified class name implementing the technology, for example "android.nfc.tech.NfcA".
-     *
-     * <p>A tag matches if any of the
-     * <code>tech-list</code> sets is a subset of {@link Tag#getTechList() Tag.getTechList()}. Each
-     * of the <code>tech-list</code>s is considered independently and the
-     * activity is considered a match is any single <code>tech-list</code> matches the tag that was
-     * discovered. This provides AND and OR semantics for filtering desired techs. Here is an
-     * example that will match any tag using {@link NfcF} or any tag using {@link NfcA},
-     * {@link MifareClassic}, and {@link Ndef}:
-     *
-     * <pre>
-     * &lt;resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"&gt;
-     *     &lt;!-- capture anything using NfcF --&gt;
-     *     &lt;tech-list&gt;
-     *         &lt;tech&gt;android.nfc.tech.NfcF&lt;/tech&gt;
-     *     &lt;/tech-list&gt;
-     *
-     *     &lt;!-- OR --&gt;
-     *
-     *     &lt;!-- capture all MIFARE Classics with NDEF payloads --&gt;
-     *     &lt;tech-list&gt;
-     *         &lt;tech&gt;android.nfc.tech.NfcA&lt;/tech&gt;
-     *         &lt;tech&gt;android.nfc.tech.MifareClassic&lt;/tech&gt;
-     *         &lt;tech&gt;android.nfc.tech.Ndef&lt;/tech&gt;
-     *     &lt;/tech-list&gt;
-     * &lt;/resources&gt;</pre>
-     *
-     * <p>This intent is started after {@link #ACTION_NDEF_DISCOVERED} and before
-     * {@link #ACTION_TAG_DISCOVERED}. If any activities respond to {@link #ACTION_NDEF_DISCOVERED}
-     * this intent will not be started. If any activities respond to this intent
-     * {@link #ACTION_TAG_DISCOVERED} will not be started.
-     */
-    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
-    public static final String ACTION_TECH_DISCOVERED = "android.nfc.action.TECH_DISCOVERED";
-
-    /**
-     * Intent to start an activity when a tag is discovered.
-     *
-     * <p>This intent will not be started when a tag is discovered if any activities respond to
-     * {@link #ACTION_NDEF_DISCOVERED} or {@link #ACTION_TECH_DISCOVERED} for the current tag.
-     */
-    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
-    public static final String ACTION_TAG_DISCOVERED = "android.nfc.action.TAG_DISCOVERED";
-
-    /**
-     * Broadcast Action: Intent to notify an application that a transaction event has occurred
-     * on the Secure Element.
-     *
-     * <p>This intent will only be sent if the application has requested permission for
-     * {@link android.Manifest.permission#NFC_TRANSACTION_EVENT} and if the application has the
-     * necessary access to Secure Element which witnessed the particular event.
-     */
-    @RequiresPermission(android.Manifest.permission.NFC_TRANSACTION_EVENT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_TRANSACTION_DETECTED =
-            "android.nfc.action.TRANSACTION_DETECTED";
-
-    /**
-     * Broadcast Action: Intent to notify if the preferred payment service changed.
-     *
-     * <p>This intent will only be sent to the application has requested permission for
-     * {@link android.Manifest.permission#NFC_PREFERRED_PAYMENT_INFO} and if the application
-     * has the necessary access to Secure Element which witnessed the particular event.
-     */
-    @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_PREFERRED_PAYMENT_CHANGED =
-            "android.nfc.action.PREFERRED_PAYMENT_CHANGED";
-
-    /**
-     * Broadcast to only the activity that handles ACTION_TAG_DISCOVERED
-     * @hide
-     */
-    public static final String ACTION_TAG_LEFT_FIELD = "android.nfc.action.TAG_LOST";
-
-    /**
-     * Mandatory extra containing the {@link Tag} that was discovered for the
-     * {@link #ACTION_NDEF_DISCOVERED}, {@link #ACTION_TECH_DISCOVERED}, and
-     * {@link #ACTION_TAG_DISCOVERED} intents.
-     */
-    public static final String EXTRA_TAG = "android.nfc.extra.TAG";
-
-    /**
-     * Extra containing an array of {@link NdefMessage} present on the discovered tag.<p>
-     * This extra is mandatory for {@link #ACTION_NDEF_DISCOVERED} intents,
-     * and optional for {@link #ACTION_TECH_DISCOVERED}, and
-     * {@link #ACTION_TAG_DISCOVERED} intents.<p>
-     * When this extra is present there will always be at least one
-     * {@link NdefMessage} element. Most NDEF tags have only one NDEF message,
-     * but we use an array for future compatibility.
-     */
-    public static final String EXTRA_NDEF_MESSAGES = "android.nfc.extra.NDEF_MESSAGES";
-
-    /**
-     * Optional extra containing a byte array containing the ID of the discovered tag for
-     * the {@link #ACTION_NDEF_DISCOVERED}, {@link #ACTION_TECH_DISCOVERED}, and
-     * {@link #ACTION_TAG_DISCOVERED} intents.
-     */
-    public static final String EXTRA_ID = "android.nfc.extra.ID";
-
-    /**
-     * Broadcast Action: The state of the local NFC adapter has been
-     * changed.
-     * <p>For example, NFC has been turned on or off.
-     * <p>Always contains the extra field {@link #EXTRA_ADAPTER_STATE}
-     */
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_ADAPTER_STATE_CHANGED =
-            "android.nfc.action.ADAPTER_STATE_CHANGED";
-
-    /**
-     * Used as an int extra field in {@link #ACTION_ADAPTER_STATE_CHANGED}
-     * intents to request the current power state. Possible values are:
-     * {@link #STATE_OFF},
-     * {@link #STATE_TURNING_ON},
-     * {@link #STATE_ON},
-     * {@link #STATE_TURNING_OFF},
-     */
-    public static final String EXTRA_ADAPTER_STATE = "android.nfc.extra.ADAPTER_STATE";
-
-    /**
-     * Mandatory byte[] extra field in {@link #ACTION_TRANSACTION_DETECTED}
-     */
-    public static final String EXTRA_AID = "android.nfc.extra.AID";
-
-    /**
-     * Optional byte[] extra field in {@link #ACTION_TRANSACTION_DETECTED}
-     */
-    public static final String EXTRA_DATA = "android.nfc.extra.DATA";
-
-    /**
-     * Mandatory String extra field in {@link #ACTION_TRANSACTION_DETECTED}
-     * Indicates the Secure Element on which the transaction occurred.
-     * eSE1...eSEn for Embedded Secure Elements, SIM1...SIMn for UICC/EUICC, etc.
-     */
-    public static final String EXTRA_SECURE_ELEMENT_NAME = "android.nfc.extra.SECURE_ELEMENT_NAME";
-
-    /**
-     * Mandatory String extra field in {@link #ACTION_PREFERRED_PAYMENT_CHANGED}
-     * Indicates the condition when trigger this event. Possible values are:
-     * {@link #PREFERRED_PAYMENT_LOADED},
-     * {@link #PREFERRED_PAYMENT_CHANGED},
-     * {@link #PREFERRED_PAYMENT_UPDATED},
-     */
-    public static final String EXTRA_PREFERRED_PAYMENT_CHANGED_REASON =
-            "android.nfc.extra.PREFERRED_PAYMENT_CHANGED_REASON";
-    /**
-     * Nfc is enabled and the preferred payment aids are registered.
-     */
-    public static final int PREFERRED_PAYMENT_LOADED = 1;
-    /**
-     * User selected another payment application as the preferred payment.
-     */
-    public static final int PREFERRED_PAYMENT_CHANGED = 2;
-    /**
-     * Current preferred payment has issued an update (registered/unregistered new aids or has been
-     * updated itself).
-     */
-    public static final int PREFERRED_PAYMENT_UPDATED = 3;
-
-    public static final int STATE_OFF = 1;
-    public static final int STATE_TURNING_ON = 2;
-    public static final int STATE_ON = 3;
-    public static final int STATE_TURNING_OFF = 4;
-
-    /**
-     * Possible states from {@link #getAdapterState}.
-     *
-     * @hide
-     */
-    @IntDef(prefix = { "STATE_" }, value = {
-            STATE_OFF,
-            STATE_TURNING_ON,
-            STATE_ON,
-            STATE_TURNING_OFF
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface AdapterState{}
-
-    /**
-     * Flag for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}.
-     * <p>
-     * Setting this flag enables polling for Nfc-A technology.
-     */
-    public static final int FLAG_READER_NFC_A = 0x1;
-
-    /**
-     * Flag for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}.
-     * <p>
-     * Setting this flag enables polling for Nfc-B technology.
-     */
-    public static final int FLAG_READER_NFC_B = 0x2;
-
-    /**
-     * Flag for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}.
-     * <p>
-     * Setting this flag enables polling for Nfc-F technology.
-     */
-    public static final int FLAG_READER_NFC_F = 0x4;
-
-    /**
-     * Flag for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}.
-     * <p>
-     * Setting this flag enables polling for Nfc-V (ISO15693) technology.
-     */
-    public static final int FLAG_READER_NFC_V = 0x8;
-
-    /**
-     * Flag for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}.
-     * <p>
-     * Setting this flag enables polling for NfcBarcode technology.
-     */
-    public static final int FLAG_READER_NFC_BARCODE = 0x10;
-
-    /** @hide */
-    @IntDef(flag = true, value = {
-        FLAG_SET_DEFAULT_TECH,
-        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>
-     * Setting this flag allows the caller to prevent the
-     * platform from performing an NDEF check on the tags it
-     * finds.
-     */
-    public static final int FLAG_READER_SKIP_NDEF_CHECK = 0x80;
-
-    /**
-     * Flag for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}.
-     * <p>
-     * Setting this flag allows the caller to prevent the
-     * platform from playing sounds when it discovers a tag.
-     */
-    public static final int FLAG_READER_NO_PLATFORM_SOUNDS = 0x100;
-
-    /**
-     * Int Extra for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}.
-     * <p>
-     * Setting this integer extra allows the calling application to specify
-     * the delay that the platform will use for performing presence checks
-     * on any discovered tag.
-     */
-    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 keep the current technology configuration.
-     */
-    @FlaggedApi(Flags.FLAG_ENABLE_NFC_SET_DISCOVERY_TECH)
-    public static final int FLAG_LISTEN_KEEP = 0x80000000;
-
-    /**
-     * Flags for use with {@link #setDiscoveryTechnology(Activity, int, int)}.
-     * <p>
-     * Setting this flag makes polling to keep the current technology configuration.
-     */
-    @FlaggedApi(Flags.FLAG_ENABLE_NFC_SET_DISCOVERY_TECH)
-    public static final int FLAG_READER_KEEP = 0x80000000;
-
-    /** @hide */
-    public static final int FLAG_USE_ALL_TECH = 0xff;
-
-    /** @hide */
-    @IntDef(flag = true, value = {
-        FLAG_SET_DEFAULT_TECH,
-        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 {}
-
-    /**
-     * Flag used in {@link #setDiscoveryTechnology(Activity, int, int)}.
-     * <p>
-     * Setting this flag changes the default listen or poll tech.
-     * Only available to privileged apps.
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_NFC_SET_DEFAULT_DISC_TECH)
-    @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
-    public static final int FLAG_SET_DEFAULT_TECH = 0x40000000;
-
-    /**
-     * @hide
-     * @removed
-     */
-    @SystemApi
-    @UnsupportedAppUsage
-    public static final int FLAG_NDEF_PUSH_NO_CONFIRM = 0x1;
-
-    /** @hide */
-    public static final String ACTION_HANDOVER_TRANSFER_STARTED =
-            "android.nfc.action.HANDOVER_TRANSFER_STARTED";
-
-    /** @hide */
-    public static final String ACTION_HANDOVER_TRANSFER_DONE =
-            "android.nfc.action.HANDOVER_TRANSFER_DONE";
-
-    /** @hide */
-    public static final String EXTRA_HANDOVER_TRANSFER_STATUS =
-            "android.nfc.extra.HANDOVER_TRANSFER_STATUS";
-
-    /** @hide */
-    public static final int HANDOVER_TRANSFER_STATUS_SUCCESS = 0;
-    /** @hide */
-    public static final int HANDOVER_TRANSFER_STATUS_FAILURE = 1;
-
-    /** @hide */
-    public static final String EXTRA_HANDOVER_TRANSFER_URI =
-            "android.nfc.extra.HANDOVER_TRANSFER_URI";
-
-    /**
-     * Broadcast Action: Notify possible NFC transaction blocked because device is locked.
-     * <p>An external NFC field detected when device locked and SecureNfc enabled.
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
-    public static final String ACTION_REQUIRE_UNLOCK_FOR_NFC =
-            "android.nfc.action.REQUIRE_UNLOCK_FOR_NFC";
-
-    /**
-     * Intent action to start a NFC resolver activity in a customized share session with list of
-     * {@link ResolveInfo}.
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
-    @RequiresPermission(Manifest.permission.SHOW_CUSTOMIZED_RESOLVER)
-    public static final String ACTION_SHOW_NFC_RESOLVER = "android.nfc.action.SHOW_NFC_RESOLVER";
-
-    /**
-     * "Extras" key for an ArrayList of {@link ResolveInfo} records which are to be shown as the
-     * targets in the customized share session.
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
-    public static final String EXTRA_RESOLVE_INFOS = "android.nfc.extra.RESOLVE_INFOS";
-
-    /**
-     * 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 {}
-
-    /**
-     * Mode Type for {@link NfcOemExtension#setControllerAlwaysOnMode(int)}.
-     * @hide
-     */
-    public static final int CONTROLLER_ALWAYS_ON_MODE_DEFAULT = 1;
-
-    /**
-     * Mode Type for {@link NfcOemExtension#setControllerAlwaysOnMode(int)}.
-     * @hide
-     */
-    public static final int CONTROLLER_ALWAYS_ON_DISABLE = 0;
-
-    // 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
-    @UnsupportedAppUsage
-    static INfcAdapter sService;
-    static NfcServiceManager.ServiceRegisterer sServiceRegisterer;
-    static INfcTag sTagService;
-    static INfcCardEmulation sCardEmulationService;
-    static INfcFCardEmulation sNfcFCardEmulationService;
-    static IT4tNdefNfcee sNdefNfceeService;
-
-    /**
-     * The NfcAdapter object for each application context.
-     * There is a 1-1 relationship between application context and
-     * NfcAdapter object.
-     */
-    static HashMap<Context, NfcAdapter> sNfcAdapters = new HashMap(); //guard by NfcAdapter.class
-
-    /**
-     * NfcAdapter used with a null context. This ctor was deprecated but we have
-     * to support it for backwards compatibility. New methods that require context
-     * might throw when called on the null-context NfcAdapter.
-     */
-    static NfcAdapter sNullContextNfcAdapter;  // protected by NfcAdapter.class
-
-    final NfcActivityManager mNfcActivityManager;
-    final Context mContext;
-    final HashMap<NfcUnlockHandler, INfcUnlockHandler> mNfcUnlockHandlers;
-    final Object mLock;
-    final NfcOemExtension mNfcOemExtension;
-
-    ITagRemovedCallback mTagRemovedListener; // protected by mLock
-
-    /**
-     * A callback to be invoked when the system finds a tag while the foreground activity is
-     * operating in reader mode.
-     * <p>Register your {@code ReaderCallback} implementation with {@link
-     * NfcAdapter#enableReaderMode} and disable it with {@link
-     * NfcAdapter#disableReaderMode}.
-     * @see NfcAdapter#enableReaderMode
-     */
-    public interface ReaderCallback {
-        public void onTagDiscovered(Tag tag);
-    }
-
-    /**
-     * A listener to be invoked when NFC controller always on state changes.
-     * <p>Register your {@code ControllerAlwaysOnListener} implementation with {@link
-     * NfcAdapter#registerControllerAlwaysOnListener} and disable it with {@link
-     * NfcAdapter#unregisterControllerAlwaysOnListener}.
-     * @see #registerControllerAlwaysOnListener
-     * @hide
-     */
-    @SystemApi
-    public interface ControllerAlwaysOnListener {
-        /**
-         * Called on NFC controller always on state changes
-         */
-        void onControllerAlwaysOnChanged(boolean isEnabled);
-    }
-
-    /**
-     * A callback to be invoked when the system successfully delivers your {@link NdefMessage}
-     * to another device.
-     * @deprecated this feature is removed. File sharing can work using other technology like
-     * Bluetooth.
-     */
-    @java.lang.Deprecated
-    public interface OnNdefPushCompleteCallback {
-        /**
-         * Called on successful NDEF push.
-         *
-         * <p>This callback is usually made on a binder thread (not the UI thread).
-         *
-         * @param event {@link NfcEvent} with the {@link NfcEvent#nfcAdapter} field set
-         */
-        public void onNdefPushComplete(NfcEvent event);
-    }
-
-    /**
-     * A callback to be invoked when another NFC device capable of NDEF push (Android Beam)
-     * is within range.
-     * <p>Implement this interface and pass it to {@code
-     * NfcAdapter#setNdefPushMessageCallback setNdefPushMessageCallback()} in order to create an
-     * {@link NdefMessage} at the moment that another device is within range for NFC. Using this
-     * callback allows you to create a message with data that might vary based on the
-     * content currently visible to the user. Alternatively, you can call {@code
-     * #setNdefPushMessage setNdefPushMessage()} if the {@link NdefMessage} always contains the
-     * same data.
-     * @deprecated this feature is removed. File sharing can work using other technology like
-     * Bluetooth.
-     */
-    @java.lang.Deprecated
-    public interface CreateNdefMessageCallback {
-        /**
-         * Called to provide a {@link NdefMessage} to push.
-         *
-         * <p>This callback is usually made on a binder thread (not the UI thread).
-         *
-         * <p>Called when this device is in range of another device
-         * that might support NDEF push. It allows the application to
-         * create the NDEF message only when it is required.
-         *
-         * <p>NDEF push cannot occur until this method returns, so do not
-         * block for too long.
-         *
-         * <p>The Android operating system will usually show a system UI
-         * on top of your activity during this time, so do not try to request
-         * input from the user to complete the callback, or provide custom NDEF
-         * push UI. The user probably will not see it.
-         *
-         * @param event {@link NfcEvent} with the {@link NfcEvent#nfcAdapter} field set
-         * @return NDEF message to push, or null to not provide a message
-         */
-        public NdefMessage createNdefMessage(NfcEvent event);
-    }
-
-
-     /**
-     * @deprecated this feature is removed. File sharing can work using other technology like
-     * Bluetooth.
-     */
-    @java.lang.Deprecated
-    public interface CreateBeamUrisCallback {
-        public Uri[] createBeamUris(NfcEvent event);
-    }
-
-    /**
-     * A callback that is invoked when a tag is removed from the field.
-     * @see NfcAdapter#ignore
-     */
-    public interface OnTagRemovedListener {
-        void onTagRemoved();
-    }
-
-    /**
-     * A callback to be invoked when an application has registered as a
-     * handler to unlock the device given an NFC tag at the lockscreen.
-     * @hide
-     */
-    @SystemApi
-    public interface NfcUnlockHandler {
-        /**
-         * Called at the lock screen to attempt to unlock the device with the given tag.
-         * @param tag the detected tag, to be used to unlock the device
-         * @return true if the device was successfully unlocked
-         */
-        public boolean onUnlockAttempted(Tag tag);
-    }
-
-    /**
-     * Return list of Secure Elements which support off host card emulation.
-     *
-     * @return List<String> containing secure elements on the device which supports
-     *                      off host card emulation. eSE for Embedded secure element,
-     *                      SIM for UICC/EUICC and so on.
-     * @hide
-     */
-    public @NonNull List<String> getSupportedOffHostSecureElements() {
-        if (mContext == null) {
-            throw new UnsupportedOperationException("You need a context on NfcAdapter to use the "
-                    + " getSupportedOffHostSecureElements APIs");
-        }
-        List<String> offHostSE = new ArrayList<String>();
-        PackageManager pm = mContext.getPackageManager();
-        if (pm == null) {
-            Log.e(TAG, "Cannot get package manager, assuming no off-host CE feature");
-            return offHostSE;
-        }
-        if (pm.hasSystemFeature(PackageManager.FEATURE_NFC_OFF_HOST_CARD_EMULATION_UICC)) {
-            offHostSE.add("SIM");
-        }
-        if (pm.hasSystemFeature(PackageManager.FEATURE_NFC_OFF_HOST_CARD_EMULATION_ESE)) {
-            offHostSE.add("eSE");
-        }
-        return offHostSE;
-    }
-
-    private static void retrieveServiceRegisterer() {
-        if (sServiceRegisterer == null) {
-            NfcServiceManager manager = NfcFrameworkInitializer.getNfcServiceManager();
-            if (manager == null) {
-                Log.e(TAG, "NfcServiceManager is null");
-                throw new UnsupportedOperationException();
-            }
-            sServiceRegisterer = manager.getNfcManagerServiceRegisterer();
-        }
-    }
-
-    /**
-     * Returns the NfcAdapter for application context,
-     * or throws if NFC is not available.
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public static synchronized NfcAdapter getNfcAdapter(Context context) {
-        if (context == null) {
-            if (sNullContextNfcAdapter == null) {
-                sNullContextNfcAdapter = new NfcAdapter(null);
-            }
-            return sNullContextNfcAdapter;
-        }
-        if (!sIsInitialized) {
-            PackageManager pm;
-            pm = context.getPackageManager();
-            sHasNfcFeature = pm.hasSystemFeature(PackageManager.FEATURE_NFC);
-            sHasCeFeature =
-                    pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION)
-                    || pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION_NFCF)
-                    || pm.hasSystemFeature(PackageManager.FEATURE_NFC_OFF_HOST_CARD_EMULATION_UICC)
-                    || pm.hasSystemFeature(PackageManager.FEATURE_NFC_OFF_HOST_CARD_EMULATION_ESE);
-            sHasNfcWlcFeature = pm.hasSystemFeature(PackageManager.FEATURE_NFC_CHARGING);
-            /* is this device meant to have NFC */
-            if (!sHasNfcFeature && !sHasCeFeature && !sHasNfcWlcFeature) {
-                Log.v(TAG, "this device does not have NFC support");
-                throw new UnsupportedOperationException();
-            }
-            retrieveServiceRegisterer();
-            sService = getServiceInterface();
-            if (sService == null) {
-                Log.e(TAG, "could not retrieve NFC service");
-                throw new UnsupportedOperationException();
-            }
-            if (sHasNfcFeature) {
-                try {
-                    sTagService = sService.getNfcTagInterface();
-                } catch (RemoteException e) {
-                    sTagService = null;
-                    Log.e(TAG, "could not retrieve NFC Tag service");
-                    throw new UnsupportedOperationException();
-                }
-            }
-            if (sHasCeFeature) {
-                try {
-                    sNfcFCardEmulationService = sService.getNfcFCardEmulationInterface();
-                } catch (RemoteException e) {
-                    sNfcFCardEmulationService = null;
-                    Log.e(TAG, "could not retrieve NFC-F card emulation service");
-                    throw new UnsupportedOperationException();
-                }
-                try {
-                    sCardEmulationService = sService.getNfcCardEmulationInterface();
-                } catch (RemoteException e) {
-                    sCardEmulationService = null;
-                    Log.e(TAG, "could not retrieve card emulation service");
-                    throw new UnsupportedOperationException();
-                }
-            }
-            try {
-                sNdefNfceeService = sService.getT4tNdefNfceeInterface();
-            } catch (RemoteException e) {
-                sNdefNfceeService = null;
-                Log.e(TAG, "could not retrieve NDEF NFCEE service");
-                throw new UnsupportedOperationException();
-            }
-            sIsInitialized = true;
-        }
-        NfcAdapter adapter = sNfcAdapters.get(context);
-        if (adapter == null) {
-            adapter = new NfcAdapter(context);
-            sNfcAdapters.put(context, adapter);
-        }
-        return adapter;
-    }
-
-    /** get handle to NFC service interface */
-    private static INfcAdapter getServiceInterface() {
-        /* get a handle to NFC service */
-        IBinder b = sServiceRegisterer.get();
-        if (b == null) {
-            return null;
-        }
-        return INfcAdapter.Stub.asInterface(b);
-    }
-
-    /**
-     * Helper to get the default NFC Adapter.
-     * <p>
-     * Most Android devices will only have one NFC Adapter (NFC Controller).
-     * <p>
-     * This helper is the equivalent of:
-     * <pre>
-     * NfcManager manager = (NfcManager) context.getSystemService(Context.NFC_SERVICE);
-     * NfcAdapter adapter = manager.getDefaultAdapter();</pre>
-     * @param context the calling application's context
-     *
-     * @return the default NFC adapter, or null if no NFC adapter exists
-     */
-    public static NfcAdapter getDefaultAdapter(Context context) {
-        if (context == null) {
-            throw new IllegalArgumentException("context cannot be null");
-        }
-        context = context.getApplicationContext();
-        if (context == null) {
-            throw new IllegalArgumentException(
-                    "context not associated with any application (using a mock context?)");
-        }
-        retrieveServiceRegisterer();
-        if (sServiceRegisterer.tryGet() == null) {
-            if (sIsInitialized) {
-                synchronized (NfcAdapter.class) {
-                    /* Stale sService pointer */
-                    if (sIsInitialized) sIsInitialized = false;
-                }
-            }
-            return null;
-        }
-        /* Try to initialize the service */
-        NfcManager manager = (NfcManager) context.getSystemService(Context.NFC_SERVICE);
-        if (manager == null) {
-            // NFC not available
-            return null;
-        }
-        return manager.getDefaultAdapter();
-    }
-
-    /**
-     * Legacy NfcAdapter getter, always use {@link #getDefaultAdapter(Context)} instead.<p>
-     * This method was deprecated at API level 10 (Gingerbread MR1) because a context is required
-     * for many NFC API methods. Those methods will fail when called on an NfcAdapter
-     * object created from this method.<p>
-     * @deprecated use {@link #getDefaultAdapter(Context)}
-     * @hide
-     */
-    @Deprecated
-    @UnsupportedAppUsage
-    public static NfcAdapter getDefaultAdapter() {
-        // introduced in API version 9 (GB 2.3)
-        // deprecated in API version 10 (GB 2.3.3)
-        // removed from public API in version 16 (ICS MR2)
-        // should maintain as a hidden API for binary compatibility for a little longer
-        Log.w(TAG, "WARNING: NfcAdapter.getDefaultAdapter() is deprecated, use " +
-                "NfcAdapter.getDefaultAdapter(Context) instead", new Exception());
-
-        return NfcAdapter.getNfcAdapter(null);
-    }
-
-    NfcAdapter(Context context) {
-        mContext = context;
-        mNfcActivityManager = new NfcActivityManager(this);
-        mNfcUnlockHandlers = new HashMap<NfcUnlockHandler, INfcUnlockHandler>();
-        mTagRemovedListener = null;
-        mLock = new Object();
-        mControllerAlwaysOnListener = new NfcControllerAlwaysOnListener(getService());
-        mNfcWlcStateListener = new NfcWlcStateListener(getService());
-        mNfcVendorNciCallbackListener = new NfcVendorNciCallbackListener(getService());
-        mNfcOemExtension = new NfcOemExtension(mContext, this);
-    }
-
-    /**
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public Context getContext() {
-        return mContext;
-    }
-
-    /**
-     * Returns the binder interface to the service.
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public static INfcAdapter getService() {
-        isEnabledStatic();  // NOP call to recover sService if it is stale
-        return sService;
-    }
-
-    /**
-     * Returns the binder interface to the tag service.
-     * @hide
-     */
-    public static INfcTag getTagService() {
-        isEnabledStatic();  // NOP call to recover sTagService if it is stale
-        return sTagService;
-    }
-
-    /**
-     * Returns the binder interface to the card emulation service.
-     * @hide
-     */
-    public static INfcCardEmulation getCardEmulationService() {
-        isEnabledStatic();
-        return sCardEmulationService;
-    }
-
-    /**
-     * Returns the binder interface to the NFC-F card emulation service.
-     * @hide
-     */
-    public static INfcFCardEmulation getNfcFCardEmulationService() {
-        isEnabledStatic();
-        return sNfcFCardEmulationService;
-    }
-
-    /**
-     * Returns the binder interface to the NFC-DTA test interface.
-     * @hide
-     */
-    public INfcDta getNfcDtaInterface() {
-        if (mContext == null) {
-            throw new UnsupportedOperationException("You need a context on NfcAdapter to use the "
-                    + " NFC extras APIs");
-        }
-        return callServiceReturn(() ->  sService.getNfcDtaInterface(mContext.getPackageName()),
-                null);
-
-    }
-
-    /**
-     * NFC service dead - attempt best effort recovery
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public static void attemptDeadServiceRecovery(RemoteException e) {
-        Log.e(TAG, "NFC service dead - attempting to recover", e);
-        INfcAdapter service = getServiceInterface();
-        if (service == null) {
-            Log.e(TAG, "could not retrieve NFC service during service recovery");
-            // nothing more can be done now, sService is still stale, we'll hit
-            // this recovery path again later
-            e.rethrowAsRuntimeException();
-        }
-        // assigning to sService is not thread-safe, but this is best-effort code
-        // and on a well-behaved system should never happen
-        sService = service;
-        if (sHasNfcFeature) {
-            try {
-                sTagService = service.getNfcTagInterface();
-            } catch (RemoteException ee) {
-                sTagService = null;
-                Log.e(TAG, "could not retrieve NFC tag service during service recovery");
-                // nothing more can be done now, sService is still stale, we'll hit
-                // this recovery path again later
-                ee.rethrowAsRuntimeException();
-            }
-        }
-
-        if (sHasCeFeature) {
-            try {
-                sCardEmulationService = service.getNfcCardEmulationInterface();
-            } catch (RemoteException ee) {
-                sCardEmulationService = null;
-                Log.e(TAG,
-                        "could not retrieve NFC card emulation service during service recovery");
-            }
-
-            try {
-                sNfcFCardEmulationService = service.getNfcFCardEmulationInterface();
-            } catch (RemoteException ee) {
-                sNfcFCardEmulationService = null;
-                Log.e(TAG,
-                        "could not retrieve NFC-F card emulation service during service recovery");
-            }
-        }
-    }
-
-    private static boolean isCardEmulationEnabled() {
-        if (sHasCeFeature) {
-            return (sCardEmulationService != null || sNfcFCardEmulationService != null);
-        }
-        return false;
-    }
-
-    private static boolean isTagReadingEnabled() {
-        if (sHasNfcFeature) {
-            return sTagService != null;
-        }
-        return false;
-    }
-
-    private static boolean isEnabledStatic() {
-        boolean serviceState = callServiceReturn(() -> sService.getState() == STATE_ON, false);
-        return serviceState
-                && (isTagReadingEnabled() || isCardEmulationEnabled() || sHasNfcWlcFeature);
-    }
-
-    /**
-     * Return true if this NFC Adapter has any features enabled.
-     *
-     * <p>If this method returns false, the NFC hardware is guaranteed not to
-     * generate or respond to any NFC communication over its NFC radio.
-     * <p>Applications can use this to check if NFC is enabled. Applications
-     * can request Settings UI allowing the user to toggle NFC using:
-     * <p><pre>startActivity(new Intent(Settings.ACTION_NFC_SETTINGS))</pre>
-     *
-     * @see android.provider.Settings#ACTION_NFC_SETTINGS
-     * @return true if this NFC Adapter has any features enabled
-     */
-    public boolean isEnabled() {
-        return isEnabledStatic();
-    }
-
-    /**
-     * Return the state of this NFC Adapter.
-     *
-     * <p>Returns one of {@link #STATE_ON}, {@link #STATE_TURNING_ON},
-     * {@link #STATE_OFF}, {@link #STATE_TURNING_OFF}.
-     *
-     * <p>{@link #isEnabled()} is equivalent to
-     * <code>{@link #getAdapterState()} == {@link #STATE_ON}</code>
-     *
-     * @return the current state of this NFC adapter
-     *
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
-    public @AdapterState int getAdapterState() {
-        return callServiceReturn(() ->  sService.getState(), NfcAdapter.STATE_OFF);
-
-    }
-
-    /**
-     * Enable NFC hardware.
-     *
-     * <p>This call is asynchronous. Listen for
-     * {@link #ACTION_ADAPTER_STATE_CHANGED} broadcasts to find out when the
-     * operation is complete.
-     *
-     * <p>This API is only allowed to be called by system apps
-     * or apps which are Device Owner or Profile Owner.
-     *
-     * <p>If this returns true, then either NFC is already on, or
-     * a {@link #ACTION_ADAPTER_STATE_CHANGED} broadcast will be sent
-     * to indicate a state transition. If this returns false, then
-     * there is some problem that prevents an attempt to turn
-     * NFC on (for example we are in airplane mode and NFC is not
-     * toggleable in airplane mode on this platform).
-     *
-     */
-    @FlaggedApi(Flags.FLAG_NFC_STATE_CHANGE)
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public boolean enable() {
-        return callServiceReturn(() ->  sService.enable(mContext.getPackageName()), false);
-
-    }
-
-    /**
-     * Disable NFC hardware.
-     *
-     * <p>No NFC features will work after this call, and the hardware
-     * will not perform or respond to any NFC communication.
-     *
-     * <p>This call is asynchronous. Listen for
-     * {@link #ACTION_ADAPTER_STATE_CHANGED} broadcasts to find out when the
-     * operation is complete.
-     *
-     * <p>This API is only allowed to be called by system apps
-     * or apps which are Device Owner or Profile Owner.
-     *
-     * <p>If this returns true, then either NFC is already off, or
-     * a {@link #ACTION_ADAPTER_STATE_CHANGED} broadcast will be sent
-     * to indicate a state transition. If this returns false, then
-     * there is some problem that prevents an attempt to turn
-     * NFC off.
-     *
-     */
-    @FlaggedApi(Flags.FLAG_NFC_STATE_CHANGE)
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public boolean disable() {
-        return callServiceReturn(() ->  sService.disable(true, mContext.getPackageName()),
-                false);
-
-    }
-
-    /**
-     * Disable NFC hardware.
-     * @hide
-    */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public boolean disable(boolean persist) {
-        return callServiceReturn(() ->  sService.disable(persist, mContext.getPackageName()),
-                false);
-
-    }
-
-    /**
-     * Pauses NFC tag reader mode polling for a {@code timeoutInMs} millisecond.
-     * In case of {@code timeoutInMs} is zero or invalid polling will be stopped indefinitely
-     * use {@link #resumePolling() to resume the polling.
-     * @hide
-     */
-    public void pausePolling(int timeoutInMs) {
-        callService(() -> sService.pausePolling(timeoutInMs));
-    }
-
-
-    /**
-     * Returns whether the device supports observe mode or not. When observe mode is enabled, the
-     * NFC hardware will listen to NFC readers, but not respond to them. While enabled, observed
-     * polling frames will be sent to the APDU service (see {@link #setObserveModeEnabled(boolean)}.
-     * When observe mode is disabled (or if it's not supported), the NFC hardware will automatically
-     * respond to the reader and proceed with the transaction.
-     * @return true if the mode is supported, false otherwise.
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OBSERVE_MODE)
-    public boolean isObserveModeSupported() {
-        return callServiceReturn(() ->  sService.isObserveModeSupported(), false);
-    }
-
-    /**
-     * Returns whether Observe Mode is currently enabled or not.
-     *
-     * @return true if observe mode is enabled, false otherwise.
-     */
-
-    @FlaggedApi(Flags.FLAG_NFC_OBSERVE_MODE)
-    public boolean isObserveModeEnabled() {
-        return callServiceReturn(() ->  sService.isObserveModeEnabled(), false);
-    }
-
-    /**
-     * Controls whether the NFC adapter will allow transactions to proceed or be in observe mode
-     * and simply observe and notify the APDU service of polling loop frames. See
-     * {@link #isObserveModeSupported()} for a description of observe mode. Only the package of the
-     * currently preferred service (the service set as preferred by the current foreground
-     * application via {@link android.nfc.cardemulation.CardEmulation#setPreferredService(Activity,
-     * android.content.ComponentName)} or the current Default Wallet Role Holder
-     * {@link android.app.role.RoleManager#ROLE_WALLET}), otherwise a call to this method will fail
-     * and return false.
-     *
-     * @param enabled false disables observe mode to allow the transaction to proceed while true
-     *                enables observe mode and does not allow transactions to proceed.
-     *
-     * @return boolean indicating success or failure.
-     */
-
-    @FlaggedApi(Flags.FLAG_NFC_OBSERVE_MODE)
-    public boolean setObserveModeEnabled(boolean enabled) {
-        if (mContext == null) {
-            throw new UnsupportedOperationException("You need a context on NfcAdapter to use the "
-                    + " observe mode APIs");
-        }
-        return callServiceReturn(() ->  sService.setObserveMode(enabled, mContext.getPackageName()),
-                false);
-    }
-
-    /**
-     * Resumes default NFC tag reader mode polling for the current device state if polling is
-     * paused. Calling this while already in polling is a no-op.
-     * @hide
-     */
-    public void resumePolling() {
-        callService(() -> sService.resumePolling());
-    }
-
-    /**
-     * Set one or more {@link Uri}s to send using Android Beam (TM). Every
-     * Uri you provide must have either scheme 'file' or scheme 'content'.
-     *
-     * <p>For the data provided through this method, Android Beam tries to
-     * switch to alternate transports such as Bluetooth to achieve a fast
-     * transfer speed. Hence this method is very suitable
-     * for transferring large files such as pictures or songs.
-     *
-     * <p>The receiving side will store the content of each Uri in
-     * a file and present a notification to the user to open the file
-     * with a {@link android.content.Intent} with action
-     * {@link android.content.Intent#ACTION_VIEW}.
-     * If multiple URIs are sent, the {@link android.content.Intent} will refer
-     * to the first of the stored files.
-     *
-     * <p>This method may be called at any time before {@link Activity#onDestroy},
-     * but the URI(s) are only made available for Android Beam when the
-     * specified activity(s) are in resumed (foreground) state. The recommended
-     * approach is to call this method during your Activity's
-     * {@link Activity#onCreate} - see sample
-     * code below. This method does not immediately perform any I/O or blocking work,
-     * so is safe to call on your main thread.
-     *
-     * <p>{@link #setBeamPushUris} and {@link #setBeamPushUrisCallback}
-     * have priority over both {@link #setNdefPushMessage} and
-     * {@link #setNdefPushMessageCallback}.
-     *
-     * <p>If {@link #setBeamPushUris} is called with a null Uri array,
-     * and/or {@link #setBeamPushUrisCallback} is called with a null callback,
-     * then the Uri push will be completely disabled for the specified activity(s).
-     *
-     * <p>Code example:
-     * <pre>
-     * protected void onCreate(Bundle savedInstanceState) {
-     *     super.onCreate(savedInstanceState);
-     *     NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
-     *     if (nfcAdapter == null) return;  // NFC not available on this device
-     *     nfcAdapter.setBeamPushUris(new Uri[] {uri1, uri2}, this);
-     * }</pre>
-     * And that is it. Only one call per activity is necessary. The Android
-     * OS will automatically release its references to the Uri(s) and the
-     * Activity object when it is destroyed if you follow this pattern.
-     *
-     * <p>If your Activity wants to dynamically supply Uri(s),
-     * then set a callback using {@link #setBeamPushUrisCallback} instead
-     * of using this method.
-     *
-     * <p class="note">Do not pass in an Activity that has already been through
-     * {@link Activity#onDestroy}. This is guaranteed if you call this API
-     * during {@link Activity#onCreate}.
-     *
-     * <p class="note">If this device does not support alternate transports
-     * such as Bluetooth or WiFI, calling this method does nothing.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param uris an array of Uri(s) to push over Android Beam
-     * @param activity activity for which the Uri(s) will be pushed
-     * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
-     * @removed this feature is removed. File sharing can work using other technology like
-     * Bluetooth.
-     */
-    @java.lang.Deprecated
-    @UnsupportedAppUsage
-    public void setBeamPushUris(Uri[] uris, Activity activity) {
-        synchronized (sLock) {
-            if (!sHasNfcFeature) {
-                throw new UnsupportedOperationException();
-            }
-        }
-    }
-
-    /**
-     * Set a callback that will dynamically generate one or more {@link Uri}s
-     * to send using Android Beam (TM). Every Uri the callback provides
-     * must have either scheme 'file' or scheme 'content'.
-     *
-     * <p>For the data provided through this callback, Android Beam tries to
-     * switch to alternate transports such as Bluetooth to achieve a fast
-     * transfer speed. Hence this method is very suitable
-     * for transferring large files such as pictures or songs.
-     *
-     * <p>The receiving side will store the content of each Uri in
-     * a file and present a notification to the user to open the file
-     * with a {@link android.content.Intent} with action
-     * {@link android.content.Intent#ACTION_VIEW}.
-     * If multiple URIs are sent, the {@link android.content.Intent} will refer
-     * to the first of the stored files.
-     *
-     * <p>This method may be called at any time before {@link Activity#onDestroy},
-     * but the URI(s) are only made available for Android Beam when the
-     * specified activity(s) are in resumed (foreground) state. The recommended
-     * approach is to call this method during your Activity's
-     * {@link Activity#onCreate} - see sample
-     * code below. This method does not immediately perform any I/O or blocking work,
-     * so is safe to call on your main thread.
-     *
-     * <p>{@link #setBeamPushUris} and {@link #setBeamPushUrisCallback}
-     * have priority over both {@link #setNdefPushMessage} and
-     * {@link #setNdefPushMessageCallback}.
-     *
-     * <p>If {@link #setBeamPushUris} is called with a null Uri array,
-     * and/or {@link #setBeamPushUrisCallback} is called with a null callback,
-     * then the Uri push will be completely disabled for the specified activity(s).
-     *
-     * <p>Code example:
-     * <pre>
-     * protected void onCreate(Bundle savedInstanceState) {
-     *     super.onCreate(savedInstanceState);
-     *     NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
-     *     if (nfcAdapter == null) return;  // NFC not available on this device
-     *     nfcAdapter.setBeamPushUrisCallback(callback, this);
-     * }</pre>
-     * And that is it. Only one call per activity is necessary. The Android
-     * OS will automatically release its references to the Uri(s) and the
-     * Activity object when it is destroyed if you follow this pattern.
-     *
-     * <p class="note">Do not pass in an Activity that has already been through
-     * {@link Activity#onDestroy}. This is guaranteed if you call this API
-     * during {@link Activity#onCreate}.
-     *
-     * <p class="note">If this device does not support alternate transports
-     * such as Bluetooth or WiFI, calling this method does nothing.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param callback callback, or null to disable
-     * @param activity activity for which the Uri(s) will be pushed
-     * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
-     * @removed this feature is removed. File sharing can work using other technology like
-     * Bluetooth.
-     */
-    @java.lang.Deprecated
-    @UnsupportedAppUsage
-    public void setBeamPushUrisCallback(CreateBeamUrisCallback callback, Activity activity) {
-        synchronized (sLock) {
-            if (!sHasNfcFeature) {
-                throw new UnsupportedOperationException();
-            }
-        }
-    }
-
-    /**
-     * Set a static {@link NdefMessage} to send using Android Beam (TM).
-     *
-     * <p>This method may be called at any time before {@link Activity#onDestroy},
-     * but the NDEF message is only made available for NDEF push when the
-     * specified activity(s) are in resumed (foreground) state. The recommended
-     * approach is to call this method during your Activity's
-     * {@link Activity#onCreate} - see sample
-     * code below. This method does not immediately perform any I/O or blocking work,
-     * so is safe to call on your main thread.
-     *
-     * <p>Only one NDEF message can be pushed by the currently resumed activity.
-     * If both {@link #setNdefPushMessage} and
-     * {@link #setNdefPushMessageCallback} are set, then
-     * the callback will take priority.
-     *
-     * <p>If neither {@link #setNdefPushMessage} or
-     * {@link #setNdefPushMessageCallback} have been called for your activity, then
-     * the Android OS may choose to send a default NDEF message on your behalf,
-     * such as a URI for your application.
-     *
-     * <p>If {@link #setNdefPushMessage} is called with a null NDEF message,
-     * and/or {@link #setNdefPushMessageCallback} is called with a null callback,
-     * then NDEF push will be completely disabled for the specified activity(s).
-     * This also disables any default NDEF message the Android OS would have
-     * otherwise sent on your behalf for those activity(s).
-     *
-     * <p>If you want to prevent the Android OS from sending default NDEF
-     * messages completely (for all activities), you can include a
-     * {@code <meta-data>} element inside the {@code <application>}
-     * element of your AndroidManifest.xml file, like this:
-     * <pre>
-     * &lt;application ...>
-     *     &lt;meta-data android:name="android.nfc.disable_beam_default"
-     *         android:value="true" />
-     * &lt;/application></pre>
-     *
-     * <p>The API allows for multiple activities to be specified at a time,
-     * but it is strongly recommended to just register one at a time,
-     * and to do so during the activity's {@link Activity#onCreate}. For example:
-     * <pre>
-     * protected void onCreate(Bundle savedInstanceState) {
-     *     super.onCreate(savedInstanceState);
-     *     NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
-     *     if (nfcAdapter == null) return;  // NFC not available on this device
-     *     nfcAdapter.setNdefPushMessage(ndefMessage, this);
-     * }</pre>
-     * And that is it. Only one call per activity is necessary. The Android
-     * OS will automatically release its references to the NDEF message and the
-     * Activity object when it is destroyed if you follow this pattern.
-     *
-     * <p>If your Activity wants to dynamically generate an NDEF message,
-     * then set a callback using {@link #setNdefPushMessageCallback} instead
-     * of a static message.
-     *
-     * <p class="note">Do not pass in an Activity that has already been through
-     * {@link Activity#onDestroy}. This is guaranteed if you call this API
-     * during {@link Activity#onCreate}.
-     *
-     * <p class="note">For sending large content such as pictures and songs,
-     * consider using {@link #setBeamPushUris}, which switches to alternate transports
-     * such as Bluetooth to achieve a fast transfer rate.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param message NDEF message to push over NFC, or null to disable
-     * @param activity activity for which the NDEF message will be pushed
-     * @param activities optional additional activities, however we strongly recommend
-     *        to only register one at a time, and to do so in that activity's
-     *        {@link Activity#onCreate}
-     * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
-     * @removed this feature is removed. File sharing can work using other technology like
-     * Bluetooth.
-     */
-    @java.lang.Deprecated
-    @UnsupportedAppUsage
-    public void setNdefPushMessage(NdefMessage message, Activity activity,
-            Activity ... activities) {
-        synchronized (sLock) {
-            if (!sHasNfcFeature) {
-                throw new UnsupportedOperationException();
-            }
-        }
-    }
-
-    /**
-     * @hide
-     * @removed
-     */
-    @SystemApi
-    @UnsupportedAppUsage
-    public void setNdefPushMessage(NdefMessage message, Activity activity, int flags) {
-        synchronized (sLock) {
-            if (!sHasNfcFeature) {
-                throw new UnsupportedOperationException();
-            }
-        }
-    }
-
-    /**
-     * Set a callback that dynamically generates NDEF messages to send using Android Beam (TM).
-     *
-     * <p>This method may be called at any time before {@link Activity#onDestroy},
-     * but the NDEF message callback can only occur when the
-     * specified activity(s) are in resumed (foreground) state. The recommended
-     * approach is to call this method during your Activity's
-     * {@link Activity#onCreate} - see sample
-     * code below. This method does not immediately perform any I/O or blocking work,
-     * so is safe to call on your main thread.
-     *
-     * <p>Only one NDEF message can be pushed by the currently resumed activity.
-     * If both {@link #setNdefPushMessage} and
-     * {@link #setNdefPushMessageCallback} are set, then
-     * the callback will take priority.
-     *
-     * <p>If neither {@link #setNdefPushMessage} or
-     * {@link #setNdefPushMessageCallback} have been called for your activity, then
-     * the Android OS may choose to send a default NDEF message on your behalf,
-     * such as a URI for your application.
-     *
-     * <p>If {@link #setNdefPushMessage} is called with a null NDEF message,
-     * and/or {@link #setNdefPushMessageCallback} is called with a null callback,
-     * then NDEF push will be completely disabled for the specified activity(s).
-     * This also disables any default NDEF message the Android OS would have
-     * otherwise sent on your behalf for those activity(s).
-     *
-     * <p>If you want to prevent the Android OS from sending default NDEF
-     * messages completely (for all activities), you can include a
-     * {@code <meta-data>} element inside the {@code <application>}
-     * element of your AndroidManifest.xml file, like this:
-     * <pre>
-     * &lt;application ...>
-     *     &lt;meta-data android:name="android.nfc.disable_beam_default"
-     *         android:value="true" />
-     * &lt;/application></pre>
-     *
-     * <p>The API allows for multiple activities to be specified at a time,
-     * but it is strongly recommended to just register one at a time,
-     * and to do so during the activity's {@link Activity#onCreate}. For example:
-     * <pre>
-     * protected void onCreate(Bundle savedInstanceState) {
-     *     super.onCreate(savedInstanceState);
-     *     NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
-     *     if (nfcAdapter == null) return;  // NFC not available on this device
-     *     nfcAdapter.setNdefPushMessageCallback(callback, this);
-     * }</pre>
-     * And that is it. Only one call per activity is necessary. The Android
-     * OS will automatically release its references to the callback and the
-     * Activity object when it is destroyed if you follow this pattern.
-     *
-     * <p class="note">Do not pass in an Activity that has already been through
-     * {@link Activity#onDestroy}. This is guaranteed if you call this API
-     * during {@link Activity#onCreate}.
-     * <p class="note">For sending large content such as pictures and songs,
-     * consider using {@link #setBeamPushUris}, which switches to alternate transports
-     * such as Bluetooth to achieve a fast transfer rate.
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param callback callback, or null to disable
-     * @param activity activity for which the NDEF message will be pushed
-     * @param activities optional additional activities, however we strongly recommend
-     *        to only register one at a time, and to do so in that activity's
-     *        {@link Activity#onCreate}
-     * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
-     * @removed this feature is removed. File sharing can work using other technology like
-     * Bluetooth.
-     */
-    @java.lang.Deprecated
-    @UnsupportedAppUsage
-    public void setNdefPushMessageCallback(CreateNdefMessageCallback callback, Activity activity,
-            Activity ... activities) {
-        synchronized (sLock) {
-            if (!sHasNfcFeature) {
-                throw new UnsupportedOperationException();
-            }
-        }
-    }
-
-    /**
-     * Set a callback on successful Android Beam (TM).
-     *
-     * <p>This method may be called at any time before {@link Activity#onDestroy},
-     * but the callback can only occur when the
-     * specified activity(s) are in resumed (foreground) state. The recommended
-     * approach is to call this method during your Activity's
-     * {@link Activity#onCreate} - see sample
-     * code below. This method does not immediately perform any I/O or blocking work,
-     * so is safe to call on your main thread.
-     *
-     * <p>The API allows for multiple activities to be specified at a time,
-     * but it is strongly recommended to just register one at a time,
-     * and to do so during the activity's {@link Activity#onCreate}. For example:
-     * <pre>
-     * protected void onCreate(Bundle savedInstanceState) {
-     *     super.onCreate(savedInstanceState);
-     *     NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
-     *     if (nfcAdapter == null) return;  // NFC not available on this device
-     *     nfcAdapter.setOnNdefPushCompleteCallback(callback, this);
-     * }</pre>
-     * And that is it. Only one call per activity is necessary. The Android
-     * OS will automatically release its references to the callback and the
-     * Activity object when it is destroyed if you follow this pattern.
-     *
-     * <p class="note">Do not pass in an Activity that has already been through
-     * {@link Activity#onDestroy}. This is guaranteed if you call this API
-     * during {@link Activity#onCreate}.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param callback callback, or null to disable
-     * @param activity activity for which the NDEF message will be pushed
-     * @param activities optional additional activities, however we strongly recommend
-     *        to only register one at a time, and to do so in that activity's
-     *        {@link Activity#onCreate}
-     * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
-     * @removed this feature is removed. File sharing can work using other technology like
-     * Bluetooth.
-     */
-    @java.lang.Deprecated
-    @UnsupportedAppUsage
-    public void setOnNdefPushCompleteCallback(OnNdefPushCompleteCallback callback,
-            Activity activity, Activity ... activities) {
-        synchronized (sLock) {
-            if (!sHasNfcFeature) {
-                throw new UnsupportedOperationException();
-            }
-        }
-    }
-
-    /**
-     * Enable foreground dispatch to the given Activity.
-     *
-     * <p>This will give priority to the foreground activity when
-     * dispatching a discovered {@link Tag} to an application.
-     *
-     * <p>If any IntentFilters are provided to this method they are used to match dispatch Intents
-     * for both the {@link NfcAdapter#ACTION_NDEF_DISCOVERED} and
-     * {@link NfcAdapter#ACTION_TAG_DISCOVERED}. Since {@link NfcAdapter#ACTION_TECH_DISCOVERED}
-     * relies on meta data outside of the IntentFilter matching for that dispatch Intent is handled
-     * by passing in the tech lists separately. Each first level entry in the tech list represents
-     * an array of technologies that must all be present to match. If any of the first level sets
-     * match then the dispatch is routed through the given PendingIntent. In other words, the second
-     * level is ANDed together and the first level entries are ORed together.
-     *
-     * <p>If you pass {@code null} for both the {@code filters} and {@code techLists} parameters
-     * that acts a wild card and will cause the foreground activity to receive all tags via the
-     * {@link NfcAdapter#ACTION_TAG_DISCOVERED} intent.
-     *
-     * <p>This method must be called from the main thread, and only when the activity is in the
-     * foreground (resumed). Also, activities must call {@link #disableForegroundDispatch} before
-     * the completion of their {@link Activity#onPause} callback to disable foreground dispatch
-     * after it has been enabled.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param activity the Activity to dispatch to
-     * @param intent the PendingIntent to start for the dispatch
-     * @param filters the IntentFilters to override dispatching for, or null to always dispatch
-     * @param techLists the tech lists used to perform matching for dispatching of the
-     *      {@link NfcAdapter#ACTION_TECH_DISCOVERED} intent
-     * @throws IllegalStateException if the Activity is not currently in the foreground
-     * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
-     */
-    public void enableForegroundDispatch(Activity activity, PendingIntent intent,
-            IntentFilter[] filters, String[][] techLists) {
-        synchronized (sLock) {
-            if (!sHasNfcFeature) {
-                throw new UnsupportedOperationException();
-            }
-        }
-        if (activity == null || intent == null) {
-            throw new NullPointerException();
-        }
-        final TechListParcel parcel = (techLists != null && techLists.length > 0)
-            ? new TechListParcel(techLists)
-            : null;
-        callService(() -> sService.setForegroundDispatch(intent, filters, parcel));
-    }
-
-    /**
-     * Disable foreground dispatch to the given activity.
-     *
-     * <p>After calling {@link #enableForegroundDispatch}, an activity
-     * must call this method before its {@link Activity#onPause} callback
-     * completes.
-     *
-     * <p>This method must be called from the main thread.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param activity the Activity to disable dispatch to
-     * @throws IllegalStateException if the Activity has already been paused
-     * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
-     */
-    public void disableForegroundDispatch(Activity activity) {
-        synchronized (sLock) {
-            if (!sHasNfcFeature) {
-                throw new UnsupportedOperationException();
-            }
-        }
-        callService(() -> sService.setForegroundDispatch(null, null, null));
-    }
-
-    /**
-     * Limit the NFC controller to reader mode while this Activity is in the foreground.
-     *
-     * <p>In this mode the NFC controller will only act as an NFC tag reader/writer,
-     * thus disabling any peer-to-peer (Android Beam) and card-emulation modes of
-     * the NFC adapter on this device.
-     *
-     * <p>Use {@link #FLAG_READER_SKIP_NDEF_CHECK} to prevent the platform from
-     * performing any NDEF checks in reader mode. Note that this will prevent the
-     * {@link Ndef} tag technology from being enumerated on the tag, and that
-     * NDEF-based tag dispatch will not be functional.
-     *
-     * <p>For interacting with tags that are emulated on another Android device
-     * using Android's host-based card-emulation, the recommended flags are
-     * {@link #FLAG_READER_NFC_A} and {@link #FLAG_READER_SKIP_NDEF_CHECK}.
-     *
-     * @param activity the Activity that requests the adapter to be in reader mode
-     * @param callback the callback to be called when a tag is discovered
-     * @param flags Flags indicating poll technologies and other optional parameters
-     * @param extras Additional extras for configuring reader mode.
-     * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
-     */
-    public void enableReaderMode(Activity activity, ReaderCallback callback, int flags,
-            Bundle extras) {
-        synchronized (sLock) {
-            if (!sHasNfcFeature) {
-                throw new UnsupportedOperationException();
-            }
-        }
-        mNfcActivityManager.enableReaderMode(activity, callback, flags, extras);
-    }
-
-    /**
-     * Restore the NFC adapter to normal mode of operation: supporting
-     * peer-to-peer (Android Beam), card emulation, and polling for
-     * all supported tag technologies.
-     *
-     * @param activity the Activity that currently has reader mode enabled
-     * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
-     */
-    public void disableReaderMode(Activity activity) {
-        synchronized (sLock) {
-            if (!sHasNfcFeature) {
-                throw new UnsupportedOperationException();
-            }
-        }
-        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 or disable reader polling.
-     * Unlike {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}, this API does not
-     * need a foreground activity to control reader mode parameters
-     * 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 setReaderModePollingEnabled(boolean enable) {
-        synchronized (sLock) {
-            if (!sHasNfcFeature) {
-                throw new UnsupportedOperationException();
-            }
-        }
-        Binder token = new Binder();
-        int flags = enable ? ENABLE_POLLING_FLAGS : DISABLE_POLLING_FLAGS;
-        callService(() -> sService.setReaderMode(
-                token, null, flags, null, mContext.getPackageName()));
-    }
-
-    /**
-     * 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.
-     * (if the _KEEP flag is specified the other technology flags shouldn't be set
-     * and are quietly ignored otherwise).
-     * 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 pollTechnology, listenTechnology 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 pollTechnology Flags indicating poll technologies.
-     * @param listenTechnology Flags indicating listen technologies.
-     * @throws UnsupportedOperationException if FEATURE_NFC,
-     * FEATURE_NFC_HOST_CARD_EMULATION, FEATURE_NFC_HOST_CARD_EMULATION_NFCF are unavailable.
-     *
-     * NOTE: This API overrides all technology flags regardless of the current device state,
-     *       it is incompatible with enableReaderMode() API and the others that either update
-     *       or assume any techlology flag set by the OS.
-     *       Please use with care.
-     */
-
-    @FlaggedApi(Flags.FLAG_ENABLE_NFC_SET_DISCOVERY_TECH)
-    public void setDiscoveryTechnology(@NonNull Activity activity,
-            @PollTechnology int pollTechnology, @ListenTechnology int listenTechnology) {
-
-        if (listenTechnology == FLAG_LISTEN_DISABLE) {
-            synchronized (sLock) {
-                if (!sHasNfcFeature) {
-                    throw new UnsupportedOperationException();
-                }
-            }
-        } else if (pollTechnology == FLAG_READER_DISABLE) {
-            synchronized (sLock) {
-                if (!sHasCeFeature) {
-                    throw new UnsupportedOperationException();
-                }
-            }
-        } else {
-            synchronized (sLock) {
-                if (!sHasNfcFeature || !sHasCeFeature) {
-                    throw new UnsupportedOperationException();
-                }
-            }
-        }
-    /*
-     * Privileged FLAG to set technology mask for all data processed by NFC controller
-     * Note: Use with caution! The app is responsible for ensuring that the discovery
-     * technology mask is returned to default.
-     * Note: FLAG_USE_ALL_TECH used with _KEEP flags will reset the technolody to android default
-     */
-        if (Flags.nfcSetDefaultDiscTech()
-                && ((pollTechnology & FLAG_SET_DEFAULT_TECH) == FLAG_SET_DEFAULT_TECH
-                || (listenTechnology & FLAG_SET_DEFAULT_TECH) == FLAG_SET_DEFAULT_TECH)) {
-            Binder token = new Binder();
-            callService( () ->
-                    sService.updateDiscoveryTechnology(
-                            token, pollTechnology, listenTechnology, mContext.getPackageName()));
-        } else {
-            mNfcActivityManager.setDiscoveryTech(activity, pollTechnology, listenTechnology);
-        }
-    }
-
-    /**
-     * Restore the poll/listen technologies of NFC controller to its default state,
-     * which were changed by {@link #setDiscoveryTechnology(Activity , int , int)}
-     *
-     * @param activity The Activity that requested to change 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.
-     *
-     * <p>The Android Beam animation is normally only shown when two NFC-capable
-     * devices come into range.
-     * By calling this method, an Activity can invoke the Beam animation directly
-     * even if no other NFC device is in range yet. The Beam animation will then
-     * prompt the user to tap another NFC-capable device to complete the data
-     * transfer.
-     *
-     * <p>The main advantage of using this method is that it avoids the need for the
-     * user to tap the screen to complete the transfer, as this method already
-     * establishes the direction of the transfer and the consent of the user to
-     * share data. Callers are responsible for making sure that the user has
-     * consented to sharing data on NFC tap.
-     *
-     * <p>Note that to use this method, the passed in Activity must have already
-     * set data to share over Beam by using method calls such as
-     * {@link #setNdefPushMessageCallback} or
-     * {@link #setBeamPushUrisCallback}.
-     *
-     * @param activity the current foreground Activity that has registered data to share
-     * @return whether the Beam animation was successfully invoked
-     * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
-     * @removed this feature is removed. File sharing can work using other technology like
-     * Bluetooth.
-     */
-    @java.lang.Deprecated
-    @UnsupportedAppUsage
-    public boolean invokeBeam(Activity activity) {
-        synchronized (sLock) {
-            if (!sHasNfcFeature) {
-                throw new UnsupportedOperationException();
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Enable NDEF message push over NFC while this Activity is in the foreground.
-     *
-     * <p>You must explicitly call this method every time the activity is
-     * resumed, and you must call {@link #disableForegroundNdefPush} before
-     * your activity completes {@link Activity#onPause}.
-     *
-     * <p>Strongly recommend to use the new {@link #setNdefPushMessage}
-     * instead: it automatically hooks into your activity life-cycle,
-     * so you do not need to call enable/disable in your onResume/onPause.
-     *
-     * <p>For NDEF push to function properly the other NFC device must
-     * support either NFC Forum's SNEP (Simple Ndef Exchange Protocol), or
-     * Android's "com.android.npp" (Ndef Push Protocol). This was optional
-     * on Gingerbread level Android NFC devices, but SNEP is mandatory on
-     * Ice-Cream-Sandwich and beyond.
-     *
-     * <p>This method must be called from the main thread.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param activity foreground activity
-     * @param message a NDEF Message to push over NFC
-     * @throws UnsupportedOperationException if FEATURE_NFC is unavailable
-     * @removed this feature is removed. File sharing can work using other technology like
-     * Bluetooth.
-     */
-    @Deprecated
-    @UnsupportedAppUsage
-    public void enableForegroundNdefPush(Activity activity, NdefMessage message) {
-        synchronized (sLock) {
-            if (!sHasNfcFeature) {
-                throw new UnsupportedOperationException();
-            }
-        }
-    }
-
-    /**
-     * Disable NDEF message push over P2P.
-     *
-     * <p>After calling {@link #enableForegroundNdefPush}, an activity
-     * must call this method before its {@link Activity#onPause} callback
-     * completes.
-     *
-     * <p>Strongly recommend to use the new {@link #setNdefPushMessage}
-     * instead: it automatically hooks into your activity life-cycle,
-     * so you do not need to call enable/disable in your onResume/onPause.
-     *
-     * <p>This method must be called from the main thread.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param activity the Foreground activity
-     * @throws UnsupportedOperationException if FEATURE_NFC is unavailable
-     * @removed this feature is removed. File sharing can work using other technology like
-     * Bluetooth.
-     */
-    @Deprecated
-    @UnsupportedAppUsage
-    public void disableForegroundNdefPush(Activity activity) {
-        synchronized (sLock) {
-            if (!sHasNfcFeature) {
-                throw new UnsupportedOperationException();
-            }
-        }
-    }
-
-    /**
-     * Sets Secure NFC feature.
-     * <p>This API is for the Settings application.
-     * @return True if successful
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public boolean enableSecureNfc(boolean enable) {
-        if (!sHasNfcFeature && !sHasCeFeature) {
-            throw new UnsupportedOperationException();
-        }
-        return callServiceReturn(() ->  sService.setNfcSecure(enable), false);
-
-    }
-
-    /**
-     * Checks if the device supports Secure NFC functionality.
-     *
-     * @return True if device supports Secure NFC, false otherwise
-     * @throws UnsupportedOperationException if FEATURE_NFC,
-     * FEATURE_NFC_HOST_CARD_EMULATION, FEATURE_NFC_HOST_CARD_EMULATION_NFCF,
-     * FEATURE_NFC_OFF_HOST_CARD_EMULATION_UICC and FEATURE_NFC_OFF_HOST_CARD_EMULATION_ESE
-     * are unavailable
-     */
-    public boolean isSecureNfcSupported() {
-        if (!sHasNfcFeature && !sHasCeFeature) {
-            throw new UnsupportedOperationException();
-        }
-        return callServiceReturn(() ->  sService.deviceSupportsNfcSecure(), false);
-
-    }
-
-    /**
-     * Returns information regarding Nfc antennas on the device
-     * such as their relative positioning on the device.
-     *
-     * @return Information on the nfc antenna(s) on the device.
-     * @throws UnsupportedOperationException if FEATURE_NFC,
-     * FEATURE_NFC_HOST_CARD_EMULATION, FEATURE_NFC_HOST_CARD_EMULATION_NFCF,
-     * FEATURE_NFC_OFF_HOST_CARD_EMULATION_UICC and FEATURE_NFC_OFF_HOST_CARD_EMULATION_ESE
-     * are unavailable
-     */
-    @Nullable
-    public NfcAntennaInfo getNfcAntennaInfo() {
-        if (!sHasNfcFeature && !sHasCeFeature) {
-            throw new UnsupportedOperationException();
-        }
-        return callServiceReturn(() ->  sService.getNfcAntennaInfo(), null);
-
-    }
-
-    /**
-     * Checks Secure NFC feature is enabled.
-     *
-     * @return True if Secure NFC is enabled, false otherwise
-     * @throws UnsupportedOperationException if FEATURE_NFC,
-     * FEATURE_NFC_HOST_CARD_EMULATION, FEATURE_NFC_HOST_CARD_EMULATION_NFCF,
-     * FEATURE_NFC_OFF_HOST_CARD_EMULATION_UICC and FEATURE_NFC_OFF_HOST_CARD_EMULATION_ESE
-     * are unavailable
-     * @throws UnsupportedOperationException if device doesn't support
-     *         Secure NFC functionality. {@link #isSecureNfcSupported}
-     */
-    public boolean isSecureNfcEnabled() {
-        if (!sHasNfcFeature && !sHasCeFeature) {
-            throw new UnsupportedOperationException();
-        }
-        return callServiceReturn(() ->  sService.isNfcSecureEnabled(), false);
-
-    }
-
-    /**
-     * Sets NFC Reader option feature.
-     * <p>This API is for the Settings application.
-     * @return True if successful
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_ENABLE_NFC_READER_OPTION)
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public boolean enableReaderOption(boolean enable) {
-        if (!sHasNfcFeature) {
-            throw new UnsupportedOperationException();
-        }
-        return callServiceReturn(() ->
-                sService.enableReaderOption(enable, mContext.getPackageName()), false);
-
-    }
-
-    /**
-     * Checks if the device supports NFC Reader option functionality.
-     *
-     * @return True if device supports NFC Reader option, false otherwise
-     * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
-     */
-    @FlaggedApi(Flags.FLAG_ENABLE_NFC_READER_OPTION)
-    public boolean isReaderOptionSupported() {
-        if (!sHasNfcFeature) {
-            throw new UnsupportedOperationException();
-        }
-        return callServiceReturn(() ->  sService.isReaderOptionSupported(), false);
-
-    }
-
-    /**
-     * Checks NFC Reader option feature is enabled.
-     *
-     * @return True if NFC Reader option  is enabled, false otherwise
-     * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
-     * @throws UnsupportedOperationException if device doesn't support
-     *         NFC Reader option functionality. {@link #isReaderOptionSupported}
-     */
-    @FlaggedApi(Flags.FLAG_ENABLE_NFC_READER_OPTION)
-    public boolean isReaderOptionEnabled() {
-        if (!sHasNfcFeature) {
-            throw new UnsupportedOperationException();
-        }
-        return callServiceReturn(() ->  sService.isReaderOptionEnabled(), false);
-
-    }
-
-    /**
-     * Enable NDEF Push feature.
-     * <p>This API is for the Settings application.
-     * @hide
-     * @removed
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    @UnsupportedAppUsage
-    public boolean enableNdefPush() {
-        return false;
-    }
-
-    /**
-     * Disable NDEF Push feature.
-     * <p>This API is for the Settings application.
-     * @hide
-     * @removed
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    @UnsupportedAppUsage
-    public boolean disableNdefPush() {
-        return false;
-    }
-
-    /**
-     * Return true if the NDEF Push (Android Beam) feature is enabled.
-     * <p>This function will return true only if both NFC is enabled, and the
-     * NDEF Push feature is enabled.
-     * <p>Note that if NFC is enabled but NDEF Push is disabled then this
-     * device can still <i>receive</i> NDEF messages, it just cannot send them.
-     * <p>Applications cannot directly toggle the NDEF Push feature, but they
-     * can request Settings UI allowing the user to toggle NDEF Push using
-     * <code>startActivity(new Intent(Settings.ACTION_NFCSHARING_SETTINGS))</code>
-     * <p>Example usage in an Activity that requires NDEF Push:
-     * <p><pre>
-     * protected void onResume() {
-     *     super.onResume();
-     *     if (!nfcAdapter.isEnabled()) {
-     *         startActivity(new Intent(Settings.ACTION_NFC_SETTINGS));
-     *     } else if (!nfcAdapter.isNdefPushEnabled()) {
-     *         startActivity(new Intent(Settings.ACTION_NFCSHARING_SETTINGS));
-     *     }
-     * }</pre>
-     *
-     * @see android.provider.Settings#ACTION_NFCSHARING_SETTINGS
-     * @return true if NDEF Push feature is enabled
-     * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
-     * @removed this feature is removed. File sharing can work using other technology like
-     * Bluetooth.
-     */
-    @java.lang.Deprecated
-    @UnsupportedAppUsage
-    public boolean isNdefPushEnabled() {
-        synchronized (sLock) {
-            if (!sHasNfcFeature) {
-                throw new UnsupportedOperationException();
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Signals that you are no longer interested in communicating with an NFC tag
-     * for as long as it remains in range.
-     *
-     * All future attempted communication to this tag will fail with {@link IOException}.
-     * The NFC controller will be put in a low-power polling mode, allowing the device
-     * to save power in cases where it's "attached" to a tag all the time (e.g. a tag in
-     * car dock).
-     *
-     * Additionally the debounceMs parameter allows you to specify for how long the tag needs
-     * to have gone out of range, before it will be dispatched again.
-     *
-     * Note: the NFC controller typically polls at a pretty slow interval (100 - 500 ms).
-     * This means that if the tag repeatedly goes in and out of range (for example, in
-     * case of a flaky connection), and the controller happens to poll every time the
-     * tag is out of range, it *will* re-dispatch the tag after debounceMs, despite the tag
-     * having been "in range" during the interval.
-     *
-     * Note 2: if a tag with another UID is detected after this API is called, its effect
-     * will be cancelled; if this tag shows up before the amount of time specified in
-     * debounceMs, it will be dispatched again.
-     *
-     * Note 3: some tags have a random UID, in which case this API won't work reliably.
-     *
-     * @param tag        the {@link android.nfc.Tag Tag} to ignore.
-     * @param debounceMs minimum amount of time the tag needs to be out of range before being
-     *                   dispatched again.
-     * @param tagRemovedListener listener to be called when the tag is removed from the field.
-     *                           Note that this will only be called if the tag has been out of range
-     *                           for at least debounceMs, or if another tag came into range before
-     *                           debounceMs. May be null in case you don't want a callback.
-     * @param handler the {@link android.os.Handler Handler} that will be used for delivering
-     *                the callback. if the handler is null, then the thread used for delivering
-     *                the callback is unspecified.
-     * @return false if the tag couldn't be found (or has already gone out of range), true otherwise
-     */
-    public boolean ignore(final Tag tag, int debounceMs,
-                          final OnTagRemovedListener tagRemovedListener, final Handler handler) {
-        ITagRemovedCallback.Stub iListener = null;
-        if (tagRemovedListener != null) {
-            iListener = new ITagRemovedCallback.Stub() {
-                @Override
-                public void onTagRemoved() throws RemoteException {
-                    if (handler != null) {
-                        handler.post(new Runnable() {
-                            @Override
-                            public void run() {
-                                tagRemovedListener.onTagRemoved();
-                            }
-                        });
-                    } else {
-                        tagRemovedListener.onTagRemoved();
-                    }
-                    synchronized (mLock) {
-                        mTagRemovedListener = null;
-                    }
-                }
-            };
-        }
-        synchronized (mLock) {
-            mTagRemovedListener = iListener;
-        }
-        final ITagRemovedCallback.Stub passedListener = iListener;
-        return callServiceReturn(() ->
-                sService.ignore(tag.getServiceHandle(), debounceMs, passedListener), false);
-    }
-
-    /**
-     * Inject a mock NFC tag.<p>
-     * Used for testing purposes.
-     * <p class="note">Requires the
-     * {@link android.Manifest.permission#WRITE_SECURE_SETTINGS} permission.
-     * @hide
-     */
-    public void dispatch(Tag tag) {
-        if (tag == null) {
-            throw new NullPointerException("tag cannot be null");
-        }
-        callService(() -> sService.dispatch(tag));
-    }
-
-    /**
-     * Registers a new NFC unlock handler with the NFC service.
-     *
-     * <p />NFC unlock handlers are intended to unlock the keyguard in the presence of a trusted
-     * NFC device. The handler should return true if it successfully authenticates the user and
-     * unlocks the keyguard.
-     *
-     * <p /> The parameter {@code tagTechnologies} determines which Tag technologies will be polled for
-     * at the lockscreen. Polling for less tag technologies reduces latency, and so it is
-     * strongly recommended to only provide the Tag technologies that the handler is expected to
-     * receive. There must be at least one tag technology provided, otherwise the unlock handler
-     * is ignored.
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public boolean addNfcUnlockHandler(final NfcUnlockHandler unlockHandler,
-                                       String[] tagTechnologies) {
-        synchronized (sLock) {
-            if (!sHasNfcFeature) {
-                throw new UnsupportedOperationException();
-            }
-        }
-        // If there are no tag technologies, don't bother adding unlock handler
-        if (tagTechnologies.length == 0) {
-            return false;
-        }
-
-        try {
-            synchronized (mLock) {
-                if (mNfcUnlockHandlers.containsKey(unlockHandler)) {
-                    // update the tag technologies
-                    callService(() -> {
-                        sService.removeNfcUnlockHandler(mNfcUnlockHandlers.get(unlockHandler));
-                        mNfcUnlockHandlers.remove(unlockHandler);
-                    });
-                }
-
-                INfcUnlockHandler.Stub iHandler = new INfcUnlockHandler.Stub() {
-                    @Override
-                    public boolean onUnlockAttempted(Tag tag) throws RemoteException {
-                        return unlockHandler.onUnlockAttempted(tag);
-                    }
-                };
-                return callServiceReturn(() -> {
-                        sService.addNfcUnlockHandler(
-                            iHandler, Tag.getTechCodesFromStrings(tagTechnologies));
-                        mNfcUnlockHandlers.put(unlockHandler, iHandler);
-                        return true;
-                    }, false);
-            }
-        } catch (IllegalArgumentException e) {
-            Log.e(TAG, "Unable to register LockscreenDispatch", e);
-            return false;
-        }
-
-    }
-
-    /**
-     * Removes a previously registered unlock handler. Also removes the tag technologies
-     * associated with the removed unlock handler.
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public boolean removeNfcUnlockHandler(NfcUnlockHandler unlockHandler) {
-        synchronized (sLock) {
-            if (!sHasNfcFeature) {
-                throw new UnsupportedOperationException();
-            }
-        }
-        synchronized (mLock) {
-            if (mNfcUnlockHandlers.containsKey(unlockHandler)) {
-                return callServiceReturn(() -> {
-                    sService.removeNfcUnlockHandler(mNfcUnlockHandlers.remove(unlockHandler));
-                    return true;
-                }, false);
-            }
-            return true;
-        }
-    }
-
-    /**
-     * @hide
-     */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    public INfcAdapterExtras getNfcAdapterExtrasInterface() {
-        if (mContext == null) {
-            throw new UnsupportedOperationException("You need a context on NfcAdapter to use the "
-                    + " NFC extras APIs");
-        }
-        return callServiceReturn(() ->
-                sService.getNfcAdapterExtrasInterface(mContext.getPackageName()), null);
-
-    }
-
-    void enforceResumed(Activity activity) {
-        if (!activity.isResumed()) {
-            throw new IllegalStateException("API cannot be called while activity is paused");
-        }
-    }
-
-    int getSdkVersion() {
-        if (mContext == null) {
-            return android.os.Build.VERSION_CODES.GINGERBREAD; // best guess
-        } else {
-            return mContext.getApplicationInfo().targetSdkVersion;
-        }
-    }
-
-    /**
-     * Sets NFC controller always on feature.
-     * <p>This API is for the NFCC internal state management. It allows to discriminate
-     * the controller function from the NFC function by keeping the NFC controller on without
-     * any NFC RF enabled if necessary.
-     * <p>This call is asynchronous. Register a listener {@link ControllerAlwaysOnListener}
-     * by {@link #registerControllerAlwaysOnListener} to find out when the operation is
-     * complete.
-     * <p>If this returns true, then either NFCC always on state has been set based on the value,
-     * or a {@link ControllerAlwaysOnListener#onControllerAlwaysOnChanged(boolean)} will be invoked
-     * to indicate the state change.
-     * If this returns false, then there is some problem that prevents an attempt to turn NFCC
-     * always on.
-     * @param value if true the NFCC will be kept on (with no RF enabled if NFC adapter is
-     * disabled), if false the NFCC will follow completely the Nfc adapter state.
-     * @throws UnsupportedOperationException if FEATURE_NFC,
-     * FEATURE_NFC_HOST_CARD_EMULATION, FEATURE_NFC_HOST_CARD_EMULATION_NFCF,
-     * FEATURE_NFC_OFF_HOST_CARD_EMULATION_UICC and FEATURE_NFC_OFF_HOST_CARD_EMULATION_ESE
-     * are unavailable
-     * @return true if feature is supported by the device and operation has been initiated,
-     * false if the feature is not supported by the device.
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON)
-    public boolean setControllerAlwaysOn(boolean value) {
-        if (!sHasNfcFeature && !sHasCeFeature) {
-            throw new UnsupportedOperationException();
-        }
-        int mode = value ? CONTROLLER_ALWAYS_ON_MODE_DEFAULT : CONTROLLER_ALWAYS_ON_DISABLE;
-        try {
-            callService(() -> sService.setControllerAlwaysOn(mode));
-        } catch (UnsupportedOperationException e) {
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * Checks NFC controller always on feature is enabled.
-     *
-     * @return True if NFC controller always on is enabled, false otherwise
-     * @throws UnsupportedOperationException if FEATURE_NFC,
-     * FEATURE_NFC_HOST_CARD_EMULATION, FEATURE_NFC_HOST_CARD_EMULATION_NFCF,
-     * FEATURE_NFC_OFF_HOST_CARD_EMULATION_UICC and FEATURE_NFC_OFF_HOST_CARD_EMULATION_ESE
-     * are unavailable
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON)
-    public boolean isControllerAlwaysOn() {
-        return callServiceReturn(() ->  sService.isControllerAlwaysOn(), false);
-
-    }
-
-    /**
-     * Checks if the device supports NFC controller always on functionality.
-     *
-     * @return True if device supports NFC controller always on, false otherwise
-     * @throws UnsupportedOperationException if FEATURE_NFC,
-     * FEATURE_NFC_HOST_CARD_EMULATION, FEATURE_NFC_HOST_CARD_EMULATION_NFCF,
-     * FEATURE_NFC_OFF_HOST_CARD_EMULATION_UICC and FEATURE_NFC_OFF_HOST_CARD_EMULATION_ESE
-     * are unavailable
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON)
-    public boolean isControllerAlwaysOnSupported() {
-        if (!sHasNfcFeature && !sHasCeFeature) {
-            throw new UnsupportedOperationException();
-        }
-        return callServiceReturn(() ->  sService.isControllerAlwaysOnSupported(), false);
-
-    }
-
-    /**
-     * Register a {@link ControllerAlwaysOnListener} to listen for NFC controller always on
-     * state changes
-     * <p>The provided listener will be invoked by the given {@link Executor}.
-     *
-     * @param executor an {@link Executor} to execute given listener
-     * @param listener user implementation of the {@link ControllerAlwaysOnListener}
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON)
-    public void registerControllerAlwaysOnListener(
-            @NonNull @CallbackExecutor Executor executor,
-            @NonNull ControllerAlwaysOnListener listener) {
-        mControllerAlwaysOnListener.register(executor, listener);
-    }
-
-    /**
-     * Unregister the specified {@link ControllerAlwaysOnListener}
-     * <p>The same {@link ControllerAlwaysOnListener} object used when calling
-     * {@link #registerControllerAlwaysOnListener(Executor, ControllerAlwaysOnListener)}
-     * must be used.
-     *
-     * <p>Listeners are automatically unregistered when application process goes away
-     *
-     * @param listener user implementation of the {@link ControllerAlwaysOnListener}
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON)
-    public void unregisterControllerAlwaysOnListener(
-            @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();
-        }
-        return callServiceReturn(() ->
-                sService.setTagIntentAppPreferenceForUser(userId, pkg, allow),
-                        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
-     * mapped to {@code false}.
-     * <p>There are three different possible cases:
-     * <p>A package not being in the preference list.
-     * It does not contain any Tag intent filters or the user never triggers a Tag detection that
-     * matches the intent filter of the package.
-     * <p>A package being mapped to {@code true}.
-     * When a package has been launched by a tag detection for the first time, the package name is
-     * put to the map and by default mapped to {@code true}. The package will receive Tag intents as
-     * usual.
-     * <p>A package being mapped to {@code false}.
-     * The user chooses to disable this package and it will not receive any Tag intents anymore.
-     *
-     * @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();
-        }
-        return callServiceReturn( () ->
-            sService.getTagIntentAppPreferenceForUser(userId), Collections.emptyMap());
-    }
-
-    /**
-     * Checks if the device supports Tag Intent App Preference functionality.
-     *
-     * When supported, {@link #ACTION_NDEF_DISCOVERED}, {@link #ACTION_TECH_DISCOVERED} or
-     * {@link #ACTION_TAG_DISCOVERED} will not be dispatched to an Activity if
-     * {@link isTagIntentAllowed} returns {@code false}.
-     *
-     * @return {@code true} if the device supports Tag application preference, {@code false}
-     * otherwise
-     * @throws UnsupportedOperationException if FEATURE_NFC is unavailable
-     */
-    @FlaggedApi(Flags.FLAG_NFC_CHECK_TAG_INTENT_PREFERENCE)
-    public boolean isTagIntentAppPreferenceSupported() {
-        if (!sHasNfcFeature) {
-            throw new UnsupportedOperationException();
-        }
-        return callServiceReturn(() ->  sService.isTagIntentAppPreferenceSupported(), false);
-    }
-
-   /**
-     * Notifies the system of a new polling loop.
-     *
-     * @param frame is the new frame.
-     *
-     * @hide
-     */
-    @TestApi
-    @FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP)
-    public void notifyPollingLoop(@NonNull PollingFrame pollingFrame) {
-        callService(() ->  sService.notifyPollingLoop(pollingFrame));
-    }
-
-
-   /**
-     * Notifies the system of new HCE data for tests.
-     *
-     * @hide
-     */
-    @FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP)
-    public void notifyTestHceData(int technology, byte[] data) {
-        callService(() ->  sService.notifyTestHceData(technology, data));
-    }
-
-    /** @hide */
-    interface ServiceCall {
-        void call() throws RemoteException;
-    }
-    /** @hide */
-    static void callService(ServiceCall call) {
-        try {
-            if (sService == null) {
-                attemptDeadServiceRecovery(new RemoteException("NFC Service is null"));
-            }
-            call.call();
-        } catch (RemoteException e) {
-            attemptDeadServiceRecovery(e);
-            try {
-                call.call();
-            } catch (RemoteException ee) {
-                ee.rethrowAsRuntimeException();
-            }
-        }
-    }
-    /** @hide */
-    interface ServiceCallReturn<T> {
-        T call() throws RemoteException;
-    }
-    /** @hide */
-    static <T> T callServiceReturn(ServiceCallReturn<T> call, T defaultReturn) {
-        try {
-            if (sService == null) {
-                attemptDeadServiceRecovery(new RemoteException("NFC Service is null"));
-            }
-            return call.call();
-        } catch (RemoteException e) {
-            attemptDeadServiceRecovery(e);
-            // Try one more time
-            try {
-                return call.call();
-            } catch (RemoteException ee) {
-                ee.rethrowAsRuntimeException();
-            }
-        }
-        return defaultReturn;
-    }
-
-   /**
-     * Notifies the system of a an HCE session being deactivated.
-     *     *
-     * @hide
-     */
-    @TestApi
-    @FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP)
-    public void notifyHceDeactivated() {
-        callService(() ->  sService.notifyHceDeactivated());
-    }
-
-    /**
-     * Sets NFC charging feature.
-     * <p>This API is for the Settings application.
-     * @return True if successful
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_ENABLE_NFC_CHARGING)
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public boolean setWlcEnabled(boolean enable) {
-        if (!sHasNfcWlcFeature) {
-            throw new UnsupportedOperationException();
-        }
-        return callServiceReturn(() ->  sService.setWlcEnabled(enable), false);
-    }
-
-    /**
-     * Checks NFC charging feature is enabled.
-     *
-     * @return True if NFC charging is enabled, false otherwise
-     * @throws UnsupportedOperationException if FEATURE_NFC_CHARGING
-     * is unavailable
-     */
-    @FlaggedApi(Flags.FLAG_ENABLE_NFC_CHARGING)
-    public boolean isWlcEnabled() {
-        if (!sHasNfcWlcFeature) {
-            throw new UnsupportedOperationException();
-        }
-        return callServiceReturn(() ->  sService.isWlcEnabled(), false);
-
-    }
-
-    /**
-     * A listener to be invoked when NFC controller always on state changes.
-     * <p>Register your {@code ControllerAlwaysOnListener} implementation with {@link
-     * NfcAdapter#registerWlcStateListener} and disable it with {@link
-     * NfcAdapter#unregisterWlcStateListenerListener}.
-     * @see #registerWlcStateListener
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_ENABLE_NFC_CHARGING)
-    public interface WlcStateListener {
-        /**
-         * Called on NFC WLC state changes
-         */
-        void onWlcStateChanged(@NonNull WlcListenerDeviceInfo wlcListenerDeviceInfo);
-    }
-
-    /**
-     * Register a {@link WlcStateListener} to listen for NFC WLC state changes
-     * <p>The provided listener will be invoked by the given {@link Executor}.
-     *
-     * @param executor an {@link Executor} to execute given listener
-     * @param listener user implementation of the {@link WlcStateListener}
-     * @throws UnsupportedOperationException if FEATURE_NFC_CHARGING
-     * is unavailable
-     *
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_ENABLE_NFC_CHARGING)
-    public void registerWlcStateListener(
-            @NonNull @CallbackExecutor Executor executor,
-            @NonNull WlcStateListener listener) {
-        if (!sHasNfcWlcFeature) {
-            throw new UnsupportedOperationException();
-        }
-        mNfcWlcStateListener.register(executor, listener);
-    }
-
-    /**
-     * Unregister the specified {@link WlcStateListener}
-     * <p>The same {@link WlcStateListener} object used when calling
-     * {@link #registerWlcStateListener(Executor, WlcStateListener)}
-     * must be used.
-     *
-     * <p>Listeners are automatically unregistered when application process goes away
-     *
-     * @param listener user implementation of the {@link WlcStateListener}a
-     * @throws UnsupportedOperationException if FEATURE_NFC_CHARGING
-     * is unavailable
-     *
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_ENABLE_NFC_CHARGING)
-    public void unregisterWlcStateListener(
-            @NonNull WlcStateListener listener) {
-        if (!sHasNfcWlcFeature) {
-            throw new UnsupportedOperationException();
-        }
-        mNfcWlcStateListener.unregister(listener);
-    }
-
-    /**
-     * Returns information on the NFC charging listener device
-     *
-     * @return Information on the NFC charging listener device
-     * @throws UnsupportedOperationException if FEATURE_NFC_CHARGING
-     * is unavailable
-     */
-    @FlaggedApi(Flags.FLAG_ENABLE_NFC_CHARGING)
-    @Nullable
-    public WlcListenerDeviceInfo getWlcListenerDeviceInfo() {
-        if (!sHasNfcWlcFeature) {
-            throw new UnsupportedOperationException();
-        }
-        return callServiceReturn(() ->  sService.getWlcListenerDeviceInfo(), null);
-
-    }
-
-    /**
-     * Vendor NCI command success.
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_NFC_VENDOR_CMD)
-    public static final int SEND_VENDOR_NCI_STATUS_SUCCESS = 0;
-    /**
-     * Vendor NCI command rejected.
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_NFC_VENDOR_CMD)
-    public static final int SEND_VENDOR_NCI_STATUS_REJECTED = 1;
-    /**
-     * Vendor NCI command corrupted.
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_NFC_VENDOR_CMD)
-    public static final int SEND_VENDOR_NCI_STATUS_MESSAGE_CORRUPTED  = 2;
-    /**
-     * Vendor NCI command failed with unknown reason.
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_NFC_VENDOR_CMD)
-    public static final int SEND_VENDOR_NCI_STATUS_FAILED = 3;
-
-    /**
-     * @hide
-     */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(value = {
-            SEND_VENDOR_NCI_STATUS_SUCCESS,
-            SEND_VENDOR_NCI_STATUS_REJECTED,
-            SEND_VENDOR_NCI_STATUS_MESSAGE_CORRUPTED,
-            SEND_VENDOR_NCI_STATUS_FAILED,
-    })
-    @interface SendVendorNciStatus {}
-
-    /**
-     * Message Type for NCI Command.
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_NFC_VENDOR_CMD)
-    public static final int MESSAGE_TYPE_COMMAND = 1;
-
-    /**
-     * @hide
-     */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(value = {
-            MESSAGE_TYPE_COMMAND,
-    })
-    @interface MessageType {}
-
-    /**
-     * Send Vendor specific Nci Messages with custom message type.
-     *
-     * The format of the NCI messages are defined in the NCI specification. The platform is
-     * responsible for fragmenting the payload if necessary.
-     *
-     * Note that mt (message type) is added at the beginning of method parameters as it is more
-     * distinctive than other parameters and was requested from vendor.
-     *
-     * @param mt message Type of the command
-     * @param gid group ID of the command. This needs to be one of the vendor reserved GIDs from
-     *            the NCI specification
-     * @param oid opcode ID of the command. This is left to the OEM / vendor to decide
-     * @param payload containing vendor Nci message payload
-     * @return message send status
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_NFC_VENDOR_CMD)
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public @SendVendorNciStatus int sendVendorNciMessage(@MessageType int mt,
-            @IntRange(from = 0, to = 15) int gid, @IntRange(from = 0) int oid,
-            @NonNull byte[] payload) {
-        Objects.requireNonNull(payload, "Payload must not be null");
-        return callServiceReturn(() ->  sService.sendVendorNciMessage(mt, gid, oid, payload),
-                SEND_VENDOR_NCI_STATUS_FAILED);
-    }
-
-    /**
-     * Register an {@link NfcVendorNciCallback} to listen for Nfc vendor responses and notifications
-     * <p>The provided callback will be invoked by the given {@link Executor}.
-     *
-     * <p>When first registering a callback, the callbacks's
-     * {@link NfcVendorNciCallback#onVendorNciCallBack(byte[])} is immediately invoked to
-     * notify the vendor notification.
-     *
-     * @param executor an {@link Executor} to execute given callback
-     * @param callback user implementation of the {@link NfcVendorNciCallback}
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_NFC_VENDOR_CMD)
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public void registerNfcVendorNciCallback(@NonNull @CallbackExecutor Executor executor,
-            @NonNull NfcVendorNciCallback callback) {
-        mNfcVendorNciCallbackListener.register(executor, callback);
-    }
-
-    /**
-     * Unregister the specified {@link NfcVendorNciCallback}
-     *
-     * <p>The same {@link NfcVendorNciCallback} object used when calling
-     * {@link #registerNfcVendorNciCallback(Executor, NfcVendorNciCallback)} must be used.
-     *
-     * <p>Callbacks are automatically unregistered when application process goes away
-     *
-     * @param callback user implementation of the {@link NfcVendorNciCallback}
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_NFC_VENDOR_CMD)
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public void unregisterNfcVendorNciCallback(@NonNull NfcVendorNciCallback callback) {
-        mNfcVendorNciCallbackListener.unregister(callback);
-    }
-
-    /**
-     * Interface for receiving vendor NCI responses and notifications.
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_NFC_VENDOR_CMD)
-    public interface NfcVendorNciCallback {
-        /**
-         * Invoked when a vendor specific NCI response is received.
-         *
-         * @param gid group ID of the command. This needs to be one of the vendor reserved GIDs from
-         *            the NCI specification.
-         * @param oid opcode ID of the command. This is left to the OEM / vendor to decide.
-         * @param payload containing vendor Nci message payload.
-         */
-        @FlaggedApi(Flags.FLAG_NFC_VENDOR_CMD)
-        void onVendorNciResponse(
-                @IntRange(from = 0, to = 15) int gid, int oid, @NonNull byte[] payload);
-
-        /**
-         * Invoked when a vendor specific NCI notification is received.
-         *
-         * @param gid group ID of the command. This needs to be one of the vendor reserved GIDs from
-         *            the NCI specification.
-         * @param oid opcode ID of the command. This is left to the OEM / vendor to decide.
-         * @param payload containing vendor Nci message payload.
-         */
-        @FlaggedApi(Flags.FLAG_NFC_VENDOR_CMD)
-        void onVendorNciNotification(
-                @IntRange(from = 9, to = 15) int gid, int oid, @NonNull byte[] payload);
-    }
-
-    /**
-     * Used by data migration to indicate data migration is in progrerss or not.
-     *
-     * Note: This is @hide intentionally since the client is inside the NFC apex.
-     * @param inProgress true if migration is in progress, false once done.
-     * @hide
-     */
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public void indicateDataMigration(boolean inProgress) {
-        callService(() -> sService.indicateDataMigration(inProgress, mContext.getPackageName()));
-    }
-
-    /**
-     * Returns an instance of {@link NfcOemExtension} associated with {@link NfcAdapter} instance.
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    @NonNull public NfcOemExtension getNfcOemExtension() {
-        synchronized (sLock) {
-            if (!sHasNfcFeature) {
-                throw new UnsupportedOperationException();
-            }
-        }
-        return mNfcOemExtension;
-    }
-
-    /**
-     * Activity action: Bring up the settings page that allows the user to enable or disable tag
-     * intent reception for apps.
-     *
-     * <p>This will direct user to the settings page shows a list that asks users whether
-     * they want to allow or disallow the package to start an activity when a tag is discovered.
-     *
-     */
-    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
-    @FlaggedApi(Flags.FLAG_NFC_CHECK_TAG_INTENT_PREFERENCE)
-    public static final String ACTION_CHANGE_TAG_INTENT_PREFERENCE =
-            "android.nfc.action.CHANGE_TAG_INTENT_PREFERENCE";
-
-    /**
-     * Checks whether the user has disabled the calling app from receiving NFC tag intents.
-     *
-     * <p>This method checks whether the caller package name is either not present in the user
-     * disabled list or is explicitly allowed by the user.
-     *
-     * @return {@code true} if an app is either not present in the list or is added to the list
-     * with the flag set to {@code true}. Otherwise, it returns {@code false}.
-     * It also returns {@code true} if {@link isTagIntentAppPreferenceSupported} returns
-     * {@code false}.
-     *
-     * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
-     */
-    @FlaggedApi(Flags.FLAG_NFC_CHECK_TAG_INTENT_PREFERENCE)
-    public boolean isTagIntentAllowed() {
-        if (!sHasNfcFeature) {
-            throw new UnsupportedOperationException();
-        }
-        if (!isTagIntentAppPreferenceSupported()) {
-            return true;
-        }
-        return callServiceReturn(() ->  sService.isTagIntentAllowed(mContext.getPackageName(),
-                UserHandle.myUserId()), false);
-    }
-}
diff --git a/nfc/java/android/nfc/NfcAntennaInfo.aidl b/nfc/java/android/nfc/NfcAntennaInfo.aidl
deleted file mode 100644
index d5e79fc..0000000
--- a/nfc/java/android/nfc/NfcAntennaInfo.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-parcelable NfcAntennaInfo;
diff --git a/nfc/java/android/nfc/NfcAntennaInfo.java b/nfc/java/android/nfc/NfcAntennaInfo.java
deleted file mode 100644
index c57b2e0..0000000
--- a/nfc/java/android/nfc/NfcAntennaInfo.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import android.annotation.NonNull;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.ArrayList;
-import java.util.List;
-
-
-/**
- * Contains information on all available Nfc
- * antennas on an Android device as well as information
- * on the device itself in relation positioning of the
- * antennas.
- */
-public final class NfcAntennaInfo implements Parcelable {
-    // Width of the device in millimeters.
-    private final int mDeviceWidth;
-    // Height of the device in millimeters.
-    private final int mDeviceHeight;
-    // Whether the device is foldable.
-    private final boolean mDeviceFoldable;
-    // All available Nfc Antennas on the device.
-    private final List<AvailableNfcAntenna> mAvailableNfcAntennas;
-
-    public NfcAntennaInfo(int deviceWidth, int deviceHeight, boolean deviceFoldable,
-            @NonNull List<AvailableNfcAntenna> availableNfcAntennas) {
-        this.mDeviceWidth = deviceWidth;
-        this.mDeviceHeight = deviceHeight;
-        this.mDeviceFoldable = deviceFoldable;
-        this.mAvailableNfcAntennas = availableNfcAntennas;
-    }
-
-    /**
-     * Width of the device in millimeters.
-     */
-    public int getDeviceWidth() {
-        return mDeviceWidth;
-    }
-
-    /**
-     * Height of the device in millimeters.
-     */
-    public int getDeviceHeight() {
-        return mDeviceHeight;
-    }
-
-    /**
-     * Whether the device is foldable. When the device is foldable,
-     * the 0, 0 is considered to be top-left when the device is unfolded and
-     * the screens are facing the user. For non-foldable devices 0, 0
-     * is top-left when the user is facing the screen.
-     */
-    public boolean isDeviceFoldable() {
-        return mDeviceFoldable;
-    }
-
-    /**
-     * Get all NFC antennas that exist on the device.
-     */
-    @NonNull
-    public List<AvailableNfcAntenna> getAvailableNfcAntennas() {
-        return mAvailableNfcAntennas;
-    }
-
-    private NfcAntennaInfo(Parcel in) {
-        this.mDeviceWidth = in.readInt();
-        this.mDeviceHeight = in.readInt();
-        this.mDeviceFoldable = in.readByte() != 0;
-        this.mAvailableNfcAntennas = new ArrayList<>();
-        in.readTypedList(this.mAvailableNfcAntennas,
-                AvailableNfcAntenna.CREATOR);
-    }
-
-    public static final @NonNull Parcelable.Creator<NfcAntennaInfo> CREATOR =
-            new Parcelable.Creator<NfcAntennaInfo>() {
-        @Override
-        public NfcAntennaInfo createFromParcel(Parcel in) {
-            return new NfcAntennaInfo(in);
-        }
-
-        @Override
-        public NfcAntennaInfo[] newArray(int size) {
-            return new NfcAntennaInfo[size];
-        }
-    };
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(@NonNull Parcel dest, int flags) {
-        dest.writeInt(mDeviceWidth);
-        dest.writeInt(mDeviceHeight);
-        dest.writeByte((byte) (mDeviceFoldable ? 1 : 0));
-        dest.writeTypedList(mAvailableNfcAntennas, 0);
-    }
-}
diff --git a/nfc/java/android/nfc/NfcControllerAlwaysOnListener.java b/nfc/java/android/nfc/NfcControllerAlwaysOnListener.java
deleted file mode 100644
index 6ae58fd..0000000
--- a/nfc/java/android/nfc/NfcControllerAlwaysOnListener.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import android.annotation.NonNull;
-import android.nfc.NfcAdapter.ControllerAlwaysOnListener;
-import android.os.Binder;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.Executor;
-
-/**
- * @hide
- */
-public class NfcControllerAlwaysOnListener extends INfcControllerAlwaysOnListener.Stub {
-    private static final String TAG = NfcControllerAlwaysOnListener.class.getSimpleName();
-
-    private final INfcAdapter mAdapter;
-
-    private final Map<ControllerAlwaysOnListener, Executor> mListenerMap = new HashMap<>();
-
-    private boolean mCurrentState = false;
-    private boolean mIsRegistered = false;
-
-    public NfcControllerAlwaysOnListener(@NonNull INfcAdapter adapter) {
-        mAdapter = adapter;
-    }
-
-    /**
-     * Register a {@link ControllerAlwaysOnListener} with this
-     * {@link NfcControllerAlwaysOnListener}
-     *
-     * @param executor an {@link Executor} to execute given listener
-     * @param listener user implementation of the {@link ControllerAlwaysOnListener}
-     */
-    public void register(@NonNull Executor executor,
-            @NonNull ControllerAlwaysOnListener listener) {
-        try {
-            if (!mAdapter.isControllerAlwaysOnSupported()) {
-                return;
-            }
-        } catch (RemoteException e) {
-            Log.w(TAG, "Failed to register");
-            return;
-        }
-        synchronized (this) {
-            if (mListenerMap.containsKey(listener)) {
-                return;
-            }
-
-            mListenerMap.put(listener, executor);
-            if (!mIsRegistered) {
-                try {
-                    mAdapter.registerControllerAlwaysOnListener(this);
-                    mIsRegistered = true;
-                } catch (RemoteException e) {
-                    Log.w(TAG, "Failed to register");
-                }
-            }
-        }
-    }
-
-    /**
-     * Unregister the specified {@link ControllerAlwaysOnListener}
-     *
-     * @param listener user implementation of the {@link ControllerAlwaysOnListener}
-     */
-    public void unregister(@NonNull ControllerAlwaysOnListener listener) {
-        try {
-            if (!mAdapter.isControllerAlwaysOnSupported()) {
-                return;
-            }
-        } catch (RemoteException e) {
-            Log.w(TAG, "Failed to unregister");
-            return;
-        }
-        synchronized (this) {
-            if (!mListenerMap.containsKey(listener)) {
-                return;
-            }
-
-            mListenerMap.remove(listener);
-
-            if (mListenerMap.isEmpty() && mIsRegistered) {
-                try {
-                    mAdapter.unregisterControllerAlwaysOnListener(this);
-                } catch (RemoteException e) {
-                    Log.w(TAG, "Failed to unregister");
-                }
-                mIsRegistered = false;
-            }
-        }
-    }
-
-    private void sendCurrentState(@NonNull ControllerAlwaysOnListener listener) {
-        synchronized (this) {
-            Executor executor = mListenerMap.get(listener);
-
-            final long identity = Binder.clearCallingIdentity();
-            try {
-                executor.execute(() -> listener.onControllerAlwaysOnChanged(
-                        mCurrentState));
-            } finally {
-                Binder.restoreCallingIdentity(identity);
-            }
-        }
-    }
-
-    @Override
-    public void onControllerAlwaysOnChanged(boolean isEnabled) {
-        synchronized (this) {
-            mCurrentState = isEnabled;
-            for (ControllerAlwaysOnListener cb : mListenerMap.keySet()) {
-                sendCurrentState(cb);
-            }
-        }
-    }
-}
-
diff --git a/nfc/java/android/nfc/NfcEvent.java b/nfc/java/android/nfc/NfcEvent.java
deleted file mode 100644
index aff4f52..0000000
--- a/nfc/java/android/nfc/NfcEvent.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-/**
- * Wraps information associated with any NFC event.
- *
- * <p>Immutable object, with direct access to the (final) fields.
- *
- * <p>An {@link NfcEvent} object is usually included in callbacks from
- * {@link NfcAdapter}. Check the documentation of the callback to see
- * which fields may be set.
- *
- * <p>This wrapper object is used (instead of parameters
- * in the callback) because it allows new fields to be added without breaking
- * API compatibility.
- *
- * @see NfcAdapter.OnNdefPushCompleteCallback#onNdefPushComplete
- * @see NfcAdapter.CreateNdefMessageCallback#createNdefMessage
- */
-public final class NfcEvent {
-    /**
-     * The {@link NfcAdapter} associated with the NFC event.
-     */
-    public final NfcAdapter nfcAdapter;
-
-    /**
-     * The major LLCP version number of the peer associated with the NFC event.
-     */
-    public final int peerLlcpMajorVersion;
-
-    /**
-     * The minor LLCP version number of the peer associated with the NFC event.
-     */
-    public final int peerLlcpMinorVersion;
-
-    NfcEvent(NfcAdapter nfcAdapter, byte peerLlcpVersion) {
-        this.nfcAdapter = nfcAdapter;
-        this.peerLlcpMajorVersion = (peerLlcpVersion & 0xF0) >> 4;
-        this.peerLlcpMinorVersion = peerLlcpVersion & 0x0F;
-    }
-}
diff --git a/nfc/java/android/nfc/NfcFrameworkInitializer.java b/nfc/java/android/nfc/NfcFrameworkInitializer.java
deleted file mode 100644
index 1ab8a1e..0000000
--- a/nfc/java/android/nfc/NfcFrameworkInitializer.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.nfc;
-
-import android.annotation.NonNull;
-import android.annotation.SystemApi;
-import android.app.SystemServiceRegistry;
-import android.content.Context;
-
-/**
- * Class for performing registration for Nfc service.
- *
- * @hide
- */
-@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
-public class NfcFrameworkInitializer {
-    private NfcFrameworkInitializer() {}
-
-    private static volatile NfcServiceManager sNfcServiceManager;
-
-    /**
-     * Sets an instance of {@link NfcServiceManager} that allows
-     * the nfc mainline module to register/obtain nfc binder services. This is called
-     * by the platform during the system initialization.
-     *
-     * @param nfcServiceManager instance of {@link NfcServiceManager} that allows
-     * the nfc mainline module to register/obtain nfcd binder services.
-     */
-    public static void setNfcServiceManager(
-            @NonNull NfcServiceManager nfcServiceManager) {
-        if (sNfcServiceManager != null) {
-            throw new IllegalStateException("setNfcServiceManager called twice!");
-        }
-
-        if (nfcServiceManager == null) {
-            throw new IllegalArgumentException("nfcServiceManager must not be null");
-        }
-
-        sNfcServiceManager = nfcServiceManager;
-    }
-
-    /** @hide */
-    public static NfcServiceManager getNfcServiceManager() {
-        return sNfcServiceManager;
-    }
-
-    /**
-     * Called by {@link SystemServiceRegistry}'s static initializer and registers NFC service
-     * to {@link Context}, so that {@link Context#getSystemService} can return them.
-     *
-     * @throws IllegalStateException if this is called from anywhere besides
-     * {@link SystemServiceRegistry}
-     */
-    public static void registerServiceWrappers() {
-        SystemServiceRegistry.registerContextAwareService(Context.NFC_SERVICE,
-                NfcManager.class, context -> new NfcManager(context));
-    }
-}
diff --git a/nfc/java/android/nfc/NfcManager.java b/nfc/java/android/nfc/NfcManager.java
deleted file mode 100644
index 644e312..0000000
--- a/nfc/java/android/nfc/NfcManager.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import android.annotation.SystemService;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.content.Context;
-import android.os.Build;
-
-/**
- * High level manager used to obtain an instance of an {@link NfcAdapter}.
- * <p>
- * Use {@link android.content.Context#getSystemService(java.lang.String)}
- * with {@link Context#NFC_SERVICE} to create an {@link NfcManager},
- * then call {@link #getDefaultAdapter} to obtain the {@link NfcAdapter}.
- * <p>
- * Alternately, you can just call the static helper
- * {@link NfcAdapter#getDefaultAdapter(android.content.Context)}.
- *
- * <div class="special reference">
- * <h3>Developer Guides</h3>
- * <p>For more information about using NFC, read the
- * <a href="{@docRoot}guide/topics/nfc/index.html">Near Field Communication</a> developer guide.</p>
- * </div>
- *
- * @see NfcAdapter#getDefaultAdapter(android.content.Context)
- */
-@SystemService(Context.NFC_SERVICE)
-public final class NfcManager {
-    private final NfcAdapter mAdapter;
-
-    /**
-     * @hide
-     */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
-    public NfcManager(Context context) {
-        NfcAdapter adapter;
-        context = context.getApplicationContext();
-        if (context == null) {
-            throw new IllegalArgumentException(
-                    "context not associated with any application (using a mock context?)");
-        }
-        try {
-            adapter = NfcAdapter.getNfcAdapter(context);
-        } catch (UnsupportedOperationException e) {
-            adapter = null;
-        }
-        mAdapter = adapter;
-    }
-
-    /**
-     * Get the default NFC Adapter for this device.
-     *
-     * @return the default NFC Adapter
-     */
-    public NfcAdapter getDefaultAdapter() {
-        return mAdapter;
-    }
-}
diff --git a/nfc/java/android/nfc/NfcOemExtension.java b/nfc/java/android/nfc/NfcOemExtension.java
deleted file mode 100644
index b46e343..0000000
--- a/nfc/java/android/nfc/NfcOemExtension.java
+++ /dev/null
@@ -1,1248 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import static android.nfc.cardemulation.CardEmulation.PROTOCOL_AND_TECHNOLOGY_ROUTE_DH;
-import static android.nfc.cardemulation.CardEmulation.PROTOCOL_AND_TECHNOLOGY_ROUTE_ESE;
-import static android.nfc.cardemulation.CardEmulation.PROTOCOL_AND_TECHNOLOGY_ROUTE_UICC;
-import static android.nfc.cardemulation.CardEmulation.routeIntToString;
-
-import android.Manifest;
-import android.annotation.CallbackExecutor;
-import android.annotation.DurationMillisLong;
-import android.annotation.FlaggedApi;
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.RequiresPermission;
-import android.annotation.SystemApi;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.nfc.cardemulation.ApduServiceInfo;
-import android.nfc.cardemulation.CardEmulation;
-import android.nfc.cardemulation.CardEmulation.ProtocolAndTechnologyRoute;
-import android.os.Binder;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.os.ResultReceiver;
-import android.se.omapi.Reader;
-import android.util.Log;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Executor;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.FutureTask;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-import java.util.function.BiConsumer;
-import java.util.function.Consumer;
-import java.util.function.Function;
-import java.util.function.Supplier;
-
-/**
- * Used for OEM extension APIs.
- * This class holds all the APIs and callbacks defined for OEMs/vendors to extend the NFC stack
- * for their proprietary features.
- *
- * @hide
- */
-@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-@SystemApi
-public final class NfcOemExtension {
-    private static final String TAG = "NfcOemExtension";
-    private static final int OEM_EXTENSION_RESPONSE_THRESHOLD_MS = 2000;
-    private static final int TYPE_TECHNOLOGY = 0;
-    private static final int TYPE_PROTOCOL = 1;
-    private static final int TYPE_AID = 2;
-    private static final int TYPE_SYSTEMCODE = 3;
-
-    private final NfcAdapter mAdapter;
-    private final NfcOemExtensionCallback mOemNfcExtensionCallback;
-    private boolean mIsRegistered = false;
-    private final Map<Callback, Executor> mCallbackMap = new HashMap<>();
-    private final Context mContext;
-    private final Object mLock = new Object();
-    private boolean mCardEmulationActivated = false;
-    private boolean mRfFieldActivated = false;
-    private boolean mRfDiscoveryStarted = false;
-    private boolean mEeListenActivated = false;
-
-    /**
-     * Broadcast Action: Sent on NFC stack initialization when NFC OEM extensions are enabled.
-     * <p> OEM extension modules should use this intent to start their extension service </p>
-     * @hide
-     */
-    public static final String ACTION_OEM_EXTENSION_INIT = "android.nfc.action.OEM_EXTENSION_INIT";
-
-    /**
-     * Mode Type for {@link #setControllerAlwaysOnMode(int)}.
-     * Enables the controller in default mode when NFC is disabled (existing API behavior).
-     * works same as {@link NfcAdapter#setControllerAlwaysOn(boolean)}.
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    public static final int ENABLE_DEFAULT = NfcAdapter.CONTROLLER_ALWAYS_ON_MODE_DEFAULT;
-
-    /**
-     * Mode Type for {@link #setControllerAlwaysOnMode(int)}.
-     * Enables the controller in transparent mode when NFC is disabled.
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    public static final int ENABLE_TRANSPARENT = 2;
-
-    /**
-     * Mode Type for {@link #setControllerAlwaysOnMode(int)}.
-     * Enables the controller and initializes and enables the EE subsystem when NFC is disabled.
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    public static final int ENABLE_EE = 3;
-
-    /**
-     * Mode Type for {@link #setControllerAlwaysOnMode(int)}.
-     * Disable the Controller Always On Mode.
-     * works same as {@link NfcAdapter#setControllerAlwaysOn(boolean)}.
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    public static final int DISABLE = NfcAdapter.CONTROLLER_ALWAYS_ON_DISABLE;
-
-    /**
-     * Possible controller modes for {@link #setControllerAlwaysOnMode(int)}.
-     *
-     * @hide
-     */
-    @IntDef(prefix = { "" }, value = {
-        ENABLE_DEFAULT,
-        ENABLE_TRANSPARENT,
-        ENABLE_EE,
-        DISABLE,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface ControllerMode{}
-
-    /**
-     * Technology Type for {@link #getActiveNfceeList()}.
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    public static final int NFCEE_TECH_NONE = 0;
-
-    /**
-     * Technology Type for {@link #getActiveNfceeList()}.
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    public static final int NFCEE_TECH_A = 1;
-
-    /**
-     * Technology Type for {@link #getActiveNfceeList()}.
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    public static final int NFCEE_TECH_B = 1 << 1;
-
-    /**
-     * Technology Type for {@link #getActiveNfceeList()}.
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    public static final int NFCEE_TECH_F = 1 << 2;
-
-    /**
-     * Nfc technology flags for {@link #getActiveNfceeList()}.
-     *
-     * @hide
-     */
-    @IntDef(flag = true, value = {
-        NFCEE_TECH_NONE,
-        NFCEE_TECH_A,
-        NFCEE_TECH_B,
-        NFCEE_TECH_F,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface NfceeTechnology {}
-
-    /**
-     * Event that Host Card Emulation is activated.
-     */
-    public static final int HCE_ACTIVATE = 1;
-    /**
-     * Event that some data is transferred in Host Card Emulation.
-     */
-    public static final int HCE_DATA_TRANSFERRED = 2;
-    /**
-     * Event that Host Card Emulation is deactivated.
-     */
-    public static final int HCE_DEACTIVATE = 3;
-    /**
-     * Possible events from {@link Callback#onHceEventReceived}.
-     *
-     * @hide
-     */
-    @IntDef(value = {
-            HCE_ACTIVATE,
-            HCE_DATA_TRANSFERRED,
-            HCE_DEACTIVATE
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface HostCardEmulationAction {}
-
-    /**
-     * Status code returned when the polling state change request succeeded.
-     * @see #pausePolling()
-     * @see #resumePolling()
-     */
-    public static final int POLLING_STATE_CHANGE_SUCCEEDED = 1;
-    /**
-     * Status code returned when the polling state change request is already in
-     * required state.
-     * @see #pausePolling()
-     * @see #resumePolling()
-     */
-    public static final int POLLING_STATE_CHANGE_ALREADY_IN_REQUESTED_STATE = 2;
-    /**
-     * Possible status codes for {@link #pausePolling()} and
-     * {@link #resumePolling()}.
-     * @hide
-     */
-    @IntDef(value = {
-            POLLING_STATE_CHANGE_SUCCEEDED,
-            POLLING_STATE_CHANGE_ALREADY_IN_REQUESTED_STATE,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface PollingStateChangeStatusCode {}
-
-    /**
-     * Status OK
-     */
-    public static final int STATUS_OK = 0;
-    /**
-     * Status unknown error
-     */
-    public static final int STATUS_UNKNOWN_ERROR = 1;
-
-    /**
-     * Status codes passed to OEM extension callbacks.
-     *
-     * @hide
-     */
-    @IntDef(value = {
-            STATUS_OK,
-            STATUS_UNKNOWN_ERROR
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface StatusCode {}
-
-    /**
-     * Routing commit succeeded.
-     */
-    public static final int COMMIT_ROUTING_STATUS_OK = 0;
-    /**
-     * Routing commit failed.
-     */
-    public static final int COMMIT_ROUTING_STATUS_FAILED = 3;
-    /**
-     * Routing commit failed due to the update is in progress.
-     */
-    public static final int COMMIT_ROUTING_STATUS_FAILED_UPDATE_IN_PROGRESS = 6;
-
-    /**
-     * Status codes returned when calling {@link #forceRoutingTableCommit()}
-     * @hide
-     */
-    @IntDef(prefix = "COMMIT_ROUTING_STATUS_", value = {
-            COMMIT_ROUTING_STATUS_OK,
-            COMMIT_ROUTING_STATUS_FAILED,
-            COMMIT_ROUTING_STATUS_FAILED_UPDATE_IN_PROGRESS,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface CommitRoutingStatusCode {}
-    /**
-     * Interface for Oem extensions for NFC.
-     */
-    public interface Callback {
-        /**
-         * Notify Oem to tag is connected or not
-         * ex - if tag is connected  notify cover and Nfctest app if app is in testing mode
-         *
-         * @param connected status of the tag true if tag is connected otherwise false
-         */
-        void onTagConnected(boolean connected);
-
-        /**
-         * Update the Nfc Adapter State
-         * @param state new state that need to be updated
-         */
-        void onStateUpdated(@NfcAdapter.AdapterState int state);
-        /**
-         * Check if NfcService apply routing method need to be skipped for
-         * some feature.
-         * @param isSkipped The {@link Consumer} to be completed. If apply routing can be skipped,
-         *                  the {@link Consumer#accept(Object)} should be called with
-         *                  {@link Boolean#TRUE}, otherwise call with {@link Boolean#FALSE}.
-         */
-        void onApplyRouting(@NonNull Consumer<Boolean> isSkipped);
-        /**
-         * Check if NfcService ndefRead method need to be skipped To skip
-         * and start checking for presence of tag
-         * @param isSkipped The {@link Consumer} to be completed. If Ndef read can be skipped,
-         *                  the {@link Consumer#accept(Object)} should be called with
-         *                  {@link Boolean#TRUE}, otherwise call with {@link Boolean#FALSE}.
-         */
-        void onNdefRead(@NonNull Consumer<Boolean> isSkipped);
-        /**
-         * Method to check if Nfc is allowed to be enabled by OEMs.
-         * @param isAllowed The {@link Consumer} to be completed. If enabling NFC is allowed,
-         *                  the {@link Consumer#accept(Object)} should be called with
-         *                  {@link Boolean#TRUE}, otherwise call with {@link Boolean#FALSE}.
-         * false if NFC cannot be enabled at this time.
-         */
-        void onEnableRequested(@NonNull Consumer<Boolean> isAllowed);
-        /**
-         * Method to check if Nfc is allowed to be disabled by OEMs.
-         * @param isAllowed The {@link Consumer} to be completed. If disabling NFC is allowed,
-         *                  the {@link Consumer#accept(Object)} should be called with
-         *                  {@link Boolean#TRUE}, otherwise call with {@link Boolean#FALSE}.
-         * false if NFC cannot be disabled at this time.
-         */
-        void onDisableRequested(@NonNull Consumer<Boolean> isAllowed);
-
-        /**
-         * Callback to indicate that Nfc starts to boot.
-         */
-        void onBootStarted();
-
-        /**
-         * Callback to indicate that Nfc starts to enable.
-         */
-        void onEnableStarted();
-
-        /**
-         * Callback to indicate that Nfc starts to disable.
-         */
-        void onDisableStarted();
-
-        /**
-         * Callback to indicate if NFC boots successfully or not.
-         * @param status the status code indicating if boot finished successfully
-         */
-        void onBootFinished(@StatusCode int status);
-
-        /**
-         * Callback to indicate if NFC is successfully enabled.
-         * @param status the status code indicating if enable finished successfully
-         */
-        void onEnableFinished(@StatusCode int status);
-
-        /**
-         * Callback to indicate if NFC is successfully disabled.
-         * @param status the status code indicating if disable finished successfully
-         */
-        void onDisableFinished(@StatusCode int status);
-
-        /**
-         * Check if NfcService tag dispatch need to be skipped.
-         * @param isSkipped The {@link Consumer} to be completed. If tag dispatch can be skipped,
-         *                  the {@link Consumer#accept(Object)} should be called with
-         *                  {@link Boolean#TRUE}, otherwise call with {@link Boolean#FALSE}.
-         */
-        void onTagDispatch(@NonNull Consumer<Boolean> isSkipped);
-
-        /**
-         * Notifies routing configuration is changed.
-         * @param isCommitRoutingSkipped The {@link Consumer} to be
-         * completed. If routing commit should be skipped,
-         * the {@link Consumer#accept(Object)} should be called with
-         * {@link Boolean#TRUE}, otherwise call with {@link Boolean#FALSE}.
-         */
-        void onRoutingChanged(@NonNull Consumer<Boolean> isCommitRoutingSkipped);
-
-        /**
-         * API to activate start stop cpu boost on hce event.
-         *
-         * <p>When HCE is activated, transferring data, and deactivated,
-         * must call this method to activate, start and stop cpu boost respectively.
-         * @param action Flag indicating actions to activate, start and stop cpu boost.
-         */
-        void onHceEventReceived(@HostCardEmulationAction int action);
-
-        /**
-         * API to notify when reader option has been changed using
-         * {@link NfcAdapter#enableReaderOption(boolean)} by some app.
-         * @param enabled Flag indicating ReaderMode enabled/disabled
-         */
-        void onReaderOptionChanged(boolean enabled);
-
-        /**
-        * Notifies NFC is activated in listen mode.
-        * NFC Forum NCI-2.3 ch.5.2.6 specification
-        *
-        * <p>NFCC is ready to communicate with a Card reader
-        *
-        * @param isActivated true, if card emulation activated, else de-activated.
-        */
-        void onCardEmulationActivated(boolean isActivated);
-
-        /**
-        * Notifies the Remote NFC Endpoint RF Field is activated.
-        * NFC Forum NCI-2.3 ch.5.3 specification
-        *
-        * @param isActivated true, if RF Field is ON, else RF Field is OFF.
-        */
-        void onRfFieldActivated(boolean isActivated);
-
-        /**
-        * Notifies the NFC RF discovery is started or in the IDLE state.
-        * NFC Forum NCI-2.3 ch.5.2 specification
-        *
-        * @param isDiscoveryStarted true, if RF discovery started, else RF state is Idle.
-        */
-        void onRfDiscoveryStarted(boolean isDiscoveryStarted);
-
-        /**
-        * Notifies the NFCEE (NFC Execution Environment) Listen has been activated.
-        *
-        * @param isActivated true, if EE Listen is ON, else EE Listen is OFF.
-        */
-        void onEeListenActivated(boolean isActivated);
-
-        /**
-        * Notifies that some NFCEE (NFC Execution Environment) has been updated.
-        *
-        * <p> This indicates that some applet has been installed/updated/removed in
-        * one of the NFCEE's.
-        * </p>
-        */
-        void onEeUpdated();
-
-        /**
-         * Gets the intent to find the OEM package in the OEM App market. If the consumer returns
-         * {@code null} or a timeout occurs, the intent from the first available package will be
-         * used instead.
-         *
-         * @param packages the OEM packages name stored in the tag
-         * @param intentConsumer The {@link Consumer} to be completed.
-         *                       The {@link Consumer#accept(Object)} should be called with
-         *                       the Intent required.
-         *
-         */
-        void onGetOemAppSearchIntent(@NonNull List<String> packages,
-                                     @NonNull Consumer<Intent> intentConsumer);
-
-        /**
-         * Checks if the NDEF message contains any specific OEM package executable content
-         *
-         * @param tag        the {@link android.nfc.Tag Tag}
-         * @param message NDEF Message to read from tag
-         * @param hasOemExecutableContent The {@link Consumer} to be completed. If there is
-         *                                OEM package executable content, the
-         *                                {@link Consumer#accept(Object)} should be called with
-         *                                {@link Boolean#TRUE}, otherwise call with
-         *                                {@link Boolean#FALSE}.
-         */
-        void onNdefMessage(@NonNull Tag tag, @NonNull NdefMessage message,
-                           @NonNull Consumer<Boolean> hasOemExecutableContent);
-
-        /**
-         * Callback to indicate the app chooser activity should be launched for handling CE
-         * transaction. This is invoked for example when there are more than 1 app installed that
-         * can handle the HCE transaction. OEMs can launch the Activity based
-         * on their requirement.
-         *
-         * @param selectedAid the selected AID from APDU
-         * @param services {@link ApduServiceInfo} of the service triggering the activity
-         * @param failedComponent the component failed to be resolved
-         * @param category the category of the service
-         */
-        void onLaunchHceAppChooserActivity(@NonNull String selectedAid,
-                                           @NonNull List<ApduServiceInfo> services,
-                                           @NonNull ComponentName failedComponent,
-                                           @NonNull String category);
-
-        /**
-         * Callback to indicate tap again dialog should be launched for handling HCE transaction.
-         * This is invoked for example when a CE service needs the device to unlocked before
-         * handling the transaction. OEMs can launch the Activity based on their requirement.
-         *
-         * @param service {@link ApduServiceInfo} of the service triggering the dialog
-         * @param category the category of the service
-         */
-        void onLaunchHceTapAgainDialog(@NonNull ApduServiceInfo service, @NonNull String category);
-
-        /**
-         * Callback to indicate that routing table is full and the OEM can optionally launch a
-         * dialog to request the user to remove some Card Emulation apps from the device to free
-         * routing table space.
-         */
-        void onRoutingTableFull();
-
-        /**
-         * Callback when OEM specified log event are notified.
-         * @param item the log items that contains log information of NFC event.
-         */
-        void onLogEventNotified(@NonNull OemLogItems item);
-
-        /**
-         * Callback to to extract OEM defined packages from given NDEF message when
-         * a NFC tag is detected. These are used to handle NFC tags encoded with a
-         * proprietary format for storing app name (Android native app format).
-         *
-         * @param message NDEF message containing OEM package names
-         * @param packageConsumer The {@link Consumer} to be completed.
-         *                        The {@link Consumer#accept(Object)} should be called with
-         *                        the list of package names.
-         */
-        void onExtractOemPackages(@NonNull NdefMessage message,
-                @NonNull Consumer<List<String>> packageConsumer);
-    }
-
-
-    /**
-     * Constructor to be used only by {@link NfcAdapter}.
-     */
-    NfcOemExtension(@NonNull Context context, @NonNull NfcAdapter adapter) {
-        mContext = context;
-        mAdapter = adapter;
-        mOemNfcExtensionCallback = new NfcOemExtensionCallback();
-    }
-
-    /**
-     * Get an instance of {@link T4tNdefNfcee} object for performing T4T (Type-4 Tag)
-     * NDEF (NFC Data Exchange Format) NFCEE (NFC Execution Environment) operations.
-     * This can be used to write NDEF data to emulate a T4T tag in an NFCEE
-     * (NFC Execution Environment - eSE, SIM, etc). Refer to the NFC forum specification
-     * "NFCForum-TS-NCI-2.3 section 10.4" and "NFCForum-TS-T4T-1.1 section 4.2" for more details.
-     *
-     * This is a singleton object which shall be used by OEM extension module to do NDEF-NFCEE
-     * read/write operations.
-     *
-     * <p>Returns {@link T4tNdefNfcee}
-     * <p>Does not cause any RF activity and does not block.
-     * @return NFC Data Exchange Format (NDEF) NFC Execution Environment (NFCEE) object
-     * @hide
-     */
-    @SystemApi
-    @NonNull
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    public T4tNdefNfcee getT4tNdefNfcee() {
-        return T4tNdefNfcee.getInstance();
-    }
-
-    /**
-     * Register an {@link Callback} to listen for NFC oem extension callbacks
-     * Multiple clients can register and callbacks will be invoked asynchronously.
-     *
-     * <p>The provided callback will be invoked by the given {@link Executor}.
-     * As part of {@link #registerCallback(Executor, Callback)} the
-     * {@link Callback} will be invoked with current NFC state
-     * before the {@link #registerCallback(Executor, Callback)} function completes.
-     *
-     * @param executor an {@link Executor} to execute given callback
-     * @param callback oem implementation of {@link Callback}
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public void registerCallback(@NonNull @CallbackExecutor Executor executor,
-            @NonNull Callback callback) {
-        synchronized (mLock) {
-            if (executor == null || callback == null) {
-                Log.e(TAG, "Executor and Callback must not be null!");
-                throw new IllegalArgumentException();
-            }
-
-            if (mCallbackMap.containsKey(callback)) {
-                Log.e(TAG, "Callback already registered. Unregister existing callback before"
-                        + "registering");
-                throw new IllegalArgumentException();
-            }
-            mCallbackMap.put(callback, executor);
-            if (!mIsRegistered) {
-                NfcAdapter.callService(() -> {
-                    NfcAdapter.sService.registerOemExtensionCallback(mOemNfcExtensionCallback);
-                    mIsRegistered = true;
-                });
-            } else {
-                updateNfCState(callback, executor);
-            }
-        }
-    }
-
-    private void updateNfCState(Callback callback, Executor executor) {
-        if (callback != null) {
-            Log.i(TAG, "updateNfCState");
-            executor.execute(() -> {
-                callback.onCardEmulationActivated(mCardEmulationActivated);
-                callback.onRfFieldActivated(mRfFieldActivated);
-                callback.onRfDiscoveryStarted(mRfDiscoveryStarted);
-                callback.onEeListenActivated(mEeListenActivated);
-            });
-        }
-    }
-
-    /**
-     * Unregister the specified {@link Callback}
-     *
-     * <p>The same {@link Callback} object used when calling
-     * {@link #registerCallback(Executor, Callback)} must be used.
-     *
-     * <p>Callbacks are automatically unregistered when an application process goes away
-     *
-     * @param callback oem implementation of {@link Callback}
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public void unregisterCallback(@NonNull Callback callback) {
-        synchronized (mLock) {
-            if (!mCallbackMap.containsKey(callback) || !mIsRegistered) {
-                Log.e(TAG, "Callback not registered");
-                throw new IllegalArgumentException();
-            }
-            if (mCallbackMap.size() == 1) {
-                NfcAdapter.callService(() -> {
-                    NfcAdapter.sService.unregisterOemExtensionCallback(mOemNfcExtensionCallback);
-                    mIsRegistered = false;
-                    mCallbackMap.remove(callback);
-                });
-            } else {
-                mCallbackMap.remove(callback);
-            }
-        }
-    }
-
-    /**
-     * Clear NfcService preference, interface method to clear NFC preference values on OEM specific
-     * events. For ex: on soft reset, Nfc default values needs to be overridden by OEM defaults.
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public void clearPreference() {
-        NfcAdapter.callService(() -> NfcAdapter.sService.clearPreference());
-    }
-
-    /**
-     * Get the screen state from system and set it to current screen state.
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public void synchronizeScreenState() {
-        NfcAdapter.callService(() -> NfcAdapter.sService.setScreenState());
-    }
-
-    /**
-     * Check if the firmware needs updating.
-     *
-     * <p>If an update is needed, a firmware will be triggered when NFC is disabled.
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public void maybeTriggerFirmwareUpdate() {
-        NfcAdapter.callService(() -> NfcAdapter.sService.checkFirmware());
-    }
-
-    /**
-     * Get the Active NFCEE (NFC Execution Environment) List
-     *
-     * @return Map< String, @NfceeTechnology Integer >
-     *         A HashMap where keys are activated secure elements and
-     *         the values are bitmap of technologies supported by each secure element:
-     *          NFCEE_TECH_A == 0x1
-     *          NFCEE_TECH_B == 0x2
-     *          NFCEE_TECH_F == 0x4
-     *         and keys can contain "eSE" and "SIM" with a number,
-     *         in case of failure an empty map is returned.
-     *         @see Reader#getName() for the list of possible NFCEE names.
-     */
-    @NonNull
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    public Map<String, Integer> getActiveNfceeList() {
-        return NfcAdapter.callServiceReturn(() ->
-            NfcAdapter.sService.fetchActiveNfceeList(), new HashMap<String, Integer>());
-    }
-
-    /**
-     * Sets NFC controller always on feature.
-     * <p>This API is for the NFCC internal state management. It allows to discriminate
-     * the controller function from the NFC function by keeping the NFC controller on without
-     * any NFC RF enabled if necessary.
-     * <p>This call is asynchronous, register listener {@link NfcAdapter.ControllerAlwaysOnListener}
-     * by {@link NfcAdapter#registerControllerAlwaysOnListener} to find out when the operation is
-     * complete.
-     * <p> Note: This adds more always on modes on top of existing
-     * {@link NfcAdapter#setControllerAlwaysOn(boolean)} API which can be used to set the NFCC in
-     * only {@link #ENABLE_DEFAULT} and {@link #DISABLE} modes.
-     * @param mode one of {@link ControllerMode} modes
-     * @throws UnsupportedOperationException if
-     *   <li> if FEATURE_NFC, FEATURE_NFC_HOST_CARD_EMULATION, FEATURE_NFC_HOST_CARD_EMULATION_NFCF,
-     *   FEATURE_NFC_OFF_HOST_CARD_EMULATION_UICC and FEATURE_NFC_OFF_HOST_CARD_EMULATION_ESE
-     *   are unavailable </li>
-     *   <li> if the feature is unavailable @see NfcAdapter#isNfcControllerAlwaysOnSupported() </li>
-     * @hide
-     * @see NfcAdapter#setControllerAlwaysOn(boolean)
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON)
-    public void setControllerAlwaysOnMode(@ControllerMode int mode) {
-        if (!NfcAdapter.sHasNfcFeature && !NfcAdapter.sHasCeFeature) {
-            throw new UnsupportedOperationException();
-        }
-        NfcAdapter.callService(() -> NfcAdapter.sService.setControllerAlwaysOn(mode));
-    }
-
-    /**
-     * Triggers NFC initialization. If OEM extension is registered
-     * (indicated via `enable_oem_extension` NFC overlay), the NFC stack initialization at bootup
-     * is delayed until the OEM extension app triggers the initialization via this call.
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public void triggerInitialization() {
-        NfcAdapter.callService(() -> NfcAdapter.sService.triggerInitialization());
-    }
-
-    /**
-     * Gets the last user toggle status.
-     * @return true if NFC is set to ON, false otherwise
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public boolean hasUserEnabledNfc() {
-        return NfcAdapter.callServiceReturn(() -> NfcAdapter.sService.getSettingStatus(), false);
-    }
-
-    /**
-     * Checks if the tag is present or not.
-     * @return true if the tag is present, false otherwise
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public boolean isTagPresent() {
-        return NfcAdapter.callServiceReturn(() -> NfcAdapter.sService.isTagPresent(), false);
-    }
-
-    /**
-     * Pauses NFC tag reader mode polling for a {@code timeoutInMs} millisecond.
-     * In case of {@code timeoutInMs} is zero or invalid polling will be stopped indefinitely.
-     * Use {@link #resumePolling()} to resume the polling.
-     * Use {@link #getMaxPausePollingTimeoutMs()} to check the max timeout value.
-     * @param timeoutInMs the pause polling duration in millisecond.
-     * @return status of the operation
-     * @throws IllegalArgumentException if timeoutInMs value is invalid
-     *         (0 < timeoutInMs < max).
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public @PollingStateChangeStatusCode int pausePolling(@DurationMillisLong long timeoutInMs) {
-        return NfcAdapter.callServiceReturn(() ->
-                NfcAdapter.sService.pausePolling(timeoutInMs),
-                POLLING_STATE_CHANGE_ALREADY_IN_REQUESTED_STATE);
-    }
-
-    /**
-     * Resumes default NFC tag reader mode polling for the current device state if polling is
-     * paused. Calling this while already in polling is a no-op.
-     * @return status of the operation
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public @PollingStateChangeStatusCode int resumePolling() {
-        return NfcAdapter.callServiceReturn(() ->
-                NfcAdapter.sService.resumePolling(),
-                POLLING_STATE_CHANGE_ALREADY_IN_REQUESTED_STATE);
-    }
-
-    /**
-     * Gets the max pause polling timeout value in millisecond.
-     * @return long integer representing the max timeout
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    @DurationMillisLong
-    public long getMaxPausePollingTimeoutMills() {
-        return NfcAdapter.callServiceReturn(() ->
-                NfcAdapter.sService.getMaxPausePollingTimeoutMs(), 0L);
-    }
-
-    /**
-     * Set whether to enable auto routing change or not (enabled by default).
-     * If disabled, routing targets are limited to a single off-host destination.
-     *
-     * @param state status of auto routing change, true if enable, otherwise false
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
-    public void setAutoChangeEnabled(boolean state) {
-        NfcAdapter.callService(() ->
-                NfcAdapter.sCardEmulationService.setAutoChangeStatus(state));
-    }
-
-    /**
-     * Check if auto routing change is enabled or not.
-     *
-     * @return true if enabled, otherwise false
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
-    public boolean isAutoChangeEnabled() {
-        return NfcAdapter.callServiceReturn(() ->
-                NfcAdapter.sCardEmulationService.isAutoChangeEnabled(), false);
-    }
-
-    /**
-     * Get current routing status
-     *
-     * @return {@link RoutingStatus} indicating the default route, default ISO-DEP
-     * route and default off-host route.
-     */
-    @NonNull
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
-    public RoutingStatus getRoutingStatus() {
-        List<String> status = NfcAdapter.callServiceReturn(() ->
-                NfcAdapter.sCardEmulationService.getRoutingStatus(), new ArrayList<>());
-        return new RoutingStatus(routeStringToInt(status.get(0)),
-                routeStringToInt(status.get(1)),
-                routeStringToInt(status.get(2)));
-    }
-
-    /**
-     * Overwrites NFC controller routing table, which includes Protocol Route, Technology Route,
-     * and Empty AID Route.
-     *
-     * The parameter set to
-     * {@link ProtocolAndTechnologyRoute#PROTOCOL_AND_TECHNOLOGY_ROUTE_UNSET}
-     * can be used to keep current values for that entry. At least one route should be overridden
-     * when calling this API, otherwise throw {@link IllegalArgumentException}.
-     *
-     * @param protocol ISO-DEP route destination, where the possible inputs are defined in
-     *                 {@link ProtocolAndTechnologyRoute}.
-     * @param technology Tech-A, Tech-B and Tech-F route destination, where the possible inputs
-     *                   are defined in
-     *                   {@link ProtocolAndTechnologyRoute}
-     * @param emptyAid Zero-length AID route destination, where the possible inputs are defined in
-     *                 {@link ProtocolAndTechnologyRoute}
-     * @param systemCode System Code route destination, where the possible inputs are defined in
-     *                   {@link ProtocolAndTechnologyRoute}
-     */
-    @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    public void overwriteRoutingTable(
-            @CardEmulation.ProtocolAndTechnologyRoute int protocol,
-            @CardEmulation.ProtocolAndTechnologyRoute int technology,
-            @CardEmulation.ProtocolAndTechnologyRoute int emptyAid,
-            @CardEmulation.ProtocolAndTechnologyRoute int systemCode) {
-
-        String protocolRoute = routeIntToString(protocol);
-        String technologyRoute = routeIntToString(technology);
-        String emptyAidRoute = routeIntToString(emptyAid);
-        String systemCodeRoute = routeIntToString(systemCode);
-
-        NfcAdapter.callService(() ->
-                NfcAdapter.sCardEmulationService.overwriteRoutingTable(
-                        mContext.getUser().getIdentifier(),
-                        emptyAidRoute,
-                        protocolRoute,
-                        technologyRoute,
-                        systemCodeRoute
-                ));
-    }
-
-    /**
-     * Gets current routing table entries.
-     * @return List of {@link NfcRoutingTableEntry} representing current routing table
-     */
-    @NonNull
-    @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    public List<NfcRoutingTableEntry> getRoutingTable() {
-        List<Entry> entryList = NfcAdapter.callServiceReturn(() ->
-                NfcAdapter.sService.getRoutingTableEntryList(), null);
-        List<NfcRoutingTableEntry> result = new ArrayList<>();
-        for (Entry entry : entryList) {
-            switch (entry.getType()) {
-                case TYPE_TECHNOLOGY -> result.add(
-                        new RoutingTableTechnologyEntry(entry.getNfceeId(),
-                                RoutingTableTechnologyEntry.techStringToInt(entry.getEntry()),
-                                routeStringToInt(entry.getRoutingType()))
-                );
-                case TYPE_PROTOCOL -> result.add(
-                        new RoutingTableProtocolEntry(entry.getNfceeId(),
-                                RoutingTableProtocolEntry.protocolStringToInt(entry.getEntry()),
-                                routeStringToInt(entry.getRoutingType()))
-                );
-                case TYPE_AID -> result.add(
-                        new RoutingTableAidEntry(entry.getNfceeId(), entry.getEntry(),
-                                routeStringToInt(entry.getRoutingType()))
-                );
-                case TYPE_SYSTEMCODE -> result.add(
-                        new RoutingTableSystemCodeEntry(entry.getNfceeId(),
-                                entry.getEntry().getBytes(StandardCharsets.UTF_8),
-                                routeStringToInt(entry.getRoutingType()))
-                );
-            }
-        }
-        return result;
-    }
-
-    /**
-     * API to force a routing table commit.
-     * @return a {@link StatusCode} to indicate if commit routing succeeded or not
-     */
-    @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    @CommitRoutingStatusCode
-    public int forceRoutingTableCommit() {
-        return NfcAdapter.callServiceReturn(
-                () -> NfcAdapter.sService.commitRouting(), COMMIT_ROUTING_STATUS_FAILED);
-    }
-
-    private final class NfcOemExtensionCallback extends INfcOemExtensionCallback.Stub {
-
-        @Override
-        public void onTagConnected(boolean connected) throws RemoteException {
-            mCallbackMap.forEach((cb, ex) ->
-                    handleVoidCallback(connected, cb::onTagConnected, ex));
-        }
-
-        @Override
-        public void onCardEmulationActivated(boolean isActivated) throws RemoteException {
-            mCardEmulationActivated = isActivated;
-            mCallbackMap.forEach((cb, ex) ->
-                    handleVoidCallback(isActivated, cb::onCardEmulationActivated, ex));
-        }
-
-        @Override
-        public void onRfFieldActivated(boolean isActivated) throws RemoteException {
-            mRfFieldActivated = isActivated;
-            mCallbackMap.forEach((cb, ex) ->
-                    handleVoidCallback(isActivated, cb::onRfFieldActivated, ex));
-        }
-
-        @Override
-        public void onRfDiscoveryStarted(boolean isDiscoveryStarted) throws RemoteException {
-            mRfDiscoveryStarted = isDiscoveryStarted;
-            mCallbackMap.forEach((cb, ex) ->
-                    handleVoidCallback(isDiscoveryStarted, cb::onRfDiscoveryStarted, ex));
-        }
-
-        @Override
-        public void onEeListenActivated(boolean isActivated) throws RemoteException {
-            mEeListenActivated = isActivated;
-            mCallbackMap.forEach((cb, ex) ->
-                    handleVoidCallback(isActivated, cb::onEeListenActivated, ex));
-        }
-
-        @Override
-        public void onEeUpdated() throws RemoteException {
-            mCallbackMap.forEach((cb, ex) ->
-                    handleVoidCallback(null, (Object input) -> cb.onEeUpdated(), ex));
-        }
-
-        @Override
-        public void onStateUpdated(int state) throws RemoteException {
-            mCallbackMap.forEach((cb, ex) ->
-                    handleVoidCallback(state, cb::onStateUpdated, ex));
-        }
-
-        @Override
-        public void onApplyRouting(ResultReceiver isSkipped) throws RemoteException {
-            mCallbackMap.forEach((cb, ex) ->
-                    handleVoidCallback(
-                        new ReceiverWrapper<>(isSkipped), cb::onApplyRouting, ex));
-        }
-        @Override
-        public void onNdefRead(ResultReceiver isSkipped) throws RemoteException {
-            mCallbackMap.forEach((cb, ex) ->
-                    handleVoidCallback(
-                        new ReceiverWrapper<>(isSkipped), cb::onNdefRead, ex));
-        }
-        @Override
-        public void onEnable(ResultReceiver isAllowed) throws RemoteException {
-            mCallbackMap.forEach((cb, ex) ->
-                    handleVoidCallback(
-                        new ReceiverWrapper<>(isAllowed), cb::onEnableRequested, ex));
-        }
-        @Override
-        public void onDisable(ResultReceiver isAllowed) throws RemoteException {
-            mCallbackMap.forEach((cb, ex) ->
-                    handleVoidCallback(
-                        new ReceiverWrapper<>(isAllowed), cb::onDisableRequested, ex));
-        }
-        @Override
-        public void onBootStarted() throws RemoteException {
-            mCallbackMap.forEach((cb, ex) ->
-                    handleVoidCallback(null, (Object input) -> cb.onBootStarted(), ex));
-        }
-        @Override
-        public void onEnableStarted() throws RemoteException {
-            mCallbackMap.forEach((cb, ex) ->
-                    handleVoidCallback(null, (Object input) -> cb.onEnableStarted(), ex));
-        }
-        @Override
-        public void onDisableStarted() throws RemoteException {
-            mCallbackMap.forEach((cb, ex) ->
-                    handleVoidCallback(null, (Object input) -> cb.onDisableStarted(), ex));
-        }
-        @Override
-        public void onBootFinished(int status) throws RemoteException {
-            mCallbackMap.forEach((cb, ex) ->
-                    handleVoidCallback(status, cb::onBootFinished, ex));
-        }
-        @Override
-        public void onEnableFinished(int status) throws RemoteException {
-            mCallbackMap.forEach((cb, ex) ->
-                    handleVoidCallback(status, cb::onEnableFinished, ex));
-        }
-        @Override
-        public void onDisableFinished(int status) throws RemoteException {
-            mCallbackMap.forEach((cb, ex) ->
-                    handleVoidCallback(status, cb::onDisableFinished, ex));
-        }
-        @Override
-        public void onTagDispatch(ResultReceiver isSkipped) throws RemoteException {
-            mCallbackMap.forEach((cb, ex) ->
-                    handleVoidCallback(
-                        new ReceiverWrapper<>(isSkipped), cb::onTagDispatch, ex));
-        }
-        @Override
-        public void onRoutingChanged(ResultReceiver isSkipped) throws RemoteException {
-            mCallbackMap.forEach((cb, ex) ->
-                    handleVoidCallback(
-                            new ReceiverWrapper<>(isSkipped), cb::onRoutingChanged, ex));
-        }
-        @Override
-        public void onHceEventReceived(int action) throws RemoteException {
-            mCallbackMap.forEach((cb, ex) ->
-                    handleVoidCallback(action, cb::onHceEventReceived, ex));
-        }
-
-        @Override
-        public void onReaderOptionChanged(boolean enabled) throws RemoteException {
-            mCallbackMap.forEach((cb, ex) ->
-                    handleVoidCallback(enabled, cb::onReaderOptionChanged, ex));
-        }
-
-        public void onRoutingTableFull() throws RemoteException {
-            mCallbackMap.forEach((cb, ex) ->
-                    handleVoidCallback(null,
-                            (Object input) -> cb.onRoutingTableFull(), ex));
-        }
-
-        @Override
-        public void onGetOemAppSearchIntent(List<String> packages, ResultReceiver intentConsumer)
-                throws RemoteException {
-            mCallbackMap.forEach((cb, ex) ->
-                    handleVoid2ArgCallback(packages, new ReceiverWrapper<>(intentConsumer),
-                            cb::onGetOemAppSearchIntent, ex));
-        }
-
-        @Override
-        public void onNdefMessage(Tag tag, NdefMessage message,
-                                  ResultReceiver hasOemExecutableContent) throws RemoteException {
-            mCallbackMap.forEach((cb, ex) -> {
-                synchronized (mLock) {
-                    final long identity = Binder.clearCallingIdentity();
-                    try {
-                        ex.execute(() -> cb.onNdefMessage(
-                                tag, message, new ReceiverWrapper<>(hasOemExecutableContent)));
-                    } catch (RuntimeException exception) {
-                        throw exception;
-                    } finally {
-                        Binder.restoreCallingIdentity(identity);
-                    }
-                }
-            });
-        }
-
-        @Override
-        public void onLaunchHceAppChooserActivity(String selectedAid,
-                                                  List<ApduServiceInfo> services,
-                                                  ComponentName failedComponent, String category)
-                throws RemoteException {
-            mCallbackMap.forEach((cb, ex) -> {
-                synchronized (mLock) {
-                    final long identity = Binder.clearCallingIdentity();
-                    try {
-                        ex.execute(() -> cb.onLaunchHceAppChooserActivity(
-                                selectedAid, services, failedComponent, category));
-                    } catch (RuntimeException exception) {
-                        throw exception;
-                    } finally {
-                        Binder.restoreCallingIdentity(identity);
-                    }
-                }
-            });
-        }
-
-        @Override
-        public void onLaunchHceTapAgainActivity(ApduServiceInfo service, String category)
-                throws RemoteException {
-            mCallbackMap.forEach((cb, ex) ->
-                    handleVoid2ArgCallback(service, category, cb::onLaunchHceTapAgainDialog, ex));
-        }
-
-        @Override
-        public void onLogEventNotified(OemLogItems item) throws RemoteException  {
-            mCallbackMap.forEach((cb, ex) ->
-                    handleVoidCallback(item, cb::onLogEventNotified, ex));
-        }
-
-        @Override
-        public void onExtractOemPackages(NdefMessage message, ResultReceiver packageConsumer)
-                throws RemoteException {
-            mCallbackMap.forEach((cb, ex) ->
-                    handleVoid2ArgCallback(message,
-                            new ReceiverWrapper<>(packageConsumer),
-                            cb::onExtractOemPackages, ex));
-        }
-
-        private <T> void handleVoidCallback(
-                T input, Consumer<T> callbackMethod, Executor executor) {
-            synchronized (mLock) {
-                final long identity = Binder.clearCallingIdentity();
-                try {
-                    executor.execute(() -> callbackMethod.accept(input));
-                } catch (RuntimeException ex) {
-                    throw ex;
-                } finally {
-                    Binder.restoreCallingIdentity(identity);
-                }
-            }
-        }
-
-        private <T1, T2> void handleVoid2ArgCallback(
-                T1 input1, T2 input2, BiConsumer<T1, T2> callbackMethod, Executor executor) {
-            synchronized (mLock) {
-                final long identity = Binder.clearCallingIdentity();
-                try {
-                    executor.execute(() -> callbackMethod.accept(input1, input2));
-                } catch (RuntimeException ex) {
-                    throw ex;
-                } finally {
-                    Binder.restoreCallingIdentity(identity);
-                }
-            }
-        }
-
-        private <S, T> S handleNonVoidCallbackWithInput(
-                S defaultValue, T input, Function<T, S> callbackMethod) throws RemoteException {
-            synchronized (mLock) {
-                final long identity = Binder.clearCallingIdentity();
-                S result = defaultValue;
-                try {
-                    ExecutorService executor = Executors.newSingleThreadExecutor();
-                    FutureTask<S> futureTask = new FutureTask<>(() -> callbackMethod.apply(input));
-                    var unused = executor.submit(futureTask);
-                    try {
-                        result = futureTask.get(
-                                OEM_EXTENSION_RESPONSE_THRESHOLD_MS, TimeUnit.MILLISECONDS);
-                    } catch (ExecutionException | InterruptedException e) {
-                        e.printStackTrace();
-                    } catch (TimeoutException e) {
-                        Log.w(TAG, "Callback timed out: " + callbackMethod);
-                        e.printStackTrace();
-                    } finally {
-                        executor.shutdown();
-                    }
-                } finally {
-                    Binder.restoreCallingIdentity(identity);
-                }
-                return result;
-            }
-        }
-
-        private <T> T handleNonVoidCallbackWithoutInput(T defaultValue, Supplier<T> callbackMethod)
-                throws RemoteException {
-            synchronized (mLock) {
-                final long identity = Binder.clearCallingIdentity();
-                T result = defaultValue;
-                try {
-                    ExecutorService executor = Executors.newSingleThreadExecutor();
-                    FutureTask<T> futureTask = new FutureTask<>(callbackMethod::get);
-                    var unused = executor.submit(futureTask);
-                    try {
-                        result = futureTask.get(
-                                OEM_EXTENSION_RESPONSE_THRESHOLD_MS, TimeUnit.MILLISECONDS);
-                    } catch (ExecutionException | InterruptedException e) {
-                        e.printStackTrace();
-                    } catch (TimeoutException e) {
-                        Log.w(TAG, "Callback timed out: " + callbackMethod);
-                        e.printStackTrace();
-                    } finally {
-                        executor.shutdown();
-                    }
-                } finally {
-                    Binder.restoreCallingIdentity(identity);
-                }
-                return result;
-            }
-        }
-    }
-
-    private @CardEmulation.ProtocolAndTechnologyRoute int routeStringToInt(String route) {
-        if (route.equals("DH")) {
-            return PROTOCOL_AND_TECHNOLOGY_ROUTE_DH;
-        } else if (route.startsWith("eSE")) {
-            return PROTOCOL_AND_TECHNOLOGY_ROUTE_ESE;
-        } else if (route.startsWith("SIM")) {
-            return PROTOCOL_AND_TECHNOLOGY_ROUTE_UICC;
-        } else {
-            throw new IllegalStateException("Unexpected value: " + route);
-        }
-    }
-
-    private class ReceiverWrapper<T> implements Consumer<T> {
-        private final ResultReceiver mResultReceiver;
-
-        ReceiverWrapper(ResultReceiver resultReceiver) {
-            mResultReceiver = resultReceiver;
-        }
-
-        @Override
-        public void accept(T result) {
-            if (result instanceof Boolean) {
-                mResultReceiver.send((Boolean) result ? 1 : 0, null);
-            } else if (result instanceof Intent) {
-                Bundle bundle = new Bundle();
-                bundle.putParcelable("intent", (Intent) result);
-                mResultReceiver.send(0, bundle);
-            } else if (result instanceof List<?> list) {
-                if (list.stream().allMatch(String.class::isInstance)) {
-                    Bundle bundle = new Bundle();
-                    bundle.putStringArray("packageNames",
-                            list.stream().map(pkg -> (String) pkg).toArray(String[]::new));
-                    mResultReceiver.send(0, bundle);
-                }
-            }
-        }
-
-        @Override
-        public Consumer<T> andThen(Consumer<? super T> after) {
-            return Consumer.super.andThen(after);
-        }
-    }
-}
diff --git a/nfc/java/android/nfc/NfcRoutingTableEntry.java b/nfc/java/android/nfc/NfcRoutingTableEntry.java
deleted file mode 100644
index 4153779..0000000
--- a/nfc/java/android/nfc/NfcRoutingTableEntry.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.nfc;
-
-
-import android.annotation.FlaggedApi;
-import android.annotation.IntDef;
-import android.annotation.SystemApi;
-import android.nfc.cardemulation.CardEmulation;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Class to represent an entry of routing table. This class is abstract and extended by
- * {@link RoutingTableTechnologyEntry}, {@link RoutingTableProtocolEntry},
- * {@link RoutingTableAidEntry} and {@link RoutingTableSystemCodeEntry}.
- *
- * @hide
- */
-@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-@SystemApi
-public abstract class NfcRoutingTableEntry {
-    private final int mNfceeId;
-    private final int mType;
-    private final int mRouteType;
-
-    /**
-     * AID routing table type.
-     */
-    public static final int TYPE_AID = 0;
-    /**
-     * Protocol routing table type.
-     */
-    public static final int TYPE_PROTOCOL = 1;
-    /**
-     * Technology routing table type.
-     */
-    public static final int TYPE_TECHNOLOGY = 2;
-    /**
-     * System Code routing table type.
-     */
-    public static final int TYPE_SYSTEM_CODE = 3;
-
-    /**
-     * Possible type of this routing table entry.
-     * @hide
-     */
-    @IntDef(prefix = "TYPE_", value = {
-            TYPE_AID,
-            TYPE_PROTOCOL,
-            TYPE_TECHNOLOGY,
-            TYPE_SYSTEM_CODE
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface RoutingTableType {}
-
-    /** @hide */
-    protected NfcRoutingTableEntry(int nfceeId, @RoutingTableType int type,
-            @CardEmulation.ProtocolAndTechnologyRoute int routeType) {
-        mNfceeId = nfceeId;
-        mType = type;
-        mRouteType = routeType;
-    }
-
-    /**
-     * Gets the NFCEE Id of this entry.
-     * @return an integer of NFCEE Id.
-     */
-    public int getNfceeId() {
-        return mNfceeId;
-    }
-
-    /**
-     * Get the type of this entry.
-     * @return an integer defined in {@link RoutingTableType}
-     */
-    @RoutingTableType
-    public int getType() {
-        return mType;
-    }
-
-    /**
-     * Get the route type of this entry.
-     * @return an integer defined in
-     * {@link android.nfc.cardemulation.CardEmulation.ProtocolAndTechnologyRoute}
-     */
-    @CardEmulation.ProtocolAndTechnologyRoute
-    public int getRouteType() {
-        return mRouteType;
-    }
-}
diff --git a/nfc/java/android/nfc/NfcVendorNciCallbackListener.java b/nfc/java/android/nfc/NfcVendorNciCallbackListener.java
deleted file mode 100644
index 742d75f..0000000
--- a/nfc/java/android/nfc/NfcVendorNciCallbackListener.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.nfc;
-
-import android.annotation.NonNull;
-import android.nfc.NfcAdapter.NfcVendorNciCallback;
-import android.os.Binder;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.Executor;
-
-/**
- * @hide
- */
-public final class NfcVendorNciCallbackListener extends INfcVendorNciCallback.Stub {
-    private static final String TAG = "Nfc.NfcVendorNciCallbacks";
-    private final INfcAdapter mAdapter;
-    private boolean mIsRegistered = false;
-    private final Map<NfcVendorNciCallback, Executor> mCallbackMap = new HashMap<>();
-
-    public NfcVendorNciCallbackListener(@NonNull INfcAdapter adapter) {
-        mAdapter = adapter;
-    }
-
-    public void register(@NonNull Executor executor, @NonNull NfcVendorNciCallback callback) {
-        synchronized (this) {
-            if (mCallbackMap.containsKey(callback)) {
-                return;
-            }
-            mCallbackMap.put(callback, executor);
-            if (!mIsRegistered) {
-                try {
-                    mAdapter.registerVendorExtensionCallback(this);
-                    mIsRegistered = true;
-                } catch (RemoteException e) {
-                    Log.w(TAG, "Failed to register adapter state callback");
-                    mCallbackMap.remove(callback);
-                    throw e.rethrowFromSystemServer();
-                }
-            }
-        }
-    }
-
-    public void unregister(@NonNull NfcVendorNciCallback callback) {
-        synchronized (this) {
-            if (!mCallbackMap.containsKey(callback) || !mIsRegistered) {
-                return;
-            }
-            if (mCallbackMap.size() == 1) {
-                try {
-                    mAdapter.unregisterVendorExtensionCallback(this);
-                    mIsRegistered = false;
-                    mCallbackMap.remove(callback);
-                } catch (RemoteException e) {
-                    Log.w(TAG, "Failed to unregister AdapterStateCallback with service");
-                    throw e.rethrowFromSystemServer();
-                }
-            } else {
-                mCallbackMap.remove(callback);
-            }
-        }
-    }
-
-    @Override
-    public void onVendorResponseReceived(int gid, int oid, @NonNull byte[] payload)
-            throws RemoteException {
-        synchronized (this) {
-            final long identity = Binder.clearCallingIdentity();
-            try {
-                for (NfcVendorNciCallback callback : mCallbackMap.keySet()) {
-                    Executor executor = mCallbackMap.get(callback);
-                    executor.execute(() -> callback.onVendorNciResponse(gid, oid, payload));
-                }
-            } catch (RuntimeException ex) {
-                throw ex;
-            } finally {
-                Binder.restoreCallingIdentity(identity);
-            }
-        }
-    }
-
-    @Override
-    public void onVendorNotificationReceived(int gid, int oid, @NonNull byte[] payload)
-            throws RemoteException {
-        synchronized (this) {
-            final long identity = Binder.clearCallingIdentity();
-            try {
-                for (NfcVendorNciCallback callback : mCallbackMap.keySet()) {
-                    Executor executor = mCallbackMap.get(callback);
-                    executor.execute(() -> callback.onVendorNciNotification(gid, oid, payload));
-                }
-            } catch (RuntimeException ex) {
-                throw ex;
-            } finally {
-                Binder.restoreCallingIdentity(identity);
-            }
-        }
-    }
-}
diff --git a/nfc/java/android/nfc/NfcWlcStateListener.java b/nfc/java/android/nfc/NfcWlcStateListener.java
deleted file mode 100644
index 890cb09..0000000
--- a/nfc/java/android/nfc/NfcWlcStateListener.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import android.annotation.NonNull;
-import android.nfc.NfcAdapter.WlcStateListener;
-import android.os.Binder;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.Executor;
-
-/**
- * @hide
- */
-public class NfcWlcStateListener extends INfcWlcStateListener.Stub {
-    private static final String TAG = NfcWlcStateListener.class.getSimpleName();
-
-    private final INfcAdapter mAdapter;
-
-    private final Map<WlcStateListener, Executor> mListenerMap = new HashMap<>();
-
-    private WlcListenerDeviceInfo mCurrentState = null;
-    private boolean mIsRegistered = false;
-
-    public NfcWlcStateListener(@NonNull INfcAdapter adapter) {
-        mAdapter = adapter;
-    }
-
-    /**
-     * Register a {@link WlcStateListener} with this
-     * {@link WlcStateListener}
-     *
-     * @param executor an {@link Executor} to execute given listener
-     * @param listener user implementation of the {@link WlcStateListener}
-     */
-    public void register(@NonNull Executor executor, @NonNull WlcStateListener listener) {
-        synchronized (this) {
-            if (mListenerMap.containsKey(listener)) {
-                return;
-            }
-
-            mListenerMap.put(listener, executor);
-
-            if (!mIsRegistered) {
-                try {
-                    mAdapter.registerWlcStateListener(this);
-                    mIsRegistered = true;
-                } catch (RemoteException e) {
-                    Log.w(TAG, "Failed to register");
-                }
-            }
-        }
-    }
-
-    /**
-     * Unregister the specified {@link WlcStateListener}
-     *
-     * @param listener user implementation of the {@link WlcStateListener}
-     */
-    public void unregister(@NonNull WlcStateListener listener) {
-        synchronized (this) {
-            if (!mListenerMap.containsKey(listener)) {
-                return;
-            }
-
-            mListenerMap.remove(listener);
-
-            if (mListenerMap.isEmpty() && mIsRegistered) {
-                try {
-                    mAdapter.unregisterWlcStateListener(this);
-                } catch (RemoteException e) {
-                    Log.w(TAG, "Failed to unregister");
-                }
-                mIsRegistered = false;
-            }
-        }
-    }
-
-    private void sendCurrentState(@NonNull WlcStateListener listener) {
-        synchronized (this) {
-            Executor executor = mListenerMap.get(listener);
-            final long identity = Binder.clearCallingIdentity();
-            try {
-                if (Flags.enableNfcCharging()) {
-                    executor.execute(() -> listener.onWlcStateChanged(
-                            mCurrentState));
-                }
-            } finally {
-                Binder.restoreCallingIdentity(identity);
-            }
-        }
-    }
-
-    @Override
-    public void onWlcStateChanged(@NonNull WlcListenerDeviceInfo wlcListenerDeviceInfo) {
-        synchronized (this) {
-            mCurrentState = wlcListenerDeviceInfo;
-
-            for (WlcStateListener cb : mListenerMap.keySet()) {
-                sendCurrentState(cb);
-            }
-        }
-    }
-}
-
diff --git a/nfc/java/android/nfc/OemLogItems.aidl b/nfc/java/android/nfc/OemLogItems.aidl
deleted file mode 100644
index 3bcb445..0000000
--- a/nfc/java/android/nfc/OemLogItems.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-parcelable OemLogItems;
\ No newline at end of file
diff --git a/nfc/java/android/nfc/OemLogItems.java b/nfc/java/android/nfc/OemLogItems.java
deleted file mode 100644
index 4f3e199..0000000
--- a/nfc/java/android/nfc/OemLogItems.java
+++ /dev/null
@@ -1,333 +0,0 @@
-/*
- * Copyright 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import android.annotation.FlaggedApi;
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.time.Instant;
-
-/**
- * A log class for OEMs to get log information of NFC events.
- * @hide
- */
-@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-@SystemApi
-public final class OemLogItems implements Parcelable {
-    /**
-     * Used when RF field state is changed.
-     */
-    public static final int LOG_ACTION_RF_FIELD_STATE_CHANGED = 0X01;
-    /**
-     * Used when NFC is toggled. Event should be set to {@link LogEvent#EVENT_ENABLE} or
-     * {@link LogEvent#EVENT_DISABLE} if this action is used.
-     */
-    public static final int LOG_ACTION_NFC_TOGGLE = 0x0201;
-    /**
-     * Used when sending host routing status.
-     */
-    public static final int LOG_ACTION_HCE_DATA = 0x0204;
-    /**
-     * Used when screen state is changed.
-     */
-    public static final int LOG_ACTION_SCREEN_STATE_CHANGED = 0x0206;
-    /**
-     * Used when tag is detected.
-     */
-    public static final int LOG_ACTION_TAG_DETECTED = 0x03;
-
-    /**
-     * @hide
-     */
-    @IntDef(prefix = { "LOG_ACTION_" }, value = {
-            LOG_ACTION_RF_FIELD_STATE_CHANGED,
-            LOG_ACTION_NFC_TOGGLE,
-            LOG_ACTION_HCE_DATA,
-            LOG_ACTION_SCREEN_STATE_CHANGED,
-            LOG_ACTION_TAG_DETECTED,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface LogAction {}
-
-    /**
-     * Represents the event is not set.
-     */
-    public static final int EVENT_UNSET = 0;
-    /**
-     * Represents nfc enable is called.
-     */
-    public static final int EVENT_ENABLE = 1;
-    /**
-     * Represents nfc disable is called.
-     */
-    public static final int EVENT_DISABLE = 2;
-    /** @hide */
-    @IntDef(prefix = { "EVENT_" }, value = {
-            EVENT_UNSET,
-            EVENT_ENABLE,
-            EVENT_DISABLE,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface LogEvent {}
-    private int mAction;
-    private int mEvent;
-    private int mCallingPid;
-    private byte[] mCommandApdus;
-    private byte[] mResponseApdus;
-    private Instant mRfFieldOnTime;
-    private Tag mTag;
-
-    /** @hide */
-    public OemLogItems(@LogAction int action, @LogEvent int event, int callingPid,
-            byte[] commandApdus, byte[] responseApdus, Instant rfFieldOnTime,
-            Tag tag) {
-        mAction = action;
-        mEvent = event;
-        mTag = tag;
-        mCallingPid = callingPid;
-        mCommandApdus = commandApdus;
-        mResponseApdus = responseApdus;
-        mRfFieldOnTime = rfFieldOnTime;
-    }
-
-    /**
-     * Describe the kinds of special objects contained in this Parcelable
-     * instance's marshaled representation. For example, if the object will
-     * include a file descriptor in the output of {@link #writeToParcel(Parcel, int)},
-     * the return value of this method must include the
-     * {@link #CONTENTS_FILE_DESCRIPTOR} bit.
-     *
-     * @return a bitmask indicating the set of special object types marshaled
-     * by this Parcelable object instance.
-     */
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    /**
-     * Flatten this object in to a Parcel.
-     *
-     * @param dest  The Parcel in which the object should be written.
-     * @param flags Additional flags about how the object should be written.
-     *              May be 0 or {@link #PARCELABLE_WRITE_RETURN_VALUE}.
-     */
-    @Override
-    public void writeToParcel(@NonNull Parcel dest, int flags) {
-        dest.writeInt(mAction);
-        dest.writeInt(mEvent);
-        dest.writeInt(mCallingPid);
-        dest.writeInt(mCommandApdus.length);
-        dest.writeByteArray(mCommandApdus);
-        dest.writeInt(mResponseApdus.length);
-        dest.writeByteArray(mResponseApdus);
-        dest.writeBoolean(mRfFieldOnTime != null);
-        if (mRfFieldOnTime != null) {
-            dest.writeLong(mRfFieldOnTime.getEpochSecond());
-            dest.writeInt(mRfFieldOnTime.getNano());
-        }
-        dest.writeParcelable(mTag, 0);
-    }
-
-    /** @hide */
-    public static class Builder {
-        private final OemLogItems mItem;
-
-        public Builder(@LogAction int type) {
-            mItem = new OemLogItems(type, EVENT_UNSET, 0, new byte[0], new byte[0], null, null);
-        }
-
-        /** Setter of the log action. */
-        public OemLogItems.Builder setAction(@LogAction int action) {
-            mItem.mAction = action;
-            return this;
-        }
-
-        /** Setter of the log calling event. */
-        public OemLogItems.Builder setCallingEvent(@LogEvent int event) {
-            mItem.mEvent = event;
-            return this;
-        }
-
-        /** Setter of the log calling Pid. */
-        public OemLogItems.Builder setCallingPid(int pid) {
-            mItem.mCallingPid = pid;
-            return this;
-        }
-
-        /** Setter of APDU command. */
-        public OemLogItems.Builder setApduCommand(byte[] apdus) {
-            mItem.mCommandApdus = apdus;
-            return this;
-        }
-
-        /** Setter of RF field on time. */
-        public OemLogItems.Builder setRfFieldOnTime(Instant time) {
-            mItem.mRfFieldOnTime = time;
-            return this;
-        }
-
-        /** Setter of APDU response. */
-        public OemLogItems.Builder setApduResponse(byte[] apdus) {
-            mItem.mResponseApdus = apdus;
-            return this;
-        }
-
-        /** Setter of dispatched tag. */
-        public OemLogItems.Builder setTag(Tag tag) {
-            mItem.mTag = tag;
-            return this;
-        }
-
-        /** Builds an {@link OemLogItems} instance. */
-        public OemLogItems build() {
-            return mItem;
-        }
-    }
-
-    /**
-     * Gets the action of this log.
-     * @return one of {@link LogAction}
-     */
-    @LogAction
-    public int getAction() {
-        return mAction;
-    }
-
-    /**
-     * Gets the event of this log. This will be set to {@link LogEvent#EVENT_ENABLE} or
-     * {@link LogEvent#EVENT_DISABLE} only when action is set to
-     * {@link LogAction#LOG_ACTION_NFC_TOGGLE}
-     * @return one of {@link LogEvent}
-     */
-    @LogEvent
-    public int getEvent() {
-        return mEvent;
-    }
-
-    /**
-     * Gets the calling Pid of this log. This field will be set only when action is set to
-     * {@link LogAction#LOG_ACTION_NFC_TOGGLE}
-     * @return calling Pid
-     */
-    public int getCallingPid() {
-        return mCallingPid;
-    }
-
-    /**
-     * Gets the command APDUs of this log. This field will be set only when action is set to
-     * {@link LogAction#LOG_ACTION_HCE_DATA}
-     * @return a byte array of command APDUs with the same format as
-     * {@link android.nfc.cardemulation.HostApduService#sendResponseApdu(byte[])}
-     */
-    @Nullable
-    public byte[] getCommandApdu() {
-        return mCommandApdus;
-    }
-
-    /**
-     * Gets the response APDUs of this log. This field will be set only when action is set to
-     * {@link LogAction#LOG_ACTION_HCE_DATA}
-     * @return a byte array of response APDUs with the same format as
-     * {@link android.nfc.cardemulation.HostApduService#sendResponseApdu(byte[])}
-     */
-    @Nullable
-    public byte[] getResponseApdu() {
-        return mResponseApdus;
-    }
-
-    /**
-     * Gets the RF field event time in this log in millisecond. This field will be set only when
-     * action is set to {@link LogAction#LOG_ACTION_RF_FIELD_STATE_CHANGED}
-     * @return an {@link Instant} of RF field event time.
-     */
-    @Nullable
-    public Instant getRfFieldEventTimeMillis() {
-        return mRfFieldOnTime;
-    }
-
-    /**
-     * Gets the tag of this log. This field will be set only when action is set to
-     * {@link LogAction#LOG_ACTION_TAG_DETECTED}
-     * @return a detected {@link Tag} in {@link #LOG_ACTION_TAG_DETECTED} case. Return
-     * null otherwise.
-     */
-    @Nullable
-    public Tag getTag() {
-        return mTag;
-    }
-
-    private String byteToHex(byte[] bytes) {
-        char[] HexArray = "0123456789ABCDEF".toCharArray();
-        char[] hexChars = new char[bytes.length * 2];
-        for (int j = 0; j < bytes.length; j++) {
-            int v = bytes[j] & 0xFF;
-            hexChars[j * 2] = HexArray[v >>> 4];
-            hexChars[j * 2 + 1] = HexArray[v & 0x0F];
-        }
-        return new String(hexChars);
-    }
-
-    @Override
-    public String toString() {
-        return "[mCommandApdus: "
-                + ((mCommandApdus != null) ? byteToHex(mCommandApdus) : "null")
-                + "[mResponseApdus: "
-                + ((mResponseApdus != null) ? byteToHex(mResponseApdus) : "null")
-                + ", mCallingApi= " + mEvent
-                + ", mAction= " + mAction
-                + ", mCallingPId = " + mCallingPid
-                + ", mRfFieldOnTime= " + mRfFieldOnTime;
-    }
-    private OemLogItems(Parcel in) {
-        this.mAction = in.readInt();
-        this.mEvent = in.readInt();
-        this.mCallingPid = in.readInt();
-        this.mCommandApdus = new byte[in.readInt()];
-        in.readByteArray(this.mCommandApdus);
-        this.mResponseApdus = new byte[in.readInt()];
-        in.readByteArray(this.mResponseApdus);
-        boolean isRfFieldOnTimeSet = in.readBoolean();
-        if (isRfFieldOnTimeSet) {
-            this.mRfFieldOnTime = Instant.ofEpochSecond(in.readLong(), in.readInt());
-        } else {
-            this.mRfFieldOnTime = null;
-        }
-        this.mTag = in.readParcelable(Tag.class.getClassLoader(), Tag.class);
-    }
-
-    public static final @NonNull Parcelable.Creator<OemLogItems> CREATOR =
-            new Parcelable.Creator<OemLogItems>() {
-                @Override
-                public OemLogItems createFromParcel(Parcel in) {
-                    return new OemLogItems(in);
-                }
-
-                @Override
-                public OemLogItems[] newArray(int size) {
-                    return new OemLogItems[size];
-                }
-            };
-
-}
diff --git a/nfc/java/android/nfc/Placeholder.java b/nfc/java/android/nfc/Placeholder.java
deleted file mode 100644
index 3509644..0000000
--- a/nfc/java/android/nfc/Placeholder.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-/**
- * Placeholder class so new framework-nfc module isn't empty, will be removed once module is
- * populated.
- *
- * @hide
- *
- */
-public class Placeholder {
-}
diff --git a/nfc/java/android/nfc/RoutingStatus.java b/nfc/java/android/nfc/RoutingStatus.java
deleted file mode 100644
index 4a1b1f3..0000000
--- a/nfc/java/android/nfc/RoutingStatus.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.nfc;
-
-import android.annotation.FlaggedApi;
-import android.annotation.RequiresPermission;
-import android.annotation.SystemApi;
-import android.nfc.cardemulation.CardEmulation;
-
-/**
- * A class indicating default route, ISO-DEP route and off-host route.
- *
- * @hide
- */
-@SystemApi
-@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-public class RoutingStatus {
-    private final @CardEmulation.ProtocolAndTechnologyRoute int mDefaultRoute;
-    private final @CardEmulation.ProtocolAndTechnologyRoute int mDefaultIsoDepRoute;
-    private final @CardEmulation.ProtocolAndTechnologyRoute int mDefaultOffHostRoute;
-
-    RoutingStatus(@CardEmulation.ProtocolAndTechnologyRoute int mDefaultRoute,
-                  @CardEmulation.ProtocolAndTechnologyRoute int mDefaultIsoDepRoute,
-                  @CardEmulation.ProtocolAndTechnologyRoute int mDefaultOffHostRoute) {
-        this.mDefaultRoute = mDefaultRoute;
-        this.mDefaultIsoDepRoute = mDefaultIsoDepRoute;
-        this.mDefaultOffHostRoute = mDefaultOffHostRoute;
-    }
-
-    /**
-     * Getter of the default route.
-     * @return an integer defined in
-     * {@link android.nfc.cardemulation.CardEmulation.ProtocolAndTechnologyRoute}
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    @CardEmulation.ProtocolAndTechnologyRoute
-    public int getDefaultRoute() {
-        return mDefaultRoute;
-    }
-
-    /**
-     * Getter of the default ISO-DEP route.
-     * @return an integer defined in
-     * {@link android.nfc.cardemulation.CardEmulation.ProtocolAndTechnologyRoute}
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    @CardEmulation.ProtocolAndTechnologyRoute
-    public int getDefaultIsoDepRoute() {
-        return mDefaultIsoDepRoute;
-    }
-
-    /**
-     * Getter of the default off-host route.
-     * @return an integer defined in
-     * {@link android.nfc.cardemulation.CardEmulation.ProtocolAndTechnologyRoute}
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    @CardEmulation.ProtocolAndTechnologyRoute
-    public int getDefaultOffHostRoute() {
-        return mDefaultOffHostRoute;
-    }
-
-}
diff --git a/nfc/java/android/nfc/RoutingTableAidEntry.java b/nfc/java/android/nfc/RoutingTableAidEntry.java
deleted file mode 100644
index be94f9f..0000000
--- a/nfc/java/android/nfc/RoutingTableAidEntry.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.nfc;
-
-import android.annotation.FlaggedApi;
-import android.annotation.NonNull;
-import android.annotation.SystemApi;
-import android.nfc.cardemulation.CardEmulation;
-
-/**
- * Represents an Application ID (AID) entry in current routing table.
- * @hide
- */
-@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-@SystemApi
-public class RoutingTableAidEntry extends NfcRoutingTableEntry {
-    private final String mValue;
-
-    /** @hide */
-    public RoutingTableAidEntry(int nfceeId, String value,
-            @CardEmulation.ProtocolAndTechnologyRoute int routeType) {
-        super(nfceeId, TYPE_AID, routeType);
-        this.mValue = value;
-    }
-
-    /**
-     * Gets AID value.
-     * @return String of AID
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    @NonNull
-    public String getAid() {
-        return mValue;
-    }
-}
diff --git a/nfc/java/android/nfc/RoutingTableProtocolEntry.java b/nfc/java/android/nfc/RoutingTableProtocolEntry.java
deleted file mode 100644
index a68d8c1..0000000
--- a/nfc/java/android/nfc/RoutingTableProtocolEntry.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.nfc;
-
-import android.annotation.FlaggedApi;
-import android.annotation.IntDef;
-import android.annotation.SystemApi;
-import android.nfc.cardemulation.CardEmulation;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Represents a protocol entry in current routing table.
- * @hide
- */
-@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-@SystemApi
-public class RoutingTableProtocolEntry extends NfcRoutingTableEntry {
-    /**
-     * Protocol undetermined.
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    public static final int PROTOCOL_UNDETERMINED = 0;
-    /**
-     * T1T Protocol
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    public static final int PROTOCOL_T1T = 1;
-    /**
-     * T2T Protocol
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    public static final int PROTOCOL_T2T = 2;
-    /**
-     * T3T Protocol
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    public static final int PROTOCOL_T3T = 3;
-    /**
-     * ISO-DEP Protocol
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    public static final int PROTOCOL_ISO_DEP = 4;
-    /**
-     * DEP Protocol
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    public static final int PROTOCOL_NFC_DEP = 5;
-    /**
-     * T5T Protocol
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    public static final int PROTOCOL_T5T = 6;
-    /**
-     * NDEF Protocol
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    public static final int PROTOCOL_NDEF = 7;
-    /**
-     * Unsupported Protocol
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    public static final int PROTOCOL_UNSUPPORTED = -1;
-
-    /**
-     *
-     * @hide
-     */
-    @IntDef(prefix = { "PROTOCOL_" }, value = {
-            PROTOCOL_UNDETERMINED,
-            PROTOCOL_T1T,
-            PROTOCOL_T2T,
-            PROTOCOL_T3T,
-            PROTOCOL_ISO_DEP,
-            PROTOCOL_NFC_DEP,
-            PROTOCOL_T5T,
-            PROTOCOL_NDEF,
-            PROTOCOL_UNSUPPORTED
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface ProtocolValue {}
-
-    private final @ProtocolValue int mValue;
-
-    /** @hide */
-    public RoutingTableProtocolEntry(int nfceeId, @ProtocolValue int value,
-            @CardEmulation.ProtocolAndTechnologyRoute int routeType) {
-        super(nfceeId, TYPE_PROTOCOL, routeType);
-        this.mValue = value;
-    }
-
-    /**
-     * Gets Protocol value.
-     * @return Protocol defined in {@link ProtocolValue}
-     */
-    @ProtocolValue
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    public int getProtocol() {
-        return mValue;
-    }
-
-    /** @hide */
-    @ProtocolValue
-    public static int protocolStringToInt(String protocolString) {
-        return switch (protocolString) {
-            case "PROTOCOL_T1T" -> PROTOCOL_T1T;
-            case "PROTOCOL_T2T" -> PROTOCOL_T2T;
-            case "PROTOCOL_T3T" -> PROTOCOL_T3T;
-            case "PROTOCOL_ISO_DEP" -> PROTOCOL_ISO_DEP;
-            case "PROTOCOL_NFC_DEP" -> PROTOCOL_NFC_DEP;
-            case "PROTOCOL_T5T" -> PROTOCOL_T5T;
-            case "PROTOCOL_NDEF" -> PROTOCOL_NDEF;
-            case "PROTOCOL_UNDETERMINED" -> PROTOCOL_UNDETERMINED;
-            default -> PROTOCOL_UNSUPPORTED;
-        };
-    }
-}
diff --git a/nfc/java/android/nfc/RoutingTableSystemCodeEntry.java b/nfc/java/android/nfc/RoutingTableSystemCodeEntry.java
deleted file mode 100644
index 06cc0a5..0000000
--- a/nfc/java/android/nfc/RoutingTableSystemCodeEntry.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.nfc;
-
-import android.annotation.FlaggedApi;
-import android.annotation.NonNull;
-import android.annotation.SystemApi;
-import android.nfc.cardemulation.CardEmulation;
-
-/**
- * Represents a system code entry in current routing table, where system codes are two-byte values
- * used in NFC-F technology (a type of NFC communication) to identify specific
- * device configurations.
- * @hide
- */
-@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-@SystemApi
-public class RoutingTableSystemCodeEntry extends NfcRoutingTableEntry {
-    private final byte[] mValue;
-
-    /** @hide */
-    public RoutingTableSystemCodeEntry(int nfceeId, byte[] value,
-            @CardEmulation.ProtocolAndTechnologyRoute int routeType) {
-        super(nfceeId, TYPE_SYSTEM_CODE, routeType);
-        this.mValue = value;
-    }
-
-    /**
-     * Gets system code value.
-     * @return Byte array of system code
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    @NonNull
-    public byte[] getSystemCode() {
-        return mValue;
-    }
-}
diff --git a/nfc/java/android/nfc/RoutingTableTechnologyEntry.java b/nfc/java/android/nfc/RoutingTableTechnologyEntry.java
deleted file mode 100644
index 86239ce..0000000
--- a/nfc/java/android/nfc/RoutingTableTechnologyEntry.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.nfc;
-
-import android.annotation.FlaggedApi;
-import android.annotation.IntDef;
-import android.annotation.SystemApi;
-import android.nfc.cardemulation.CardEmulation;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Represents a technology entry in current routing table.
- * @hide
- */
-@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-@SystemApi
-public class RoutingTableTechnologyEntry extends NfcRoutingTableEntry {
-    /**
-     * Technology-A.
-     * <p>Tech-A is mostly used for payment and ticketing applications. It supports various
-     * Tag platforms including Type 1, Type 2 and Type 4A tags. </p>
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    public static final int TECHNOLOGY_A = 0;
-    /**
-     * Technology-B which is based on ISO/IEC 14443-3 standard.
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    public static final int TECHNOLOGY_B = 1;
-    /**
-     * Technology-F.
-     * <p>Tech-F is a standard which supports Type 3 Tags and NFC-DEP protocol etc.</p>
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    public static final int TECHNOLOGY_F = 2;
-    /**
-     * Technology-V.
-     * <p>Tech-V is an NFC technology used for communication with passive tags that operate
-     * at a longer range than other NFC technologies. </p>
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    public static final int TECHNOLOGY_V = 3;
-    /**
-     * Unsupported technology
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    public static final int TECHNOLOGY_UNSUPPORTED = -1;
-
-    /**
-     *
-     * @hide
-     */
-    @IntDef(prefix = { "TECHNOLOGY_" }, value = {
-            TECHNOLOGY_A,
-            TECHNOLOGY_B,
-            TECHNOLOGY_F,
-            TECHNOLOGY_V,
-            TECHNOLOGY_UNSUPPORTED
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface TechnologyValue{}
-
-    private final @TechnologyValue int mValue;
-
-    /** @hide */
-    public RoutingTableTechnologyEntry(int nfceeId, @TechnologyValue int value,
-            @CardEmulation.ProtocolAndTechnologyRoute int routeType) {
-        super(nfceeId, TYPE_TECHNOLOGY, routeType);
-        this.mValue = value;
-    }
-
-    /**
-     * Gets technology value.
-     * @return technology value
-     */
-    @TechnologyValue
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    public int getTechnology() {
-        return mValue;
-    }
-
-    /** @hide */
-    @TechnologyValue
-    public static int techStringToInt(String tech) {
-        return switch (tech) {
-            case "TECHNOLOGY_A" -> TECHNOLOGY_A;
-            case "TECHNOLOGY_B" -> TECHNOLOGY_B;
-            case "TECHNOLOGY_F" -> TECHNOLOGY_F;
-            case "TECHNOLOGY_V" -> TECHNOLOGY_V;
-            default -> TECHNOLOGY_UNSUPPORTED;
-        };
-    }
-}
diff --git a/nfc/java/android/nfc/T4tNdefNfcee.java b/nfc/java/android/nfc/T4tNdefNfcee.java
deleted file mode 100644
index 05a30aa..0000000
--- a/nfc/java/android/nfc/T4tNdefNfcee.java
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.nfc;
-
-import android.annotation.FlaggedApi;
-import android.annotation.IntDef;
-import android.annotation.IntRange;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.RequiresPermission;
-import android.annotation.SystemApi;
-import android.annotation.WorkerThread;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * This class is used for performing T4T (Type-4 Tag) NDEF (NFC Data Exchange Format)
- * NFCEE (NFC Execution Environment) operations.
- * This can be used to write NDEF data to emulate a T4T tag in an NFCEE
- * (NFC Execution Environment - eSE, SIM, etc). Refer to the NFC forum specification
- * "NFCForum-TS-NCI-2.3 section 10.4" and "NFCForum-TS-T4T-1.1 section 4.2" for more details.
- * @hide
- */
-@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-@SystemApi
-public final class T4tNdefNfcee {
-    private static final String TAG = "NdefNfcee";
-    static T4tNdefNfcee sNdefNfcee;
-
-    private T4tNdefNfcee() {
-    }
-
-    /**
-     * Helper to get an instance of this class.
-     *
-     * @return
-     * @hide
-     */
-    @NonNull
-    public static T4tNdefNfcee getInstance() {
-        if (sNdefNfcee == null) {
-            sNdefNfcee = new T4tNdefNfcee();
-        }
-        return sNdefNfcee;
-    }
-
-    /**
-     * Return flag for {@link #writeData(int, byte[])}.
-     * It indicates write data is successful.
-     */
-    public static final int WRITE_DATA_SUCCESS = 0;
-    /**
-     * Return flag for {@link #writeData(int, byte[])}.
-     * It indicates write data fail due to unknown reasons.
-     */
-    public static final int WRITE_DATA_ERROR_INTERNAL = -1;
-    /**
-     * Return flag for {@link #writeData(int, byte[])}.
-     * It indicates write data fail due to ongoing rf activity.
-     */
-    public static final int WRITE_DATA_ERROR_RF_ACTIVATED = -2;
-    /**
-     * Return flag for {@link #writeData(int, byte[])}.
-     * It indicates write data fail due to Nfc off.
-     */
-    public static final int WRITE_DATA_ERROR_NFC_NOT_ON = -3;
-    /**
-     * Return flag for {@link #writeData(int, byte[])}.
-     * It indicates write data fail due to invalid file id.
-     */
-    public static final int WRITE_DATA_ERROR_INVALID_FILE_ID = -4;
-    /**
-     * Return flag for {@link #writeData(int, byte[])}.
-     * It indicates write data fail due to invalid length.
-     */
-    public static final int WRITE_DATA_ERROR_INVALID_LENGTH = -5;
-    /**
-     * Return flag for {@link #writeData(int, byte[])}.
-     * It indicates write data fail due to core connection create failure.
-     */
-    public static final int WRITE_DATA_ERROR_CONNECTION_FAILED = -6;
-    /**
-     * Return flag for {@link #writeData(int, byte[])}.
-     * It indicates write data fail due to empty payload.
-     */
-    public static final int WRITE_DATA_ERROR_EMPTY_PAYLOAD = -7;
-    /**
-     * Returns flag for {@link #writeData(int, byte[])}.
-     * It indicates write data fail due to invalid ndef format.
-     */
-    public static final int WRITE_DATA_ERROR_NDEF_VALIDATION_FAILED = -8;
-    /**
-     * Returns flag for {@link #writeData(int, byte[])}.
-     * It indicates write data fail if a concurrent NDEF NFCEE operation is ongoing.
-     */
-    public static final int WRITE_DATA_ERROR_DEVICE_BUSY = -9;
-
-    /**
-     * Possible return values for {@link #writeData(int, byte[])}.
-     *
-     * @hide
-     */
-    @IntDef(prefix = { "WRITE_DATA_" }, value = {
-        WRITE_DATA_SUCCESS,
-        WRITE_DATA_ERROR_INTERNAL,
-        WRITE_DATA_ERROR_RF_ACTIVATED,
-        WRITE_DATA_ERROR_NFC_NOT_ON,
-        WRITE_DATA_ERROR_INVALID_FILE_ID,
-        WRITE_DATA_ERROR_INVALID_LENGTH,
-        WRITE_DATA_ERROR_CONNECTION_FAILED,
-        WRITE_DATA_ERROR_EMPTY_PAYLOAD,
-        WRITE_DATA_ERROR_NDEF_VALIDATION_FAILED,
-        WRITE_DATA_ERROR_DEVICE_BUSY,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface WriteDataStatus{}
-
-    /**
-     * This API performs writes of T4T data to NFCEE.
-     *
-     * <p>This is an I/O operation and will block until complete. It must
-     * not be called from the main application thread.</p>
-     * <p>Applications must send complete Ndef Message payload, do not need to fragment
-     * the payload, it will be automatically fragmented and defragmented by
-     * {@link #writeData} if it exceeds max message length limits</p>
-     *
-     * @param fileId File id (Refer NFC Forum Type 4 Tag Specification
-     *               Section 4.2 File Identifiers and Access Conditions
-     *               for more information) to which to write.
-     * @param data   This should be valid Ndef Message format.
-     *               Refer to Nfc forum NDEF specification NDEF Message section
-     * @return status of the operation.
-     * @hide
-     */
-    @SystemApi
-    @WorkerThread
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public @WriteDataStatus int writeData(@IntRange(from = 0, to = 65535) int fileId,
-            @NonNull byte[] data) {
-        return NfcAdapter.callServiceReturn(() ->
-                NfcAdapter.sNdefNfceeService.writeData(fileId, data), WRITE_DATA_ERROR_INTERNAL);
-    }
-
-    /**
-     * This API performs reading of T4T content of Nfcee.
-     *
-     * <p>This is an I/O operation and will block until complete. It must
-     * not be called from the main application thread.</p>
-     *
-     * @param fileId File Id (Refer
-     *               Section 4.2 File Identifiers and Access Conditions
-     *               for more information) from which to read.
-     * @return - Returns complete Ndef message if success
-     *           Refer to Nfc forum NDEF specification NDEF Message section
-     * @throws IllegalStateException if read fails because the fileId is invalid
-     *         or if a concurrent operation is in progress.
-     * @hide
-     */
-    @SystemApi
-    @WorkerThread
-    @NonNull
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public byte[] readData(@IntRange(from = 0, to = 65535) int fileId) {
-        return NfcAdapter.callServiceReturn(() ->
-            NfcAdapter.sNdefNfceeService.readData(fileId), null);
-    }
-
-    /**
-     * Return flag for {@link #clearNdefData()}.
-     * It indicates clear data is successful.
-     */
-    public static final int CLEAR_DATA_SUCCESS = 1;
-     /**
-     * Return flag for {@link #clearNdefData()}.
-     * It indicates clear data failed due to internal error while processing the clear.
-     */
-    public static final int CLEAR_DATA_FAILED_INTERNAL = 0;
-    /**
-     * Return flag for {@link #clearNdefData()}.
-     * It indicates clear data failed  if a concurrent NDEF NFCEE operation is ongoing.
-     */
-    public static final int CLEAR_DATA_FAILED_DEVICE_BUSY = -1;
-
-
-    /**
-     * Possible return values for {@link #clearNdefData()}.
-     *
-     * @hide
-     */
-    @IntDef(prefix = { "CLEAR_DATA_" }, value = {
-        CLEAR_DATA_SUCCESS,
-        CLEAR_DATA_FAILED_INTERNAL,
-        CLEAR_DATA_FAILED_DEVICE_BUSY,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface ClearDataStatus{}
-
-    /**
-     * This API will set all the T4T NDEF NFCEE data to zero.
-     *
-     * <p>This is an I/O operation and will block until complete. It must
-     * not be called from the main application thread.
-     *
-     * <p>This API can be called regardless of NDEF file lock state.
-     * </p>
-     * @return status of the operation
-     *
-     * @hide
-     */
-    @SystemApi
-    @WorkerThread
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public @ClearDataStatus int clearData() {
-        return NfcAdapter.callServiceReturn(() ->
-            NfcAdapter.sNdefNfceeService.clearNdefData(), CLEAR_DATA_FAILED_INTERNAL);
-    }
-
-    /**
-     * Returns whether NDEF NFCEE operation is ongoing or not.
-     *
-     * @return true if NDEF NFCEE operation is ongoing, else false.
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public boolean isOperationOngoing() {
-        return NfcAdapter.callServiceReturn(() ->
-            NfcAdapter.sNdefNfceeService.isNdefOperationOngoing(), false);
-    }
-
-    /**
-     * This Api is to check the status of NDEF NFCEE emulation feature is
-     * supported or not.
-     *
-     * @return true if NDEF NFCEE emulation feature is supported, else false.
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public boolean isSupported() {
-        return NfcAdapter.callServiceReturn(() ->
-            NfcAdapter.sNdefNfceeService.isNdefNfceeEmulationSupported(), false);
-    }
-
-    /**
-     * This API performs reading of T4T NDEF NFCEE CC file content.
-     *
-     * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.4" for more details.
-     *
-     * @return Returns CC file content if success or null if failed to read.
-     * @throws IllegalStateException if the device is busy.
-     * @hide
-     */
-    @SystemApi
-    @WorkerThread
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    @Nullable
-    public T4tNdefNfceeCcFileInfo readCcfile() {
-        return NfcAdapter.callServiceReturn(() ->
-            NfcAdapter.sNdefNfceeService.readCcfile(), null);
-    }
-}
diff --git a/nfc/java/android/nfc/T4tNdefNfceeCcFileInfo.aidl b/nfc/java/android/nfc/T4tNdefNfceeCcFileInfo.aidl
deleted file mode 100644
index f72f74e..0000000
--- a/nfc/java/android/nfc/T4tNdefNfceeCcFileInfo.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-parcelable T4tNdefNfceeCcFileInfo;
-
diff --git a/nfc/java/android/nfc/T4tNdefNfceeCcFileInfo.java b/nfc/java/android/nfc/T4tNdefNfceeCcFileInfo.java
deleted file mode 100644
index ce67f8f..0000000
--- a/nfc/java/android/nfc/T4tNdefNfceeCcFileInfo.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import android.annotation.FlaggedApi;
-import android.annotation.IntDef;
-import android.annotation.IntRange;
-import android.annotation.NonNull;
-import android.annotation.SystemApi;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * This class is used to represence T4T (Type-4 Tag) NDEF (NFC Data Exchange Format)
- * NFCEE (NFC Execution Environment) CC (Capability Container) File data.
- * The CC file stores metadata about the T4T tag being emulated.
- *
- * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.4" for more details.
- * @hide
- */
-@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-@SystemApi
-public final class T4tNdefNfceeCcFileInfo implements Parcelable {
-    /**
-     * Indicates the size of this capability container (called “CC File”)<p>
-     */
-    private int mCcLength;
-    /**
-     * Indicates the mapping specification version<p>
-     */
-    private int mVersion;
-    /**
-     * Indicates the NDEF File Identifier<p>
-     */
-    private int mFileId;
-    /**
-     * Indicates the maximum Max NDEF file size<p>
-     */
-    private int mMaxSize;
-    /**
-     * Indicates the read access condition<p>
-     */
-    private boolean mIsReadAllowed;
-    /**
-     * Indicates the write access condition<p>
-     */
-    private boolean mIsWriteAllowed;
-
-    /**
-     * Constructor to be used by NFC service and internal classes.
-     * @hide
-     */
-    public T4tNdefNfceeCcFileInfo(int cclen, int version,
-                      int ndefFileId, int ndefMaxSize,
-                      boolean isReadAllowed, boolean isWriteAllowed) {
-        mCcLength = cclen;
-        mVersion = version;
-        mFileId = ndefFileId;
-        mMaxSize = ndefMaxSize;
-        mIsReadAllowed = isReadAllowed;
-        mIsWriteAllowed = isWriteAllowed;
-    }
-
-    @Override
-    public void writeToParcel(@NonNull Parcel dest, int flags) {
-        dest.writeInt(mCcLength);
-        dest.writeInt(mVersion);
-        dest.writeInt(mFileId);
-        dest.writeInt(mMaxSize);
-        dest.writeBoolean(mIsReadAllowed);
-        dest.writeBoolean(mIsWriteAllowed);
-    }
-
-    /**
-     * Indicates the size of this capability container (called “CC File”).
-     *
-     * @return length of the CC file.
-     */
-    @IntRange(from = 0xf, to = 0x7fff)
-    public int getCcFileLength() {
-        return mCcLength;
-    }
-
-    /**
-     * T4T tag mapping version 2.0.
-     * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.4" for more details.
-     */
-    public static final int VERSION_2_0 = 0x20;
-    /**
-     * T4T tag mapping version 2.0.
-     * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.4" for more details.
-     */
-    public static final int VERSION_3_0 = 0x30;
-
-    /**
-     * Possible return values for {@link #getVersion()}.
-     * @hide
-     */
-    @IntDef(prefix = { "VERSION_" }, value = {
-            VERSION_2_0,
-            VERSION_3_0,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface Version{}
-
-    /**
-     * Indicates the mapping version of the T4T tag supported.
-     *
-     * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.5" for more details.
-     *
-     * @return version of the specification
-     */
-    @Version
-    public int getVersion() {
-        return mVersion;
-    }
-
-    /**
-     * Indicates the NDEF File Identifier. This is the identifier used in the last invocation of
-     * {@link T4tNdefNfcee#writeData(int, byte[])}
-     *
-     * @return FileId of the data stored or -1 if no data is present.
-     */
-    @IntRange(from = -1, to = 65535)
-    public int getFileId() {
-        return mFileId;
-    }
-
-    /**
-     * Indicates the maximum size of T4T NDEF data that can be written to the NFCEE.
-     *
-     * @return max size of the contents.
-     */
-    @IntRange(from = 0x5, to = 0x7fff)
-    public int getMaxSize() {
-        return mMaxSize;
-    }
-
-    /**
-     * Indicates the read access condition.
-     * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.2" for more details.
-     * @return boolean true if read access is allowed, otherwise false.
-     */
-    public boolean isReadAllowed() {
-        return mIsReadAllowed;
-    }
-
-    /**
-     * Indicates the write access condition.
-     * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.2" for more details.
-     * @return boolean if write access is allowed, otherwise false.
-     */
-    public boolean isWriteAllowed() {
-        return mIsWriteAllowed;
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    public static final @NonNull Parcelable.Creator<T4tNdefNfceeCcFileInfo> CREATOR =
-            new Parcelable.Creator<>() {
-                @Override
-                public T4tNdefNfceeCcFileInfo createFromParcel(Parcel in) {
-
-                    // NdefNfceeCcFileInfo fields
-                    int cclen = in.readInt();
-                    int version = in.readInt();
-                    int ndefFileId = in.readInt();
-                    int ndefMaxSize = in.readInt();
-                    boolean isReadAllowed = in.readBoolean();
-                    boolean isWriteAllowed = in.readBoolean();
-
-                    return new T4tNdefNfceeCcFileInfo(cclen, version,
-                            ndefFileId, ndefMaxSize,
-                            isReadAllowed, isWriteAllowed);
-                }
-
-                @Override
-                public T4tNdefNfceeCcFileInfo[] newArray(int size) {
-                    return new T4tNdefNfceeCcFileInfo[size];
-                }
-            };
-}
diff --git a/nfc/java/android/nfc/Tag.aidl b/nfc/java/android/nfc/Tag.aidl
deleted file mode 100644
index 312261e..0000000
--- a/nfc/java/android/nfc/Tag.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-parcelable Tag;
\ No newline at end of file
diff --git a/nfc/java/android/nfc/Tag.java b/nfc/java/android/nfc/Tag.java
deleted file mode 100644
index 500038f..0000000
--- a/nfc/java/android/nfc/Tag.java
+++ /dev/null
@@ -1,508 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import android.compat.annotation.UnsupportedAppUsage;
-import android.content.Context;
-import android.nfc.tech.IsoDep;
-import android.nfc.tech.MifareClassic;
-import android.nfc.tech.MifareUltralight;
-import android.nfc.tech.Ndef;
-import android.nfc.tech.NdefFormatable;
-import android.nfc.tech.NfcA;
-import android.nfc.tech.NfcB;
-import android.nfc.tech.NfcBarcode;
-import android.nfc.tech.NfcF;
-import android.nfc.tech.NfcV;
-import android.nfc.tech.TagTechnology;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.RemoteException;
-
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.HashMap;
-
-/**
- * Represents an NFC tag that has been discovered.
- * <p>
- * {@link Tag} is an immutable object that represents the state of a NFC tag at
- * the time of discovery. It can be used as a handle to {@link TagTechnology} classes
- * to perform advanced operations, or directly queried for its ID via {@link #getId} and the
- * set of technologies it contains via {@link #getTechList}. Arrays passed to and
- * returned by this class are <em>not</em> cloned, so be careful not to modify them.
- * <p>
- * A new tag object is created every time a tag is discovered (comes into range), even
- * if it is the same physical tag. If a tag is removed and then returned into range, then
- * only the most recent tag object can be successfully used to create a {@link TagTechnology}.
- *
- * <h3>Tag Dispatch</h3>
- * When a tag is discovered, a {@link Tag} object is created and passed to a
- * single activity via the {@link NfcAdapter#EXTRA_TAG} extra in an
- * {@link android.content.Intent} via {@link Context#startActivity}. A four stage dispatch is used
- * to select the
- * most appropriate activity to handle the tag. The Android OS executes each stage in order,
- * and completes dispatch as soon as a single matching activity is found. If there are multiple
- * matching activities found at any one stage then the Android activity chooser dialog is shown
- * to allow the user to select the activity to receive the tag.
- *
- * <p>The Tag dispatch mechanism was designed to give a high probability of dispatching
- * a tag to the correct activity without showing the user an activity chooser dialog.
- * This is important for NFC interactions because they are very transient -- if a user has to
- * move the Android device to choose an application then the connection will likely be broken.
- *
- * <h4>1. Foreground activity dispatch</h4>
- * A foreground activity that has called
- * {@link NfcAdapter#enableForegroundDispatch NfcAdapter.enableForegroundDispatch()} is
- * given priority. See the documentation on
- * {@link NfcAdapter#enableForegroundDispatch NfcAdapter.enableForegroundDispatch()} for
- * its usage.
- * <h4>2. NDEF data dispatch</h4>
- * If the tag contains NDEF data the system inspects the first {@link NdefRecord} in the first
- * {@link NdefMessage}. If the record is a URI, SmartPoster, or MIME data
- * {@link Context#startActivity} is called with {@link NfcAdapter#ACTION_NDEF_DISCOVERED}. For URI
- * and SmartPoster records the URI is put into the intent's data field. For MIME records the MIME
- * type is put in the intent's type field. This allows activities to register to be launched only
- * when data they know how to handle is present on a tag. This is the preferred method of handling
- * data on a tag since NDEF data can be stored on many types of tags and doesn't depend on a
- * specific tag technology. 
- * See {@link NfcAdapter#ACTION_NDEF_DISCOVERED} for more detail. If the tag does not contain
- * NDEF data, or if no activity is registered
- * for {@link NfcAdapter#ACTION_NDEF_DISCOVERED} with a matching data URI or MIME type then dispatch
- * moves to stage 3.
- * <h4>3. Tag Technology dispatch</h4>
- * {@link Context#startActivity} is called with {@link NfcAdapter#ACTION_TECH_DISCOVERED} to
- * dispatch the tag to an activity that can handle the technologies present on the tag.
- * Technologies are defined as sub-classes of {@link TagTechnology}, see the package
- * {@link android.nfc.tech}. The Android OS looks for an activity that can handle one or
- * more technologies in the tag. See {@link NfcAdapter#ACTION_TECH_DISCOVERED} for more detail.
- * <h4>4. Fall-back dispatch</h4>
- * If no activity has been matched then {@link Context#startActivity} is called with
- * {@link NfcAdapter#ACTION_TAG_DISCOVERED}. This is intended as a fall-back mechanism.
- * See {@link NfcAdapter#ACTION_TAG_DISCOVERED}.
- *
- * <h3>NFC Tag Background</h3>
- * An NFC tag is a passive NFC device, powered by the NFC field of this Android device while
- * it is in range. Tag's can come in many forms, such as stickers, cards, key fobs, or
- * even embedded in a more sophisticated device.
- * <p>
- * Tags can have a wide range of capabilities. Simple tags just offer read/write semantics,
- * and contain some one time
- * programmable areas to make read-only. More complex tags offer math operations
- * and per-sector access control and authentication. The most sophisticated tags
- * contain operating environments allowing complex interactions with the
- * code executing on the tag. Use {@link TagTechnology} classes to access a broad
- * range of capabilities available in NFC tags.
- * <p>
- */
-public final class Tag implements Parcelable {
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    final byte[] mId;
-    final int[] mTechList;
-    final String[] mTechStringList;
-    final Bundle[] mTechExtras;
-    final int mServiceHandle;  // for use by NFC service, 0 indicates a mock
-    final long mCookie;        // for accessibility checking
-    final INfcTag mTagService; // interface to NFC service, will be null if mock tag
-
-    int mConnectedTechnology;
-
-    /**
-     * Hidden constructor to be used by NFC service and internal classes.
-     * @hide
-     */
-    public Tag(byte[] id, int[] techList, Bundle[] techListExtras, int serviceHandle,
-            long cookie, INfcTag tagService) {
-        if (techList == null) {
-            throw new IllegalArgumentException("rawTargets cannot be null");
-        }
-        mId = id;
-        mTechList = Arrays.copyOf(techList, techList.length);
-        mTechStringList = generateTechStringList(techList);
-        // Ensure mTechExtras is as long as mTechList
-        mTechExtras = Arrays.copyOf(techListExtras, techList.length);
-        mServiceHandle = serviceHandle;
-        mCookie = cookie;
-        mTagService = tagService;
-        mConnectedTechnology = -1;
-
-        if (tagService == null) {
-            return;
-        }
-    }
-
-    /**
-     * Construct a mock Tag.
-     * <p>This is an application constructed tag, so NfcAdapter methods on this Tag may fail
-     * with {@link IllegalArgumentException} since it does not represent a physical Tag.
-     * <p>This constructor might be useful for mock testing.
-     * @param id The tag identifier, can be null
-     * @param techList must not be null
-     * @return freshly constructed tag
-     * @hide
-     */
-    public static Tag createMockTag(byte[] id, int[] techList, Bundle[] techListExtras,
-            long cookie) {
-        // set serviceHandle to 0 and tagService to null to indicate mock tag
-        return new Tag(id, techList, techListExtras, 0, cookie, null);
-    }
-
-    private String[] generateTechStringList(int[] techList) {
-        final int size = techList.length;
-        String[] strings = new String[size];
-        for (int i = 0; i < size; i++) {
-            switch (techList[i]) {
-                case TagTechnology.ISO_DEP:
-                    strings[i] = IsoDep.class.getName();
-                    break;
-                case TagTechnology.MIFARE_CLASSIC:
-                    strings[i] = MifareClassic.class.getName();
-                    break;
-                case TagTechnology.MIFARE_ULTRALIGHT:
-                    strings[i] = MifareUltralight.class.getName();
-                    break;
-                case TagTechnology.NDEF:
-                    strings[i] = Ndef.class.getName();
-                    break;
-                case TagTechnology.NDEF_FORMATABLE:
-                    strings[i] = NdefFormatable.class.getName();
-                    break;
-                case TagTechnology.NFC_A:
-                    strings[i] = NfcA.class.getName();
-                    break;
-                case TagTechnology.NFC_B:
-                    strings[i] = NfcB.class.getName();
-                    break;
-                case TagTechnology.NFC_F:
-                    strings[i] = NfcF.class.getName();
-                    break;
-                case TagTechnology.NFC_V:
-                    strings[i] = NfcV.class.getName();
-                    break;
-                case TagTechnology.NFC_BARCODE:
-                    strings[i] = NfcBarcode.class.getName();
-                    break;
-                default:
-                    throw new IllegalArgumentException("Unknown tech type " + techList[i]);
-            }
-        }
-        return strings;
-    }
-
-    static int[] getTechCodesFromStrings(String[] techStringList) throws IllegalArgumentException {
-        if (techStringList == null) {
-            throw new IllegalArgumentException("List cannot be null");
-        }
-        int[] techIntList = new int[techStringList.length];
-        HashMap<String, Integer> stringToCodeMap = getTechStringToCodeMap();
-        for (int i = 0; i < techStringList.length; i++) {
-            Integer code = stringToCodeMap.get(techStringList[i]);
-
-            if (code == null) {
-                throw new IllegalArgumentException("Unknown tech type " + techStringList[i]);
-            }
-
-            techIntList[i] = code.intValue();
-        }
-        return techIntList;
-    }
-
-    private static HashMap<String, Integer> getTechStringToCodeMap() {
-        HashMap<String, Integer> techStringToCodeMap = new HashMap<String, Integer>();
-
-        techStringToCodeMap.put(IsoDep.class.getName(), TagTechnology.ISO_DEP);
-        techStringToCodeMap.put(MifareClassic.class.getName(), TagTechnology.MIFARE_CLASSIC);
-        techStringToCodeMap.put(MifareUltralight.class.getName(), TagTechnology.MIFARE_ULTRALIGHT);
-        techStringToCodeMap.put(Ndef.class.getName(), TagTechnology.NDEF);
-        techStringToCodeMap.put(NdefFormatable.class.getName(), TagTechnology.NDEF_FORMATABLE);
-        techStringToCodeMap.put(NfcA.class.getName(), TagTechnology.NFC_A);
-        techStringToCodeMap.put(NfcB.class.getName(), TagTechnology.NFC_B);
-        techStringToCodeMap.put(NfcF.class.getName(), TagTechnology.NFC_F);
-        techStringToCodeMap.put(NfcV.class.getName(), TagTechnology.NFC_V);
-        techStringToCodeMap.put(NfcBarcode.class.getName(), TagTechnology.NFC_BARCODE);
-
-        return techStringToCodeMap;
-    }
-
-    /**
-     * For use by NfcService only.
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public int getServiceHandle() {
-        return mServiceHandle;
-    }
-
-    /**
-     * For use by NfcService only.
-     * @hide
-     */
-    public int[] getTechCodeList() {
-        return mTechList;
-    }
-
-    /**
-     * Get the Tag Identifier (if it has one).
-     * <p>The tag identifier is a low level serial number, used for anti-collision
-     * and identification.
-     * <p> Most tags have a stable unique identifier
-     * (UID), but some tags will generate a random ID every time they are discovered
-     * (RID), and there are some tags with no ID at all (the byte array will be zero-sized).
-     * <p> The size and format of an ID is specific to the RF technology used by the tag.
-     * <p> This function retrieves the ID as determined at discovery time, and does not
-     * perform any further RF communication or block.
-     * @return ID as byte array, never null
-     */
-    public byte[] getId() {
-        return mId;
-    }
-
-    /**
-     * Get the technologies available in this tag, as fully qualified class names.
-     * <p>
-     * A technology is an implementation of the {@link TagTechnology} interface,
-     * and can be instantiated by calling the static <code>get(Tag)</code>
-     * method on the implementation with this Tag. The {@link TagTechnology}
-     * object can then be used to perform advanced, technology-specific operations on a tag.
-     * <p>
-     * Android defines a mandatory set of technologies that must be correctly
-     * enumerated by all Android NFC devices, and an optional
-     * set of proprietary technologies.
-     * See {@link TagTechnology} for more details.
-     * <p>
-     * The ordering of the returned array is undefined and should not be relied upon.
-     * @return an array of fully-qualified {@link TagTechnology} class-names.
-     */
-    public String[] getTechList() {
-        return mTechStringList;
-    }
-
-    /**
-     * Rediscover the technologies available on this tag.
-     * <p>
-     * The technologies that are available on a tag may change due to
-     * operations being performed on a tag. For example, formatting a
-     * tag as NDEF adds the {@link Ndef} technology. The {@link rediscover}
-     * method reenumerates the available technologies on the tag
-     * and returns a new {@link Tag} object containing these technologies.
-     * <p>
-     * You may not be connected to any of this {@link Tag}'s technologies
-     * when calling this method.
-     * This method guarantees that you will be returned the same Tag
-     * if it is still in the field.
-     * <p>May cause RF activity and may block. Must not be called
-     * from the main application thread. A blocked call will be canceled with
-     * {@link IOException} by calling {@link #close} from another thread.
-     * <p>Does not remove power from the RF field, so a tag having a random
-     * ID should not change its ID.
-     * @return the rediscovered tag object.
-     * @throws IOException if the tag cannot be rediscovered
-     * @hide
-     */
-    // TODO See if we need TagLostException
-    // TODO Unhide for ICS
-    // TODO Update documentation to make sure it matches with the final
-    //      implementation.
-    public Tag rediscover() throws IOException {
-        if (getConnectedTechnology() != -1) {
-            throw new IllegalStateException("Close connection to the technology first!");
-        }
-
-        if (mTagService == null) {
-            throw new IOException("Mock tags don't support this operation.");
-        }
-        try {
-            Tag newTag = mTagService.rediscover(getServiceHandle());
-            if (newTag != null) {
-                return newTag;
-            } else {
-                throw new IOException("Failed to rediscover tag");
-            }
-        } catch (RemoteException e) {
-            throw new IOException("NFC service dead");
-        }
-    }
-
-
-    /** @hide */
-    public boolean hasTech(int techType) {
-        for (int tech : mTechList) {
-            if (tech == techType) return true;
-        }
-        return false;
-    }
-
-    /** @hide */
-    public Bundle getTechExtras(int tech) {
-        int pos = -1;
-        for (int idx = 0; idx < mTechList.length; idx++) {
-          if (mTechList[idx] == tech) {
-              pos = idx;
-              break;
-          }
-        }
-        if (pos < 0) {
-            return null;
-        }
-
-        return mTechExtras[pos];
-    }
-
-    /** @hide */
-    @UnsupportedAppUsage
-    public INfcTag getTagService() {
-        if (mTagService == null) {
-            return null;
-        }
-
-        try {
-            if (!mTagService.isTagUpToDate(mCookie)) {
-                String id_str = "";
-                for (int i = 0; i < mId.length; i++) {
-                    id_str = id_str + String.format("%02X ", mId[i]);
-                }
-                String msg = "Permission Denial: Tag ( ID: " + id_str + ") is out of date";
-                throw new SecurityException(msg);
-            }
-        } catch (RemoteException e) {
-            throw e.rethrowAsRuntimeException();
-        }
-        return mTagService;
-    }
-
-    /**
-     * Human-readable description of the tag, for debugging.
-     */
-    @Override
-    public String toString() {
-        StringBuilder sb = new StringBuilder("TAG: Tech [");
-        String[] techList = getTechList();
-        int length = techList.length;
-        for (int i = 0; i < length; i++) {
-            sb.append(techList[i]);
-            if (i < length - 1) {
-                sb.append(", ");
-            }
-        }
-        sb.append("]");
-        return sb.toString();
-    }
-
-    /*package*/ static byte[] readBytesWithNull(Parcel in) {
-        int len = in.readInt();
-        byte[] result = null;
-        if (len >= 0) {
-            result = new byte[len];
-            in.readByteArray(result);
-        }
-        return result;
-    }
-
-    /*package*/ static void writeBytesWithNull(Parcel out, byte[] b) {
-        if (b == null) {
-            out.writeInt(-1);
-            return;
-        }
-        out.writeInt(b.length);
-        out.writeByteArray(b);
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        // Null mTagService means this is a mock tag
-        int isMock = (mTagService == null)?1:0;
-
-        writeBytesWithNull(dest, mId);
-        dest.writeInt(mTechList.length);
-        dest.writeIntArray(mTechList);
-        dest.writeTypedArray(mTechExtras, 0);
-        dest.writeInt(mServiceHandle);
-        dest.writeLong(mCookie);
-        dest.writeInt(isMock);
-        if (isMock == 0) {
-            dest.writeStrongBinder(mTagService.asBinder());
-        }
-    }
-
-    public static final @android.annotation.NonNull Parcelable.Creator<Tag> CREATOR =
-            new Parcelable.Creator<Tag>() {
-        @Override
-        public Tag createFromParcel(Parcel in) {
-            INfcTag tagService;
-
-            // Tag fields
-            byte[] id = Tag.readBytesWithNull(in);
-            int[] techList = new int[in.readInt()];
-            in.readIntArray(techList);
-            Bundle[] techExtras = in.createTypedArray(Bundle.CREATOR);
-            int serviceHandle = in.readInt();
-            long cookie = in.readLong();
-            int isMock = in.readInt();
-            if (isMock == 0) {
-                tagService = INfcTag.Stub.asInterface(in.readStrongBinder());
-            }
-            else {
-                tagService = null;
-            }
-
-            return new Tag(id, techList, techExtras, serviceHandle, cookie, tagService);
-        }
-
-        @Override
-        public Tag[] newArray(int size) {
-            return new Tag[size];
-        }
-    };
-
-    /**
-     * For internal use only.
-     *
-     * @hide
-     */
-    public synchronized boolean setConnectedTechnology(int technology) {
-        if (mConnectedTechnology != -1) {
-            return false;
-        }
-        mConnectedTechnology = technology;
-        return true;
-    }
-
-    /**
-     * For internal use only.
-     *
-     * @hide
-     */
-    public int getConnectedTechnology() {
-        return mConnectedTechnology;
-    }
-
-    /**
-     * For internal use only.
-     *
-     * @hide
-     */
-    public void setTechnologyDisconnected() {
-        mConnectedTechnology = -1;
-    }
-}
diff --git a/nfc/java/android/nfc/TagLostException.java b/nfc/java/android/nfc/TagLostException.java
deleted file mode 100644
index 1981d7c..0000000
--- a/nfc/java/android/nfc/TagLostException.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2011, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import java.io.IOException;
-
-public class TagLostException extends IOException {
-    public TagLostException() {
-        super();
-    }
-
-    public TagLostException(String message) {
-        super(message);
-    }
-}
diff --git a/nfc/java/android/nfc/TechListParcel.aidl b/nfc/java/android/nfc/TechListParcel.aidl
deleted file mode 100644
index 92e646f..0000000
--- a/nfc/java/android/nfc/TechListParcel.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-parcelable TechListParcel;
\ No newline at end of file
diff --git a/nfc/java/android/nfc/TechListParcel.java b/nfc/java/android/nfc/TechListParcel.java
deleted file mode 100644
index 9f01559..0000000
--- a/nfc/java/android/nfc/TechListParcel.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package android.nfc;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/** @hide */
-public class TechListParcel implements Parcelable {
-
-    private String[][] mTechLists;
-
-    public TechListParcel(String[]... strings) {
-        mTechLists = strings;
-    }
-
-    public String[][] getTechLists() {
-        return mTechLists;
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        int count = mTechLists.length;
-        dest.writeInt(count);
-        for (int i = 0; i < count; i++) {
-            String[] techList = mTechLists[i];
-            dest.writeStringArray(techList);
-        }
-    }
-
-    public static final @android.annotation.NonNull Creator<TechListParcel> CREATOR = new Creator<TechListParcel>() {
-        @Override
-        public TechListParcel createFromParcel(Parcel source) {
-            int count = source.readInt();
-            String[][] techLists = new String[count][];
-            for (int i = 0; i < count; i++) {
-                techLists[i] = source.createStringArray();
-            }
-            return new TechListParcel(techLists);
-        }
-
-        @Override
-        public TechListParcel[] newArray(int size) {
-            return new TechListParcel[size];
-        }
-    };
-}
diff --git a/nfc/java/android/nfc/TransceiveResult.aidl b/nfc/java/android/nfc/TransceiveResult.aidl
deleted file mode 100644
index 98f92ee..0000000
--- a/nfc/java/android/nfc/TransceiveResult.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-parcelable TransceiveResult;
diff --git a/nfc/java/android/nfc/TransceiveResult.java b/nfc/java/android/nfc/TransceiveResult.java
deleted file mode 100644
index 7992094..0000000
--- a/nfc/java/android/nfc/TransceiveResult.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2011, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.io.IOException;
-
-/**
- * Class used to pipe transceive result from the NFC service.
- *
- * @hide
- */
-public final class TransceiveResult implements Parcelable {
-    public static final int RESULT_SUCCESS = 0;
-    public static final int RESULT_FAILURE = 1;
-    public static final int RESULT_TAGLOST = 2;
-    public static final int RESULT_EXCEEDED_LENGTH = 3;
-
-    final int mResult;
-    final byte[] mResponseData;
-
-    public TransceiveResult(final int result, final byte[] data) {
-        mResult = result;
-        mResponseData = data;
-    }
-
-    public byte[] getResponseOrThrow() throws IOException {
-        switch (mResult) {
-            case RESULT_SUCCESS:
-                return mResponseData;
-            case RESULT_TAGLOST:
-                throw new TagLostException("Tag was lost.");
-            case RESULT_EXCEEDED_LENGTH:
-                throw new IOException("Transceive length exceeds supported maximum");
-            default:
-                throw new IOException("Transceive failed");
-        }
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(mResult);
-        if (mResult == RESULT_SUCCESS) {
-            dest.writeInt(mResponseData.length);
-            dest.writeByteArray(mResponseData);
-        }
-    }
-
-    public static final @android.annotation.NonNull Parcelable.Creator<TransceiveResult> CREATOR =
-            new Parcelable.Creator<TransceiveResult>() {
-        @Override
-        public TransceiveResult createFromParcel(Parcel in) {
-            int result = in.readInt();
-            byte[] responseData;
-
-            if (result == RESULT_SUCCESS) {
-                int responseLength = in.readInt();
-                responseData = new byte[responseLength];
-                in.readByteArray(responseData);
-            } else {
-                responseData = null;
-            }
-            return new TransceiveResult(result, responseData);
-        }
-
-        @Override
-        public TransceiveResult[] newArray(int size) {
-            return new TransceiveResult[size];
-        }
-    };
-
-}
diff --git a/nfc/java/android/nfc/WlcListenerDeviceInfo.aidl b/nfc/java/android/nfc/WlcListenerDeviceInfo.aidl
deleted file mode 100644
index 7f2ca54..0000000
--- a/nfc/java/android/nfc/WlcListenerDeviceInfo.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-parcelable WlcListenerDeviceInfo;
diff --git a/nfc/java/android/nfc/WlcListenerDeviceInfo.java b/nfc/java/android/nfc/WlcListenerDeviceInfo.java
deleted file mode 100644
index 45315f8..0000000
--- a/nfc/java/android/nfc/WlcListenerDeviceInfo.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import android.annotation.FlaggedApi;
-import android.annotation.FloatRange;
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Contains information of the nfc wireless charging listener device information.
- */
-@FlaggedApi(Flags.FLAG_ENABLE_NFC_CHARGING)
-public final class WlcListenerDeviceInfo implements Parcelable {
-    /**
-     * Device is currently not connected with any WlcListenerDevice.
-     */
-    public static final int STATE_DISCONNECTED = 1;
-
-    /**
-     * Device is currently connected with a WlcListenerDevice and is charging it.
-     */
-    public static final int STATE_CONNECTED_CHARGING = 2;
-
-    /**
-     * Device is currently connected with a WlcListenerDevice without charging it.
-     */
-    public static final int STATE_CONNECTED_DISCHARGING = 3;
-
-    /**
-     * Possible states from {@link #getState}.
-     * @hide
-     */
-    @IntDef(prefix = { "STATE_" }, value = {
-            STATE_DISCONNECTED,
-            STATE_CONNECTED_CHARGING,
-            STATE_CONNECTED_DISCHARGING
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface WlcListenerState{}
-
-    private int mProductId;
-    private double mTemperature;
-    private double mBatteryLevel;
-    private int mState;
-
-     /**
-     * Create a new object containing wlc listener information.
-     *
-     * @param productId code for the device vendor
-     * @param temperature current temperature
-     * @param batteryLevel current battery level
-     * @param state current state
-     */
-    public WlcListenerDeviceInfo(int productId, double temperature, double batteryLevel,
-            @WlcListenerState int state) {
-        this.mProductId = productId;
-        this.mTemperature = temperature;
-        this.mBatteryLevel = batteryLevel;
-        this.mState = state;
-    }
-
-    /**
-     * ProductId of the WLC listener device.
-     * @return integer that is converted from USI Stylus VendorID[11:0].
-     */
-    public int getProductId() {
-        return mProductId;
-    }
-
-    /**
-     * Temperature of the WLC listener device.
-     * @return the value represents the temperature in °C.
-     */
-    public double getTemperature() {
-        return mTemperature;
-    }
-
-    /**
-     * BatteryLevel of the WLC listener device.
-     * @return battery level in percentage [0-100]
-     */
-    public @FloatRange(from = 0.0, to = 100.0) double getBatteryLevel() {
-        return mBatteryLevel;
-    }
-
-    /**
-     * State of the WLC listener device.
-     */
-    public @WlcListenerState int getState() {
-        return mState;
-    }
-
-    private WlcListenerDeviceInfo(Parcel in) {
-        this.mProductId = in.readInt();
-        this.mTemperature = in.readDouble();
-        this.mBatteryLevel = in.readDouble();
-        this.mState = in.readInt();
-    }
-
-    public static final @NonNull Parcelable.Creator<WlcListenerDeviceInfo> CREATOR =
-            new Parcelable.Creator<WlcListenerDeviceInfo>() {
-                @Override
-                public WlcListenerDeviceInfo createFromParcel(Parcel in) {
-                    return new WlcListenerDeviceInfo(in);
-                }
-
-                @Override
-                public WlcListenerDeviceInfo[] newArray(int size) {
-                    return new WlcListenerDeviceInfo[size];
-                }
-            };
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(@NonNull Parcel dest, int flags) {
-        dest.writeInt(mProductId);
-        dest.writeDouble(mTemperature);
-        dest.writeDouble(mBatteryLevel);
-        dest.writeInt(mState);
-    }
-}
diff --git a/nfc/java/android/nfc/cardemulation/CardEmulation.java b/nfc/java/android/nfc/cardemulation/CardEmulation.java
deleted file mode 100644
index fee9c5b..0000000
--- a/nfc/java/android/nfc/cardemulation/CardEmulation.java
+++ /dev/null
@@ -1,1497 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc.cardemulation;
-
-import android.Manifest;
-import android.annotation.CallbackExecutor;
-import android.annotation.FlaggedApi;
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.RequiresFeature;
-import android.annotation.RequiresPermission;
-import android.annotation.SdkConstant;
-import android.annotation.SdkConstant.SdkConstantType;
-import android.annotation.SystemApi;
-import android.annotation.UserHandleAware;
-import android.annotation.UserIdInt;
-import android.app.Activity;
-import android.app.role.RoleManager;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.nfc.ComponentNameAndUser;
-import android.nfc.Constants;
-import android.nfc.Flags;
-import android.nfc.INfcCardEmulation;
-import android.nfc.INfcEventCallback;
-import android.nfc.NfcAdapter;
-import android.os.Build;
-import android.os.RemoteException;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.provider.Settings.SettingNotFoundException;
-import android.telephony.SubscriptionManager;
-import android.util.ArrayMap;
-import android.util.Log;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.HashMap;
-import java.util.HexFormat;
-import java.util.List;
-import java.util.Locale;
-import java.util.Objects;
-import java.util.concurrent.Executor;
-import java.util.regex.Pattern;
-
-/**
- * This class can be used to query the state of
- * NFC card emulation services.
- *
- * For a general introduction into NFC card emulation,
- * please read the <a href="{@docRoot}guide/topics/connectivity/nfc/hce.html">
- * NFC card emulation developer guide</a>.</p>
- *
- * <p class="note">Use of this class requires the
- * {@link PackageManager#FEATURE_NFC_HOST_CARD_EMULATION} to be present
- * on the device.
- */
-public final class CardEmulation {
-    private static final Pattern AID_PATTERN = Pattern.compile("[0-9A-Fa-f]{10,32}\\*?\\#?");
-    private static final Pattern PLPF_PATTERN = Pattern.compile("[0-9A-Fa-f,\\?,\\*\\.]*");
-
-    static final String TAG = "CardEmulation";
-
-    /**
-     * Activity action: ask the user to change the default
-     * card emulation service for a certain category. This will
-     * show a dialog that asks the user whether they want to
-     * replace the current default service with the service
-     * identified with the ComponentName specified in
-     * {@link #EXTRA_SERVICE_COMPONENT}, for the category
-     * specified in {@link #EXTRA_CATEGORY}. There is an optional
-     * extra field using {@link Intent#EXTRA_USER} to specify
-     * the {@link UserHandle} of the user that owns the app.
-     *
-     * @deprecated Please use {@link android.app.role.RoleManager#createRequestRoleIntent(String)}
-     * with {@link android.app.role.RoleManager#ROLE_WALLET} parameter
-     * and {@link Activity#startActivityForResult(Intent, int)} instead.
-     */
-    @Deprecated
-    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
-    public static final String ACTION_CHANGE_DEFAULT =
-            "android.nfc.cardemulation.action.ACTION_CHANGE_DEFAULT";
-
-    /**
-     * The category extra for {@link #ACTION_CHANGE_DEFAULT}.
-     *
-     * @see #ACTION_CHANGE_DEFAULT
-     */
-    public static final String EXTRA_CATEGORY = "category";
-
-    /**
-     * The service {@link ComponentName} object passed in as an
-     * extra for {@link #ACTION_CHANGE_DEFAULT}.
-     *
-     * @see #ACTION_CHANGE_DEFAULT
-     */
-    public static final String EXTRA_SERVICE_COMPONENT = "component";
-
-    /**
-     * Category used for NFC payment services.
-     */
-    public static final String CATEGORY_PAYMENT = "payment";
-
-    /**
-     * Category that can be used for all other card emulation
-     * services.
-     */
-    public static final String CATEGORY_OTHER = "other";
-
-    /**
-     * Return value for {@link #getSelectionModeForCategory(String)}.
-     *
-     * <p>In this mode, the user has set a default service for this
-     *    category.
-     *
-     * <p>When using ISO-DEP card emulation with {@link HostApduService}
-     *    or {@link OffHostApduService}, if a remote NFC device selects
-     *    any of the Application IDs (AIDs)
-     *    that the default service has registered in this category,
-     *    that service will automatically be bound to to handle
-     *    the transaction.
-     */
-    public static final int SELECTION_MODE_PREFER_DEFAULT = 0;
-
-    /**
-     * Return value for {@link #getSelectionModeForCategory(String)}.
-     *
-     * <p>In this mode, when using ISO-DEP card emulation with {@link HostApduService}
-     *    or {@link OffHostApduService}, whenever an Application ID (AID) of this category
-     *    is selected, the user is asked which service they want to use to handle
-     *    the transaction, even if there is only one matching service.
-     */
-    public static final int SELECTION_MODE_ALWAYS_ASK = 1;
-
-    /**
-     * Return value for {@link #getSelectionModeForCategory(String)}.
-     *
-     * <p>In this mode, when using ISO-DEP card emulation with {@link HostApduService}
-     *    or {@link OffHostApduService}, the user will only be asked to select a service
-     *    if the Application ID (AID) selected by the reader has been registered by multiple
-     *    services. If there is only one service that has registered for the AID,
-     *    that service will be invoked directly.
-     */
-    public static final int SELECTION_MODE_ASK_IF_CONFLICT = 2;
-    /**
-     * Route to Device Host (DH).
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OVERRIDE_RECOVER_ROUTING_TABLE)
-    public static final int PROTOCOL_AND_TECHNOLOGY_ROUTE_DH = 0;
-    /**
-     * Route to eSE.
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OVERRIDE_RECOVER_ROUTING_TABLE)
-    public static final int PROTOCOL_AND_TECHNOLOGY_ROUTE_ESE = 1;
-    /**
-     * Route to UICC.
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OVERRIDE_RECOVER_ROUTING_TABLE)
-    public static final int PROTOCOL_AND_TECHNOLOGY_ROUTE_UICC = 2;
-
-    /**
-     * Route to the default value in config file.
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OVERRIDE_RECOVER_ROUTING_TABLE)
-    public static final int PROTOCOL_AND_TECHNOLOGY_ROUTE_DEFAULT = 3;
-
-    /**
-     * Route unset.
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OVERRIDE_RECOVER_ROUTING_TABLE)
-    public static final int PROTOCOL_AND_TECHNOLOGY_ROUTE_UNSET = -1;
-
-    /**
-     * Status code returned when {@link #setServiceEnabledForCategoryOther(ComponentName, boolean)}
-     * succeeded.
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_NFC_SET_SERVICE_ENABLED_FOR_CATEGORY_OTHER)
-    public static final int SET_SERVICE_ENABLED_STATUS_OK = 0;
-
-    /**
-     * Status code returned when {@link #setServiceEnabledForCategoryOther(ComponentName, boolean)}
-     * failed due to the unsupported feature.
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_NFC_SET_SERVICE_ENABLED_FOR_CATEGORY_OTHER)
-    public static final int SET_SERVICE_ENABLED_STATUS_FAILURE_FEATURE_UNSUPPORTED = 1;
-
-    /**
-     * Status code returned when {@link #setServiceEnabledForCategoryOther(ComponentName, boolean)}
-     * failed due to the invalid service.
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_NFC_SET_SERVICE_ENABLED_FOR_CATEGORY_OTHER)
-    public static final int SET_SERVICE_ENABLED_STATUS_FAILURE_INVALID_SERVICE = 2;
-
-    /**
-     * Status code returned when {@link #setServiceEnabledForCategoryOther(ComponentName, boolean)}
-     * failed due to the service is already set to the requested status.
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_NFC_SET_SERVICE_ENABLED_FOR_CATEGORY_OTHER)
-    public static final int SET_SERVICE_ENABLED_STATUS_FAILURE_ALREADY_SET = 3;
-
-    /**
-     * Status code returned when {@link #setServiceEnabledForCategoryOther(ComponentName, boolean)}
-     * failed due to unknown error.
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_NFC_SET_SERVICE_ENABLED_FOR_CATEGORY_OTHER)
-    public static final int SET_SERVICE_ENABLED_STATUS_FAILURE_UNKNOWN_ERROR = 4;
-
-    /**
-     * Status code returned by {@link #setServiceEnabledForCategoryOther(ComponentName, boolean)}
-     * @hide
-     */
-    @IntDef(prefix = "SET_SERVICE_ENABLED_STATUS_", value = {
-            SET_SERVICE_ENABLED_STATUS_OK,
-            SET_SERVICE_ENABLED_STATUS_FAILURE_FEATURE_UNSUPPORTED,
-            SET_SERVICE_ENABLED_STATUS_FAILURE_INVALID_SERVICE,
-            SET_SERVICE_ENABLED_STATUS_FAILURE_ALREADY_SET,
-            SET_SERVICE_ENABLED_STATUS_FAILURE_UNKNOWN_ERROR
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface SetServiceEnabledStatusCode {}
-
-    /**
-     * Property name used to indicate that an application wants to allow associated services
-     * to share the same AID routing priority when this application is the role holder.
-     * <p>
-     * Example:
-     * <pre>
-     *     {@code
-     *     <application>
-     *       ...
-     *       <property android:name="android.nfc.cardemulation.PROPERTY_ALLOW_SHARED_ROLE_PRIORITY"
-     *         android:value="true"/>
-     *     </application>
-     *     }
-     * </pre>
-     */
-    @FlaggedApi(Flags.FLAG_NFC_ASSOCIATED_ROLE_SERVICES)
-    public static final String PROPERTY_ALLOW_SHARED_ROLE_PRIORITY =
-            "android.nfc.cardemulation.PROPERTY_ALLOW_SHARED_ROLE_PRIORITY";
-
-    static boolean sIsInitialized = false;
-    static HashMap<Context, CardEmulation> sCardEmus = new HashMap<Context, CardEmulation>();
-    static INfcCardEmulation sService;
-
-    final Context mContext;
-
-    private CardEmulation(Context context, INfcCardEmulation service) {
-        mContext = context.getApplicationContext();
-        sService = service;
-    }
-
-    /**
-     * Helper to get an instance of this class.
-     *
-     * @param adapter A reference to an NfcAdapter object.
-     * @return
-     */
-    public static synchronized CardEmulation getInstance(NfcAdapter adapter) {
-        if (adapter == null) throw new NullPointerException("NfcAdapter is null");
-        Context context = adapter.getContext();
-        if (context == null) {
-            Log.e(TAG, "NfcAdapter context is null.");
-            throw new UnsupportedOperationException();
-        }
-        if (!sIsInitialized) {
-            PackageManager pm = context.getPackageManager();
-            if (pm == null) {
-                Log.e(TAG, "Cannot get PackageManager");
-                throw new UnsupportedOperationException();
-            }
-            if (!pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION)) {
-                Log.e(TAG, "This device does not support card emulation");
-                throw new UnsupportedOperationException();
-            }
-            sIsInitialized = true;
-        }
-        CardEmulation manager = sCardEmus.get(context);
-        if (manager == null) {
-            // Get card emu service
-            INfcCardEmulation service = adapter.getCardEmulationService();
-            if (service == null) {
-                Log.e(TAG, "This device does not implement the INfcCardEmulation interface.");
-                throw new UnsupportedOperationException();
-            }
-            manager = new CardEmulation(context, service);
-            sCardEmus.put(context, manager);
-        }
-        return manager;
-    }
-
-    /**
-     * Allows an application to query whether a service is currently
-     * the default service to handle a card emulation category.
-     *
-     * <p>Note that if {@link #getSelectionModeForCategory(String)}
-     * returns {@link #SELECTION_MODE_ALWAYS_ASK} or {@link #SELECTION_MODE_ASK_IF_CONFLICT},
-     * this method will always return false. That is because in these
-     * selection modes a default can't be set at the category level. For categories where
-     * the selection mode is {@link #SELECTION_MODE_ALWAYS_ASK} or
-     * {@link #SELECTION_MODE_ASK_IF_CONFLICT}, use
-     * {@link #isDefaultServiceForAid(ComponentName, String)} to determine whether a service
-     * is the default for a specific AID.
-     *
-     * @param service The ComponentName of the service
-     * @param category The category
-     * @return whether service is currently the default service for the category.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     */
-    public boolean isDefaultServiceForCategory(ComponentName service, String category) {
-        return callServiceReturn(() ->
-            sService.isDefaultServiceForCategory(
-                mContext.getUser().getIdentifier(), service, category), false);
-    }
-
-    /**
-     *
-     * Allows an application to query whether a service is currently
-     * the default handler for a specified ISO7816-4 Application ID.
-     *
-     * @param service The ComponentName of the service
-     * @param aid The ISO7816-4 Application ID
-     * @return whether the service is the default handler for the specified AID
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     */
-    public boolean isDefaultServiceForAid(ComponentName service, String aid) {
-        return callServiceReturn(() ->
-            sService.isDefaultServiceForAid(
-                mContext.getUser().getIdentifier(), service, aid), false);
-    }
-
-    /**
-     * <p>
-     * Returns whether the user has allowed AIDs registered in the
-     * specified category to be handled by a service that is preferred
-     * by the foreground application, instead of by a pre-configured default.
-     *
-     * Foreground applications can set such preferences using the
-     * {@link #setPreferredService(Activity, ComponentName)} method.
-     * <p class="note">
-     * Starting with {@link Build.VERSION_CODES#VANILLA_ICE_CREAM}, this method will always
-     * return true.
-     *
-     * @param category The category, e.g. {@link #CATEGORY_PAYMENT}
-     * @return whether AIDs in the category can be handled by a service
-     *         specified by the foreground app.
-     */
-    @SuppressWarnings("NonUserGetterCalled")
-    public boolean categoryAllowsForegroundPreference(String category) {
-        Context contextAsUser = mContext.createContextAsUser(
-                UserHandle.of(UserHandle.myUserId()), 0);
-
-        RoleManager roleManager = contextAsUser.getSystemService(RoleManager.class);
-        if (roleManager.isRoleAvailable(RoleManager.ROLE_WALLET)) {
-            return true;
-        }
-
-        if (CATEGORY_PAYMENT.equals(category)) {
-            boolean preferForeground = false;
-            try {
-                preferForeground = Settings.Secure.getInt(
-                        contextAsUser.getContentResolver(),
-                        Constants.SETTINGS_SECURE_NFC_PAYMENT_FOREGROUND) != 0;
-            } catch (SettingNotFoundException e) {
-            }
-            return preferForeground;
-        } else {
-            // Allowed for all other categories
-            return true;
-        }
-    }
-
-    /**
-     * Returns the service selection mode for the passed in category.
-     * Valid return values are:
-     * <p>{@link #SELECTION_MODE_PREFER_DEFAULT} the user has requested a default
-     *    service for this category, which will be preferred.
-     * <p>{@link #SELECTION_MODE_ALWAYS_ASK} the user has requested to be asked
-     *    every time what service they would like to use in this category.
-     * <p>{@link #SELECTION_MODE_ASK_IF_CONFLICT} the user will only be asked
-     *    to pick a service if there is a conflict.
-     *
-     * <p class="note">
-     * Starting with {@link Build.VERSION_CODES#VANILLA_ICE_CREAM}, the default service defined
-     * by the holder of {@link android.app.role.RoleManager#ROLE_WALLET} and is category agnostic.
-     *
-     * @param category The category, for example {@link #CATEGORY_PAYMENT}
-     * @return the selection mode for the passed in category
-     */
-    public int getSelectionModeForCategory(String category) {
-        if (CATEGORY_PAYMENT.equals(category)) {
-            boolean paymentRegistered = callServiceReturn(() ->
-                    sService.isDefaultPaymentRegistered(), false);
-            if (paymentRegistered) {
-                return SELECTION_MODE_PREFER_DEFAULT;
-            } else {
-                return SELECTION_MODE_ALWAYS_ASK;
-            }
-        } else {
-            return SELECTION_MODE_ASK_IF_CONFLICT;
-        }
-    }
-    /**
-     * Sets whether when this service becomes the preferred service, if the NFC stack
-     * should enable observe mode or disable observe mode. The default is to not enable observe
-     * mode when a service either the foreground default service or the default payment service so
-     * not calling this method will preserve that behavior.
-     *
-     * @param service The component name of the service
-     * @param enable Whether the service should default to observe mode or not
-     * @return whether the change was successful.
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OBSERVE_MODE)
-    public boolean setShouldDefaultToObserveModeForService(@NonNull ComponentName service,
-            boolean enable) {
-        return callServiceReturn(() ->
-            sService.setShouldDefaultToObserveModeForService(
-                mContext.getUser().getIdentifier(), service, enable), false);
-    }
-
-    /**
-     * Register a polling loop filter (PLF) for a HostApduService and indicate whether it should
-     * auto-transact or not.  The PLF can be sequence of an
-     * even number of at least 2 hexadecimal numbers (0-9, A-F or a-f), representing a series of
-     * bytes. When non-standard polling loop frame matches this sequence exactly, it may be
-     * delivered to {@link HostApduService#processPollingFrames(List)}.  If auto-transact
-     * is set to true and this service is currently preferred or there are no other services
-     * registered for this filter then observe mode will also be disabled.
-     * @param service The HostApduService to register the filter for
-     * @param pollingLoopFilter The filter to register
-     * @param autoTransact true to have the NFC stack automatically disable observe mode and allow
-     *         transactions to proceed when this filter matches, false otherwise
-     * @return true if the filter was registered, false otherwise
-     * @throws IllegalArgumentException if the passed in string doesn't parse to at least one byte
-     */
-    @FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP)
-    public boolean registerPollingLoopFilterForService(@NonNull ComponentName service,
-            @NonNull String pollingLoopFilter, boolean autoTransact) {
-        final String pollingLoopFilterV = validatePollingLoopFilter(pollingLoopFilter);
-        return callServiceReturn(() ->
-            sService.registerPollingLoopFilterForService(
-                mContext.getUser().getIdentifier(), service, pollingLoopFilterV, autoTransact),
-            false);
-    }
-
-    /**
-     * Unregister a polling loop filter (PLF) for a HostApduService. If the PLF had previously been
-     * registered via {@link #registerPollingLoopFilterForService(ComponentName, String, boolean)}
-     * for this service it will be removed.
-     * @param service The HostApduService to unregister the filter for
-     * @param pollingLoopFilter The filter to unregister
-     * @return true if the filter was removed, false otherwise
-     * @throws IllegalArgumentException if the passed in string doesn't parse to at least one byte
-     */
-    @FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP)
-    public boolean removePollingLoopFilterForService(@NonNull ComponentName service,
-            @NonNull String pollingLoopFilter) {
-        final String pollingLoopFilterV = validatePollingLoopFilter(pollingLoopFilter);
-        return callServiceReturn(() ->
-            sService.removePollingLoopFilterForService(
-                mContext.getUser().getIdentifier(), service, pollingLoopFilterV), false);
-    }
-
-
-    /**
-     * Register a polling loop pattern filter (PLPF) for a HostApduService and indicate whether it
-     * should auto-transact or not. The pattern may include the characters 0-9 and A-F as well as
-     * the regular expression operators `.`, `?` and `*`. When the beginning of anon-standard
-     * polling loop frame matches this sequence exactly, it may be delivered to
-     * {@link HostApduService#processPollingFrames(List)}. If auto-transact is set to true and this
-     * service is currently preferred or there are no other services registered for this filter
-     * then observe mode will also be disabled.
-     * @param service The HostApduService to register the filter for
-     * @param pollingLoopPatternFilter The pattern filter to register, must to be compatible with
-     *         {@link java.util.regex.Pattern#compile(String)} and only contain hexadecimal numbers
-     *         and `.`, `?` and `*` operators
-     * @param autoTransact true to have the NFC stack automatically disable observe mode and allow
-     *         transactions to proceed when this filter matches, false otherwise
-     * @return true if the filter was registered, false otherwise
-     * @throws IllegalArgumentException if the filter containst elements other than hexadecimal
-     *         numbers and `.`, `?` and `*` operators
-     * @throws java.util.regex.PatternSyntaxException if the regex syntax is invalid
-     */
-    @FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP)
-    public boolean registerPollingLoopPatternFilterForService(@NonNull ComponentName service,
-            @NonNull String pollingLoopPatternFilter, boolean autoTransact) {
-        final String pollingLoopPatternFilterV =
-            validatePollingLoopPatternFilter(pollingLoopPatternFilter);
-        return callServiceReturn(() ->
-            sService.registerPollingLoopPatternFilterForService(
-                mContext.getUser().getIdentifier(), service, pollingLoopPatternFilterV,
-                autoTransact),
-            false);
-    }
-
-    /**
-     * Unregister a polling loop pattern filter (PLPF) for a HostApduService. If the PLF had
-     * previously been registered via
-     * {@link #registerPollingLoopFilterForService(ComponentName, String, boolean)} for this
-     * service it will be removed.
-     * @param service The HostApduService to unregister the filter for
-     * @param pollingLoopPatternFilter The filter to unregister, must to be compatible with
-     *         {@link java.util.regex.Pattern#compile(String)} and only contain hexadecimal numbers
-     *         and`.`, `?` and `*` operators
-     * @return true if the filter was removed, false otherwise
-     * @throws IllegalArgumentException if the filter containst elements other than hexadecimal
-     *         numbers and `.`, `?` and `*` operators
-     * @throws java.util.regex.PatternSyntaxException if the regex syntax is invalid
-     */
-    @FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP)
-    public boolean removePollingLoopPatternFilterForService(@NonNull ComponentName service,
-            @NonNull String pollingLoopPatternFilter) {
-        final String pollingLoopPatternFilterV =
-            validatePollingLoopPatternFilter(pollingLoopPatternFilter);
-        return callServiceReturn(() ->
-            sService.removePollingLoopPatternFilterForService(
-                mContext.getUser().getIdentifier(), service, pollingLoopPatternFilterV), false);
-    }
-
-    /**
-     * Registers a list of AIDs for a specific category for the
-     * specified service.
-     *
-     * <p>If a list of AIDs for that category was previously
-     * registered for this service (either statically
-     * through the manifest, or dynamically by using this API),
-     * that list of AIDs will be replaced with this one.
-     *
-     * <p>Note that you can only register AIDs for a service that
-     * is running under the same UID as the caller of this API. Typically
-     * this means you need to call this from the same
-     * package as the service itself, though UIDs can also
-     * be shared between packages using shared UIDs.
-     *
-     * @param service The component name of the service
-     * @param category The category of AIDs to be registered
-     * @param aids A list containing the AIDs to be registered
-     * @return whether the registration was successful.
-     */
-    public boolean registerAidsForService(ComponentName service, String category,
-            List<String> aids) {
-        final AidGroup aidGroup = new AidGroup(aids, category);
-        return callServiceReturn(() ->
-            sService.registerAidGroupForService(
-                mContext.getUser().getIdentifier(), service, aidGroup), false);
-    }
-
-    /**
-     * Unsets the off-host Secure Element for the given service.
-     *
-     * <p>Note that this will only remove Secure Element that was dynamically
-     * set using the {@link #setOffHostForService(ComponentName, String)}
-     * and resets it to a value that was statically assigned using manifest.
-     *
-     * <p>Note that you can only unset off-host SE for a service that
-     * is running under the same UID as the caller of this API. Typically
-     * this means you need to call this from the same
-     * package as the service itself, though UIDs can also
-     * be shared between packages using shared UIDs.
-     *
-     * @param service The component name of the service
-     * @return whether the registration was successful.
-     */
-    @RequiresPermission(android.Manifest.permission.NFC)
-    @NonNull
-    public boolean unsetOffHostForService(@NonNull ComponentName service) {
-        return callServiceReturn(() ->
-            sService.unsetOffHostForService(
-                mContext.getUser().getIdentifier(), service), false);
-    }
-
-    /**
-     * Sets the off-host Secure Element for the given service.
-     *
-     * <p>If off-host SE was initially set (either statically
-     * through the manifest, or dynamically by using this API),
-     * it will be replaced with this one. All AIDs registered by
-     * this service will be re-routed to this Secure Element if
-     * successful. AIDs that was statically assigned using manifest
-     * will re-route to off-host SE that stated in manifest after NFC
-     * toggle.
-     *
-     * <p>Note that you can only set off-host SE for a service that
-     * is running under the same UID as the caller of this API. Typically
-     * this means you need to call this from the same
-     * package as the service itself, though UIDs can also
-     * be shared between packages using shared UIDs.
-     *
-     * <p>Registeration will be successful only if the Secure Element
-     * exists on the device.
-     *
-     * @param service The component name of the service
-     * @param offHostSecureElement Secure Element to register the AID to. Only accept strings with
-     *                             prefix SIM or prefix eSE.
-     *                             Ref: GSMA TS.26 - NFC Handset Requirements
-     *                             TS26_NFC_REQ_069: For UICC, Secure Element Name SHALL be
-     *                                               SIM[smartcard slot]
-     *                                               (e.g. SIM/SIM1, SIM2… SIMn).
-     *                             TS26_NFC_REQ_070: For embedded SE, Secure Element Name SHALL be
-     *                                               eSE[number]
-     *                                               (e.g. eSE/eSE1, eSE2, etc.).
-     * @return whether the registration was successful.
-     */
-    @RequiresPermission(android.Manifest.permission.NFC)
-    @NonNull
-    public boolean setOffHostForService(@NonNull ComponentName service,
-            @NonNull String offHostSecureElement) {
-        NfcAdapter adapter = NfcAdapter.getDefaultAdapter(mContext);
-        if (adapter == null || offHostSecureElement == null) {
-            return false;
-        }
-
-        List<String> validSE = adapter.getSupportedOffHostSecureElements();
-        if ((offHostSecureElement.startsWith("eSE") && !validSE.contains("eSE"))
-                || (offHostSecureElement.startsWith("SIM") && !validSE.contains("SIM"))) {
-            return false;
-        }
-
-        if (!offHostSecureElement.startsWith("eSE") && !offHostSecureElement.startsWith("SIM")) {
-            return false;
-        }
-
-        if (offHostSecureElement.equals("eSE")) {
-            offHostSecureElement = "eSE1";
-        } else if (offHostSecureElement.equals("SIM")) {
-            offHostSecureElement = "SIM1";
-        }
-        final String offHostSecureElementV = new String(offHostSecureElement);
-        return callServiceReturn(() ->
-            sService.setOffHostForService(
-                mContext.getUser().getIdentifier(), service, offHostSecureElementV), false);
-    }
-
-    /**
-     * Retrieves the currently registered AIDs for the specified
-     * category for a service.
-     *
-     * <p>Note that this will only return AIDs that were dynamically
-     * registered using {@link #registerAidsForService(ComponentName, String, List)}
-     * method. It will *not* return AIDs that were statically registered
-     * in the manifest.
-     *
-     * @param service The component name of the service
-     * @param category The category for which the AIDs were registered,
-     *                 e.g. {@link #CATEGORY_PAYMENT}
-     * @return The list of AIDs registered for this category, or null if it couldn't be found.
-     */
-    public List<String> getAidsForService(ComponentName service, String category) {
-        AidGroup group = callServiceReturn(() ->
-               sService.getAidGroupForService(
-                   mContext.getUser().getIdentifier(), service, category), null);
-        return (group != null ? group.getAids() : null);
-    }
-
-    /**
-     * Removes a previously registered list of AIDs for the specified category for the
-     * service provided.
-     *
-     * <p>Note that this will only remove AIDs that were dynamically
-     * registered using the {@link #registerAidsForService(ComponentName, String, List)}
-     * method. It will *not* remove AIDs that were statically registered in
-     * the manifest. If dynamically registered AIDs are removed using
-     * this method, and a statically registered AID group for the same category
-     * exists in the manifest, the static AID group will become active again.
-     *
-     * @param service The component name of the service
-     * @param category The category of the AIDs to be removed, e.g. {@link #CATEGORY_PAYMENT}
-     * @return whether the group was successfully removed.
-     */
-    public boolean removeAidsForService(ComponentName service, String category) {
-        return callServiceReturn(() ->
-            sService.removeAidGroupForService(
-                mContext.getUser().getIdentifier(), service, category), false);
-    }
-
-    /**
-     * Allows a foreground application to specify which card emulation service
-     * should be preferred while a specific Activity is in the foreground.
-     *
-     * <p>The specified Activity must currently be in resumed state. A good
-     * paradigm is to call this method in your {@link Activity#onResume}, and to call
-     * {@link #unsetPreferredService(Activity)} in your {@link Activity#onPause}.
-     *
-     * <p>This method call will fail in two specific scenarios:
-     * <ul>
-     * <li> If the service registers one or more AIDs in the {@link #CATEGORY_PAYMENT}
-     * category, but the user has indicated that foreground apps are not allowed
-     * to override the default payment service.
-     * <li> If the service registers one or more AIDs in the {@link #CATEGORY_OTHER}
-     * category that are also handled by the default payment service, and the
-     * user has indicated that foreground apps are not allowed to override the
-     * default payment service.
-     * </ul>
-     *
-     * <p> Use {@link #categoryAllowsForegroundPreference(String)} to determine
-     * whether foreground apps can override the default payment service.
-     *
-     * <p>Note that this preference is not persisted by the OS, and hence must be
-     * called every time the Activity is resumed.
-     *
-     * @param activity The activity which prefers this service to be invoked
-     * @param service The service to be preferred while this activity is in the foreground
-     * @return whether the registration was successful
-     */
-    public boolean setPreferredService(Activity activity, ComponentName service) {
-        // Verify the activity is in the foreground before calling into NfcService
-        if (activity == null || service == null) {
-            throw new NullPointerException("activity or service or category is null");
-        }
-        return callServiceReturn(() -> sService.setPreferredService(service), false);
-    }
-
-    /**
-     * Unsets the preferred service for the specified Activity.
-     *
-     * <p>Note that the specified Activity must still be in resumed
-     * state at the time of this call. A good place to call this method
-     * is in your {@link Activity#onPause} implementation.
-     *
-     * @param activity The activity which the service was registered for
-     * @return true when successful
-     */
-    public boolean unsetPreferredService(Activity activity) {
-        if (activity == null) {
-            throw new NullPointerException("activity is null");
-        }
-        return callServiceReturn(() -> sService.unsetPreferredService(), false);
-    }
-
-    /**
-     * Some devices may allow an application to register all
-     * AIDs that starts with a certain prefix, e.g.
-     * "A000000004*" to register all MasterCard AIDs.
-     *
-     * Use this method to determine whether this device
-     * supports registering AID prefixes.
-     *
-     * @return whether AID prefix registering is supported on this device.
-     */
-    public boolean supportsAidPrefixRegistration() {
-        return callServiceReturn(() -> sService.supportsAidPrefixRegistration(), false);
-    }
-
-    /**
-     * Retrieves the registered AIDs for the preferred payment service.
-     *
-     * @return The list of AIDs registered for this category, or null if it couldn't be found.
-     */
-    @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO)
-    @Nullable
-    public List<String> getAidsForPreferredPaymentService() {
-        ApduServiceInfo serviceInfo = callServiceReturn(() ->
-                sService.getPreferredPaymentService(mContext.getUser().getIdentifier()), null);
-        return (serviceInfo != null ? serviceInfo.getAids() : null);
-    }
-
-    /**
-     * Retrieves the route destination for the preferred payment service.
-     *
-     * <p class="note">
-     * Starting with {@link Build.VERSION_CODES#VANILLA_ICE_CREAM}, the preferred payment service
-     * no longer exists and is replaced by {@link android.app.role.RoleManager#ROLE_WALLET}. This
-     * will return the route for one of the services registered by the role holder (if any). If
-     * there are multiple services registered, it is unspecified which of those will be used to
-     * determine the route.
-     *
-     * @return The route destination secure element name of the preferred payment service.
-     *         HCE payment: "Host"
-     *         OffHost payment: 1. String with prefix SIM or prefix eSE string.
-     *                             Ref: GSMA TS.26 - NFC Handset Requirements
-     *                             TS26_NFC_REQ_069: For UICC, Secure Element Name SHALL be
-     *                                               SIM[smartcard slot]
-     *                                               (e.g. SIM/SIM1, SIM2… SIMn).
-     *                             TS26_NFC_REQ_070: For embedded SE, Secure Element Name SHALL be
-     *                                               eSE[number]
-     *                                               (e.g. eSE/eSE1, eSE2, etc.).
-     *                          2. "OffHost" if the payment service does not specify secure element
-     *                             name.
-     */
-    @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO)
-    @Nullable
-    public String getRouteDestinationForPreferredPaymentService() {
-        ApduServiceInfo serviceInfo = callServiceReturn(() ->
-                sService.getPreferredPaymentService(mContext.getUser().getIdentifier()), null);
-        if (serviceInfo != null) {
-            if (!serviceInfo.isOnHost()) {
-                return serviceInfo.getOffHostSecureElement() == null ?
-                        "OffHost" : serviceInfo.getOffHostSecureElement();
-            }
-            return "Host";
-        }
-        return null;
-    }
-
-    /**
-     * Returns a user-visible description of the preferred payment service.
-     *
-     * <p class="note">
-     * Starting with {@link Build.VERSION_CODES#VANILLA_ICE_CREAM}, the preferred payment service
-     * no longer exists and is replaced by {@link android.app.role.RoleManager#ROLE_WALLET}. This
-     * will return the description for one of the services registered by the role holder (if any).
-     * If there are multiple services registered, it is unspecified which of those will be used
-     * to obtain the service description here.
-     *
-     * @return the preferred payment service description
-     */
-    @RequiresPermission(Manifest.permission.NFC_PREFERRED_PAYMENT_INFO)
-    @Nullable
-    public CharSequence getDescriptionForPreferredPaymentService() {
-        ApduServiceInfo serviceInfo = callServiceReturn(() ->
-                sService.getPreferredPaymentService(mContext.getUser().getIdentifier()), null);
-        return (serviceInfo != null ? serviceInfo.getDescription() : null);
-    }
-
-    /**
-     * @hide
-     */
-    public boolean setDefaultServiceForCategory(ComponentName service, String category) {
-        return callServiceReturn(() ->
-                sService.setDefaultServiceForCategory(
-                    mContext.getUser().getIdentifier(), service, category), false);
-    }
-
-    /**
-     * @hide
-     */
-    public boolean setDefaultForNextTap(ComponentName service) {
-        return callServiceReturn(() ->
-                sService.setDefaultForNextTap(
-                    mContext.getUser().getIdentifier(), service), false);
-    }
-
-    /**
-     * @hide
-     */
-    public boolean setDefaultForNextTap(int userId, ComponentName service) {
-        return callServiceReturn(() ->
-                sService.setDefaultForNextTap(userId, service), false);
-    }
-
-    /**
-     * @hide
-     */
-    public List<ApduServiceInfo> getServices(String category) {
-        return callServiceReturn(() ->
-                sService.getServices(
-                    mContext.getUser().getIdentifier(), category), null);
-    }
-
-    /**
-     * Retrieves list of services registered of the provided category for the provided user.
-     *
-     * @param category Category string, one of {@link #CATEGORY_PAYMENT} or {@link #CATEGORY_OTHER}
-     * @param userId the user handle of the user whose information is being requested.
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
-    @NonNull
-    public List<ApduServiceInfo> getServices(@NonNull String category, @UserIdInt int userId) {
-        return callServiceReturn(() ->
-                sService.getServices(userId, category), null);
-    }
-
-    /**
-     * Tests the validity of the polling loop filter.
-     * @param pollingLoopFilter The polling loop filter to test.
-     *
-     * @hide
-     */
-    @FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP)
-    public static @NonNull String validatePollingLoopFilter(@NonNull String pollingLoopFilter) {
-        // Verify hex characters
-        byte[] plfBytes = HexFormat.of().parseHex(pollingLoopFilter);
-        if (plfBytes.length == 0) {
-            throw new IllegalArgumentException(
-                "Polling loop filter must contain at least one byte.");
-        }
-        return HexFormat.of().withUpperCase().formatHex(plfBytes);
-    }
-
-    /**
-     * Tests the validity of the polling loop pattern filter.
-     * @param pollingLoopPatternFilter The polling loop filter to test.
-     *
-     * @hide
-     */
-    @FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP)
-    public static @NonNull String validatePollingLoopPatternFilter(
-        @NonNull String pollingLoopPatternFilter) {
-        // Verify hex characters
-        if (!PLPF_PATTERN.matcher(pollingLoopPatternFilter).matches()) {
-            throw new IllegalArgumentException(
-                "Polling loop pattern filters may only contain hexadecimal numbers, ?s and *s");
-        }
-        return Pattern.compile(pollingLoopPatternFilter.toUpperCase(Locale.ROOT)).toString();
-    }
-
-    /**
-     * A valid AID according to ISO/IEC 7816-4:
-     * <ul>
-     * <li>Has >= 5 bytes and <=16 bytes (>=10 hex chars and <= 32 hex chars)
-     * <li>Consist of only hex characters
-     * <li>Additionally, we allow an asterisk at the end, to indicate
-     *     a prefix
-     * <li>Additinally we allow an (#) at symbol at the end, to indicate
-     *     a subset
-     * </ul>
-     *
-     * @hide
-     */
-    public static boolean isValidAid(String aid) {
-        if (aid == null)
-            return false;
-
-        // If a prefix/subset AID, the total length must be odd (even # of AID chars + '*')
-        if ((aid.endsWith("*") || aid.endsWith("#")) && ((aid.length() % 2) == 0)) {
-            Log.e(TAG, "AID " + aid + " is not a valid AID.");
-            return false;
-        }
-
-        // If not a prefix/subset AID, the total length must be even (even # of AID chars)
-        if ((!(aid.endsWith("*") || aid.endsWith("#"))) && ((aid.length() % 2) != 0)) {
-            Log.e(TAG, "AID " + aid + " is not a valid AID.");
-            return false;
-        }
-
-        // Verify hex characters
-        if (!AID_PATTERN.matcher(aid).matches()) {
-            Log.e(TAG, "AID " + aid + " is not a valid AID.");
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Allows to set or unset preferred service (category other) to avoid AID Collision. The user
-     * should use corresponding context using {@link Context#createContextAsUser(UserHandle, int)}
-     *
-     * @param service The ComponentName of the service
-     * @param status  true to enable, false to disable
-     * @return status code defined in {@link SetServiceEnabledStatusCode}
-     *
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_NFC_SET_SERVICE_ENABLED_FOR_CATEGORY_OTHER)
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    @SetServiceEnabledStatusCode
-    public int setServiceEnabledForCategoryOther(@NonNull ComponentName service,
-            boolean status) {
-        return callServiceReturn(() ->
-                sService.setServiceEnabledForCategoryOther(mContext.getUser().getIdentifier(),
-                        service, status), SET_SERVICE_ENABLED_STATUS_FAILURE_UNKNOWN_ERROR);
-    }
-
-    /** @hide */
-    @IntDef(prefix = "PROTOCOL_AND_TECHNOLOGY_ROUTE_",
-            value = {
-                    PROTOCOL_AND_TECHNOLOGY_ROUTE_DH,
-                    PROTOCOL_AND_TECHNOLOGY_ROUTE_ESE,
-                    PROTOCOL_AND_TECHNOLOGY_ROUTE_UICC,
-                    PROTOCOL_AND_TECHNOLOGY_ROUTE_UNSET,
-                    PROTOCOL_AND_TECHNOLOGY_ROUTE_DEFAULT
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface ProtocolAndTechnologyRoute {}
-
-    /**
-     * Setting NFC controller routing table, which includes Protocol Route and Technology Route,
-     * while this Activity is in the foreground.
-     *
-     * The parameter set to {@link #PROTOCOL_AND_TECHNOLOGY_ROUTE_UNSET}
-     * can be used to keep current values for that entry. Either
-     * Protocol Route or Technology Route should be override when calling this API, otherwise
-     * throw {@link IllegalArgumentException}.
-     * <p>
-     * Example usage in an Activity that requires to set proto route to "ESE" and keep tech route:
-     * <pre>
-     * protected void onResume() {
-     *     mNfcAdapter.overrideRoutingTable(
-     *         this, {@link #PROTOCOL_AND_TECHNOLOGY_ROUTE_ESE},
-     *         {@link #PROTOCOL_AND_TECHNOLOGY_ROUTE_UNSET});
-     * }</pre>
-     * </p>
-     * Also activities must call {@link #recoverRoutingTable(Activity)}
-     * when it goes to the background. Only the package of the
-     * currently preferred service (the service set as preferred by the current foreground
-     * application via {@link CardEmulation#setPreferredService(Activity, ComponentName)} or the
-     * current Default Wallet Role Holder {@link RoleManager#ROLE_WALLET}),
-     * otherwise a call to this method will fail and throw {@link SecurityException}.
-     * @param activity The Activity that requests NFC controller routing table to be changed.
-     * @param protocol ISO-DEP route destination, where the possible inputs are defined
-     *                 in {@link ProtocolAndTechnologyRoute}.
-     * @param technology Tech-A, Tech-B and Tech-F route destination, where the possible inputs
-     *                   are defined in {@link ProtocolAndTechnologyRoute}
-     * @throws SecurityException if the caller is not the preferred NFC service
-     * @throws IllegalArgumentException if the activity is not resumed or the caller is not in the
-     * foreground.
-     * <p>
-     * This is a high risk API and only included to support mainline effort
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    @FlaggedApi(Flags.FLAG_NFC_OVERRIDE_RECOVER_ROUTING_TABLE)
-    public void overrideRoutingTable(
-            @NonNull Activity activity, @ProtocolAndTechnologyRoute int protocol,
-            @ProtocolAndTechnologyRoute int technology) {
-        if (!activity.isResumed()) {
-            throw new IllegalArgumentException("Activity must be resumed.");
-        }
-        String protocolRoute = routeIntToString(protocol);
-        String technologyRoute = routeIntToString(technology);
-        callService(() ->
-                sService.overrideRoutingTable(
-                        mContext.getUser().getIdentifier(),
-                        protocolRoute,
-                        technologyRoute,
-                        mContext.getPackageName()));
-    }
-
-    /**
-     * Restore the NFC controller routing table,
-     * which was changed by {@link #overrideRoutingTable(Activity, int, int)}
-     *
-     * @param activity The Activity that requested NFC controller routing table to be changed.
-     * @throws IllegalArgumentException if the caller is not in the foreground.
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    @FlaggedApi(Flags.FLAG_NFC_OVERRIDE_RECOVER_ROUTING_TABLE)
-    public void recoverRoutingTable(@NonNull Activity activity) {
-        if (!activity.isResumed()) {
-            throw new IllegalArgumentException("Activity must be resumed.");
-        }
-        callService(() ->
-                sService.recoverRoutingTable(
-                    mContext.getUser().getIdentifier()));
-    }
-
-    /**
-     * Is EUICC supported as a Secure Element EE which supports off host card emulation.
-     *
-     * @return true if the device supports EUICC for off host card emulation, false otherwise.
-     */
-    @FlaggedApi(android.nfc.Flags.FLAG_ENABLE_CARD_EMULATION_EUICC)
-    public boolean isEuiccSupported() {
-        return callServiceReturn(() -> sService.isEuiccSupported(), false);
-    }
-
-    /**
-     * Setting the default subscription ID succeeded.
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(android.nfc.Flags.FLAG_ENABLE_CARD_EMULATION_EUICC)
-    public static final int SET_SUBSCRIPTION_ID_STATUS_SUCCESS = 0;
-
-    /**
-     * Setting the default subscription ID failed because the subscription ID is invalid.
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(android.nfc.Flags.FLAG_ENABLE_CARD_EMULATION_EUICC)
-    public static final int SET_SUBSCRIPTION_ID_STATUS_FAILED_INVALID_SUBSCRIPTION_ID = 1;
-
-    /**
-     * Setting the default subscription ID failed because there was an internal error processing
-     * the request. For ex: NFC service died in the middle of handling the API.
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(android.nfc.Flags.FLAG_ENABLE_CARD_EMULATION_EUICC)
-    public static final int SET_SUBSCRIPTION_ID_STATUS_FAILED_INTERNAL_ERROR = 2;
-
-    /**
-     * Setting the default subscription ID failed because this feature is not supported on the
-     * device.
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(android.nfc.Flags.FLAG_ENABLE_CARD_EMULATION_EUICC)
-    public static final int SET_SUBSCRIPTION_ID_STATUS_FAILED_NOT_SUPPORTED = 3;
-
-    /**
-     * Setting the default subscription ID failed because of unknown error.
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_ENABLE_CARD_EMULATION_EUICC)
-    public static final int SET_SUBSCRIPTION_ID_STATUS_UNKNOWN = -1;
-
-    /** @hide */
-    @IntDef(prefix = "SET_SUBSCRIPTION_ID_STATUS_",
-            value = {
-                    SET_SUBSCRIPTION_ID_STATUS_SUCCESS,
-                    SET_SUBSCRIPTION_ID_STATUS_FAILED_INVALID_SUBSCRIPTION_ID,
-                    SET_SUBSCRIPTION_ID_STATUS_FAILED_INTERNAL_ERROR,
-                    SET_SUBSCRIPTION_ID_STATUS_FAILED_NOT_SUPPORTED,
-                    SET_SUBSCRIPTION_ID_STATUS_UNKNOWN
-            })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface SetSubscriptionIdStatus {}
-
-    /**
-     * Sets the system's default NFC subscription id.
-     *
-     * <p> For devices with multiple UICC/EUICC that is configured to be NFCEE, this sets the
-     * default UICC NFCEE that will handle NFC offhost CE transactions </p>
-     *
-     * @param subscriptionId the default NFC subscription Id to set. User can get subscription id
-     *                       from {@link SubscriptionManager#getSubscriptionId(int)}
-     * @return status of the operation.
-     *
-     * @throws UnsupportedOperationException If the device does not have
-     * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
-     * @hide
-     */
-    @SystemApi
-    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    @FlaggedApi(android.nfc.Flags.FLAG_ENABLE_CARD_EMULATION_EUICC)
-    public @SetSubscriptionIdStatus int setDefaultNfcSubscriptionId(int subscriptionId) {
-        return callServiceReturn(() ->
-                        sService.setDefaultNfcSubscriptionId(
-                                subscriptionId, mContext.getPackageName()),
-                SET_SUBSCRIPTION_ID_STATUS_FAILED_INTERNAL_ERROR);
-    }
-
-    /**
-     * Returns the system's default NFC subscription id.
-     *
-     * <p> For devices with multiple UICC/EUICC that is configured to be NFCEE, this returns the
-     * default UICC NFCEE that will handle NFC offhost CE transactions </p>
-     * <p> If the device has no UICC that can serve as NFCEE, this will return
-     * {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID}.</p>
-     *
-     * @return the default NFC subscription Id if set,
-     * {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID} otherwise.
-     *
-     * @throws UnsupportedOperationException If the device does not have
-     * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
-     */
-    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
-    @FlaggedApi(android.nfc.Flags.FLAG_ENABLE_CARD_EMULATION_EUICC)
-    public int getDefaultNfcSubscriptionId() {
-        return callServiceReturn(() ->
-                sService.getDefaultNfcSubscriptionId(mContext.getPackageName()),
-                SubscriptionManager.INVALID_SUBSCRIPTION_ID);
-    }
-
-    /**
-     * Returns the value of {@link Settings.Secure#NFC_PAYMENT_DEFAULT_COMPONENT}.
-     *
-     * @param context A context
-     * @return A ComponentName for the setting value, or null.
-     *
-     * @hide
-     */
-    @SystemApi
-    @UserHandleAware
-    @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO)
-    @SuppressWarnings("AndroidFrameworkClientSidePermissionCheck")
-    @FlaggedApi(android.permission.flags.Flags.FLAG_WALLET_ROLE_ENABLED)
-    @Nullable
-    public static ComponentName getPreferredPaymentService(@NonNull Context context) {
-        context.checkCallingOrSelfPermission(Manifest.permission.NFC_PREFERRED_PAYMENT_INFO);
-        String defaultPaymentComponent = Settings.Secure.getString(context.getContentResolver(),
-                Constants.SETTINGS_SECURE_NFC_PAYMENT_DEFAULT_COMPONENT);
-
-        if (defaultPaymentComponent == null) {
-            return null;
-        }
-
-        return ComponentName.unflattenFromString(defaultPaymentComponent);
-    }
-
-    /** @hide */
-    interface ServiceCall {
-        void call() throws RemoteException;
-    }
-    /** @hide */
-    public static void callService(ServiceCall call) {
-        try {
-            if (sService == null) {
-                NfcAdapter.attemptDeadServiceRecovery(
-                    new RemoteException("NFC CardEmulation Service is null"));
-                sService = NfcAdapter.getCardEmulationService();
-            }
-            call.call();
-        } catch (RemoteException e) {
-            NfcAdapter.attemptDeadServiceRecovery(e);
-            sService = NfcAdapter.getCardEmulationService();
-            try {
-                call.call();
-            } catch (RemoteException ee) {
-                ee.rethrowAsRuntimeException();
-            }
-        }
-    }
-    /** @hide */
-    interface ServiceCallReturn<T> {
-        T call() throws RemoteException;
-    }
-    /** @hide */
-    public static <T> T callServiceReturn(ServiceCallReturn<T> call, T defaultReturn) {
-        try {
-            if (sService == null) {
-                NfcAdapter.attemptDeadServiceRecovery(
-                    new RemoteException("NFC CardEmulation Service is null"));
-                sService = NfcAdapter.getCardEmulationService();
-            }
-            return call.call();
-        } catch (RemoteException e) {
-            NfcAdapter.attemptDeadServiceRecovery(e);
-            sService = NfcAdapter.getCardEmulationService();
-            // Try one more time
-            try {
-                return call.call();
-            } catch (RemoteException ee) {
-                ee.rethrowAsRuntimeException();
-            }
-        }
-        return defaultReturn;
-    }
-
-    /** @hide */
-    public static String routeIntToString(@ProtocolAndTechnologyRoute int route) {
-        return switch (route) {
-            case PROTOCOL_AND_TECHNOLOGY_ROUTE_DH -> "DH";
-            case PROTOCOL_AND_TECHNOLOGY_ROUTE_ESE -> "eSE";
-            case PROTOCOL_AND_TECHNOLOGY_ROUTE_UICC -> "SIM";
-            case PROTOCOL_AND_TECHNOLOGY_ROUTE_UNSET -> null;
-            case PROTOCOL_AND_TECHNOLOGY_ROUTE_DEFAULT -> "default";
-            default -> throw new IllegalStateException("Unexpected value: " + route);
-        };
-    }
-
-    @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 NfcEventCallback {
-        /**
-         * This method is called when this package gains or loses preferred Nfc service status,
-         * either the Default Wallet Role holder (see {@link
-         * android.app.role.RoleManager#ROLE_WALLET}) or the preferred service of the foreground
-         * activity set with {@link #setPreferredService(Activity, ComponentName)}
-         *
-         * @param isPreferred true is this service has become the preferred Nfc service, false if it
-         *     is no longer the preferred service
-         */
-        @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER)
-        default void onPreferredServiceChanged(boolean isPreferred) {}
-
-        /**
-         * This method is called when observe mode has been enabled or disabled.
-         *
-         * @param isEnabled true if observe mode has been enabled, false if it has been disabled
-         */
-        @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. If your service is
-         * registered for this AID you may want to instruct users to bring your app to the
-         * foreground and ensure you call {@link #setPreferredService(Activity, ComponentName)}
-         * to ensure the transaction is routed to your service.
-         *
-         * @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<NfcEventCallback, Executor> mNfcEventCallbacks = new ArrayMap<>();
-
-    final INfcEventCallback mINfcEventCallback =
-            new INfcEventCallback.Stub() {
-                public void onPreferredServiceChanged(ComponentNameAndUser componentNameAndUser) {
-                    if (!android.nfc.Flags.nfcEventListener()) {
-                        return;
-                    }
-                    boolean isPreferred =
-                            componentNameAndUser != null
-                                    && componentNameAndUser.getUserId()
-                                            == mContext.getUser().getIdentifier()
-                                    && componentNameAndUser.getComponentName() != null
-                                    && Objects.equals(
-                                            mContext.getPackageName(),
-                                            componentNameAndUser.getComponentName()
-                                                    .getPackageName());
-                    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(NfcEventCallback listener);
-                }
-
-                private void callListeners(ListenerCall listenerCall) {
-                    synchronized (mNfcEventCallbacks) {
-                        mNfcEventCallbacks.forEach(
-                            (listener, executor) -> {
-                                executor.execute(() -> listenerCall.invoke(listener));
-                            });
-                    }
-                }
-            };
-
-    /**
-     * Register a listener for NFC Events.
-     *
-     * @param executor The Executor to run the call back with
-     * @param listener The listener to register
-     */
-    @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER)
-    public void registerNfcEventCallback(
-            @NonNull @CallbackExecutor Executor executor, @NonNull NfcEventCallback listener) {
-        if (!android.nfc.Flags.nfcEventListener()) {
-            return;
-        }
-        synchronized (mNfcEventCallbacks) {
-            mNfcEventCallbacks.put(listener, executor);
-            if (mNfcEventCallbacks.size() == 1) {
-                callService(() -> sService.registerNfcEventCallback(mINfcEventCallback));
-            }
-        }
-    }
-
-    /**
-     * Unregister a preferred service listener that was previously registered with {@link
-     * #registerNfcEventCallback(Executor, NfcEventCallback)}
-     *
-     * @param listener The previously registered listener to unregister
-     */
-    @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER)
-    public void unregisterNfcEventCallback(@NonNull NfcEventCallback listener) {
-        if (!android.nfc.Flags.nfcEventListener()) {
-            return;
-        }
-        synchronized (mNfcEventCallbacks) {
-            mNfcEventCallbacks.remove(listener);
-            if (mNfcEventCallbacks.size() == 0) {
-                callService(() -> sService.unregisterNfcEventCallback(mINfcEventCallback));
-            }
-        }
-    }
-}
diff --git a/nfc/java/android/nfc/cardemulation/HostApduService.java b/nfc/java/android/nfc/cardemulation/HostApduService.java
deleted file mode 100644
index fbf2203..0000000
--- a/nfc/java/android/nfc/cardemulation/HostApduService.java
+++ /dev/null
@@ -1,446 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc.cardemulation;
-
-import android.annotation.FlaggedApi;
-import android.annotation.NonNull;
-import android.annotation.SdkConstant;
-import android.annotation.SdkConstant.SdkConstantType;
-import android.annotation.SuppressLint;
-import android.app.Service;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.nfc.NfcAdapter;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.Messenger;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * <p>HostApduService is a convenience {@link Service} class that can be
- * extended to emulate an NFC card inside an Android
- * service component.
- *
- * <div class="special reference">
- * <h3>Developer Guide</h3>
- * For a general introduction to card emulation, see
- * <a href="{@docRoot}guide/topics/connectivity/nfc/hce.html">
- * Host-based Card Emulation</a>.</p>
- * </div>
- *
- * <h3>NFC Protocols</h3>
- * <p>Cards emulated by this class are based on the NFC-Forum ISO-DEP
- * protocol (based on ISO/IEC 14443-4) and support processing
- * command Application Protocol Data Units (APDUs) as
- * defined in the ISO/IEC 7816-4 specification.
- *
- * <h3>Service selection</h3>
- * <p>When a remote NFC device wants to talk to your
- * service, it sends a so-called
- * "SELECT AID" APDU as defined in the ISO/IEC 7816-4 specification.
- * The AID is an application identifier defined in ISO/IEC 7816-4.
- *
- * <p>The registration procedure for AIDs is defined in the
- * ISO/IEC 7816-5 specification. If you don't want to register an
- * AID, you are free to use AIDs in the proprietary range:
- * bits 8-5 of the first byte must each be set to '1'. For example,
- * "0xF00102030405" is a proprietary AID. If you do use proprietary
- * AIDs, it is recommended to choose an AID of at least 6 bytes,
- * to reduce the risk of collisions with other applications that
- * might be using proprietary AIDs as well.
- *
- * <h3>AID groups</h3>
- * <p>In some cases, a service may need to register multiple AIDs
- * to implement a certain application, and it needs to be sure
- * that it is the default handler for all of these AIDs (as opposed
- * to some AIDs in the group going to another service).
- *
- * <p>An AID group is a list of AIDs that should be considered as
- * belonging together by the OS. For all AIDs in an AID group, the
- * OS will guarantee one of the following:
- * <ul>
- * <li>All AIDs in the group are routed to this service
- * <li>No AIDs in the group are routed to this service
- * </ul>
- * In other words, there is no in-between state, where some AIDs
- * in the group can be routed to this service, and some to another.
- * <h3>AID groups and categories</h3>
- * <p>Each AID group can be associated with a category. This allows
- * the Android OS to classify services, and it allows the user to
- * set defaults at the category level instead of the AID level.
- *
- * <p>You can use
- * {@link CardEmulation#isDefaultServiceForCategory(android.content.ComponentName, String)}
- * to determine if your service is the default handler for a category.
- *
- * <p>In this version of the platform, the only known categories
- * are {@link CardEmulation#CATEGORY_PAYMENT} and {@link CardEmulation#CATEGORY_OTHER}.
- * AID groups without a category, or with a category that is not recognized
- * by the current platform version, will automatically be
- * grouped into the {@link CardEmulation#CATEGORY_OTHER} category.
- * <h3>Service AID registration</h3>
- * <p>To tell the platform which AIDs groups
- * are requested by this service, a {@link #SERVICE_META_DATA}
- * entry must be included in the declaration of the service. An
- * example of a HostApduService manifest declaration is shown below:
- * <pre> &lt;service android:name=".MyHostApduService" android:exported="true" android:permission="android.permission.BIND_NFC_SERVICE"&gt;
- *     &lt;intent-filter&gt;
- *         &lt;action android:name="android.nfc.cardemulation.action.HOST_APDU_SERVICE"/&gt;
- *     &lt;/intent-filter&gt;
- *     &lt;meta-data android:name="android.nfc.cardemulation.host_apdu_service" android:resource="@xml/apduservice"/&gt;
- * &lt;/service&gt;</pre>
- *
- * This meta-data tag points to an apduservice.xml file.
- * An example of this file with a single AID group declaration is shown below:
- * <pre>
- * &lt;host-apdu-service xmlns:android="http://schemas.android.com/apk/res/android"
- *           android:description="@string/servicedesc" android:requireDeviceUnlock="false"&gt;
- *       &lt;aid-group android:description="@string/aiddescription" android:category="other">
- *           &lt;aid-filter android:name="F0010203040506"/&gt;
- *           &lt;aid-filter android:name="F0394148148100"/&gt;
- *       &lt;/aid-group&gt;
- * &lt;/host-apdu-service&gt;
- * </pre>
- *
- * <p>The {@link android.R.styleable#HostApduService &lt;host-apdu-service&gt;} is required
- * to contain a
- * {@link android.R.styleable#HostApduService_description &lt;android:description&gt;}
- * attribute that contains a user-friendly description of the service that may be shown in UI.
- * The
- * {@link android.R.styleable#HostApduService_requireDeviceUnlock &lt;requireDeviceUnlock&gt;}
- * attribute can be used to specify that the device must be unlocked before this service
- * can be invoked to handle APDUs.
- * <p>The {@link android.R.styleable#HostApduService &lt;host-apdu-service&gt;} must
- * contain one or more {@link android.R.styleable#AidGroup &lt;aid-group&gt;} tags.
- * Each {@link android.R.styleable#AidGroup &lt;aid-group&gt;} must contain one or
- * more {@link android.R.styleable#AidFilter &lt;aid-filter&gt;} tags, each of which
- * contains a single AID. The AID must be specified in hexadecimal format, and contain
- * an even number of characters.
- * <h3>AID conflict resolution</h3>
- * Multiple HostApduServices may be installed on a single device, and the same AID
- * can be registered by more than one service. The Android platform resolves AID
- * conflicts depending on which category an AID belongs to. Each category may
- * have a different conflict resolution policy. For example, for some categories
- * the user may be able to select a default service in the Android settings UI.
- * For other categories, to policy may be to always ask the user which service
- * is to be invoked in case of conflict.
- *
- * To query the conflict resolution policy for a certain category, see
- * {@link CardEmulation#getSelectionModeForCategory(String)}.
- *
- * <h3>Data exchange</h3>
- * <p>Once the platform has resolved a "SELECT AID" command APDU to a specific
- * service component, the "SELECT AID" command APDU and all subsequent
- * command APDUs will be sent to that service through
- * {@link #processCommandApdu(byte[], Bundle)}, until either:
- * <ul>
- * <li>The NFC link is broken</li>
- * <li>A "SELECT AID" APDU is received which resolves to another service</li>
- * </ul>
- * These two scenarios are indicated by a call to {@link #onDeactivated(int)}.
- *
- * <p class="note">Use of this class requires the
- * {@link PackageManager#FEATURE_NFC_HOST_CARD_EMULATION} to be present
- * on the device.
- *
- */
-public abstract class HostApduService extends Service {
-    /**
-     * The {@link Intent} action that must be declared as handled by the service.
-     */
-    @SdkConstant(SdkConstantType.SERVICE_ACTION)
-    public static final String SERVICE_INTERFACE =
-            "android.nfc.cardemulation.action.HOST_APDU_SERVICE";
-
-    /**
-     * The name of the meta-data element that contains
-     * more information about this service.
-     */
-    public static final String SERVICE_META_DATA =
-            "android.nfc.cardemulation.host_apdu_service";
-
-    /**
-     * Reason for {@link #onDeactivated(int)}.
-     * Indicates deactivation was due to the NFC link
-     * being lost.
-     */
-    public static final int DEACTIVATION_LINK_LOSS = 0;
-
-    /**
-     * Reason for {@link #onDeactivated(int)}.
-     *
-     * <p>Indicates deactivation was due to a different AID
-     * being selected (which implicitly deselects the AID
-     * currently active on the logical channel).
-     *
-     * <p>Note that this next AID may still be resolved to this
-     * service, in which case {@link #processCommandApdu(byte[], Bundle)}
-     * will be called again.
-     */
-    public static final int DEACTIVATION_DESELECTED = 1;
-
-    static final String TAG = "ApduService";
-
-    /**
-     * MSG_COMMAND_APDU is sent by NfcService when
-     * a 7816-4 command APDU has been received.
-     *
-     * @hide
-     */
-    public static final int MSG_COMMAND_APDU = 0;
-
-    /**
-     * MSG_RESPONSE_APDU is sent to NfcService to send
-     * a response APDU back to the remote device.
-     *
-     * @hide
-     */
-    public static final int MSG_RESPONSE_APDU = 1;
-
-    /**
-     * MSG_DEACTIVATED is sent by NfcService when
-     * the current session is finished; either because
-     * another AID was selected that resolved to
-     * another service, or because the NFC link
-     * was deactivated.
-     *
-     * @hide
-     */
-    public static final int MSG_DEACTIVATED = 2;
-
-    /**
-     *
-     * @hide
-     */
-    public static final int MSG_UNHANDLED = 3;
-
-    /**
-     * @hide
-     */
-    public static final int MSG_POLLING_LOOP = 4;
-
-
-    /**
-     * @hide
-     */
-    public static final String KEY_DATA = "data";
-
-    /**
-     * @hide
-     */
-    public static final String KEY_POLLING_LOOP_FRAMES_BUNDLE =
-            "android.nfc.cardemulation.POLLING_FRAMES";
-
-    /**
-     * Messenger interface to NfcService for sending responses.
-     * Only accessed on main thread by the message handler.
-     *
-     * @hide
-     */
-    Messenger mNfcService = null;
-
-    final Messenger mMessenger = new Messenger(new MsgHandler());
-
-    final class MsgHandler extends Handler {
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-            case MSG_COMMAND_APDU:
-                Bundle dataBundle = msg.getData();
-                if (dataBundle == null) {
-                    return;
-                }
-                if (mNfcService == null) mNfcService = msg.replyTo;
-
-                byte[] apdu = dataBundle.getByteArray(KEY_DATA);
-                if (apdu != null) {
-                        HostApduService has = HostApduService.this;
-                    byte[] responseApdu = processCommandApdu(apdu, null);
-                    if (responseApdu != null) {
-                        if (mNfcService == null) {
-                            Log.e(TAG, "Response not sent; service was deactivated.");
-                            return;
-                        }
-                        Message responseMsg = Message.obtain(null, MSG_RESPONSE_APDU);
-                        Bundle responseBundle = new Bundle();
-                        responseBundle.putByteArray(KEY_DATA, responseApdu);
-                        responseMsg.setData(responseBundle);
-                        responseMsg.replyTo = mMessenger;
-                        try {
-                            mNfcService.send(responseMsg);
-                        } catch (RemoteException e) {
-                            Log.e(TAG, "Response not sent; RemoteException calling into " +
-                                    "NfcService.");
-                        }
-                    }
-                } else {
-                    Log.e(TAG, "Received MSG_COMMAND_APDU without data.");
-                }
-                break;
-            case MSG_RESPONSE_APDU:
-                if (mNfcService == null) {
-                    Log.e(TAG, "Response not sent; service was deactivated.");
-                    return;
-                }
-                try {
-                    msg.replyTo = mMessenger;
-                    mNfcService.send(msg);
-                } catch (RemoteException e) {
-                    Log.e(TAG, "RemoteException calling into NfcService.");
-                }
-                break;
-            case MSG_DEACTIVATED:
-                // Make sure we won't call into NfcService again
-                mNfcService = null;
-                onDeactivated(msg.arg1);
-                break;
-            case MSG_UNHANDLED:
-                if (mNfcService == null) {
-                    Log.e(TAG, "notifyUnhandled not sent; service was deactivated.");
-                    return;
-                }
-                try {
-                    msg.replyTo = mMessenger;
-                    mNfcService.send(msg);
-                } catch (RemoteException e) {
-                    Log.e(TAG, "RemoteException calling into NfcService.");
-                }
-                break;
-                case MSG_POLLING_LOOP:
-                    if (android.nfc.Flags.nfcReadPollingLoop()) {
-                        ArrayList<PollingFrame> pollingFrames =
-                                msg.getData().getParcelableArrayList(
-                                    KEY_POLLING_LOOP_FRAMES_BUNDLE, PollingFrame.class);
-                        processPollingFrames(pollingFrames);
-                    }
-                    break;
-                default:
-                super.handleMessage(msg);
-            }
-        }
-    }
-
-    @Override
-    public final IBinder onBind(Intent intent) {
-        return mMessenger.getBinder();
-    }
-
-    /**
-     * Sends a response APDU back to the remote device.
-     *
-     * <p>Note: this method may be called from any thread and will not block.
-     * @param responseApdu A byte-array containing the reponse APDU.
-     */
-    public final void sendResponseApdu(byte[] responseApdu) {
-        Message responseMsg = Message.obtain(null, MSG_RESPONSE_APDU);
-        Bundle dataBundle = new Bundle();
-        dataBundle.putByteArray(KEY_DATA, responseApdu);
-        responseMsg.setData(dataBundle);
-        try {
-            mMessenger.send(responseMsg);
-        } catch (RemoteException e) {
-            Log.e("TAG", "Local messenger has died.");
-        }
-    }
-
-    /**
-     * Calling this method allows the service to tell the OS
-     * that it won't be able to complete this transaction -
-     * for example, because it requires data connectivity
-     * that is not present at that moment.
-     *
-     * The OS may use this indication to give the user a list
-     * of alternative applications that can handle the last
-     * AID that was selected. If the user would select an
-     * application from the list, that action by itself
-     * will not cause the default to be changed; the selected
-     * application will be invoked for the next tap only.
-     *
-     * If there are no other applications that can handle
-     * this transaction, the OS will show an error dialog
-     * indicating your service could not complete the
-     * transaction.
-     *
-     * <p>Note: this method may be called anywhere between
-     *    the first {@link #processCommandApdu(byte[], Bundle)}
-     *    call and a {@link #onDeactivated(int)} call.
-     */
-    public final void notifyUnhandled() {
-        Message unhandledMsg = Message.obtain(null, MSG_UNHANDLED);
-        try {
-            mMessenger.send(unhandledMsg);
-        } catch (RemoteException e) {
-            Log.e("TAG", "Local messenger has died.");
-        }
-    }
-
-    /**
-     * This method is called when polling frames have been received from a
-     * remote device. If the device is in observe mode, the service should
-     * call {@link NfcAdapter#allowTransaction()} once it is ready to proceed
-     * with the transaction. If the device is not in observe mode, the service
-     * can use this polling frame information to determine how to proceed if it
-     * subsequently has {@link #processCommandApdu(byte[], Bundle)} called. The
-     * service must override this method inorder to receive polling frames,
-     * otherwise the base implementation drops the frame.
-     *
-     * @param frame A description of the polling frame.
-     */
-    @SuppressLint("OnNameExpected")
-    @FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP)
-    public void processPollingFrames(@NonNull List<PollingFrame> frame) {
-    }
-
-    /**
-     * <p>This method will be called when a command APDU has been received
-     * from a remote device. A response APDU can be provided directly
-     * by returning a byte-array in this method. Note that in general
-     * response APDUs must be sent as quickly as possible, given the fact
-     * that the user is likely holding their device over an NFC reader
-     * when this method is called.
-     *
-     * <p class="note">If there are multiple services that have registered for the same
-     * AIDs in their meta-data entry, you will only get called if the user has
-     * explicitly selected your service, either as a default or just for the next tap.
-     *
-     * <p class="note">This method is running on the main thread of your application.
-     * If you cannot return a response APDU immediately, return null
-     * and use the {@link #sendResponseApdu(byte[])} method later.
-     *
-     * @param commandApdu The APDU that was received from the remote device
-     * @param extras A bundle containing extra data. May be null.
-     * @return a byte-array containing the response APDU, or null if no
-     *         response APDU can be sent at this point.
-     */
-    public abstract byte[] processCommandApdu(byte[] commandApdu, Bundle extras);
-
-    /**
-     * This method will be called in two possible scenarios:
-     * <li>The NFC link has been deactivated or lost
-     * <li>A different AID has been selected and was resolved to a different
-     *     service component
-     * @param reason Either {@link #DEACTIVATION_LINK_LOSS} or {@link #DEACTIVATION_DESELECTED}
-     */
-    public abstract void onDeactivated(int reason);
-
-}
diff --git a/nfc/java/android/nfc/cardemulation/HostNfcFService.java b/nfc/java/android/nfc/cardemulation/HostNfcFService.java
deleted file mode 100644
index 65b5ca7..0000000
--- a/nfc/java/android/nfc/cardemulation/HostNfcFService.java
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc.cardemulation;
-
-import android.annotation.SdkConstant;
-import android.annotation.SdkConstant.SdkConstantType;
-import android.app.Service;
-import android.content.ComponentName;
-import android.content.Intent;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.Messenger;
-import android.os.RemoteException;
-import android.util.Log;
-
-/**
- * <p>HostNfcFService is a convenience {@link Service} class that can be
- * extended to emulate an NFC-F card inside an Android service component.
- *
- * <h3>NFC Protocols</h3>
- * <p>Cards emulated by this class are based on the NFC-Forum NFC-F
- * protocol (based on the JIS-X 6319-4 specification.)</p>
- *
- * <h3>System Code and NFCID2 registration</h3>
- * <p>A {@link HostNfcFService HostNfcFService service} can register
- * exactly one System Code and one NFCID2. For details about the use of
- * System Code and NFCID2, see the NFC Forum Digital specification.</p>
- * <p>To statically register a System Code and NFCID2 with the service, a {@link #SERVICE_META_DATA}
- * entry must be included in the declaration of the service.
- *
- * <p>All {@link HostNfcFService HostNfcFService} declarations in the manifest must require the
- * {@link android.Manifest.permission#BIND_NFC_SERVICE} permission
- * in their &lt;service&gt; tag, to ensure that only the platform can bind to your service.</p>
- *
- * <p>An example of a HostNfcFService manifest declaration is shown below:
- *
- * <pre> &lt;service android:name=".MyHostNfcFService" android:exported="true" android:permission="android.permission.BIND_NFC_SERVICE"&gt;
- *     &lt;intent-filter&gt;
- *         &lt;action android:name="android.nfc.cardemulation.action.HOST_NFCF_SERVICE"/&gt;
- *     &lt;/intent-filter&gt;
- *     &lt;meta-data android:name="android.nfc.cardemulation.host_nfcf_service" android:resource="@xml/nfcfservice"/&gt;
- * &lt;/service&gt;</pre>
- *
- * This meta-data tag points to an nfcfservice.xml file.
- * An example of this file with a System Code and NFCID2 declaration is shown below:
- * <pre>
- * &lt;host-nfcf-service xmlns:android="http://schemas.android.com/apk/res/android"
- *           android:description="@string/servicedesc"&gt;
- *       &lt;system-code-filter android:name="4000"/&gt;
- *       &lt;nfcid2-filter android:name="02FE000000000000"/&gt;
-         &lt;t3tPmm-filter android:name="FFFFFFFFFFFFFFFF"/&gt;
- * &lt;/host-nfcf-service&gt;
- * </pre>
- *
- * <p>The {@link android.R.styleable#HostNfcFService &lt;host-nfcf-service&gt;} is required
- * to contain a
- * {@link android.R.styleable#HostApduService_description &lt;android:description&gt;}
- * attribute that contains a user-friendly description of the service that may be shown in UI.
- * <p>The {@link android.R.styleable#HostNfcFService &lt;host-nfcf-service&gt;} must
- * contain:
- * <ul>
- * <li>Exactly one {@link android.R.styleable#SystemCodeFilter &lt;system-code-filter&gt;} tag.</li>
- * <li>Exactly one {@link android.R.styleable#Nfcid2Filter &lt;nfcid2-filter&gt;} tag.</li>
- * <li>Zero or one {@link android.R.styleable#T3tPmmFilter &lt;t3tPmm-filter&gt;} tag.</li>
- * </ul>
- * </p>
- *
- * <p>Alternatively, the System Code and NFCID2 can be dynamically registererd for a service
- * by using the {@link NfcFCardEmulation#registerSystemCodeForService(ComponentName, String)} and
- * {@link NfcFCardEmulation#setNfcid2ForService(ComponentName, String)} methods.
- * </p>
- *
- * <h3>Service selection</h3>
- * <p>When a remote NFC devices wants to communicate with your service, it
- * sends a SENSF_REQ command to the NFC controller, requesting a System Code.
- * If a {@link NfcFCardEmulation NfcFCardEmulation service} has registered
- * this system code and has been enabled by the foreground application, the
- * NFC controller will respond with the NFCID2 that is registered for this service.
- * The reader can then continue data exchange with this service by using the NFCID2.</p>
- *
- * <h3>Data exchange</h3>
- * <p>After service selection, all frames addressed to the NFCID2 of this service will
- * be sent through {@link #processNfcFPacket(byte[], Bundle)}, until the NFC link is
- * broken.<p>
- *
- * <p>When the NFC link is broken, {@link #onDeactivated(int)} will be called.</p>
- */
-public abstract class HostNfcFService extends Service {
-    /**
-     * The {@link Intent} action that must be declared as handled by the service.
-     */
-    @SdkConstant(SdkConstantType.SERVICE_ACTION)
-    public static final String SERVICE_INTERFACE =
-            "android.nfc.cardemulation.action.HOST_NFCF_SERVICE";
-
-    /**
-     * The name of the meta-data element that contains
-     * more information about this service.
-     */
-    public static final String SERVICE_META_DATA =
-            "android.nfc.cardemulation.host_nfcf_service";
-
-    /**
-     * Reason for {@link #onDeactivated(int)}.
-     * Indicates deactivation was due to the NFC link
-     * being lost.
-     */
-    public static final int DEACTIVATION_LINK_LOSS = 0;
-
-    static final String TAG = "NfcFService";
-
-    /**
-     * MSG_COMMAND_PACKET is sent by NfcService when
-     * a NFC-F command packet has been received.
-     *
-     * @hide
-     */
-    public static final int MSG_COMMAND_PACKET = 0;
-
-    /**
-     * MSG_RESPONSE_PACKET is sent to NfcService to send
-     * a response packet back to the remote device.
-     *
-     * @hide
-     */
-    public static final int MSG_RESPONSE_PACKET = 1;
-
-    /**
-     * MSG_DEACTIVATED is sent by NfcService when
-     * the current session is finished; because
-     * the NFC link was deactivated.
-     *
-     * @hide
-     */
-    public static final int MSG_DEACTIVATED = 2;
-
-   /**
-     * @hide
-     */
-    public static final String KEY_DATA = "data";
-
-    /**
-     * @hide
-     */
-    public static final String KEY_MESSENGER = "messenger";
-
-    /**
-     * Messenger interface to NfcService for sending responses.
-     * Only accessed on main thread by the message handler.
-     *
-     * @hide
-     */
-    Messenger mNfcService = null;
-
-    final Messenger mMessenger = new Messenger(new MsgHandler());
-
-    final class MsgHandler extends Handler {
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-            case MSG_COMMAND_PACKET:
-                Bundle dataBundle = msg.getData();
-                if (dataBundle == null) {
-                    return;
-                }
-                if (mNfcService == null) mNfcService = msg.replyTo;
-
-                byte[] packet = dataBundle.getByteArray(KEY_DATA);
-                if (packet != null) {
-                    byte[] responsePacket = processNfcFPacket(packet, null);
-                    if (responsePacket != null) {
-                        if (mNfcService == null) {
-                            Log.e(TAG, "Response not sent; service was deactivated.");
-                            return;
-                        }
-                        Message responseMsg = Message.obtain(null, MSG_RESPONSE_PACKET);
-                        Bundle responseBundle = new Bundle();
-                        responseBundle.putByteArray(KEY_DATA, responsePacket);
-                        responseMsg.setData(responseBundle);
-                        responseMsg.replyTo = mMessenger;
-                        try {
-                            mNfcService.send(responseMsg);
-                        } catch (RemoteException e) {
-                            Log.e("TAG", "Response not sent; RemoteException calling into " +
-                                    "NfcService.");
-                        }
-                    }
-                } else {
-                    Log.e(TAG, "Received MSG_COMMAND_PACKET without data.");
-                }
-                break;
-            case MSG_RESPONSE_PACKET:
-                if (mNfcService == null) {
-                    Log.e(TAG, "Response not sent; service was deactivated.");
-                    return;
-                }
-                try {
-                    msg.replyTo = mMessenger;
-                    mNfcService.send(msg);
-                } catch (RemoteException e) {
-                    Log.e(TAG, "RemoteException calling into NfcService.");
-                }
-                break;
-            case MSG_DEACTIVATED:
-                // Make sure we won't call into NfcService again
-                mNfcService = null;
-                onDeactivated(msg.arg1);
-                break;
-            default:
-                super.handleMessage(msg);
-            }
-        }
-    }
-
-    @Override
-    public final IBinder onBind(Intent intent) {
-        return mMessenger.getBinder();
-    }
-
-    /**
-     * Sends a response packet back to the remote device.
-     *
-     * <p>Note: this method may be called from any thread and will not block.
-     * @param responsePacket A byte-array containing the response packet.
-     */
-    public final void sendResponsePacket(byte[] responsePacket) {
-        Message responseMsg = Message.obtain(null, MSG_RESPONSE_PACKET);
-        Bundle dataBundle = new Bundle();
-        dataBundle.putByteArray(KEY_DATA, responsePacket);
-        responseMsg.setData(dataBundle);
-        try {
-            mMessenger.send(responseMsg);
-        } catch (RemoteException e) {
-            Log.e("TAG", "Local messenger has died.");
-        }
-    }
-
-    /**
-     * <p>This method will be called when a NFC-F packet has been received
-     * from a remote device. A response packet can be provided directly
-     * by returning a byte-array in this method. Note that in general
-     * response packets must be sent as quickly as possible, given the fact
-     * that the user is likely holding their device over an NFC reader
-     * when this method is called.
-     *
-     * <p class="note">This method is running on the main thread of your application.
-     * If you cannot return a response packet immediately, return null
-     * and use the {@link #sendResponsePacket(byte[])} method later.
-     *
-     * @param commandPacket The NFC-F packet that was received from the remote device
-     * @param extras A bundle containing extra data. May be null.
-     * @return a byte-array containing the response packet, or null if no
-     *         response packet can be sent at this point.
-     */
-    public abstract byte[] processNfcFPacket(byte[] commandPacket, Bundle extras);
-
-    /**
-     * This method will be called in following possible scenarios:
-     * <li>The NFC link has been lost
-     * @param reason {@link #DEACTIVATION_LINK_LOSS}
-     */
-    public abstract void onDeactivated(int reason);
-}
diff --git a/nfc/java/android/nfc/cardemulation/NfcFCardEmulation.java b/nfc/java/android/nfc/cardemulation/NfcFCardEmulation.java
deleted file mode 100644
index 48bbf5b6..0000000
--- a/nfc/java/android/nfc/cardemulation/NfcFCardEmulation.java
+++ /dev/null
@@ -1,473 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc.cardemulation;
-
-import android.app.Activity;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.nfc.INfcFCardEmulation;
-import android.nfc.NfcAdapter;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.util.HashMap;
-import java.util.List;
-
-/**
- * This class can be used to query the state of
- * NFC-F card emulation services.
- *
- * For a general introduction into NFC card emulation,
- * please read the <a href="{@docRoot}guide/topics/connectivity/nfc/hce.html">
- * NFC card emulation developer guide</a>.</p>
- *
- * <p class="note">Use of this class requires the
- * {@link PackageManager#FEATURE_NFC_HOST_CARD_EMULATION_NFCF}
- * to be present on the device.
- */
-public final class NfcFCardEmulation {
-    static final String TAG = "NfcFCardEmulation";
-
-    static boolean sIsInitialized = false;
-    static HashMap<Context, NfcFCardEmulation> sCardEmus = new HashMap<Context, NfcFCardEmulation>();
-    static INfcFCardEmulation sService;
-
-    final Context mContext;
-
-    private NfcFCardEmulation(Context context, INfcFCardEmulation service) {
-        mContext = context.getApplicationContext();
-        sService = service;
-    }
-
-    /**
-     * Helper to get an instance of this class.
-     *
-     * @param adapter A reference to an NfcAdapter object.
-     * @return
-     */
-    public static synchronized NfcFCardEmulation getInstance(NfcAdapter adapter) {
-        if (adapter == null) throw new NullPointerException("NfcAdapter is null");
-        Context context = adapter.getContext();
-        if (context == null) {
-            Log.e(TAG, "NfcAdapter context is null.");
-            throw new UnsupportedOperationException();
-        }
-        if (!sIsInitialized) {
-            PackageManager pm = context.getPackageManager();
-            if (pm == null) {
-                Log.e(TAG, "Cannot get PackageManager");
-                throw new UnsupportedOperationException();
-            }
-            if (!pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION_NFCF)) {
-                Log.e(TAG, "This device does not support NFC-F card emulation");
-                throw new UnsupportedOperationException();
-            }
-            sIsInitialized = true;
-        }
-        NfcFCardEmulation manager = sCardEmus.get(context);
-        if (manager == null) {
-            // Get card emu service
-            INfcFCardEmulation service = adapter.getNfcFCardEmulationService();
-            if (service == null) {
-                Log.e(TAG, "This device does not implement the INfcFCardEmulation interface.");
-                throw new UnsupportedOperationException();
-            }
-            manager = new NfcFCardEmulation(context, service);
-            sCardEmus.put(context, manager);
-        }
-        return manager;
-    }
-
-    /**
-     * Retrieves the current System Code for the specified service.
-     *
-     * <p>Before calling {@link #registerSystemCodeForService(ComponentName, String)},
-     * the System Code contained in the Manifest file is returned. After calling
-     * {@link #registerSystemCodeForService(ComponentName, String)}, the System Code
-     * registered there is returned. After calling
-     * {@link #unregisterSystemCodeForService(ComponentName)}, "null" is returned.
-     *
-     * @param service The component name of the service
-     * @return the current System Code
-     */
-    public String getSystemCodeForService(ComponentName service) throws RuntimeException {
-        if (service == null) {
-            throw new NullPointerException("service is null");
-        }
-        try {
-            return sService.getSystemCodeForService(mContext.getUser().getIdentifier(), service);
-        } catch (RemoteException e) {
-            // Try one more time
-            recoverService();
-            if (sService == null) {
-                Log.e(TAG, "Failed to recover CardEmulationService.");
-                return null;
-            }
-            try {
-                return sService.getSystemCodeForService(mContext.getUser().getIdentifier(),
-                        service);
-            } catch (RemoteException ee) {
-                Log.e(TAG, "Failed to reach CardEmulationService.");
-                ee.rethrowAsRuntimeException();
-                return null;
-            }
-        }
-    }
-
-    /**
-     * Registers a System Code for the specified service.
-     *
-     * <p>The System Code must be in range from "4000" to "4FFF" (excluding "4*FF").
-     *
-     * <p>If a System Code was previously registered for this service
-     * (either statically through the manifest, or dynamically by using this API),
-     * it will be replaced with this one.
-     *
-     * <p>Even if the same System Code is already registered for another service,
-     * this method succeeds in registering the System Code.
-     *
-     * <p>Note that you can only register a System Code for a service that
-     * is running under the same UID as the caller of this API. Typically
-     * this means you need to call this from the same
-     * package as the service itself, though UIDs can also
-     * be shared between packages using shared UIDs.
-     *
-     * @param service The component name of the service
-     * @param systemCode The System Code to be registered
-     * @return whether the registration was successful.
-     */
-    public boolean registerSystemCodeForService(ComponentName service, String systemCode)
-            throws RuntimeException {
-        if (service == null || systemCode == null) {
-            throw new NullPointerException("service or systemCode is null");
-        }
-        try {
-            return sService.registerSystemCodeForService(mContext.getUser().getIdentifier(),
-                    service, systemCode);
-        } catch (RemoteException e) {
-            // Try one more time
-            recoverService();
-            if (sService == null) {
-                Log.e(TAG, "Failed to recover CardEmulationService.");
-                return false;
-            }
-            try {
-                return sService.registerSystemCodeForService(mContext.getUser().getIdentifier(),
-                        service, systemCode);
-            } catch (RemoteException ee) {
-                Log.e(TAG, "Failed to reach CardEmulationService.");
-                ee.rethrowAsRuntimeException();
-                return false;
-            }
-        }
-    }
-
-    /**
-     * Removes a registered System Code for the specified service.
-     *
-     * @param service The component name of the service
-     * @return whether the System Code was successfully removed.
-     */
-    public boolean unregisterSystemCodeForService(ComponentName service) throws RuntimeException {
-        if (service == null) {
-            throw new NullPointerException("service is null");
-        }
-        try {
-            return sService.removeSystemCodeForService(mContext.getUser().getIdentifier(), service);
-        } catch (RemoteException e) {
-            // Try one more time
-            recoverService();
-            if (sService == null) {
-                Log.e(TAG, "Failed to recover CardEmulationService.");
-                return false;
-            }
-            try {
-                return sService.removeSystemCodeForService(mContext.getUser().getIdentifier(),
-                        service);
-            } catch (RemoteException ee) {
-                Log.e(TAG, "Failed to reach CardEmulationService.");
-                ee.rethrowAsRuntimeException();
-                return false;
-            }
-        }
-    }
-
-    /**
-     * Retrieves the current NFCID2 for the specified service.
-     *
-     * <p>Before calling {@link #setNfcid2ForService(ComponentName, String)},
-     * the NFCID2 contained in the Manifest file is returned. If "random" is specified
-     * in the Manifest file, a random number assigned by the system at installation time
-     * is returned. After setting an NFCID2
-     * with {@link #setNfcid2ForService(ComponentName, String)}, this NFCID2 is returned.
-     *
-     * @param service The component name of the service
-     * @return the current NFCID2
-     */
-    public String getNfcid2ForService(ComponentName service) throws RuntimeException {
-        if (service == null) {
-            throw new NullPointerException("service is null");
-        }
-        try {
-            return sService.getNfcid2ForService(mContext.getUser().getIdentifier(), service);
-        } catch (RemoteException e) {
-            // Try one more time
-            recoverService();
-            if (sService == null) {
-                Log.e(TAG, "Failed to recover CardEmulationService.");
-                return null;
-            }
-            try {
-                return sService.getNfcid2ForService(mContext.getUser().getIdentifier(), service);
-            } catch (RemoteException ee) {
-                Log.e(TAG, "Failed to reach CardEmulationService.");
-                ee.rethrowAsRuntimeException();
-                return null;
-            }
-        }
-    }
-
-    /**
-     * Set a NFCID2 for the specified service.
-     *
-     * <p>The NFCID2 must be in range from "02FE000000000000" to "02FEFFFFFFFFFFFF".
-     *
-     * <p>If a NFCID2 was previously set for this service
-     * (either statically through the manifest, or dynamically by using this API),
-     * it will be replaced.
-     *
-     * <p>Note that you can only set the NFCID2 for a service that
-     * is running under the same UID as the caller of this API. Typically
-     * this means you need to call this from the same
-     * package as the service itself, though UIDs can also
-     * be shared between packages using shared UIDs.
-     *
-     * @param service The component name of the service
-     * @param nfcid2 The NFCID2 to be registered
-     * @return whether the setting was successful.
-     */
-    public boolean setNfcid2ForService(ComponentName service, String nfcid2)
-            throws RuntimeException {
-        if (service == null || nfcid2 == null) {
-            throw new NullPointerException("service or nfcid2 is null");
-        }
-        try {
-            return sService.setNfcid2ForService(mContext.getUser().getIdentifier(),
-                    service, nfcid2);
-        } catch (RemoteException e) {
-            // Try one more time
-            recoverService();
-            if (sService == null) {
-                Log.e(TAG, "Failed to recover CardEmulationService.");
-                return false;
-            }
-            try {
-                return sService.setNfcid2ForService(mContext.getUser().getIdentifier(),
-                        service, nfcid2);
-            } catch (RemoteException ee) {
-                Log.e(TAG, "Failed to reach CardEmulationService.");
-                ee.rethrowAsRuntimeException();
-                return false;
-            }
-        }
-    }
-
-    /**
-     * Allows a foreground application to specify which card emulation service
-     * should be enabled while a specific Activity is in the foreground.
-     *
-     * <p>The specified HCE-F service is only enabled when the corresponding application is
-     * in the foreground and this method has been called. When the application is moved to
-     * the background, {@link #disableService(Activity)} is called, or
-     * NFCID2 or System Code is replaced, the HCE-F service is disabled.
-     *
-     * <p>The specified Activity must currently be in resumed state. A good
-     * paradigm is to call this method in your {@link Activity#onResume}, and to call
-     * {@link #disableService(Activity)} in your {@link Activity#onPause}.
-     *
-     * <p>Note that this preference is not persisted by the OS, and hence must be
-     * called every time the Activity is resumed.
-     *
-     * @param activity The activity which prefers this service to be invoked
-     * @param service The service to be preferred while this activity is in the foreground
-     * @return whether the registration was successful
-     */
-    public boolean enableService(Activity activity, ComponentName service) throws RuntimeException {
-        if (activity == null || service == null) {
-            throw new NullPointerException("activity or service is null");
-        }
-        // Verify the activity is in the foreground before calling into NfcService
-        if (!activity.isResumed()) {
-            throw new IllegalArgumentException("Activity must be resumed.");
-        }
-        try {
-            return sService.enableNfcFForegroundService(service);
-        } catch (RemoteException e) {
-            // Try one more time
-            recoverService();
-            if (sService == null) {
-                Log.e(TAG, "Failed to recover CardEmulationService.");
-                return false;
-            }
-            try {
-                return sService.enableNfcFForegroundService(service);
-            } catch (RemoteException ee) {
-                Log.e(TAG, "Failed to reach CardEmulationService.");
-                ee.rethrowAsRuntimeException();
-                return false;
-            }
-        }
-    }
-
-    /**
-     * Disables the service for the specified Activity.
-     *
-     * <p>Note that the specified Activity must still be in resumed
-     * state at the time of this call. A good place to call this method
-     * is in your {@link Activity#onPause} implementation.
-     *
-     * @param activity The activity which the service was registered for
-     * @return true when successful
-     */
-    public boolean disableService(Activity activity) throws RuntimeException {
-        if (activity == null) {
-            throw new NullPointerException("activity is null");
-        }
-        if (!activity.isResumed()) {
-            throw new IllegalArgumentException("Activity must be resumed.");
-        }
-        try {
-            return sService.disableNfcFForegroundService();
-        } catch (RemoteException e) {
-            // Try one more time
-            recoverService();
-            if (sService == null) {
-                Log.e(TAG, "Failed to recover CardEmulationService.");
-                return false;
-            }
-            try {
-                return sService.disableNfcFForegroundService();
-            } catch (RemoteException ee) {
-                Log.e(TAG, "Failed to reach CardEmulationService.");
-                ee.rethrowAsRuntimeException();
-                return false;
-            }
-        }
-    }
-
-    /**
-     * @hide
-     */
-    public List<NfcFServiceInfo> getNfcFServices() {
-        try {
-            return sService.getNfcFServices(mContext.getUser().getIdentifier());
-        } catch (RemoteException e) {
-            // Try one more time
-            recoverService();
-            if (sService == null) {
-                Log.e(TAG, "Failed to recover CardEmulationService.");
-                return null;
-            }
-            try {
-                return sService.getNfcFServices(mContext.getUser().getIdentifier());
-            } catch (RemoteException ee) {
-                Log.e(TAG, "Failed to reach CardEmulationService.");
-                return null;
-            }
-        }
-    }
-
-    /**
-     * @hide
-     */
-    public int getMaxNumOfRegisterableSystemCodes() {
-        try {
-            return sService.getMaxNumOfRegisterableSystemCodes();
-        } catch (RemoteException e) {
-            // Try one more time
-            recoverService();
-            if (sService == null) {
-                Log.e(TAG, "Failed to recover CardEmulationService.");
-                return -1;
-            }
-            try {
-                return sService.getMaxNumOfRegisterableSystemCodes();
-            } catch (RemoteException ee) {
-                Log.e(TAG, "Failed to reach CardEmulationService.");
-                return -1;
-            }
-        }
-    }
-
-    /**
-     * @hide
-     */
-    public static boolean isValidSystemCode(String systemCode) {
-        if (systemCode == null) {
-            return false;
-        }
-        if (systemCode.length() != 4) {
-            Log.e(TAG, "System Code " + systemCode + " is not a valid System Code.");
-            return false;
-        }
-        // check if the value is between "4000" and "4FFF" (excluding "4*FF")
-        if (!systemCode.startsWith("4") || systemCode.toUpperCase().endsWith("FF")) {
-            Log.e(TAG, "System Code " + systemCode + " is not a valid System Code.");
-            return false;
-        }
-        try {
-            Integer.parseInt(systemCode, 16);
-        } catch (NumberFormatException e) {
-            Log.e(TAG, "System Code " + systemCode + " is not a valid System Code.");
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * @hide
-     */
-    public static boolean isValidNfcid2(String nfcid2) {
-        if (nfcid2 == null) {
-            return false;
-        }
-        if (nfcid2.length() != 16) {
-            Log.e(TAG, "NFCID2 " + nfcid2 + " is not a valid NFCID2.");
-            return false;
-        }
-        // check if the the value starts with "02FE"
-        if (!nfcid2.toUpperCase().startsWith("02FE")) {
-            Log.e(TAG, "NFCID2 " + nfcid2 + " is not a valid NFCID2.");
-            return false;
-        }
-        try {
-            Long.parseLong(nfcid2, 16);
-        } catch (NumberFormatException e) {
-            Log.e(TAG, "NFCID2 " + nfcid2 + " is not a valid NFCID2.");
-            return false;
-        }
-        return true;
-    }
-
-    void recoverService() {
-        NfcAdapter adapter = NfcAdapter.getDefaultAdapter(mContext);
-        sService = adapter.getNfcFCardEmulationService();
-    }
-
-}
-
diff --git a/nfc/java/android/nfc/cardemulation/OffHostApduService.java b/nfc/java/android/nfc/cardemulation/OffHostApduService.java
deleted file mode 100644
index 8d8a172..0000000
--- a/nfc/java/android/nfc/cardemulation/OffHostApduService.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc.cardemulation;
-
-import android.annotation.SdkConstant;
-import android.annotation.SdkConstant.SdkConstantType;
-import android.app.Service;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.os.IBinder;
-
-/**
- * <p>OffHostApduService is a convenience {@link Service} class that can be
- * extended to describe one or more NFC applications that are residing
- * off-host, for example on an embedded secure element or a UICC.
- *
- * <div class="special reference">
- * <h3>Developer Guide</h3>
- * For a general introduction into the topic of card emulation,
- * please read the <a href="{@docRoot}guide/topics/connectivity/nfc/hce.html">
- * NFC card emulation developer guide.</a></p>
- * </div>
- *
- * <h3>NFC Protocols</h3>
- * <p>Off-host applications represented by this class are based on the NFC-Forum ISO-DEP
- * protocol (based on ISO/IEC 14443-4) and support processing
- * command Application Protocol Data Units (APDUs) as
- * defined in the ISO/IEC 7816-4 specification.
- *
- * <h3>Service selection</h3>
- * <p>When a remote NFC device wants to talk to your
- * off-host NFC application, it sends a so-called
- * "SELECT AID" APDU as defined in the ISO/IEC 7816-4 specification.
- * The AID is an application identifier defined in ISO/IEC 7816-4.
- *
- * <p>The registration procedure for AIDs is defined in the
- * ISO/IEC 7816-5 specification. If you don't want to register an
- * AID, you are free to use AIDs in the proprietary range:
- * bits 8-5 of the first byte must each be set to '1'. For example,
- * "0xF00102030405" is a proprietary AID. If you do use proprietary
- * AIDs, it is recommended to choose an AID of at least 6 bytes,
- * to reduce the risk of collisions with other applications that
- * might be using proprietary AIDs as well.
- *
- * <h3>AID groups</h3>
- * <p>In some cases, an off-host environment may need to register multiple AIDs
- * to implement a certain application, and it needs to be sure
- * that it is the default handler for all of these AIDs (as opposed
- * to some AIDs in the group going to another service).
- *
- * <p>An AID group is a list of AIDs that should be considered as
- * belonging together by the OS. For all AIDs in an AID group, the
- * OS will guarantee one of the following:
- * <ul>
- * <li>All AIDs in the group are routed to the off-host execution environment
- * <li>No AIDs in the group are routed to the off-host execution environment
- * </ul>
- * In other words, there is no in-between state, where some AIDs
- * in the group can be routed to this off-host execution environment,
- * and some to another or a host-based {@link HostApduService}.
- * <h3>AID groups and categories</h3>
- * <p>Each AID group can be associated with a category. This allows
- * the Android OS to classify services, and it allows the user to
- * set defaults at the category level instead of the AID level.
- *
- * <p>You can use
- * {@link CardEmulation#isDefaultServiceForCategory(android.content.ComponentName, String)}
- * to determine if your off-host service is the default handler for a category.
- *
- * <p>In this version of the platform, the only known categories
- * are {@link CardEmulation#CATEGORY_PAYMENT} and {@link CardEmulation#CATEGORY_OTHER}.
- * AID groups without a category, or with a category that is not recognized
- * by the current platform version, will automatically be
- * grouped into the {@link CardEmulation#CATEGORY_OTHER} category.
- *
- * <h3>Service AID registration</h3>
- * <p>To tell the platform which AIDs
- * reside off-host and are managed by this service, a {@link #SERVICE_META_DATA}
- * entry must be included in the declaration of the service. An
- * example of a OffHostApduService manifest declaration is shown below:
- * <pre> &lt;service android:name=".MyOffHostApduService" android:exported="true" android:permission="android.permission.BIND_NFC_SERVICE"&gt;
- *     &lt;intent-filter&gt;
- *         &lt;action android:name="android.nfc.cardemulation.action.OFF_HOST_APDU_SERVICE"/&gt;
- *     &lt;/intent-filter&gt;
- *     &lt;meta-data android:name="android.nfc.cardemulation.off_host_apdu_service" android:resource="@xml/apduservice"/&gt;
- * &lt;/service&gt;</pre>
- *
- * This meta-data tag points to an apduservice.xml file.
- * An example of this file with a single AID group declaration is shown below:
- * <pre>
- * &lt;offhost-apdu-service xmlns:android="http://schemas.android.com/apk/res/android"
- *           android:description="@string/servicedesc"&gt;
- *       &lt;aid-group android:description="@string/subscription" android:category="other">
- *           &lt;aid-filter android:name="F0010203040506"/&gt;
- *           &lt;aid-filter android:name="F0394148148100"/&gt;
- *       &lt;/aid-group&gt;
- * &lt;/offhost-apdu-service&gt;
- * </pre>
- *
- * <p>The {@link android.R.styleable#OffHostApduService &lt;offhost-apdu-service&gt;} is required
- * to contain a
- * {@link android.R.styleable#OffHostApduService_description &lt;android:description&gt;}
- * attribute that contains a user-friendly description of the service that may be shown in UI.
- *
- * <p>The {@link android.R.styleable#OffHostApduService &lt;offhost-apdu-service&gt;} must
- * contain one or more {@link android.R.styleable#AidGroup &lt;aid-group&gt;} tags.
- * Each {@link android.R.styleable#AidGroup &lt;aid-group&gt;} must contain one or
- * more {@link android.R.styleable#AidFilter &lt;aid-filter&gt;} tags, each of which
- * contains a single AID. The AID must be specified in hexadecimal format, and contain
- * an even number of characters.
- *
- * <p>This registration will allow the service to be included
- * as an option for being the default handler for categories.
- * The Android OS will take care of correctly
- * routing the AIDs to the off-host execution environment,
- * based on which service the user has selected to be the handler for a certain category.
- *
- * <p>The service may define additional actions outside of the
- * Android namespace that provide further interaction with
- * the off-host execution environment.
- *
- * <p class="note">Use of this class requires the
- * {@link PackageManager#FEATURE_NFC_HOST_CARD_EMULATION} to be present
- * on the device.
- */
-public abstract class OffHostApduService extends Service {
-    /**
-     * The {@link Intent} action that must be declared as handled by the service.
-     */
-    @SdkConstant(SdkConstantType.SERVICE_ACTION)
-    public static final String SERVICE_INTERFACE =
-            "android.nfc.cardemulation.action.OFF_HOST_APDU_SERVICE";
-
-    /**
-     * The name of the meta-data element that contains
-     * more information about this service.
-     */
-    public static final String SERVICE_META_DATA =
-            "android.nfc.cardemulation.off_host_apdu_service";
-
-    /**
-     * The Android platform itself will not bind to this service,
-     * but merely uses its declaration to keep track of what AIDs
-     * the service is interested in. This information is then used
-     * to present the user with a list of applications that can handle
-     * an AID, as well as correctly route those AIDs either to the host (in case
-     * the user preferred a {@link HostApduService}), or to an off-host
-     * execution environment (in case the user preferred a {@link OffHostApduService}.
-     *
-     * Implementers may define additional actions outside of the
-     * Android namespace that allow further interactions with
-     * the off-host execution environment. Such implementations
-     * would need to override this method.
-     */
-    public abstract IBinder onBind(Intent intent);
-}
diff --git a/nfc/java/android/nfc/cardemulation/PollingFrame.aidl b/nfc/java/android/nfc/cardemulation/PollingFrame.aidl
deleted file mode 100644
index 8e09f8b..0000000
--- a/nfc/java/android/nfc/cardemulation/PollingFrame.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc.cardemulation;
-
-parcelable PollingFrame;
\ No newline at end of file
diff --git a/nfc/java/android/nfc/cardemulation/PollingFrame.java b/nfc/java/android/nfc/cardemulation/PollingFrame.java
deleted file mode 100644
index 5dcc84c..0000000
--- a/nfc/java/android/nfc/cardemulation/PollingFrame.java
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc.cardemulation;
-
-import android.annotation.FlaggedApi;
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.ComponentName;
-import android.os.Bundle;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.HexFormat;
-import java.util.List;
-
-/**
- * Polling Frames represent data about individual frames of an NFC polling loop. These frames will
- * be delivered to subclasses of {@link HostApduService} that have registered filters with
- * {@link CardEmulation#registerPollingLoopFilterForService(ComponentName, String, boolean)} that
- * match a given frame in a loop and will be delivered through calls to
- * {@link HostApduService#processPollingFrames(List)}.
- */
-@FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP)
-public final class PollingFrame implements Parcelable {
-
-    /**
-     * @hide
-     */
-    @IntDef(prefix = { "POLLING_LOOP_TYPE_"},
-        value = {
-            POLLING_LOOP_TYPE_A,
-            POLLING_LOOP_TYPE_B,
-            POLLING_LOOP_TYPE_F,
-            POLLING_LOOP_TYPE_OFF,
-            POLLING_LOOP_TYPE_ON,
-            POLLING_LOOP_TYPE_UNKNOWN
-        })
-    @Retention(RetentionPolicy.SOURCE)
-    @FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP)
-    public @interface PollingFrameType {}
-
-    /**
-     * POLLING_LOOP_TYPE_A is the value associated with the key
-     * POLLING_LOOP_TYPE  in the Bundle passed to {@link HostApduService#processPollingFrames(List)}
-     * when the polling loop is for NFC-A.
-     */
-    @FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP)
-    public static final int POLLING_LOOP_TYPE_A = 'A';
-
-    /**
-     * POLLING_LOOP_TYPE_B is the value associated with the key
-     * POLLING_LOOP_TYPE  in the Bundle passed to {@link HostApduService#processPollingFrames(List)}
-     * when the polling loop is for NFC-B.
-     */
-    @FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP)
-    public static final int POLLING_LOOP_TYPE_B = 'B';
-
-    /**
-     * POLLING_LOOP_TYPE_F is the value associated with the key
-     * POLLING_LOOP_TYPE  in the Bundle passed to {@link HostApduService#processPollingFrames(List)}
-     * when the polling loop is for NFC-F.
-     */
-    @FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP)
-    public static final int POLLING_LOOP_TYPE_F = 'F';
-
-    /**
-     * POLLING_LOOP_TYPE_ON is the value associated with the key
-     * POLLING_LOOP_TYPE  in the Bundle passed to {@link HostApduService#processPollingFrames(List)}
-     * when the polling loop turns on.
-     */
-    @FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP)
-    public static final int POLLING_LOOP_TYPE_ON = 'O';
-
-    /**
-     * POLLING_LOOP_TYPE_OFF is the value associated with the key
-     * POLLING_LOOP_TYPE  in the Bundle passed to {@link HostApduService#processPollingFrames(List)}
-     * when the polling loop turns off.
-     */
-    @FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP)
-    public static final int POLLING_LOOP_TYPE_OFF = 'X';
-
-    /**
-     * POLLING_LOOP_TYPE_UNKNOWN is the value associated with the key
-     * POLLING_LOOP_TYPE  in the Bundle passed to {@link HostApduService#processPollingFrames(List)}
-     * when the polling loop frame isn't recognized.
-     */
-    @FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP)
-    public static final int POLLING_LOOP_TYPE_UNKNOWN = 'U';
-
-    /**
-     * KEY_POLLING_LOOP_TYPE is the Bundle key for the type of
-     * polling loop frame in the Bundle included in MSG_POLLING_LOOP.
-     */
-    @FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP)
-    private static final String KEY_POLLING_LOOP_TYPE = "android.nfc.cardemulation.TYPE";
-
-    /**
-     * KEY_POLLING_LOOP_DATA is the Bundle key for the raw data of captured from
-     * the polling loop frame in the Bundle included in MSG_POLLING_LOOP.
-     */
-    @FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP)
-    private static final String KEY_POLLING_LOOP_DATA = "android.nfc.cardemulation.DATA";
-
-    /**
-     * KEY_POLLING_LOOP_GAIN is the Bundle key for the field strength of
-     * the polling loop frame in the Bundle included in MSG_POLLING_LOOP.
-    */
-    @FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP)
-    private static final String KEY_POLLING_LOOP_GAIN = "android.nfc.cardemulation.GAIN";
-
-    /**
-     * KEY_POLLING_LOOP_TIMESTAMP is the Bundle key for the timestamp of
-     * the polling loop frame in the Bundle included in MSG_POLLING_LOOP.
-    */
-    @FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP)
-    private static final String KEY_POLLING_LOOP_TIMESTAMP = "android.nfc.cardemulation.TIMESTAMP";
-
-    /**
-     * KEY_POLLING_LOOP_TIMESTAMP is the Bundle key for whether this polling frame triggered
-     * autoTransact in the Bundle included in MSG_POLLING_LOOP.
-    */
-    @FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP)
-    private static final String KEY_POLLING_LOOP_TRIGGERED_AUTOTRANSACT =
-            "android.nfc.cardemulation.TRIGGERED_AUTOTRANSACT";
-
-
-    @PollingFrameType
-    private final int mType;
-    private final byte[] mData;
-    private final int mGain;
-    private final long mTimestamp;
-    private boolean mTriggeredAutoTransact;
-
-    public static final @NonNull Parcelable.Creator<PollingFrame> CREATOR =
-            new Parcelable.Creator<>() {
-                @Override
-                public PollingFrame createFromParcel(Parcel source) {
-                    return new PollingFrame(source.readBundle());
-                }
-
-                @Override
-                public PollingFrame[] newArray(int size) {
-                    return new PollingFrame[size];
-                }
-            };
-
-    private PollingFrame(Bundle frame) {
-        mType = frame.getInt(KEY_POLLING_LOOP_TYPE);
-        byte[] data = frame.getByteArray(KEY_POLLING_LOOP_DATA);
-        mData = (data == null) ? new byte[0] : data;
-        mGain = frame.getInt(KEY_POLLING_LOOP_GAIN, -1);
-        mTimestamp = frame.getLong(KEY_POLLING_LOOP_TIMESTAMP);
-        mTriggeredAutoTransact = frame.containsKey(KEY_POLLING_LOOP_TRIGGERED_AUTOTRANSACT)
-                && frame.getBoolean(KEY_POLLING_LOOP_TRIGGERED_AUTOTRANSACT);
-    }
-
-    /**
-     * Constructor for Polling Frames.
-     *
-     * @param type the type of the frame
-     * @param data a byte array of the data contained in the frame
-     * @param gain the vendor-specific gain of the field
-     * @param timestampMicros the timestamp in microseconds
-     * @param triggeredAutoTransact whether or not this frame triggered the device to start a
-     * transaction automatically
-     *
-     * @hide
-     */
-    public PollingFrame(@PollingFrameType int type, @Nullable byte[] data,
-            int gain, long timestampMicros, boolean triggeredAutoTransact) {
-        mType = type;
-        mData = data == null ? new byte[0] : data;
-        mGain = gain;
-        mTimestamp = timestampMicros;
-        mTriggeredAutoTransact = triggeredAutoTransact;
-    }
-
-    /**
-     * Returns the type of frame for this polling loop frame.
-     * The possible return values are:
-     * <ul>
-     *   <li>{@link #POLLING_LOOP_TYPE_ON}</li>
-     *   <li>{@link #POLLING_LOOP_TYPE_OFF}</li>
-     *   <li>{@link #POLLING_LOOP_TYPE_A}</li>
-     *   <li>{@link #POLLING_LOOP_TYPE_B}</li>
-     *   <li>{@link #POLLING_LOOP_TYPE_F}</li>
-     * </ul>
-     */
-    public @PollingFrameType int getType() {
-        return mType;
-    }
-
-    /**
-     * Returns the raw data from the polling type frame.
-     */
-    public @NonNull byte[] getData() {
-        return mData;
-    }
-
-    /**
-     * Returns the gain representing the field strength of the NFC field when this polling loop
-     * frame was observed.
-     * @return the gain or -1 if there is no gain measurement associated with this frame.
-     */
-    public int getVendorSpecificGain() {
-        return mGain;
-    }
-
-    /**
-     * Returns the timestamp of when the polling loop frame was observed, in microseconds. These
-     * timestamps are relative and should only be used for comparing the timing of frames relative
-     * to each other.
-     * @return the timestamp in microseconds
-     */
-    public long getTimestamp() {
-        return mTimestamp;
-    }
-
-    /**
-     * @hide
-     */
-    public void setTriggeredAutoTransact(boolean triggeredAutoTransact) {
-        mTriggeredAutoTransact = triggeredAutoTransact;
-    }
-
-    /**
-     * Returns whether this frame triggered the device to automatically disable observe mode and
-     * allow one transaction.
-     */
-    public boolean getTriggeredAutoTransact() {
-        return mTriggeredAutoTransact;
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(@NonNull Parcel dest, int flags) {
-        dest.writeBundle(toBundle());
-    }
-
-    /**
-     * @return a Bundle representing this frame
-     */
-    private Bundle toBundle() {
-        Bundle frame = new Bundle();
-        frame.putInt(KEY_POLLING_LOOP_TYPE, getType());
-        if (getVendorSpecificGain() != -1) {
-            frame.putInt(KEY_POLLING_LOOP_GAIN, (byte) getVendorSpecificGain());
-        }
-        frame.putByteArray(KEY_POLLING_LOOP_DATA, getData());
-        frame.putLong(KEY_POLLING_LOOP_TIMESTAMP, getTimestamp());
-        frame.putBoolean(KEY_POLLING_LOOP_TRIGGERED_AUTOTRANSACT, getTriggeredAutoTransact());
-        return frame;
-    }
-
-    @Override
-    public String toString() {
-        return "PollingFrame { Type: " + (char) getType()
-                + ", gain: " + getVendorSpecificGain()
-                + ", timestamp: " + Long.toUnsignedString(getTimestamp())
-                + ", data: [" + HexFormat.ofDelimiter(" ").formatHex(getData()) + "] }";
-    }
-}
diff --git a/nfc/java/android/nfc/cardemulation/Utils.java b/nfc/java/android/nfc/cardemulation/Utils.java
deleted file mode 100644
index 202e1cf..0000000
--- a/nfc/java/android/nfc/cardemulation/Utils.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc.cardemulation;
-
-import android.annotation.NonNull;
-import android.content.ComponentName;
-import android.content.ComponentNameProto;
-import android.util.proto.ProtoOutputStream;
-
-/** @hide */
-public final class Utils {
-    private Utils() {
-    }
-
-    /** Copied from {@link ComponentName#dumpDebug(ProtoOutputStream, long)} */
-    public static void dumpDebugComponentName(
-            @NonNull ComponentName componentName, @NonNull ProtoOutputStream proto, long fieldId) {
-        final long token = proto.start(fieldId);
-        proto.write(ComponentNameProto.PACKAGE_NAME, componentName.getPackageName());
-        proto.write(ComponentNameProto.CLASS_NAME, componentName.getClassName());
-        proto.end(token);
-    }
-}
diff --git a/nfc/java/android/nfc/dta/NfcDta.java b/nfc/java/android/nfc/dta/NfcDta.java
deleted file mode 100644
index 8801662..0000000
--- a/nfc/java/android/nfc/dta/NfcDta.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc.dta;
-
-import android.content.Context;
-import android.nfc.INfcDta;
-import android.nfc.NfcAdapter;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.util.HashMap;
-
-/**
- * This class provides the primary API for DTA operations.
- * @hide
- */
-public final class NfcDta {
-    private static final String TAG = "NfcDta";
-
-    private static INfcDta sService;
-    private static HashMap<Context, NfcDta> sNfcDtas = new HashMap<Context, NfcDta>();
-
-    private final Context mContext;
-
-    private NfcDta(Context context, INfcDta service) {
-        mContext = context.getApplicationContext();
-        sService = service;
-    }
-
-    /**
-     * Helper to get an instance of this class.
-     *
-     * @param adapter A reference to an NfcAdapter object.
-     * @return
-     */
-    public static synchronized NfcDta getInstance(NfcAdapter adapter) {
-        if (adapter == null) throw new NullPointerException("NfcAdapter is null");
-        Context context = adapter.getContext();
-        if (context == null) {
-            Log.e(TAG, "NfcAdapter context is null.");
-            throw new UnsupportedOperationException();
-        }
-
-        NfcDta manager = sNfcDtas.get(context);
-        if (manager == null) {
-            INfcDta service = adapter.getNfcDtaInterface();
-            if (service == null) {
-                Log.e(TAG, "This device does not implement the INfcDta interface.");
-                throw new UnsupportedOperationException();
-            }
-            manager = new NfcDta(context, service);
-            sNfcDtas.put(context, manager);
-        }
-        return manager;
-    }
-
-    /**
-     * Enables DTA mode
-     *
-     * @return true/false if enabling was successful
-     */
-    public boolean enableDta() {
-        try {
-            sService.enableDta();
-        } catch (RemoteException e) {
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * Disables DTA mode
-     *
-     * @return true/false if disabling was successful
-     */
-    public boolean disableDta() {
-        try {
-            sService.disableDta();
-        } catch (RemoteException e) {
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * Enables Server
-     *
-     * @return true/false if enabling was successful
-     */
-    public boolean enableServer(String serviceName, int serviceSap, int miu,
-            int rwSize, int testCaseId) {
-        try {
-            return sService.enableServer(serviceName, serviceSap, miu, rwSize, testCaseId);
-        } catch (RemoteException e) {
-            return false;
-        }
-    }
-
-    /**
-     * Disables Server
-     *
-     * @return true/false if disabling was successful
-     */
-    public boolean disableServer() {
-        try {
-            sService.disableServer();
-        } catch (RemoteException e) {
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * Enables Client
-     *
-     * @return true/false if enabling was successful
-     */
-    public boolean enableClient(String serviceName, int miu, int rwSize,
-            int testCaseId) {
-        try {
-            return sService.enableClient(serviceName, miu, rwSize, testCaseId);
-        } catch (RemoteException e) {
-            return false;
-        }
-    }
-
-    /**
-     * Disables client
-     *
-     * @return true/false if disabling was successful
-     */
-    public boolean disableClient() {
-        try {
-            sService.disableClient();
-        } catch (RemoteException e) {
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * Registers Message Service
-     *
-     * @return true/false if registration was successful
-     */
-    public boolean registerMessageService(String msgServiceName) {
-        try {
-            return sService.registerMessageService(msgServiceName);
-        } catch (RemoteException e) {
-            return false;
-        }
-    }
-}
diff --git a/nfc/java/android/nfc/package.html b/nfc/java/android/nfc/package.html
deleted file mode 100644
index 55c1d16..0000000
--- a/nfc/java/android/nfc/package.html
+++ /dev/null
@@ -1,33 +0,0 @@
-<HTML>
-<BODY>
-<p>Provides access to Near Field Communication (NFC) functionality, allowing applications to read
-NDEF message in NFC tags. A "tag" may actually be another device that appears as a tag.</p>
-
-<p>For more information, see the
-<a href="{@docRoot}guide/topics/connectivity/nfc/index.html">Near Field Communication</a> guide.</p>
-{@more}
-
-<p>Here's a summary of the classes:</p>
-
-<dl>
-  <dt>{@link android.nfc.NfcManager}</dt>
-  <dd>This is the high level manager, used to obtain this device's {@link android.nfc.NfcAdapter}. You can
-acquire an instance using {@link android.content.Context#getSystemService}.</dd>
-  <dt>{@link android.nfc.NfcAdapter}</dt>
-  <dd>This represents the device's NFC adapter, which is your entry-point to performing NFC
-operations. You can acquire an instance with {@link android.nfc.NfcManager#getDefaultAdapter}, or
-{@link android.nfc.NfcAdapter#getDefaultAdapter(android.content.Context)}.</dd>
-  <dt>{@link android.nfc.NdefMessage}</dt>
-  <dd>Represents an NDEF data message, which is the standard format in which "records"
-carrying data are transmitted between devices and tags. Your application can receive these
-messages from an {@link android.nfc.NfcAdapter#ACTION_TAG_DISCOVERED} intent.</dd>
-  <dt>{@link android.nfc.NdefRecord}</dt>
-  <dd>Represents a record, which is delivered in a {@link android.nfc.NdefMessage} and describes the
-type of data being shared and carries the data itself.</dd>
-</dl>
-
-<p class="note"><strong>Note:</strong>
-Not all Android-powered devices provide NFC functionality.</p>
-
-</BODY>
-</HTML>
diff --git a/nfc/java/android/nfc/tech/BasicTagTechnology.java b/nfc/java/android/nfc/tech/BasicTagTechnology.java
deleted file mode 100644
index ae468fe..0000000
--- a/nfc/java/android/nfc/tech/BasicTagTechnology.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc.tech;
-
-import android.nfc.ErrorCodes;
-import android.nfc.Tag;
-import android.nfc.TransceiveResult;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.io.IOException;
-
-/**
- * A base class for tag technologies that are built on top of transceive().
- */
-abstract class BasicTagTechnology implements TagTechnology {
-    private static final String TAG = "NFC";
-
-    final Tag mTag;
-
-    boolean mIsConnected;
-    int mSelectedTechnology;
-
-    BasicTagTechnology(Tag tag, int tech) throws RemoteException {
-        mTag = tag;
-        mSelectedTechnology = tech;
-    }
-
-    @Override
-    public Tag getTag() {
-        return mTag;
-    }
-
-    /** Internal helper to throw IllegalStateException if the technology isn't connected */
-    void checkConnected() {
-       if ((mTag.getConnectedTechnology() != mSelectedTechnology) ||
-               (mTag.getConnectedTechnology() == -1)) {
-           throw new IllegalStateException("Call connect() first!");
-       }
-    }
-
-    @Override
-    public boolean isConnected() {
-        if (!mIsConnected) {
-            return false;
-        }
-
-        try {
-            return mTag.getTagService().isPresent(mTag.getServiceHandle());
-        } catch (RemoteException e) {
-            Log.e(TAG, "NFC service dead", e);
-            return false;
-        }
-    }
-
-    @Override
-    public void connect() throws IOException {
-        try {
-            int errorCode = mTag.getTagService().connect(mTag.getServiceHandle(),
-                    mSelectedTechnology);
-
-            if (errorCode == ErrorCodes.SUCCESS) {
-                // Store this in the tag object
-                if (!mTag.setConnectedTechnology(mSelectedTechnology)) {
-                    Log.e(TAG, "Close other technology first!");
-                    throw new IOException("Only one TagTechnology can be connected at a time.");
-                }
-                mIsConnected = true;
-            } else if (errorCode == ErrorCodes.ERROR_NOT_SUPPORTED) {
-                throw new UnsupportedOperationException("Connecting to " +
-                        "this technology is not supported by the NFC " +
-                        "adapter.");
-            } else {
-                throw new IOException();
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "NFC service dead", e);
-            throw new IOException("NFC service died");
-        }
-    }
-
-    /** @hide */
-    @Override
-    public void reconnect() throws IOException {
-        if (!mIsConnected) {
-            throw new IllegalStateException("Technology not connected yet");
-        }
-
-        try {
-            int errorCode = mTag.getTagService().reconnect(mTag.getServiceHandle());
-
-            if (errorCode != ErrorCodes.SUCCESS) {
-                mIsConnected = false;
-                mTag.setTechnologyDisconnected();
-                throw new IOException();
-            }
-        } catch (RemoteException e) {
-            mIsConnected = false;
-            mTag.setTechnologyDisconnected();
-            Log.e(TAG, "NFC service dead", e);
-            throw new IOException("NFC service died");
-        }
-    }
-
-    @Override
-    public void close() throws IOException {
-        try {
-            /* Note that we don't want to physically disconnect the tag,
-             * but just reconnect to it to reset its state
-             */
-            mTag.getTagService().resetTimeouts();
-            mTag.getTagService().reconnect(mTag.getServiceHandle());
-        } catch (RemoteException e) {
-            Log.e(TAG, "NFC service dead", e);
-        } finally {
-            mIsConnected = false;
-            mTag.setTechnologyDisconnected();
-        }
-    }
-
-    /** Internal getMaxTransceiveLength() */
-    int getMaxTransceiveLengthInternal() {
-        try {
-            return mTag.getTagService().getMaxTransceiveLength(mSelectedTechnology);
-        } catch (RemoteException e) {
-            Log.e(TAG, "NFC service dead", e);
-            return 0;
-        }
-    }
-    /** Internal transceive */
-    byte[] transceive(byte[] data, boolean raw) throws IOException {
-        checkConnected();
-
-        try {
-            TransceiveResult result = mTag.getTagService().transceive(mTag.getServiceHandle(),
-                    data, raw);
-            if (result == null) {
-                throw new IOException("transceive failed");
-            } else {
-                return result.getResponseOrThrow();
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "NFC service dead", e);
-            throw new IOException("NFC service died");
-        }
-    }
-}
diff --git a/nfc/java/android/nfc/tech/IsoDep.java b/nfc/java/android/nfc/tech/IsoDep.java
deleted file mode 100644
index 0ba0c5a..0000000
--- a/nfc/java/android/nfc/tech/IsoDep.java
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc.tech;
-
-import android.nfc.ErrorCodes;
-import android.nfc.Tag;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.io.IOException;
-
-/**
- * Provides access to ISO-DEP (ISO 14443-4) properties and I/O operations on a {@link Tag}.
- *
- * <p>Acquire an {@link IsoDep} object using {@link #get}.
- * <p>The primary ISO-DEP I/O operation is {@link #transceive}. Applications must
- * implement their own protocol stack on top of {@link #transceive}.
- * <p>Tags that enumerate the {@link IsoDep} technology in {@link Tag#getTechList}
- * will also enumerate
- * {@link NfcA} or {@link NfcB} (since IsoDep builds on top of either of these).
- *
- * <p class="note"><strong>Note:</strong> Methods that perform I/O operations
- * require the {@link android.Manifest.permission#NFC} permission.
- */
-public final class IsoDep extends BasicTagTechnology {
-    private static final String TAG = "NFC";
-
-    /** @hide */
-    public static final String EXTRA_HI_LAYER_RESP = "hiresp";
-    /** @hide */
-    public static final String EXTRA_HIST_BYTES = "histbytes";
-
-    private byte[] mHiLayerResponse = null;
-    private byte[] mHistBytes = null;
-
-    /**
-     * Get an instance of {@link IsoDep} for the given tag.
-     * <p>Does not cause any RF activity and does not block.
-     * <p>Returns null if {@link IsoDep} was not enumerated in {@link Tag#getTechList}.
-     * This indicates the tag does not support ISO-DEP.
-     *
-     * @param tag an ISO-DEP compatible tag
-     * @return ISO-DEP object
-     */
-    public static IsoDep get(Tag tag) {
-        if (!tag.hasTech(TagTechnology.ISO_DEP)) return null;
-        try {
-            return new IsoDep(tag);
-        } catch (RemoteException e) {
-            return null;
-        }
-    }
-
-    /** @hide */
-    public IsoDep(Tag tag)
-            throws RemoteException {
-        super(tag, TagTechnology.ISO_DEP);
-        Bundle extras = tag.getTechExtras(TagTechnology.ISO_DEP);
-        if (extras != null) {
-            mHiLayerResponse = extras.getByteArray(EXTRA_HI_LAYER_RESP);
-            mHistBytes = extras.getByteArray(EXTRA_HIST_BYTES);
-        }
-    }
-
-    /**
-     * Set the timeout of {@link #transceive} in milliseconds.
-     * <p>The timeout only applies to ISO-DEP {@link #transceive}, and is
-     * reset to a default value when {@link #close} is called.
-     * <p>Setting a longer timeout may be useful when performing
-     * transactions that require a long processing time on the tag
-     * such as key generation.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param timeout timeout value in milliseconds
-     * @throws SecurityException if the tag object is reused after the tag has left the field
-     */
-    public void setTimeout(int timeout) {
-        try {
-            int err = mTag.getTagService().setTimeout(TagTechnology.ISO_DEP, timeout);
-            if (err != ErrorCodes.SUCCESS) {
-                throw new IllegalArgumentException("The supplied timeout is not valid");
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "NFC service dead", e);
-        }
-    }
-
-    /**
-     * Get the current timeout for {@link #transceive} in milliseconds.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @return timeout value in milliseconds
-     * @throws SecurityException if the tag object is reused after the tag has left the field
-     */
-    public int getTimeout() {
-        try {
-            return mTag.getTagService().getTimeout(TagTechnology.ISO_DEP);
-        } catch (RemoteException e) {
-            Log.e(TAG, "NFC service dead", e);
-            return 0;
-        }
-    }
-
-    /**
-     * Return the ISO-DEP historical bytes for {@link NfcA} tags.
-     * <p>Does not cause any RF activity and does not block.
-     * <p>The historical bytes can be used to help identify a tag. They are present
-     * only on {@link IsoDep} tags that are based on {@link NfcA} RF technology.
-     * If this tag is not {@link NfcA} then null is returned.
-     * <p>In ISO 14443-4 terminology, the historical bytes are a subset of the RATS
-     * response.
-     *
-     * @return ISO-DEP historical bytes, or null if this is not a {@link NfcA} tag
-     */
-    public byte[] getHistoricalBytes() {
-        return mHistBytes;
-    }
-
-    /**
-     * Return the higher layer response bytes for {@link NfcB} tags.
-     * <p>Does not cause any RF activity and does not block.
-     * <p>The higher layer response bytes can be used to help identify a tag.
-     * They are present only on {@link IsoDep} tags that are based on {@link NfcB}
-     * RF technology. If this tag is not {@link NfcB} then null is returned.
-     * <p>In ISO 14443-4 terminology, the higher layer bytes are a subset of the
-     * ATTRIB response.
-     *
-     * @return ISO-DEP historical bytes, or null if this is not a {@link NfcB} tag
-     */
-    public byte[] getHiLayerResponse() {
-        return mHiLayerResponse;
-    }
-
-    /**
-     * Send raw ISO-DEP data to the tag and receive the response.
-     *
-     * <p>Applications must only send the INF payload, and not the start of frame and
-     * end of frame indicators. Applications do not need to fragment the payload, it
-     * will be automatically fragmented and defragmented by {@link #transceive} if
-     * it exceeds FSD/FSC limits.
-     *
-     * <p>Use {@link #getMaxTransceiveLength} to retrieve the maximum number of bytes
-     * that can be sent with {@link #transceive}.
-     *
-     * <p>This is an I/O operation and will block until complete. It must
-     * not be called from the main application thread. A blocked call will be canceled with
-     * {@link IOException} if {@link #close} is called from another thread.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param data command bytes to send, must not be null
-     * @return response bytes received, will not be null
-     * @throws TagLostException if the tag leaves the field
-     * @throws IOException if there is an I/O failure, or this operation is canceled
-     * @throws SecurityException if the tag object is reused after the tag has left the field
-     */
-    public byte[] transceive(byte[] data) throws IOException {
-        return transceive(data, true);
-    }
-
-    /**
-     * Return the maximum number of bytes that can be sent with {@link #transceive}.
-     * @return the maximum number of bytes that can be sent with {@link #transceive}.
-     */
-    public int getMaxTransceiveLength() {
-        return getMaxTransceiveLengthInternal();
-    }
-
-    /**
-     * <p>Standard APDUs have a 1-byte length field, allowing a maximum of
-     * 255 payload bytes, which results in a maximum APDU length of 261 bytes.
-     *
-     * <p>Extended length APDUs have a 3-byte length field, allowing 65535
-     * payload bytes.
-     *
-     * <p>Some NFC adapters, like the one used in the Nexus S and the Galaxy Nexus
-     * do not support extended length APDUs. They are expected to be well-supported
-     * in the future though. Use this method to check for extended length APDU
-     * support.
-     *
-     * @return whether the NFC adapter on this device supports extended length APDUs.
-     * @throws SecurityException if the tag object is reused after the tag has left the field
-     */
-    public boolean isExtendedLengthApduSupported() {
-        try {
-            return mTag.getTagService().getExtendedLengthApdusSupported();
-        } catch (RemoteException e) {
-            Log.e(TAG, "NFC service dead", e);
-            return false;
-        }
-    }
-}
diff --git a/nfc/java/android/nfc/tech/MifareClassic.java b/nfc/java/android/nfc/tech/MifareClassic.java
deleted file mode 100644
index 26f54e6..0000000
--- a/nfc/java/android/nfc/tech/MifareClassic.java
+++ /dev/null
@@ -1,655 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc.tech;
-
-import android.nfc.ErrorCodes;
-import android.nfc.Tag;
-import android.nfc.TagLostException;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-/**
- * Provides access to MIFARE Classic properties and I/O operations on a {@link Tag}.
- *
- * <p>Acquire a {@link MifareClassic} object using {@link #get}.
- *
- * <p>MIFARE Classic is also known as MIFARE Standard.
- * <p>MIFARE Classic tags are divided into sectors, and each sector is sub-divided into
- * blocks. Block size is always 16 bytes ({@link #BLOCK_SIZE}. Sector size varies.
- * <ul>
- * <li>MIFARE Classic Mini are 320 bytes ({@link #SIZE_MINI}), with 5 sectors each of 4 blocks.
- * <li>MIFARE Classic 1k are 1024 bytes ({@link #SIZE_1K}), with 16 sectors each of 4 blocks.
- * <li>MIFARE Classic 2k are 2048 bytes ({@link #SIZE_2K}), with 32 sectors each of 4 blocks.
- * <li>MIFARE Classic 4k are 4096 bytes ({@link #SIZE_4K}). The first 32 sectors contain 4 blocks
- * and the last 8 sectors contain 16 blocks.
- * </ul>
- *
- * <p>MIFARE Classic tags require authentication on a per-sector basis before any
- * other I/O operations on that sector can be performed. There are two keys per sector,
- * and ACL bits determine what I/O operations are allowed on that sector after
- * authenticating with a key. {@see #authenticateSectorWithKeyA} and
- * {@see #authenticateSectorWithKeyB}.
- *
- * <p>Three well-known authentication keys are defined in this class:
- * {@link #KEY_DEFAULT}, {@link #KEY_MIFARE_APPLICATION_DIRECTORY},
- * {@link #KEY_NFC_FORUM}.
- * <ul>
- * <li>{@link #KEY_DEFAULT} is the default factory key for MIFARE Classic.
- * <li>{@link #KEY_MIFARE_APPLICATION_DIRECTORY} is the well-known key for
- * MIFARE Classic cards that have been formatted according to the
- * MIFARE Application Directory (MAD) specification.
- * <li>{@link #KEY_NFC_FORUM} is the well-known key for MIFARE Classic cards that
- * have been formatted according to the NXP specification for NDEF on MIFARE Classic.
- *
- * <p>Implementation of this class on a Android NFC device is optional.
- * If it is not implemented, then
- * {@link MifareClassic} will never be enumerated in {@link Tag#getTechList}.
- * If it is enumerated, then all {@link MifareClassic} I/O operations will be supported,
- * and {@link Ndef#MIFARE_CLASSIC} NDEF tags will also be supported. In either case,
- * {@link NfcA} will also be enumerated on the tag, because all MIFARE Classic tags are also
- * {@link NfcA}.
- *
- * <p class="note"><strong>Note:</strong> Methods that perform I/O operations
- * require the {@link android.Manifest.permission#NFC} permission.
- */
-public final class MifareClassic extends BasicTagTechnology {
-    private static final String TAG = "NFC";
-
-    /**
-     * The default factory key.
-     */
-    public static final byte[] KEY_DEFAULT =
-            {(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF};
-    /**
-     * The well-known key for tags formatted according to the
-     * MIFARE Application Directory (MAD) specification.
-     */
-    public static final byte[] KEY_MIFARE_APPLICATION_DIRECTORY =
-            {(byte)0xA0,(byte)0xA1,(byte)0xA2,(byte)0xA3,(byte)0xA4,(byte)0xA5};
-    /**
-     * The well-known key for tags formatted according to the
-     * NDEF on MIFARE Classic specification.
-     */
-    public static final byte[] KEY_NFC_FORUM =
-            {(byte)0xD3,(byte)0xF7,(byte)0xD3,(byte)0xF7,(byte)0xD3,(byte)0xF7};
-
-    /** A MIFARE Classic compatible card of unknown type */
-    public static final int TYPE_UNKNOWN = -1;
-    /** A MIFARE Classic tag */
-    public static final int TYPE_CLASSIC = 0;
-    /** A MIFARE Plus tag */
-    public static final int TYPE_PLUS = 1;
-    /** A MIFARE Pro tag */
-    public static final int TYPE_PRO = 2;
-
-    /** Tag contains 16 sectors, each with 4 blocks. */
-    public static final int SIZE_1K = 1024;
-    /** Tag contains 32 sectors, each with 4 blocks. */
-    public static final int SIZE_2K = 2048;
-    /**
-     * Tag contains 40 sectors. The first 32 sectors contain 4 blocks and the last 8 sectors
-     * contain 16 blocks.
-     */
-    public static final int SIZE_4K = 4096;
-    /** Tag contains 5 sectors, each with 4 blocks. */
-    public static final int SIZE_MINI = 320;
-
-    /** Size of a MIFARE Classic block (in bytes) */
-    public static final int BLOCK_SIZE = 16;
-
-    private static final int MAX_BLOCK_COUNT = 256;
-    private static final int MAX_SECTOR_COUNT = 40;
-
-    private boolean mIsEmulated;
-    private int mType;
-    private int mSize;
-
-    /**
-     * Get an instance of {@link MifareClassic} for the given tag.
-     * <p>Does not cause any RF activity and does not block.
-     * <p>Returns null if {@link MifareClassic} was not enumerated in {@link Tag#getTechList}.
-     * This indicates the tag is not MIFARE Classic compatible, or this Android
-     * device does not support MIFARE Classic.
-     *
-     * @param tag an MIFARE Classic compatible tag
-     * @return MIFARE Classic object
-     */
-    public static MifareClassic get(Tag tag) {
-        if (!tag.hasTech(TagTechnology.MIFARE_CLASSIC)) return null;
-        try {
-            return new MifareClassic(tag);
-        } catch (RemoteException e) {
-            return null;
-        }
-    }
-
-    /** @hide */
-    public MifareClassic(Tag tag) throws RemoteException {
-        super(tag, TagTechnology.MIFARE_CLASSIC);
-
-        NfcA a = NfcA.get(tag);  // MIFARE Classic is always based on NFC a
-
-        mIsEmulated = false;
-
-        switch (a.getSak()) {
-        case 0x01:
-        case 0x08:
-            mType = TYPE_CLASSIC;
-            mSize = SIZE_1K;
-            break;
-        case 0x09:
-            mType = TYPE_CLASSIC;
-            mSize = SIZE_MINI;
-            break;
-        case 0x10:
-            mType = TYPE_PLUS;
-            mSize = SIZE_2K;
-            // SecLevel = SL2
-            break;
-        case 0x11:
-            mType = TYPE_PLUS;
-            mSize = SIZE_4K;
-            // Seclevel = SL2
-            break;
-        case 0x18:
-            mType = TYPE_CLASSIC;
-            mSize = SIZE_4K;
-            break;
-        case 0x28:
-            mType = TYPE_CLASSIC;
-            mSize = SIZE_1K;
-            mIsEmulated = true;
-            break;
-        case 0x38:
-            mType = TYPE_CLASSIC;
-            mSize = SIZE_4K;
-            mIsEmulated = true;
-            break;
-        case 0x88:
-            mType = TYPE_CLASSIC;
-            mSize = SIZE_1K;
-            // NXP-tag: false
-            break;
-        case 0x98:
-        case 0xB8:
-            mType = TYPE_PRO;
-            mSize = SIZE_4K;
-            break;
-        default:
-            // Stack incorrectly reported a MifareClassic. We cannot handle this
-            // gracefully - we have no idea of the memory layout. Bail.
-            throw new RuntimeException(
-                    "Tag incorrectly enumerated as MIFARE Classic, SAK = " + a.getSak());
-        }
-    }
-
-    /**
-     * Return the type of this MIFARE Classic compatible tag.
-     * <p>One of {@link #TYPE_UNKNOWN}, {@link #TYPE_CLASSIC}, {@link #TYPE_PLUS} or
-     * {@link #TYPE_PRO}.
-     * <p>Does not cause any RF activity and does not block.
-     *
-     * @return type
-     */
-    public int getType() {
-        return mType;
-    }
-
-    /**
-     * Return the size of the tag in bytes
-     * <p>One of {@link #SIZE_MINI}, {@link #SIZE_1K}, {@link #SIZE_2K}, {@link #SIZE_4K}.
-     * These constants are equal to their respective size in bytes.
-     * <p>Does not cause any RF activity and does not block.
-     * @return size in bytes
-     */
-    public int getSize() {
-        return mSize;
-    }
-
-    /**
-     * Return true if the tag is emulated, determined at discovery time.
-     * These are actually smart-cards that emulate a MIFARE Classic interface.
-     * They can be treated identically to a MIFARE Classic tag.
-     * @hide
-     */
-    public boolean isEmulated() {
-        return mIsEmulated;
-    }
-
-    /**
-     * Return the number of MIFARE Classic sectors.
-     * <p>Does not cause any RF activity and does not block.
-     * @return number of sectors
-     */
-    public int getSectorCount() {
-        switch (mSize) {
-        case SIZE_1K:
-            return 16;
-        case SIZE_2K:
-            return 32;
-        case SIZE_4K:
-            return 40;
-        case SIZE_MINI:
-            return 5;
-        default:
-            return 0;
-        }
-    }
-
-    /**
-     * Return the total number of MIFARE Classic blocks.
-     * <p>Does not cause any RF activity and does not block.
-     * @return total number of blocks
-     */
-    public int getBlockCount() {
-        return mSize / BLOCK_SIZE;
-    }
-
-    /**
-     * Return the number of blocks in the given sector.
-     * <p>Does not cause any RF activity and does not block.
-     *
-     * @param sectorIndex index of sector, starting from 0
-     * @return number of blocks in the sector
-     */
-    public int getBlockCountInSector(int sectorIndex) {
-        validateSector(sectorIndex);
-
-        if (sectorIndex < 32) {
-            return 4;
-        } else {
-            return 16;
-        }
-    }
-
-    /**
-     * Return the sector that contains a given block.
-     * <p>Does not cause any RF activity and does not block.
-     *
-     * @param blockIndex index of block to lookup, starting from 0
-     * @return sector index that contains the block
-     */
-    public int blockToSector(int blockIndex) {
-        validateBlock(blockIndex);
-
-        if (blockIndex < 32 * 4) {
-            return blockIndex / 4;
-        } else {
-            return 32 + (blockIndex - 32 * 4) / 16;
-        }
-    }
-
-    /**
-     * Return the first block of a given sector.
-     * <p>Does not cause any RF activity and does not block.
-     *
-     * @param sectorIndex index of sector to lookup, starting from 0
-     * @return block index of first block in sector
-     */
-    public int sectorToBlock(int sectorIndex) {
-        if (sectorIndex < 32) {
-            return sectorIndex * 4;
-        } else {
-            return 32 * 4 + (sectorIndex - 32) * 16;
-        }
-    }
-
-    /**
-     * Authenticate a sector with key A.
-     *
-     * <p>Successful authentication of a sector with key A enables other
-     * I/O operations on that sector. The set of operations granted by key A
-     * key depends on the ACL bits set in that sector. For more information
-     * see the MIFARE Classic specification on <a href="http://www.nxp.com">http://www.nxp.com</a>.
-     *
-     * <p>A failed authentication attempt causes an implicit reconnection to the
-     * tag, so authentication to other sectors will be lost.
-     *
-     * <p>This is an I/O operation and will block until complete. It must
-     * not be called from the main application thread. A blocked call will be canceled with
-     * {@link IOException} if {@link #close} is called from another thread.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param sectorIndex index of sector to authenticate, starting from 0
-     * @param key 6-byte authentication key
-     * @return true on success, false on authentication failure
-     * @throws TagLostException if the tag leaves the field
-     * @throws IOException if there is an I/O failure, or the operation is canceled
-     */
-    public boolean authenticateSectorWithKeyA(int sectorIndex, byte[] key) throws IOException {
-        return authenticate(sectorIndex, key, true);
-    }
-
-    /**
-     * Authenticate a sector with key B.
-     *
-     * <p>Successful authentication of a sector with key B enables other
-     * I/O operations on that sector. The set of operations granted by key B
-     * depends on the ACL bits set in that sector. For more information
-     * see the MIFARE Classic specification on <a href="http://www.nxp.com">http://www.nxp.com</a>.
-     *
-     * <p>A failed authentication attempt causes an implicit reconnection to the
-     * tag, so authentication to other sectors will be lost.
-     *
-     * <p>This is an I/O operation and will block until complete. It must
-     * not be called from the main application thread. A blocked call will be canceled with
-     * {@link IOException} if {@link #close} is called from another thread.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param sectorIndex index of sector to authenticate, starting from 0
-     * @param key 6-byte authentication key
-     * @return true on success, false on authentication failure
-     * @throws TagLostException if the tag leaves the field
-     * @throws IOException if there is an I/O failure, or the operation is canceled
-     */
-    public boolean authenticateSectorWithKeyB(int sectorIndex, byte[] key) throws IOException {
-        return authenticate(sectorIndex, key, false);
-    }
-
-    private boolean authenticate(int sector, byte[] key, boolean keyA) throws IOException {
-        validateSector(sector);
-        checkConnected();
-
-        byte[] cmd = new byte[12];
-
-        // First byte is the command
-        if (keyA) {
-            cmd[0] = 0x60; // phHal_eMifareAuthentA
-        } else {
-            cmd[0] = 0x61; // phHal_eMifareAuthentB
-        }
-
-        // Second byte is block address
-        // Authenticate command takes a block address. Authenticating a block
-        // of a sector will authenticate the entire sector.
-        cmd[1] = (byte) sectorToBlock(sector);
-
-        // Next 4 bytes are last 4 bytes of UID
-        byte[] uid = getTag().getId();
-        System.arraycopy(uid, uid.length - 4, cmd, 2, 4);
-
-        // Next 6 bytes are key
-        System.arraycopy(key, 0, cmd, 6, 6);
-
-        try {
-            if (transceive(cmd, false) != null) {
-                return true;
-            }
-        } catch (TagLostException e) {
-            throw e;
-        } catch (IOException e) {
-            // No need to deal with, will return false anyway
-        }
-        return false;
-    }
-
-    /**
-     * Read 16-byte block.
-     *
-     * <p>This is an I/O operation and will block until complete. It must
-     * not be called from the main application thread. A blocked call will be canceled with
-     * {@link IOException} if {@link #close} is called from another thread.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param blockIndex index of block to read, starting from 0
-     * @return 16 byte block
-     * @throws TagLostException if the tag leaves the field
-     * @throws IOException if there is an I/O failure, or the operation is canceled
-     */
-    public byte[] readBlock(int blockIndex) throws IOException {
-        validateBlock(blockIndex);
-        checkConnected();
-
-        byte[] cmd = { 0x30, (byte) blockIndex };
-        return transceive(cmd, false);
-    }
-
-    /**
-     * Write 16-byte block.
-     *
-     * <p>This is an I/O operation and will block until complete. It must
-     * not be called from the main application thread. A blocked call will be canceled with
-     * {@link IOException} if {@link #close} is called from another thread.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param blockIndex index of block to write, starting from 0
-     * @param data 16 bytes of data to write
-     * @throws TagLostException if the tag leaves the field
-     * @throws IOException if there is an I/O failure, or the operation is canceled
-     */
-    public void writeBlock(int blockIndex, byte[] data) throws IOException {
-        validateBlock(blockIndex);
-        checkConnected();
-        if (data.length != 16) {
-            throw new IllegalArgumentException("must write 16-bytes");
-        }
-
-        byte[] cmd = new byte[data.length + 2];
-        cmd[0] = (byte) 0xA0; // MF write command
-        cmd[1] = (byte) blockIndex;
-        System.arraycopy(data, 0, cmd, 2, data.length);
-
-        transceive(cmd, false);
-    }
-
-    /**
-     * Increment a value block, storing the result in the temporary block on the tag.
-     *
-     * <p>This is an I/O operation and will block until complete. It must
-     * not be called from the main application thread. A blocked call will be canceled with
-     * {@link IOException} if {@link #close} is called from another thread.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param blockIndex index of block to increment, starting from 0
-     * @param value non-negative to increment by
-     * @throws TagLostException if the tag leaves the field
-     * @throws IOException if there is an I/O failure, or the operation is canceled
-     */
-    public void increment(int blockIndex, int value) throws IOException {
-        validateBlock(blockIndex);
-        validateValueOperand(value);
-        checkConnected();
-
-        ByteBuffer cmd = ByteBuffer.allocate(6);
-        cmd.order(ByteOrder.LITTLE_ENDIAN);
-        cmd.put( (byte) 0xC1 );
-        cmd.put( (byte) blockIndex );
-        cmd.putInt(value);
-
-        transceive(cmd.array(), false);
-    }
-
-    /**
-     * Decrement a value block, storing the result in the temporary block on the tag.
-     *
-     * <p>This is an I/O operation and will block until complete. It must
-     * not be called from the main application thread. A blocked call will be canceled with
-     * {@link IOException} if {@link #close} is called from another thread.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param blockIndex index of block to decrement, starting from 0
-     * @param value non-negative to decrement by
-     * @throws TagLostException if the tag leaves the field
-     * @throws IOException if there is an I/O failure, or the operation is canceled
-     */
-    public void decrement(int blockIndex, int value) throws IOException {
-        validateBlock(blockIndex);
-        validateValueOperand(value);
-        checkConnected();
-
-        ByteBuffer cmd = ByteBuffer.allocate(6);
-        cmd.order(ByteOrder.LITTLE_ENDIAN);
-        cmd.put( (byte) 0xC0 );
-        cmd.put( (byte) blockIndex );
-        cmd.putInt(value);
-
-        transceive(cmd.array(), false);
-    }
-
-    /**
-     * Copy from the temporary block to a value block.
-     *
-     * <p>This is an I/O operation and will block until complete. It must
-     * not be called from the main application thread. A blocked call will be canceled with
-     * {@link IOException} if {@link #close} is called from another thread.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param blockIndex index of block to copy to
-     * @throws TagLostException if the tag leaves the field
-     * @throws IOException if there is an I/O failure, or the operation is canceled
-     */
-    public void transfer(int blockIndex) throws IOException {
-        validateBlock(blockIndex);
-        checkConnected();
-
-        byte[] cmd = { (byte) 0xB0, (byte) blockIndex };
-
-        transceive(cmd, false);
-    }
-
-    /**
-     * Copy from a value block to the temporary block.
-     *
-     * <p>This is an I/O operation and will block until complete. It must
-     * not be called from the main application thread. A blocked call will be canceled with
-     * {@link IOException} if {@link #close} is called from another thread.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param blockIndex index of block to copy from
-     * @throws TagLostException if the tag leaves the field
-     * @throws IOException if there is an I/O failure, or the operation is canceled
-     */
-    public void restore(int blockIndex) throws IOException {
-        validateBlock(blockIndex);
-        checkConnected();
-
-        byte[] cmd = { (byte) 0xC2, (byte) blockIndex };
-
-        transceive(cmd, false);
-    }
-
-    /**
-     * Send raw NfcA data to a tag and receive the response.
-     *
-     * <p>This is equivalent to connecting to this tag via {@link NfcA}
-     * and calling {@link NfcA#transceive}. Note that all MIFARE Classic
-     * tags are based on {@link NfcA} technology.
-     *
-     * <p>Use {@link #getMaxTransceiveLength} to retrieve the maximum number of bytes
-     * that can be sent with {@link #transceive}.
-     *
-     * <p>This is an I/O operation and will block until complete. It must
-     * not be called from the main application thread. A blocked call will be canceled with
-     * {@link IOException} if {@link #close} is called from another thread.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @see NfcA#transceive
-     */
-    public byte[] transceive(byte[] data) throws IOException {
-        return transceive(data, true);
-    }
-
-    /**
-     * Return the maximum number of bytes that can be sent with {@link #transceive}.
-     * @return the maximum number of bytes that can be sent with {@link #transceive}.
-     */
-    public int getMaxTransceiveLength() {
-        return getMaxTransceiveLengthInternal();
-    }
-
-    /**
-     * Set the {@link #transceive} timeout in milliseconds.
-     *
-     * <p>The timeout only applies to {@link #transceive} on this object,
-     * and is reset to a default value when {@link #close} is called.
-     *
-     * <p>Setting a longer timeout may be useful when performing
-     * transactions that require a long processing time on the tag
-     * such as key generation.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param timeout timeout value in milliseconds
-     * @throws SecurityException if the tag object is reused after the tag has left the field
-     */
-    public void setTimeout(int timeout) {
-        try {
-            int err = mTag.getTagService().setTimeout(TagTechnology.MIFARE_CLASSIC, timeout);
-            if (err != ErrorCodes.SUCCESS) {
-                throw new IllegalArgumentException("The supplied timeout is not valid");
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "NFC service dead", e);
-        }
-    }
-
-    /**
-     * Get the current {@link #transceive} timeout in milliseconds.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @return timeout value in milliseconds
-     * @throws SecurityException if the tag object is reused after the tag has left the field
-     */
-    public int getTimeout() {
-        try {
-            return mTag.getTagService().getTimeout(TagTechnology.MIFARE_CLASSIC);
-        } catch (RemoteException e) {
-            Log.e(TAG, "NFC service dead", e);
-            return 0;
-        }
-    }
-
-    private static void validateSector(int sector) {
-        // Do not be too strict on upper bounds checking, since some cards
-        // have more addressable memory than they report. For example,
-        // MIFARE Plus 2k cards will appear as MIFARE Classic 1k cards when in
-        // MIFARE Classic compatibility mode.
-        // Note that issuing a command to an out-of-bounds block is safe - the
-        // tag should report error causing IOException. This validation is a
-        // helper to guard against obvious programming mistakes.
-        if (sector < 0 || sector >= MAX_SECTOR_COUNT) {
-            throw new IndexOutOfBoundsException("sector out of bounds: " + sector);
-        }
-    }
-
-    private static void validateBlock(int block) {
-        // Just looking for obvious out of bounds...
-        if (block < 0 || block >= MAX_BLOCK_COUNT) {
-            throw new IndexOutOfBoundsException("block out of bounds: " + block);
-        }
-    }
-
-    private static void validateValueOperand(int value) {
-        if (value < 0) {
-            throw new IllegalArgumentException("value operand negative");
-        }
-    }
-}
diff --git a/nfc/java/android/nfc/tech/MifareUltralight.java b/nfc/java/android/nfc/tech/MifareUltralight.java
deleted file mode 100644
index c0416a3..0000000
--- a/nfc/java/android/nfc/tech/MifareUltralight.java
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc.tech;
-
-import android.nfc.ErrorCodes;
-import android.nfc.Tag;
-import android.nfc.TagLostException;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.io.IOException;
-
-//TOOD: Ultralight C 3-DES authentication, one-way counter
-
-/**
- * Provides access to MIFARE Ultralight properties and I/O operations on a {@link Tag}.
- *
- * <p>Acquire a {@link MifareUltralight} object using {@link #get}.
- *
- * <p>MIFARE Ultralight compatible tags have 4 byte pages {@link #PAGE_SIZE}.
- * The primary operations on an Ultralight tag are {@link #readPages} and
- * {@link #writePage}.
- *
- * <p>The original MIFARE Ultralight consists of a 64 byte EEPROM. The first
- * 4 pages are for the OTP area, manufacturer data, and locking bits. They are
- * readable and some bits are writable. The final 12 pages are the user
- * read/write area. For more information see the NXP data sheet MF0ICU1.
- *
- * <p>The MIFARE Ultralight C consists of a 192 byte EEPROM. The first 4 pages
- * are for OTP, manufacturer data, and locking bits. The next 36 pages are the
- * user read/write area. The next 4 pages are additional locking bits, counters
- * and authentication configuration and are readable. The final 4 pages are for
- * the authentication key and are not readable. For more information see the
- * NXP data sheet MF0ICU2.
- *
- * <p>Implementation of this class on a Android NFC device is optional.
- * If it is not implemented, then
- * {@link MifareUltralight} will never be enumerated in {@link Tag#getTechList}.
- * If it is enumerated, then all {@link MifareUltralight} I/O operations will be supported.
- * In either case, {@link NfcA} will also be enumerated on the tag,
- * because all MIFARE Ultralight tags are also {@link NfcA} tags.
- *
- * <p class="note"><strong>Note:</strong> Methods that perform I/O operations
- * require the {@link android.Manifest.permission#NFC} permission.
- */
-public final class MifareUltralight extends BasicTagTechnology {
-    private static final String TAG = "NFC";
-
-    /** A MIFARE Ultralight compatible tag of unknown type */
-    public static final int TYPE_UNKNOWN = -1;
-    /** A MIFARE Ultralight tag */
-    public static final int TYPE_ULTRALIGHT = 1;
-    /** A MIFARE Ultralight C tag */
-    public static final int TYPE_ULTRALIGHT_C = 2;
-
-    /** Size of a MIFARE Ultralight page in bytes */
-    public static final int PAGE_SIZE = 4;
-
-    private static final int NXP_MANUFACTURER_ID = 0x04;
-    private static final int MAX_PAGE_COUNT = 256;
-
-    /** @hide */
-    public static final String EXTRA_IS_UL_C = "isulc";
-
-    private int mType;
-
-    /**
-     * Get an instance of {@link MifareUltralight} for the given tag.
-     * <p>Returns null if {@link MifareUltralight} was not enumerated in
-     * {@link Tag#getTechList} - this indicates the tag is not MIFARE
-     * Ultralight compatible, or that this Android
-     * device does not implement MIFARE Ultralight.
-     * <p>Does not cause any RF activity and does not block.
-     *
-     * @param tag an MIFARE Ultralight compatible tag
-     * @return MIFARE Ultralight object
-     */
-    public static MifareUltralight get(Tag tag) {
-        if (!tag.hasTech(TagTechnology.MIFARE_ULTRALIGHT)) return null;
-        try {
-            return new MifareUltralight(tag);
-        } catch (RemoteException e) {
-            return null;
-        }
-    }
-
-    /** @hide */
-    public MifareUltralight(Tag tag) throws RemoteException {
-        super(tag, TagTechnology.MIFARE_ULTRALIGHT);
-
-        // Check if this could actually be a MIFARE
-        NfcA a = NfcA.get(tag);
-
-        mType = TYPE_UNKNOWN;
-
-        if (a.getSak() == 0x00 && tag.getId()[0] == NXP_MANUFACTURER_ID) {
-            Bundle extras = tag.getTechExtras(TagTechnology.MIFARE_ULTRALIGHT);
-            if (extras.getBoolean(EXTRA_IS_UL_C)) {
-                mType = TYPE_ULTRALIGHT_C;
-            } else {
-                mType = TYPE_ULTRALIGHT;
-            }
-        }
-    }
-
-    /**
-     * Return the MIFARE Ultralight type of the tag.
-     * <p>One of {@link #TYPE_ULTRALIGHT} or {@link #TYPE_ULTRALIGHT_C} or
-     * {@link #TYPE_UNKNOWN}.
-     * <p>Depending on how the tag has been formatted, it can be impossible
-     * to accurately classify between original MIFARE Ultralight and
-     * Ultralight C. So treat this method as a hint.
-     * <p>Does not cause any RF activity and does not block.
-     *
-     * @return the type
-     */
-    public int getType() {
-        return mType;
-    }
-
-    /**
-     * Read 4 pages (16 bytes).
-     *
-     * <p>The MIFARE Ultralight protocol always reads 4 pages at a time, to
-     * reduce the number of commands required to read an entire tag.
-     * <p>If a read spans past the last readable block, then the tag will
-     * return pages that have been wrapped back to the first blocks. MIFARE
-     * Ultralight tags have readable blocks 0x00 through 0x0F. So a read to
-     * block offset 0x0E would return blocks 0x0E, 0x0F, 0x00, 0x01. MIFARE
-     * Ultralight C tags have readable blocks 0x00 through 0x2B. So a read to
-     * block 0x2A would return blocks 0x2A, 0x2B, 0x00, 0x01.
-     *
-     * <p>This is an I/O operation and will block until complete. It must
-     * not be called from the main application thread. A blocked call will be canceled with
-     * {@link IOException} if {@link #close} is called from another thread.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param pageOffset index of first page to read, starting from 0
-     * @return 4 pages (16 bytes)
-     * @throws TagLostException if the tag leaves the field
-     * @throws IOException if there is an I/O failure, or the operation is canceled
-     */
-    public byte[] readPages(int pageOffset) throws IOException {
-        validatePageIndex(pageOffset);
-        checkConnected();
-
-        byte[] cmd = { 0x30, (byte) pageOffset};
-        return transceive(cmd, false);
-    }
-
-    /**
-     * Write 1 page (4 bytes).
-     *
-     * <p>The MIFARE Ultralight protocol always writes 1 page at a time, to
-     * minimize EEPROM write cycles.
-     *
-     * <p>This is an I/O operation and will block until complete. It must
-     * not be called from the main application thread. A blocked call will be canceled with
-     * {@link IOException} if {@link #close} is called from another thread.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param pageOffset index of page to write, starting from 0
-     * @param data 4 bytes to write
-     * @throws TagLostException if the tag leaves the field
-     * @throws IOException if there is an I/O failure, or the operation is canceled
-     */
-    public void writePage(int pageOffset, byte[] data) throws IOException {
-        validatePageIndex(pageOffset);
-        checkConnected();
-
-        byte[] cmd = new byte[data.length + 2];
-        cmd[0] = (byte) 0xA2;
-        cmd[1] = (byte) pageOffset;
-        System.arraycopy(data, 0, cmd, 2, data.length);
-
-        transceive(cmd, false);
-    }
-
-    /**
-     * Send raw NfcA data to a tag and receive the response.
-     *
-     * <p>This is equivalent to connecting to this tag via {@link NfcA}
-     * and calling {@link NfcA#transceive}. Note that all MIFARE Classic
-     * tags are based on {@link NfcA} technology.
-     *
-     * <p>Use {@link #getMaxTransceiveLength} to retrieve the maximum number of bytes
-     * that can be sent with {@link #transceive}.
-     *
-     * <p>This is an I/O operation and will block until complete. It must
-     * not be called from the main application thread. A blocked call will be canceled with
-     * {@link IOException} if {@link #close} is called from another thread.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @see NfcA#transceive
-     */
-    public byte[] transceive(byte[] data) throws IOException {
-        return transceive(data, true);
-    }
-
-    /**
-     * Return the maximum number of bytes that can be sent with {@link #transceive}.
-     * @return the maximum number of bytes that can be sent with {@link #transceive}.
-     */
-    public int getMaxTransceiveLength() {
-        return getMaxTransceiveLengthInternal();
-    }
-
-    /**
-     * Set the {@link #transceive} timeout in milliseconds.
-     *
-     * <p>The timeout only applies to {@link #transceive} on this object,
-     * and is reset to a default value when {@link #close} is called.
-     *
-     * <p>Setting a longer timeout may be useful when performing
-     * transactions that require a long processing time on the tag
-     * such as key generation.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param timeout timeout value in milliseconds
-     * @throws SecurityException if the tag object is reused after the tag has left the field
-     */
-    public void setTimeout(int timeout) {
-        try {
-            int err = mTag.getTagService().setTimeout(
-                    TagTechnology.MIFARE_ULTRALIGHT, timeout);
-            if (err != ErrorCodes.SUCCESS) {
-                throw new IllegalArgumentException("The supplied timeout is not valid");
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "NFC service dead", e);
-        }
-    }
-
-    /**
-     * Get the current {@link #transceive} timeout in milliseconds.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @return timeout value in milliseconds
-     * @throws SecurityException if the tag object is reused after the tag has left the field
-     */
-    public int getTimeout() {
-        try {
-            return mTag.getTagService().getTimeout(TagTechnology.MIFARE_ULTRALIGHT);
-        } catch (RemoteException e) {
-            Log.e(TAG, "NFC service dead", e);
-            return 0;
-        }
-    }
-
-    private static void validatePageIndex(int pageIndex) {
-        // Do not be too strict on upper bounds checking, since some cards
-        // may have more addressable memory than they report.
-        // Note that issuing a command to an out-of-bounds block is safe - the
-        // tag will wrap the read to an addressable area. This validation is a
-        // helper to guard against obvious programming mistakes.
-        if (pageIndex < 0 || pageIndex >= MAX_PAGE_COUNT) {
-            throw new IndexOutOfBoundsException("page out of bounds: " + pageIndex);
-        }
-    }
-}
diff --git a/nfc/java/android/nfc/tech/Ndef.java b/nfc/java/android/nfc/tech/Ndef.java
deleted file mode 100644
index 7d83f15..0000000
--- a/nfc/java/android/nfc/tech/Ndef.java
+++ /dev/null
@@ -1,408 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc.tech;
-
-import android.nfc.ErrorCodes;
-import android.nfc.FormatException;
-import android.nfc.INfcTag;
-import android.nfc.NdefMessage;
-import android.nfc.Tag;
-import android.nfc.TagLostException;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.io.IOException;
-
-/**
- * Provides access to NDEF content and operations on a {@link Tag}.
- *
- * <p>Acquire a {@link Ndef} object using {@link #get}.
- *
- * <p>NDEF is an NFC Forum data format. The data formats are implemented in
- * {@link android.nfc.NdefMessage} and
- * {@link android.nfc.NdefRecord}. This class provides methods to
- * retrieve and modify the {@link android.nfc.NdefMessage}
- * on a tag.
- *
- * <p>There are currently four NFC Forum standardized tag types that can be
- * formatted to contain NDEF data.
- * <ul>
- * <li>NFC Forum Type 1 Tag ({@link #NFC_FORUM_TYPE_1}), such as the Innovision Topaz
- * <li>NFC Forum Type 2 Tag ({@link #NFC_FORUM_TYPE_2}), such as the NXP MIFARE Ultralight
- * <li>NFC Forum Type 3 Tag ({@link #NFC_FORUM_TYPE_3}), such as Sony Felica
- * <li>NFC Forum Type 4 Tag ({@link #NFC_FORUM_TYPE_4}), such as NXP MIFARE Desfire
- * </ul>
- * It is mandatory for all Android devices with NFC to correctly enumerate
- * {@link Ndef} on NFC Forum Tag Types 1-4, and implement all NDEF operations
- * as defined in this class.
- *
- * <p>Some vendors have their own well defined specifications for storing NDEF data
- * on tags that do not fall into the above categories. Android devices with NFC
- * should enumerate and implement {@link Ndef} under these vendor specifications
- * where possible, but it is not mandatory. {@link #getType} returns a String
- * describing this specification, for example {@link #MIFARE_CLASSIC} is
- * <code>com.nxp.ndef.mifareclassic</code>.
- *
- * <p>Android devices that support MIFARE Classic must also correctly
- * implement {@link Ndef} on MIFARE Classic tags formatted to NDEF.
- *
- * <p>For guaranteed compatibility across all Android devices with NFC, it is
- * recommended to use NFC Forum Types 1-4 in new deployments of NFC tags
- * with NDEF payload. Vendor NDEF formats will not work on all Android devices.
- *
- * <p class="note"><strong>Note:</strong> Methods that perform I/O operations
- * require the {@link android.Manifest.permission#NFC} permission.
- */
-public final class Ndef extends BasicTagTechnology {
-    private static final String TAG = "NFC";
-
-    /** @hide */
-    public static final int NDEF_MODE_READ_ONLY = 1;
-    /** @hide */
-    public static final int NDEF_MODE_READ_WRITE = 2;
-    /** @hide */
-    public static final int NDEF_MODE_UNKNOWN = 3;
-
-    /** @hide */
-    public static final String EXTRA_NDEF_MSG = "ndefmsg";
-
-    /** @hide */
-    public static final String EXTRA_NDEF_MAXLENGTH = "ndefmaxlength";
-
-    /** @hide */
-    public static final String EXTRA_NDEF_CARDSTATE = "ndefcardstate";
-
-    /** @hide */
-    public static final String EXTRA_NDEF_TYPE = "ndeftype";
-
-    /** @hide */
-    public static final int TYPE_OTHER = -1;
-    /** @hide */
-    public static final int TYPE_1 = 1;
-    /** @hide */
-    public static final int TYPE_2 = 2;
-    /** @hide */
-    public static final int TYPE_3 = 3;
-    /** @hide */
-    public static final int TYPE_4 = 4;
-    /** @hide */
-    public static final int TYPE_MIFARE_CLASSIC = 101;
-    /** @hide */
-    public static final int TYPE_ICODE_SLI = 102;
-
-    /** @hide */
-    public static final String UNKNOWN = "android.ndef.unknown";
-
-    /** NFC Forum Tag Type 1 */
-    public static final String NFC_FORUM_TYPE_1 = "org.nfcforum.ndef.type1";
-    /** NFC Forum Tag Type 2 */
-    public static final String NFC_FORUM_TYPE_2 = "org.nfcforum.ndef.type2";
-    /** NFC Forum Tag Type 3 */
-    public static final String NFC_FORUM_TYPE_3 = "org.nfcforum.ndef.type3";
-    /** NFC Forum Tag Type 4 */
-    public static final String NFC_FORUM_TYPE_4 = "org.nfcforum.ndef.type4";
-    /** NDEF on MIFARE Classic */
-    public static final String MIFARE_CLASSIC = "com.nxp.ndef.mifareclassic";
-    /**
-     * NDEF on iCODE SLI
-     * @hide
-     */
-    public static final String ICODE_SLI = "com.nxp.ndef.icodesli";
-
-    private final int mMaxNdefSize;
-    private final int mCardState;
-    private final NdefMessage mNdefMsg;
-    private final int mNdefType;
-
-    /**
-     * Get an instance of {@link Ndef} for the given tag.
-     *
-     * <p>Returns null if {@link Ndef} was not enumerated in {@link Tag#getTechList}.
-     * This indicates the tag is not NDEF formatted, or that this tag
-     * is NDEF formatted but under a vendor specification that this Android
-     * device does not implement.
-     *
-     * <p>Does not cause any RF activity and does not block.
-     *
-     * @param tag an NDEF compatible tag
-     * @return Ndef object
-     */
-    public static Ndef get(Tag tag) {
-        if (!tag.hasTech(TagTechnology.NDEF)) return null;
-        try {
-            return new Ndef(tag);
-        } catch (RemoteException e) {
-            return null;
-        }
-    }
-
-    /**
-     * Internal constructor, to be used by NfcAdapter
-     * @hide
-     */
-    public Ndef(Tag tag) throws RemoteException {
-        super(tag, TagTechnology.NDEF);
-        Bundle extras = tag.getTechExtras(TagTechnology.NDEF);
-        if (extras != null) {
-            mMaxNdefSize = extras.getInt(EXTRA_NDEF_MAXLENGTH);
-            mCardState = extras.getInt(EXTRA_NDEF_CARDSTATE);
-            mNdefMsg = extras.getParcelable(EXTRA_NDEF_MSG, android.nfc.NdefMessage.class);
-            mNdefType = extras.getInt(EXTRA_NDEF_TYPE);
-        } else {
-            throw new NullPointerException("NDEF tech extras are null.");
-        }
-
-    }
-
-    /**
-     * Get the {@link NdefMessage} that was read from the tag at discovery time.
-     *
-     * <p>If the NDEF Message is modified by an I/O operation then it
-     * will not be updated here, this function only returns what was discovered
-     * when the tag entered the field.
-     * <p>Note that this method may return null if the tag was in the
-     * INITIALIZED state as defined by NFC Forum, as in this state the
-     * tag is formatted to support NDEF but does not contain a message yet.
-     * <p>Does not cause any RF activity and does not block.
-     * @return NDEF Message read from the tag at discovery time, can be null
-     */
-    public NdefMessage getCachedNdefMessage() {
-        return mNdefMsg;
-    }
-
-    /**
-     * Get the NDEF tag type.
-     *
-     * <p>Returns one of {@link #NFC_FORUM_TYPE_1}, {@link #NFC_FORUM_TYPE_2},
-     * {@link #NFC_FORUM_TYPE_3}, {@link #NFC_FORUM_TYPE_4},
-     * {@link #MIFARE_CLASSIC} or another NDEF tag type that has not yet been
-     * formalized in this Android API.
-     *
-     * <p>Does not cause any RF activity and does not block.
-     *
-     * @return a string representing the NDEF tag type
-     */
-    public String getType() {
-        switch (mNdefType) {
-            case TYPE_1:
-                return NFC_FORUM_TYPE_1;
-            case TYPE_2:
-                return NFC_FORUM_TYPE_2;
-            case TYPE_3:
-                return NFC_FORUM_TYPE_3;
-            case TYPE_4:
-                return NFC_FORUM_TYPE_4;
-            case TYPE_MIFARE_CLASSIC:
-                return MIFARE_CLASSIC;
-            case TYPE_ICODE_SLI:
-                return ICODE_SLI;
-            default:
-                return UNKNOWN;
-        }
-    }
-
-    /**
-     * Get the maximum NDEF message size in bytes.
-     *
-     * <p>Does not cause any RF activity and does not block.
-     *
-     * @return size in bytes
-     */
-    public int getMaxSize() {
-        return mMaxNdefSize;
-    }
-
-    /**
-     * Determine if the tag is writable.
-     *
-     * <p>NFC Forum tags can be in read-only or read-write states.
-     *
-     * <p>Does not cause any RF activity and does not block.
-     *
-     * <p>Requires {@link android.Manifest.permission#NFC} permission.
-     *
-     * @return true if the tag is writable
-     */
-    public boolean isWritable() {
-        return (mCardState == NDEF_MODE_READ_WRITE);
-    }
-
-    /**
-     * Read the current {@link android.nfc.NdefMessage} on this tag.
-     *
-     * <p>This always reads the current NDEF Message stored on the tag.
-     *
-     * <p>Note that this method may return null if the tag was in the
-     * INITIALIZED state as defined by NFC Forum, as in that state the
-     * tag is formatted to support NDEF but does not contain a message yet.
-     *
-     * <p>This is an I/O operation and will block until complete. It must
-     * not be called from the main application thread. A blocked call will be canceled with
-     * {@link IOException} if {@link #close} is called from another thread.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @return the NDEF Message, can be null
-     * @throws TagLostException if the tag leaves the field
-     * @throws IOException if there is an I/O failure, or the operation is canceled
-     * @throws FormatException if the NDEF Message on the tag is malformed
-     * @throws SecurityException if the tag object is reused after the tag has left the field
-     */
-    public NdefMessage getNdefMessage() throws IOException, FormatException {
-        checkConnected();
-
-        try {
-            INfcTag tagService = mTag.getTagService();
-            if (tagService == null) {
-                throw new IOException("Mock tags don't support this operation.");
-            }
-            int serviceHandle = mTag.getServiceHandle();
-            if (tagService.isNdef(serviceHandle)) {
-                NdefMessage msg = tagService.ndefRead(serviceHandle);
-                if (msg == null && !tagService.isPresent(serviceHandle)) {
-                    throw new TagLostException();
-                }
-                return msg;
-            } else if (!tagService.isPresent(serviceHandle)) {
-                throw new TagLostException();
-            } else {
-                return null;
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "NFC service dead", e);
-            return null;
-        }
-    }
-
-    /**
-     * Overwrite the {@link NdefMessage} on this tag.
-     *
-     * <p>This is an I/O operation and will block until complete. It must
-     * not be called from the main application thread. A blocked call will be canceled with
-     * {@link IOException} if {@link #close} is called from another thread.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param msg the NDEF Message to write, must not be null
-     * @throws TagLostException if the tag leaves the field
-     * @throws IOException if there is an I/O failure, or the operation is canceled
-     * @throws FormatException if the NDEF Message to write is malformed
-     * @throws SecurityException if the tag object is reused after the tag has left the field
-     */
-    public void writeNdefMessage(NdefMessage msg) throws IOException, FormatException {
-        checkConnected();
-
-        try {
-            INfcTag tagService = mTag.getTagService();
-            if (tagService == null) {
-                throw new IOException("Mock tags don't support this operation.");
-            }
-            int serviceHandle = mTag.getServiceHandle();
-            if (tagService.isNdef(serviceHandle)) {
-                int errorCode = tagService.ndefWrite(serviceHandle, msg);
-                switch (errorCode) {
-                    case ErrorCodes.SUCCESS:
-                        break;
-                    case ErrorCodes.ERROR_IO:
-                        throw new IOException();
-                    case ErrorCodes.ERROR_INVALID_PARAM:
-                        throw new FormatException();
-                    default:
-                        // Should not happen
-                        throw new IOException();
-                }
-            }
-            else {
-                throw new IOException("Tag is not ndef");
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "NFC service dead", e);
-        }
-    }
-
-    /**
-     * Indicates whether a tag can be made read-only with {@link #makeReadOnly()}.
-     *
-     * <p>Does not cause any RF activity and does not block.
-     *
-     * @return true if it is possible to make this tag read-only
-     * @throws SecurityException if the tag object is reused after the tag has left the field
-     */
-    public boolean canMakeReadOnly() {
-        INfcTag tagService = mTag.getTagService();
-        if (tagService == null) {
-            return false;
-        }
-        try {
-            return tagService.canMakeReadOnly(mNdefType);
-        } catch (RemoteException e) {
-            Log.e(TAG, "NFC service dead", e);
-            return false;
-        }
-    }
-
-    /**
-     * Make a tag read-only.
-     *
-     * <p>This sets the CC field to indicate the tag is read-only,
-     * and where possible permanently sets the lock bits to prevent
-     * any further modification of the memory.
-     * <p>This is a one-way process and cannot be reverted!
-     *
-     * <p>This is an I/O operation and will block until complete. It must
-     * not be called from the main application thread. A blocked call will be canceled with
-     * {@link IOException} if {@link #close} is called from another thread.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @return true on success, false if it is not possible to make this tag read-only
-     * @throws TagLostException if the tag leaves the field
-     * @throws IOException if there is an I/O failure, or the operation is canceled
-     * @throws SecurityException if the tag object is reused after the tag has left the field
-     */
-    public boolean makeReadOnly() throws IOException {
-        checkConnected();
-
-        try {
-            INfcTag tagService = mTag.getTagService();
-            if (tagService == null) {
-                return false;
-            }
-            if (tagService.isNdef(mTag.getServiceHandle())) {
-                int errorCode = tagService.ndefMakeReadOnly(mTag.getServiceHandle());
-                switch (errorCode) {
-                    case ErrorCodes.SUCCESS:
-                        return true;
-                    case ErrorCodes.ERROR_IO:
-                        throw new IOException();
-                    case ErrorCodes.ERROR_INVALID_PARAM:
-                        return false;
-                    default:
-                        // Should not happen
-                        throw new IOException();
-                }
-           }
-           else {
-               throw new IOException("Tag is not ndef");
-           }
-        } catch (RemoteException e) {
-            Log.e(TAG, "NFC service dead", e);
-            return false;
-        }
-    }
-}
diff --git a/nfc/java/android/nfc/tech/NdefFormatable.java b/nfc/java/android/nfc/tech/NdefFormatable.java
deleted file mode 100644
index 2240fe7..0000000
--- a/nfc/java/android/nfc/tech/NdefFormatable.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc.tech;
-
-import android.nfc.ErrorCodes;
-import android.nfc.FormatException;
-import android.nfc.INfcTag;
-import android.nfc.NdefMessage;
-import android.nfc.Tag;
-import android.nfc.TagLostException;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.io.IOException;
-
-/**
- * Provide access to NDEF format operations on a {@link Tag}.
- *
- * <p>Acquire a {@link NdefFormatable} object using {@link #get}.
- *
- * <p>Android devices with NFC must only enumerate and implement this
- * class for tags for which it can format to NDEF.
- *
- * <p>Unfortunately the procedures to convert unformated tags to NDEF formatted
- * tags are not specified by NFC Forum, and are not generally well-known. So
- * there is no mandatory set of tags for which all Android devices with NFC
- * must support {@link NdefFormatable}.
- *
- * <p class="note"><strong>Note:</strong> Methods that perform I/O operations
- * require the {@link android.Manifest.permission#NFC} permission.
- */
-public final class NdefFormatable extends BasicTagTechnology {
-    private static final String TAG = "NFC";
-
-    /**
-     * Get an instance of {@link NdefFormatable} for the given tag.
-     * <p>Does not cause any RF activity and does not block.
-     * <p>Returns null if {@link NdefFormatable} was not enumerated in {@link Tag#getTechList}.
-     * This indicates the tag is not NDEF formatable by this Android device.
-     *
-     * @param tag an NDEF formatable tag
-     * @return NDEF formatable object
-     */
-    public static NdefFormatable get(Tag tag) {
-        if (!tag.hasTech(TagTechnology.NDEF_FORMATABLE)) return null;
-        try {
-            return new NdefFormatable(tag);
-        } catch (RemoteException e) {
-            return null;
-        }
-    }
-
-    /**
-     * Internal constructor, to be used by NfcAdapter
-     * @hide
-     */
-    public NdefFormatable(Tag tag) throws RemoteException {
-        super(tag, TagTechnology.NDEF_FORMATABLE);
-    }
-
-    /**
-     * Format a tag as NDEF, and write a {@link NdefMessage}.
-     *
-     * <p>This is a multi-step process, an IOException is thrown
-     * if any one step fails.
-     * <p>The card is left in a read-write state after this operation.
-     *
-     * <p>This is an I/O operation and will block until complete. It must
-     * not be called from the main application thread. A blocked call will be canceled with
-     * {@link IOException} if {@link #close} is called from another thread.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param firstMessage the NDEF message to write after formatting, can be null
-     * @throws TagLostException if the tag leaves the field
-     * @throws IOException if there is an I/O failure, or the operation is canceled
-     * @throws FormatException if the NDEF Message to write is malformed
-     */
-    public void format(NdefMessage firstMessage) throws IOException, FormatException {
-        format(firstMessage, false);
-    }
-
-    /**
-     * Formats a tag as NDEF, write a {@link NdefMessage}, and make read-only.
-     *
-     * <p>This is a multi-step process, an IOException is thrown
-     * if any one step fails.
-     * <p>The card is left in a read-only state if this method returns successfully.
-     *
-     * <p>This is an I/O operation and will block until complete. It must
-     * not be called from the main application thread. A blocked call will be canceled with
-     * {@link IOException} if {@link #close} is called from another thread.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param firstMessage the NDEF message to write after formatting
-     * @throws TagLostException if the tag leaves the field
-     * @throws IOException if there is an I/O failure, or the operation is canceled
-     * @throws FormatException if the NDEF Message to write is malformed
-     * @throws SecurityException if the tag object is reused after the tag has left the field
-     */
-    public void formatReadOnly(NdefMessage firstMessage) throws IOException, FormatException {
-        format(firstMessage, true);
-    }
-
-    /*package*/ void format(NdefMessage firstMessage, boolean makeReadOnly) throws IOException,
-            FormatException {
-        checkConnected();
-
-        try {
-            int serviceHandle = mTag.getServiceHandle();
-            INfcTag tagService = mTag.getTagService();
-            if (tagService == null) {
-                throw new IOException();
-            }
-            int errorCode = tagService.formatNdef(serviceHandle, MifareClassic.KEY_DEFAULT);
-            switch (errorCode) {
-                case ErrorCodes.SUCCESS:
-                    break;
-                case ErrorCodes.ERROR_IO:
-                    throw new IOException();
-                case ErrorCodes.ERROR_INVALID_PARAM:
-                    throw new FormatException();
-                default:
-                    // Should not happen
-                    throw new IOException();
-            }
-            // Now check and see if the format worked
-            if (!tagService.isNdef(serviceHandle)) {
-                throw new IOException();
-            }
-
-            // Write a message, if one was provided
-            if (firstMessage != null) {
-                errorCode = tagService.ndefWrite(serviceHandle, firstMessage);
-                switch (errorCode) {
-                    case ErrorCodes.SUCCESS:
-                        break;
-                    case ErrorCodes.ERROR_IO:
-                        throw new IOException();
-                    case ErrorCodes.ERROR_INVALID_PARAM:
-                        throw new FormatException();
-                    default:
-                        // Should not happen
-                        throw new IOException();
-                }
-            }
-
-            // optionally make read-only
-            if (makeReadOnly) {
-                errorCode = tagService.ndefMakeReadOnly(serviceHandle);
-                switch (errorCode) {
-                    case ErrorCodes.SUCCESS:
-                        break;
-                    case ErrorCodes.ERROR_IO:
-                        throw new IOException();
-                    case ErrorCodes.ERROR_INVALID_PARAM:
-                        throw new IOException();
-                    default:
-                        // Should not happen
-                        throw new IOException();
-                }
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "NFC service dead", e);
-        }
-    }
-}
diff --git a/nfc/java/android/nfc/tech/NfcA.java b/nfc/java/android/nfc/tech/NfcA.java
deleted file mode 100644
index 7e66483..0000000
--- a/nfc/java/android/nfc/tech/NfcA.java
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc.tech;
-
-import android.nfc.ErrorCodes;
-import android.nfc.Tag;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.io.IOException;
-
-/**
- * Provides access to NFC-A (ISO 14443-3A) properties and I/O operations on a {@link Tag}.
- *
- * <p>Acquire a {@link NfcA} object using {@link #get}.
- * <p>The primary NFC-A I/O operation is {@link #transceive}. Applications must
- * implement their own protocol stack on top of {@link #transceive}.
- *
- * <p class="note"><strong>Note:</strong> Methods that perform I/O operations
- * require the {@link android.Manifest.permission#NFC} permission.
- */
-public final class NfcA extends BasicTagTechnology {
-    private static final String TAG = "NFC";
-
-    /** @hide */
-    public static final String EXTRA_SAK = "sak";
-    /** @hide */
-    public static final String EXTRA_ATQA = "atqa";
-
-    private short mSak;
-    private byte[] mAtqa;
-
-    /**
-     * Get an instance of {@link NfcA} for the given tag.
-     * <p>Returns null if {@link NfcA} was not enumerated in {@link Tag#getTechList}.
-     * This indicates the tag does not support NFC-A.
-     * <p>Does not cause any RF activity and does not block.
-     *
-     * @param tag an NFC-A compatible tag
-     * @return NFC-A object
-     */
-    public static NfcA get(Tag tag) {
-        if (!tag.hasTech(TagTechnology.NFC_A)) return null;
-        try {
-            return new NfcA(tag);
-        } catch (RemoteException e) {
-            return null;
-        }
-    }
-
-    /** @hide */
-    public NfcA(Tag tag) throws RemoteException {
-        super(tag, TagTechnology.NFC_A);
-        Bundle extras = tag.getTechExtras(TagTechnology.NFC_A);
-        mSak = extras.getShort(EXTRA_SAK);
-        mAtqa = extras.getByteArray(EXTRA_ATQA);
-    }
-
-    /**
-     * Return the ATQA/SENS_RES bytes from tag discovery.
-     *
-     * <p>Does not cause any RF activity and does not block.
-     *
-     * @return ATQA/SENS_RES bytes
-     */
-    public byte[] getAtqa() {
-        return mAtqa;
-    }
-
-    /**
-     * Return the SAK/SEL_RES bytes from tag discovery.
-     *
-     * <p>Does not cause any RF activity and does not block.
-     *
-     * @return SAK bytes
-     */
-    public short getSak() {
-        return mSak;
-    }
-
-    /**
-     * Send raw NFC-A commands to the tag and receive the response.
-     *
-     * <p>Applications must not append the EoD (CRC) to the payload,
-     * it will be automatically calculated.
-     * <p>Applications must only send commands that are complete bytes,
-     * for example a SENS_REQ is not possible (these are used to
-     * manage tag polling and initialization).
-     *
-     * <p>Use {@link #getMaxTransceiveLength} to retrieve the maximum number of bytes
-     * that can be sent with {@link #transceive}.
-     *
-     * <p>This is an I/O operation and will block until complete. It must
-     * not be called from the main application thread. A blocked call will be canceled with
-     * {@link IOException} if {@link #close} is called from another thread.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param data bytes to send
-     * @return bytes received in response
-     * @throws TagLostException if the tag leaves the field
-     * @throws IOException if there is an I/O failure, or this operation is canceled
-     */
-    public byte[] transceive(byte[] data) throws IOException {
-        return transceive(data, true);
-    }
-
-    /**
-     * Return the maximum number of bytes that can be sent with {@link #transceive}.
-     * @return the maximum number of bytes that can be sent with {@link #transceive}.
-     */
-    public int getMaxTransceiveLength() {
-        return getMaxTransceiveLengthInternal();
-    }
-
-    /**
-     * Set the {@link #transceive} timeout in milliseconds.
-     *
-     * <p>The timeout only applies to {@link #transceive} on this object,
-     * and is reset to a default value when {@link #close} is called.
-     *
-     * <p>Setting a longer timeout may be useful when performing
-     * transactions that require a long processing time on the tag
-     * such as key generation.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param timeout timeout value in milliseconds
-     * @throws SecurityException if the tag object is reused after the tag has left the field
-     */
-    public void setTimeout(int timeout) {
-        try {
-            int err = mTag.getTagService().setTimeout(TagTechnology.NFC_A, timeout);
-            if (err != ErrorCodes.SUCCESS) {
-                throw new IllegalArgumentException("The supplied timeout is not valid");
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "NFC service dead", e);
-        }
-    }
-
-    /**
-     * Get the current {@link #transceive} timeout in milliseconds.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @return timeout value in milliseconds
-     * @throws SecurityException if the tag object is reused after the tag has left the field
-     */
-    public int getTimeout() {
-        try {
-            return mTag.getTagService().getTimeout(TagTechnology.NFC_A);
-        } catch (RemoteException e) {
-            Log.e(TAG, "NFC service dead", e);
-            return 0;
-        }
-    }
-}
diff --git a/nfc/java/android/nfc/tech/NfcB.java b/nfc/java/android/nfc/tech/NfcB.java
deleted file mode 100644
index 3ebd47f..0000000
--- a/nfc/java/android/nfc/tech/NfcB.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc.tech;
-
-import android.nfc.Tag;
-import android.os.Bundle;
-import android.os.RemoteException;
-
-import java.io.IOException;
-
-/**
- * Provides access to NFC-B (ISO 14443-3B) properties and I/O operations on a {@link Tag}.
- *
- * <p>Acquire a {@link NfcB} object using {@link #get}.
- * <p>The primary NFC-B I/O operation is {@link #transceive}. Applications must
- * implement their own protocol stack on top of {@link #transceive}.
- *
- * <p class="note"><strong>Note:</strong> Methods that perform I/O operations
- * require the {@link android.Manifest.permission#NFC} permission.
- */
-public final class NfcB extends BasicTagTechnology {
-    /** @hide */
-    public static final String EXTRA_APPDATA = "appdata";
-    /** @hide */
-    public static final String EXTRA_PROTINFO = "protinfo";
-
-    private byte[] mAppData;
-    private byte[] mProtInfo;
-
-    /**
-     * Get an instance of {@link NfcB} for the given tag.
-     * <p>Returns null if {@link NfcB} was not enumerated in {@link Tag#getTechList}.
-     * This indicates the tag does not support NFC-B.
-     * <p>Does not cause any RF activity and does not block.
-     *
-     * @param tag an NFC-B compatible tag
-     * @return NFC-B object
-     */
-    public static NfcB get(Tag tag) {
-        if (!tag.hasTech(TagTechnology.NFC_B)) return null;
-        try {
-            return new NfcB(tag);
-        } catch (RemoteException e) {
-            return null;
-        }
-    }
-
-    /** @hide */
-    public NfcB(Tag tag) throws RemoteException {
-        super(tag, TagTechnology.NFC_B);
-        Bundle extras = tag.getTechExtras(TagTechnology.NFC_B);
-        mAppData = extras.getByteArray(EXTRA_APPDATA);
-        mProtInfo = extras.getByteArray(EXTRA_PROTINFO);
-    }
-
-    /**
-     * Return the Application Data bytes from ATQB/SENSB_RES at tag discovery.
-     *
-     * <p>Does not cause any RF activity and does not block.
-     *
-     * @return Application Data bytes from ATQB/SENSB_RES bytes
-     */
-    public byte[] getApplicationData() {
-        return mAppData;
-    }
-
-    /**
-     * Return the Protocol Info bytes from ATQB/SENSB_RES at tag discovery.
-     *
-     * <p>Does not cause any RF activity and does not block.
-     *
-     * @return Protocol Info bytes from ATQB/SENSB_RES bytes
-     */
-    public byte[] getProtocolInfo() {
-        return mProtInfo;
-    }
-
-    /**
-     * Send raw NFC-B commands to the tag and receive the response.
-     *
-     * <p>Applications must not append the EoD (CRC) to the payload,
-     * it will be automatically calculated.
-     * <p>Applications must not send commands that manage the polling
-     * loop and initialization (SENSB_REQ, SLOT_MARKER etc).
-     *
-     * <p>Use {@link #getMaxTransceiveLength} to retrieve the maximum number of bytes
-     * that can be sent with {@link #transceive}.
-     *
-     * <p>This is an I/O operation and will block until complete. It must
-     * not be called from the main application thread. A blocked call will be canceled with
-     * {@link IOException} if {@link #close} is called from another thread.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param data bytes to send
-     * @return bytes received in response
-     * @throws TagLostException if the tag leaves the field
-     * @throws IOException if there is an I/O failure, or this operation is canceled
-     */
-    public byte[] transceive(byte[] data) throws IOException {
-        return transceive(data, true);
-    }
-
-    /**
-     * Return the maximum number of bytes that can be sent with {@link #transceive}.
-     * @return the maximum number of bytes that can be sent with {@link #transceive}.
-     */
-    public int getMaxTransceiveLength() {
-        return getMaxTransceiveLengthInternal();
-    }
-}
diff --git a/nfc/java/android/nfc/tech/NfcBarcode.java b/nfc/java/android/nfc/tech/NfcBarcode.java
deleted file mode 100644
index 421ba78..0000000
--- a/nfc/java/android/nfc/tech/NfcBarcode.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc.tech;
-
-import android.nfc.Tag;
-import android.os.Bundle;
-import android.os.RemoteException;
-
-/**
- * Provides access to tags containing just a barcode.
- *
- * <p>Acquire an {@link NfcBarcode} object using {@link #get}.
- *
- */
-public final class NfcBarcode extends BasicTagTechnology {
-
-    /** Kovio Tags */
-    public static final int TYPE_KOVIO = 1;
-    public static final int TYPE_UNKNOWN = -1;
-
-    /** @hide */
-    public static final String EXTRA_BARCODE_TYPE = "barcodetype";
-
-    private int mType;
-
-    /**
-     * Get an instance of {@link NfcBarcode} for the given tag.
-     *
-     * <p>Returns null if {@link NfcBarcode} was not enumerated in {@link Tag#getTechList}.
-     *
-     * <p>Does not cause any RF activity and does not block.
-     *
-     * @param tag an NfcBarcode compatible tag
-     * @return NfcBarcode object
-     */
-    public static NfcBarcode get(Tag tag) {
-        if (!tag.hasTech(TagTechnology.NFC_BARCODE)) return null;
-        try {
-            return new NfcBarcode(tag);
-        } catch (RemoteException e) {
-            return null;
-        }
-    }
-
-    /**
-     * Internal constructor, to be used by NfcAdapter
-     * @hide
-     */
-    public NfcBarcode(Tag tag) throws RemoteException {
-        super(tag, TagTechnology.NFC_BARCODE);
-        Bundle extras = tag.getTechExtras(TagTechnology.NFC_BARCODE);
-        if (extras != null) {
-            mType = extras.getInt(EXTRA_BARCODE_TYPE);
-        } else {
-            throw new NullPointerException("NfcBarcode tech extras are null.");
-        }
-    }
-
-    /**
-     * Returns the NFC Barcode tag type.
-     *
-     * <p>Currently only one of {@link #TYPE_KOVIO} or {@link #TYPE_UNKNOWN}.
-     *
-     * <p>Does not cause any RF activity and does not block.
-     *
-     * @return the NFC Barcode tag type
-     */
-    public int getType() {
-        return mType;
-    }
-
-    /**
-     * Returns the barcode of an NfcBarcode tag.
-     *
-     * <p> Tags of {@link #TYPE_KOVIO} return 16 bytes:
-     *     <ul>
-     *     <p> The first byte is 0x80 ORd with a manufacturer ID, corresponding
-     *       to ISO/IEC 7816-6.
-     *     <p> The second byte describes the payload data format. Defined data
-     *       format types include the following:<ul>
-     *       <li>0x00: Reserved for manufacturer assignment</li>
-     *       <li>0x01: 96-bit URL with "http://www." prefix</li>
-     *       <li>0x02: 96-bit URL with "https://www." prefix</li>
-     *       <li>0x03: 96-bit URL with "http://" prefix</li>
-     *       <li>0x04: 96-bit URL with "https://" prefix</li>
-     *       <li>0x05: 96-bit GS1 EPC</li>
-     *       <li>0x06-0xFF: reserved</li>
-     *       </ul>
-     *     <p>The following 12 bytes are payload:<ul>
-     *       <li> In case of a URL payload, the payload is encoded in US-ASCII,
-     *            following the limitations defined in RFC3987.
-     *            {@see <a href="http://www.ietf.org/rfc/rfc3987.txt">RFC 3987</a>}</li>
-     *       <li> In case of GS1 EPC data, see <a href="http://www.gs1.org/gsmp/kc/epcglobal/tds/">
-     *            GS1 Electronic Product Code (EPC) Tag Data Standard (TDS)</a> for more details.
-     *       </li>
-     *     </ul>
-     *     <p>The last 2 bytes comprise the CRC.
-     *     </ul>
-     * <p>Does not cause any RF activity and does not block.
-     *
-     * @return a byte array containing the barcode
-     * @see <a href="http://www.thinfilm.no/docs/thinfilm-nfc-barcode-datasheet.pdf">
-     *      Thinfilm NFC Barcode tag specification (previously Kovio NFC Barcode)</a>
-     * @see <a href="http://www.thinfilm.no/docs/thinfilm-nfc-barcode-data-format.pdf">
-     *      Thinfilm NFC Barcode data format (previously Kovio NFC Barcode)</a>
-     */
-    public byte[] getBarcode() {
-        switch (mType) {
-            case TYPE_KOVIO:
-                // For Kovio tags the barcode matches the ID
-                return mTag.getId();
-            default:
-                return null;
-        }
-    }
-}
diff --git a/nfc/java/android/nfc/tech/NfcF.java b/nfc/java/android/nfc/tech/NfcF.java
deleted file mode 100644
index 2ccd388..0000000
--- a/nfc/java/android/nfc/tech/NfcF.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc.tech;
-
-import android.nfc.ErrorCodes;
-import android.nfc.Tag;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.io.IOException;
-
-/**
- * Provides access to NFC-F (JIS 6319-4) properties and I/O operations on a {@link Tag}.
- *
- * <p>Acquire a {@link NfcF} object using {@link #get}.
- * <p>The primary NFC-F I/O operation is {@link #transceive}. Applications must
- * implement their own protocol stack on top of {@link #transceive}.
- *
- * <p class="note"><strong>Note:</strong> Methods that perform I/O operations
- * require the {@link android.Manifest.permission#NFC} permission.
- */
-public final class NfcF extends BasicTagTechnology {
-    private static final String TAG = "NFC";
-
-    /** @hide */
-    public static final String EXTRA_SC = "systemcode";
-    /** @hide */
-    public static final String EXTRA_PMM = "pmm";
-
-    private byte[] mSystemCode = null;
-    private byte[] mManufacturer = null;
-
-    /**
-     * Get an instance of {@link NfcF} for the given tag.
-     * <p>Returns null if {@link NfcF} was not enumerated in {@link Tag#getTechList}.
-     * This indicates the tag does not support NFC-F.
-     * <p>Does not cause any RF activity and does not block.
-     *
-     * @param tag an NFC-F compatible tag
-     * @return NFC-F object
-     */
-    public static NfcF get(Tag tag) {
-        if (!tag.hasTech(TagTechnology.NFC_F)) return null;
-        try {
-            return new NfcF(tag);
-        } catch (RemoteException e) {
-            return null;
-        }
-    }
-
-    /** @hide */
-    public NfcF(Tag tag) throws RemoteException {
-        super(tag, TagTechnology.NFC_F);
-        Bundle extras = tag.getTechExtras(TagTechnology.NFC_F);
-        if (extras != null) {
-            mSystemCode = extras.getByteArray(EXTRA_SC);
-            mManufacturer = extras.getByteArray(EXTRA_PMM);
-        }
-    }
-
-    /**
-     * Return the System Code bytes from tag discovery.
-     *
-     * <p>Does not cause any RF activity and does not block.
-     *
-     * @return System Code bytes
-     */
-    public byte[] getSystemCode() {
-      return mSystemCode;
-    }
-
-    /**
-     * Return the Manufacturer bytes from tag discovery.
-     *
-     * <p>Does not cause any RF activity and does not block.
-     *
-     * @return Manufacturer bytes
-     */
-    public byte[] getManufacturer() {
-      return mManufacturer;
-    }
-
-    /**
-     * Send raw NFC-F commands to the tag and receive the response.
-     *
-     * <p>Applications must not prefix the SoD (preamble and sync code)
-     * and/or append the EoD (CRC) to the payload, it will be automatically calculated.
-     *
-     * <p>A typical NFC-F frame for this method looks like:
-     * <pre>
-     * LENGTH (1 byte) --- CMD (1 byte) -- IDm (8 bytes) -- PARAMS (LENGTH - 10 bytes)
-     * </pre>
-     *
-     * <p>Use {@link #getMaxTransceiveLength} to retrieve the maximum amount of bytes
-     * that can be sent with {@link #transceive}.
-     *
-     * <p>This is an I/O operation and will block until complete. It must
-     * not be called from the main application thread. A blocked call will be canceled with
-     * {@link IOException} if {@link #close} is called from another thread.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param data bytes to send
-     * @return bytes received in response
-     * @throws TagLostException if the tag leaves the field
-     * @throws IOException if there is an I/O failure, or this operation is canceled
-     */
-    public byte[] transceive(byte[] data) throws IOException {
-        return transceive(data, true);
-    }
-
-    /**
-     * Return the maximum number of bytes that can be sent with {@link #transceive}.
-     * @return the maximum number of bytes that can be sent with {@link #transceive}.
-     */
-    public int getMaxTransceiveLength() {
-        return getMaxTransceiveLengthInternal();
-    }
-
-    /**
-     * Set the {@link #transceive} timeout in milliseconds.
-     *
-     * <p>The timeout only applies to {@link #transceive} on this object,
-     * and is reset to a default value when {@link #close} is called.
-     *
-     * <p>Setting a longer timeout may be useful when performing
-     * transactions that require a long processing time on the tag
-     * such as key generation.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param timeout timeout value in milliseconds
-     * @throws SecurityException if the tag object is reused after the tag has left the field
-     */
-    public void setTimeout(int timeout) {
-        try {
-            int err = mTag.getTagService().setTimeout(TagTechnology.NFC_F, timeout);
-            if (err != ErrorCodes.SUCCESS) {
-                throw new IllegalArgumentException("The supplied timeout is not valid");
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "NFC service dead", e);
-        }
-    }
-
-    /**
-     * Get the current {@link #transceive} timeout in milliseconds.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @return timeout value in milliseconds
-     * @throws SecurityException if the tag object is reused after the tag has left the field
-     */
-    public int getTimeout() {
-        try {
-            return mTag.getTagService().getTimeout(TagTechnology.NFC_F);
-        } catch (RemoteException e) {
-            Log.e(TAG, "NFC service dead", e);
-            return 0;
-        }
-    }
-}
diff --git a/nfc/java/android/nfc/tech/NfcV.java b/nfc/java/android/nfc/tech/NfcV.java
deleted file mode 100644
index 186c63b..0000000
--- a/nfc/java/android/nfc/tech/NfcV.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc.tech;
-
-import android.nfc.Tag;
-import android.os.Bundle;
-import android.os.RemoteException;
-
-import java.io.IOException;
-
-/**
- * Provides access to NFC-V (ISO 15693) properties and I/O operations on a {@link Tag}.
- *
- * <p>Acquire a {@link NfcV} object using {@link #get}.
- * <p>The primary NFC-V I/O operation is {@link #transceive}. Applications must
- * implement their own protocol stack on top of {@link #transceive}.
- *
- * <p class="note"><strong>Note:</strong> Methods that perform I/O operations
- * require the {@link android.Manifest.permission#NFC} permission.
- */
-public final class NfcV extends BasicTagTechnology {
-    /** @hide */
-    public static final String EXTRA_RESP_FLAGS = "respflags";
-
-    /** @hide */
-    public static final String EXTRA_DSFID = "dsfid";
-
-    private byte mRespFlags;
-    private byte mDsfId;
-
-    /**
-     * Get an instance of {@link NfcV} for the given tag.
-     * <p>Returns null if {@link NfcV} was not enumerated in {@link Tag#getTechList}.
-     * This indicates the tag does not support NFC-V.
-     * <p>Does not cause any RF activity and does not block.
-     *
-     * @param tag an NFC-V compatible tag
-     * @return NFC-V object
-     */
-    public static NfcV get(Tag tag) {
-        if (!tag.hasTech(TagTechnology.NFC_V)) return null;
-        try {
-            return new NfcV(tag);
-        } catch (RemoteException e) {
-            return null;
-        }
-    }
-
-    /** @hide */
-    public NfcV(Tag tag) throws RemoteException {
-        super(tag, TagTechnology.NFC_V);
-        Bundle extras = tag.getTechExtras(TagTechnology.NFC_V);
-        mRespFlags = extras.getByte(EXTRA_RESP_FLAGS);
-        mDsfId = extras.getByte(EXTRA_DSFID);
-    }
-
-    /**
-     * Return the Response Flag bytes from tag discovery.
-     *
-     * <p>Does not cause any RF activity and does not block.
-     *
-     * @return Response Flag bytes
-     */
-    public byte getResponseFlags() {
-        return mRespFlags;
-    }
-
-    /**
-     * Return the DSF ID bytes from tag discovery.
-     *
-     * <p>Does not cause any RF activity and does not block.
-     *
-     * @return DSF ID bytes
-     */
-    public byte getDsfId() {
-        return mDsfId;
-    }
-
-    /**
-     * Send raw NFC-V commands to the tag and receive the response.
-     *
-     * <p>Applications must not append the CRC to the payload,
-     * it will be automatically calculated. The application does
-     * provide FLAGS, CMD and PARAMETER bytes.
-     *
-     * <p>Use {@link #getMaxTransceiveLength} to retrieve the maximum amount of bytes
-     * that can be sent with {@link #transceive}.
-     *
-     * <p>This is an I/O operation and will block until complete. It must
-     * not be called from the main application thread. A blocked call will be canceled with
-     * {@link IOException} if {@link #close} is called from another thread.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param data bytes to send
-     * @return bytes received in response
-     * @throws TagLostException if the tag leaves the field
-     * @throws IOException if there is an I/O failure, or this operation is canceled
-     */
-    public byte[] transceive(byte[] data) throws IOException {
-        return transceive(data, true);
-    }
-
-
-    /**
-     * Return the maximum number of bytes that can be sent with {@link #transceive}.
-     * @return the maximum number of bytes that can be sent with {@link #transceive}.
-     */
-    public int getMaxTransceiveLength() {
-        return getMaxTransceiveLengthInternal();
-    }
-}
diff --git a/nfc/java/android/nfc/tech/TagTechnology.java b/nfc/java/android/nfc/tech/TagTechnology.java
deleted file mode 100644
index 839fe42..0000000
--- a/nfc/java/android/nfc/tech/TagTechnology.java
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc.tech;
-
-import android.nfc.Tag;
-
-import java.io.Closeable;
-import java.io.IOException;
-
-/**
- * {@link TagTechnology} is an interface to a technology in a {@link Tag}.
- * <p>
- * Obtain a {@link TagTechnology} implementation by calling the static method <code>get()</code>
- * on the implementation class.
- * <p>
- * NFC tags are based on a number of independently developed technologies and offer a
- * wide range of capabilities. The
- * {@link TagTechnology} implementations provide access to these different
- * technologies and capabilities. Some sub-classes map to technology
- * specification (for example {@link NfcA}, {@link IsoDep}, others map to
- * pseudo-technologies or capabilities (for example {@link Ndef}, {@link NdefFormatable}).
- * <p>
- * It is mandatory for all Android NFC devices to provide the following
- * {@link TagTechnology} implementations.
- * <ul>
- * <li>{@link NfcA} (also known as ISO 14443-3A)
- * <li>{@link NfcB} (also known as ISO 14443-3B)
- * <li>{@link NfcF} (also known as JIS 6319-4)
- * <li>{@link NfcV} (also known as ISO 15693)
- * <li>{@link IsoDep}
- * <li>{@link Ndef} on NFC Forum Type 1, Type 2, Type 3 or Type 4 compliant tags
- * </ul>
- * It is optional for Android NFC devices to provide the following
- * {@link TagTechnology} implementations. If it is not provided, the
- * Android device will never enumerate that class via {@link Tag#getTechList}.
- * <ul>
- * <li>{@link MifareClassic}
- * <li>{@link MifareUltralight}
- * <li>{@link NfcBarcode}
- * <li>{@link NdefFormatable} must only be enumerated on tags for which this Android device
- * is capable of formatting. Proprietary knowledge is often required to format a tag
- * to make it NDEF compatible.
- * </ul>
- * <p>
- * {@link TagTechnology} implementations provide methods that fall into two classes:
- * <em>cached getters</em> and <em>I/O operations</em>.
- * <h4>Cached getters</h4>
- * These methods (usually prefixed by <code>get</code> or <code>is</code>) return
- * properties of the tag, as determined at discovery time. These methods will never
- * block or cause RF activity, and do not require {@link #connect} to have been called.
- * They also never update, for example if a property is changed by an I/O operation with a tag
- * then the cached getter will still return the result from tag discovery time.
- * <h4>I/O operations</h4>
- * I/O operations may require RF activity, and may block. They have the following semantics.
- * <ul>
- * <li>{@link #connect} must be called before using any other I/O operation.
- * <li>{@link #close} must be called after completing I/O operations with a
- * {@link TagTechnology}, and it will cancel all other blocked I/O operations on other threads
- * (including {@link #connect} with {@link IOException}.
- * <li>Only one {@link TagTechnology} can be connected at a time. Other calls to
- * {@link #connect} will return {@link IOException}.
- * <li>I/O operations may block, and should never be called on the main application
- * thread.
- * </ul>
- *
- * <p class="note"><strong>Note:</strong> Methods that perform I/O operations
- * require the {@link android.Manifest.permission#NFC} permission.
- */
-public interface TagTechnology extends Closeable {
-    /**
-     * This technology is an instance of {@link NfcA}.
-     * <p>Support for this technology type is mandatory.
-     * @hide
-     */
-    public static final int NFC_A = 1;
-
-    /**
-     * This technology is an instance of {@link NfcB}.
-     * <p>Support for this technology type is mandatory.
-     * @hide
-     */
-    public static final int NFC_B = 2;
-
-    /**
-     * This technology is an instance of {@link IsoDep}.
-     * <p>Support for this technology type is mandatory.
-     * @hide
-     */
-    public static final int ISO_DEP = 3;
-
-    /**
-     * This technology is an instance of {@link NfcF}.
-     * <p>Support for this technology type is mandatory.
-     * @hide
-     */
-    public static final int NFC_F = 4;
-
-    /**
-     * This technology is an instance of {@link NfcV}.
-     * <p>Support for this technology type is mandatory.
-     * @hide
-     */
-    public static final int NFC_V = 5;
-
-    /**
-     * This technology is an instance of {@link Ndef}.
-     * <p>Support for this technology type is mandatory.
-     * @hide
-     */
-    public static final int NDEF = 6;
-
-    /**
-     * This technology is an instance of {@link NdefFormatable}.
-     * <p>Support for this technology type is mandatory.
-     * @hide
-     */
-    public static final int NDEF_FORMATABLE = 7;
-
-    /**
-     * This technology is an instance of {@link MifareClassic}.
-     * <p>Support for this technology type is optional. If a stack doesn't support this technology
-     * type tags using it must still be discovered and present the lower level radio interface
-     * technologies in use.
-     * @hide
-     */
-    public static final int MIFARE_CLASSIC = 8;
-
-    /**
-     * This technology is an instance of {@link MifareUltralight}.
-     * <p>Support for this technology type is optional. If a stack doesn't support this technology
-     * type tags using it must still be discovered and present the lower level radio interface
-     * technologies in use.
-     * @hide
-     */
-    public static final int MIFARE_ULTRALIGHT = 9;
-
-    /**
-     * This technology is an instance of {@link NfcBarcode}.
-     * <p>Support for this technology type is optional. If a stack doesn't support this technology
-     * type tags using it must still be discovered and present the lower level radio interface
-     * technologies in use.
-     * @hide
-     */
-    public static final int NFC_BARCODE = 10;
-
-    /**
-     * Get the {@link Tag} object backing this {@link TagTechnology} object.
-     * @return the {@link Tag} backing this {@link TagTechnology} object.
-     */
-    public Tag getTag();
-
-    /**
-     * Enable I/O operations to the tag from this {@link TagTechnology} object.
-     * <p>May cause RF activity and may block. Must not be called
-     * from the main application thread. A blocked call will be canceled with
-     * {@link IOException} by calling {@link #close} from another thread.
-     * <p>Only one {@link TagTechnology} object can be connected to a {@link Tag} at a time.
-     * <p>Applications must call {@link #close} when I/O operations are complete.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @see #close()
-     * @throws TagLostException if the tag leaves the field
-     * @throws IOException if there is an I/O failure, or connect is canceled
-     * @throws SecurityException if the tag object is reused after the tag has left the field
-     */
-    public void connect() throws IOException;
-
-    /**
-     * Re-connect to the {@link Tag} associated with this connection. Reconnecting to a tag can be
-     * used to reset the state of the tag itself.
-     *
-     * <p>May cause RF activity and may block. Must not be called
-     * from the main application thread. A blocked call will be canceled with
-     * {@link IOException} by calling {@link #close} from another thread.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @see #connect()
-     * @see #close()
-     * @throws TagLostException if the tag leaves the field
-     * @throws IOException if there is an I/O failure, or connect is canceled
-     * @throws SecurityException if the tag object is reused after the tag has left the field
-     * @hide
-     */
-    public void reconnect() throws IOException;
-
-    /**
-     * Disable I/O operations to the tag from this {@link TagTechnology} object, and release resources.
-     * <p>Also causes all blocked I/O operations on other thread to be canceled and
-     * return with {@link IOException}.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @see #connect()
-     * @throws SecurityException if the tag object is reused after the tag has left the field
-     */
-    public void close() throws IOException;
-
-    /**
-     * Helper to indicate if I/O operations should be possible.
-     *
-     * <p>Returns true if {@link #connect} has completed, and {@link #close} has not been
-     * called, and the {@link Tag} is not known to be out of range.
-     * <p>Does not cause RF activity, and does not block.
-     *
-     * @return true if I/O operations should be possible
-     */
-    public boolean isConnected();
-}
diff --git a/nfc/java/android/nfc/tech/package.html b/nfc/java/android/nfc/tech/package.html
deleted file mode 100644
index a99828f..0000000
--- a/nfc/java/android/nfc/tech/package.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<HTML>
-<BODY>
-<p>
-These classes provide access to a tag technology's features, which vary by the type
-of tag that is scanned. A scanned tag can support multiple technologies, and you can find
-out what they are by calling {@link android.nfc.Tag#getTechList getTechList()}.</p>
-
-<p>For more information on dealing with tag technologies and handling the ones that you care about, see
-<a href="{@docRoot}guide/topics/nfc/index.html#dispatch">The Tag Dispatch System</a>.
-The {@link android.nfc.tech.TagTechnology} interface provides an overview of the
-supported technologies.</p>
-</BODY>
-</HTML>
diff --git a/nfc/lint-baseline.xml b/nfc/lint-baseline.xml
deleted file mode 100644
index 67b496e..0000000
--- a/nfc/lint-baseline.xml
+++ /dev/null
@@ -1,81 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.4.0-alpha01" type="baseline" client="" dependencies="true" name="" variant="all" version="8.4.0-alpha01">
-
-    <issue
-        id="FlaggedApi"
-        message="Method `NfcOemExtension()` is a flagged API and should be inside an `if (Flags.nfcOemExtension())` check (or annotate the surrounding method `NfcAdapter` with `@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION) to transfer requirement to caller`)"
-        errorLine1="        mNfcOemExtension = new NfcOemExtension(mContext, this);"
-        errorLine2="                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/nfc/java/android/nfc/NfcAdapter.java"
-            line="909"
-            column="28"/>
-    </issue>
-
-    <issue
-        id="FlaggedApi"
-        message="Field `FLAG_SET_DEFAULT_TECH` is a flagged API and should be inside an `if (Flags.nfcSetDefaultDiscTech())` check (or annotate the surrounding method `setDiscoveryTechnology` with `@FlaggedApi(Flags.FLAG_NFC_SET_DEFAULT_DISC_TECH) to transfer requirement to caller`)"
-        errorLine1="                &amp;&amp; ((pollTechnology &amp; FLAG_SET_DEFAULT_TECH) == FLAG_SET_DEFAULT_TECH"
-        errorLine2="                                      ~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/nfc/java/android/nfc/NfcAdapter.java"
-            line="1917"
-            column="39"/>
-    </issue>
-
-    <issue
-        id="FlaggedApi"
-        message="Field `FLAG_SET_DEFAULT_TECH` is a flagged API and should be inside an `if (Flags.nfcSetDefaultDiscTech())` check (or annotate the surrounding method `setDiscoveryTechnology` with `@FlaggedApi(Flags.FLAG_NFC_SET_DEFAULT_DISC_TECH) to transfer requirement to caller`)"
-        errorLine1="                &amp;&amp; ((pollTechnology &amp; FLAG_SET_DEFAULT_TECH) == FLAG_SET_DEFAULT_TECH"
-        errorLine2="                                                                ~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/nfc/java/android/nfc/NfcAdapter.java"
-            line="1917"
-            column="65"/>
-    </issue>
-
-    <issue
-        id="FlaggedApi"
-        message="Field `FLAG_SET_DEFAULT_TECH` is a flagged API and should be inside an `if (Flags.nfcSetDefaultDiscTech())` check (or annotate the surrounding method `setDiscoveryTechnology` with `@FlaggedApi(Flags.FLAG_NFC_SET_DEFAULT_DISC_TECH) to transfer requirement to caller`)"
-        errorLine1="                || (listenTechnology &amp; FLAG_SET_DEFAULT_TECH) == FLAG_SET_DEFAULT_TECH)) {"
-        errorLine2="                                       ~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/nfc/java/android/nfc/NfcAdapter.java"
-            line="1918"
-            column="40"/>
-    </issue>
-
-    <issue
-        id="FlaggedApi"
-        message="Field `FLAG_SET_DEFAULT_TECH` is a flagged API and should be inside an `if (Flags.nfcSetDefaultDiscTech())` check (or annotate the surrounding method `setDiscoveryTechnology` with `@FlaggedApi(Flags.FLAG_NFC_SET_DEFAULT_DISC_TECH) to transfer requirement to caller`)"
-        errorLine1="                || (listenTechnology &amp; FLAG_SET_DEFAULT_TECH) == FLAG_SET_DEFAULT_TECH)) {"
-        errorLine2="                                                                 ~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/nfc/java/android/nfc/NfcAdapter.java"
-            line="1918"
-            column="66"/>
-    </issue>
-
-    <issue
-        id="FlaggedApi"
-        message="Method `onVendorNciResponse()` is a flagged API and should be inside an `if (Flags.nfcVendorCmd())` check (or annotate the surrounding method `onVendorResponseReceived` with `@FlaggedApi(Flags.FLAG_NFC_VENDOR_CMD) to transfer requirement to caller`)"
-        errorLine1="                    executor.execute(() -> callback.onVendorNciResponse(gid, oid, payload));"
-        errorLine2="                                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/nfc/java/android/nfc/NfcVendorNciCallbackListener.java"
-            line="88"
-            column="44"/>
-    </issue>
-
-    <issue
-        id="FlaggedApi"
-        message="Method `onVendorNciNotification()` is a flagged API and should be inside an `if (Flags.nfcVendorCmd())` check (or annotate the surrounding method `onVendorNotificationReceived` with `@FlaggedApi(Flags.FLAG_NFC_VENDOR_CMD) to transfer requirement to caller`)"
-        errorLine1="                    executor.execute(() -> callback.onVendorNciNotification(gid, oid, payload));"
-        errorLine2="                                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/nfc/java/android/nfc/NfcVendorNciCallbackListener.java"
-            line="106"
-            column="44"/>
-    </issue>
-
-</issues>
diff --git a/nfc/tests/Android.bp b/nfc/tests/Android.bp
deleted file mode 100644
index 17fb810..0000000
--- a/nfc/tests/Android.bp
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2021 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package {
-    default_team: "trendy_team_fwk_nfc",
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "frameworks_base_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["frameworks_base_license"],
-}
-
-android_test {
-    name: "NfcManagerTests",
-    static_libs: [
-        "androidx.test.core",
-        "androidx.test.rules",
-        "androidx.test.runner",
-        "androidx.test.ext.junit",
-        "mockito-target-extended-minus-junit4",
-        "frameworks-base-testutils",
-        "truth",
-        "androidx.annotation_annotation",
-        "androidx.appcompat_appcompat",
-        "flag-junit",
-        "platform-test-annotations",
-        "testables",
-    ],
-    libs: [
-        "androidx.annotation_annotation",
-        "unsupportedappusage", // for android.compat.annotation.UnsupportedAppUsage
-        "framework-permission-s.stubs.module_lib",
-        "framework-permission.stubs.module_lib",
-        "android.test.base.stubs.system",
-        "android.test.mock.stubs.system",
-        "android.test.runner.stubs.system",
-        "framework-nfc.impl",
-    ],
-    jni_libs: [
-        // Required for ExtendedMockito
-        "libdexmakerjvmtiagent",
-        "libstaticjvmtiagent",
-    ],
-    srcs: [
-        "src/**/*.java",
-        ":framework-nfc-updatable-sources",
-        ":framework-nfc-non-updatable-sources",
-    ],
-    platform_apis: true,
-    certificate: "platform",
-    test_suites: [
-        "device-tests",
-        "mts-nfc",
-    ],
-    min_sdk_version: "35", // Should be 36 later.
-}
diff --git a/nfc/tests/AndroidManifest.xml b/nfc/tests/AndroidManifest.xml
deleted file mode 100644
index 9564672..0000000
--- a/nfc/tests/AndroidManifest.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2021 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.nfc">
-
-    <application android:debuggable="true">
-        <uses-library android:name="android.test.runner" />
-    </application>
-
-    <!-- This is a self-instrumenting test package. -->
-    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="android.nfc"
-                     android:label="NFC Manager Tests">
-    </instrumentation>
-
-</manifest>
-
diff --git a/nfc/tests/AndroidTest.xml b/nfc/tests/AndroidTest.xml
deleted file mode 100644
index 490d6f5..0000000
--- a/nfc/tests/AndroidTest.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2021 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<configuration description="Config for NFC Manager test cases">
-    <option name="test-suite-tag" value="apct"/>
-    <option name="test-suite-tag" value="apct-instrumentation"/>
-    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
-        <option name="cleanup-apks" value="true" />
-        <option name="test-file-name" value="NfcManagerTests.apk" />
-    </target_preparer>
-
-    <option name="test-suite-tag" value="apct"/>
-    <option name="test-tag" value="NfcManagerTests"/>
-
-    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
-        <option name="package" value="android.nfc" />
-        <option name="hidden-api-checks" value="false"/>
-        <option name="runner" value="androidx.test.runner.AndroidJUnitRunner"/>
-    </test>
-</configuration>
diff --git a/nfc/tests/src/android/nfc/NdefMessageTest.java b/nfc/tests/src/android/nfc/NdefMessageTest.java
deleted file mode 100644
index 9ca295d..0000000
--- a/nfc/tests/src/android/nfc/NdefMessageTest.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-public class NdefMessageTest {
-    private NdefMessage mNdefMessage;
-    private NdefRecord mNdefRecord;
-
-    @Before
-    public void setUp() {
-        mNdefRecord = NdefRecord.createUri("http://www.example.com");
-        mNdefMessage = new NdefMessage(mNdefRecord);
-    }
-
-    @After
-    public void tearDown() {
-    }
-
-    @Test
-    public void testGetRecords() {
-        NdefRecord[] records = mNdefMessage.getRecords();
-        assertThat(records).isNotNull();
-        assertThat(records).hasLength(1);
-        assertThat(records[0]).isEqualTo(mNdefRecord);
-    }
-
-    @Test
-    public void testToByteArray() throws FormatException {
-        byte[] bytes = mNdefMessage.toByteArray();
-        assertThat(bytes).isNotNull();
-        assertThat(bytes.length).isGreaterThan(0);
-        NdefMessage ndefMessage = new NdefMessage(bytes);
-        assertThat(ndefMessage).isNotNull();
-    }
-}
diff --git a/nfc/tests/src/android/nfc/NdefRecordTest.java b/nfc/tests/src/android/nfc/NdefRecordTest.java
deleted file mode 100644
index 044c674..0000000
--- a/nfc/tests/src/android/nfc/NdefRecordTest.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.Locale;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class NdefRecordTest {
-
-    @Test
-    public void testNdefRecordConstructor() throws FormatException {
-        NdefRecord applicationRecord = NdefRecord
-                .createApplicationRecord("com.android.test");
-        NdefRecord ndefRecord = new NdefRecord(applicationRecord.toByteArray());
-        assertThat(ndefRecord).isNotNull();
-        assertThat(ndefRecord.toByteArray().length).isGreaterThan(0);
-        assertThat(ndefRecord.getType()).isEqualTo("android.com:pkg".getBytes());
-        assertThat(ndefRecord.getPayload()).isEqualTo("com.android.test".getBytes());
-    }
-
-    @Test
-    public void testCreateExternal() {
-        NdefRecord ndefRecord = NdefRecord.createExternal("test",
-                "android.com:pkg", "com.android.test".getBytes());
-        assertThat(ndefRecord).isNotNull();
-        assertThat(ndefRecord.getType()).isEqualTo("test:android.com:pkg".getBytes());
-        assertThat(ndefRecord.getPayload()).isEqualTo("com.android.test".getBytes());
-    }
-
-    @Test
-    public void testCreateUri() {
-        NdefRecord ndefRecord = NdefRecord.createUri("http://www.example.com");
-        assertThat(ndefRecord).isNotNull();
-        assertThat(ndefRecord.getTnf()).isEqualTo(NdefRecord.TNF_WELL_KNOWN);
-        assertThat(ndefRecord.getType()).isEqualTo(NdefRecord.RTD_URI);
-    }
-
-    @Test
-    public void testCreateMime() {
-        NdefRecord ndefRecord = NdefRecord.createMime("text/plain", "example".getBytes());
-        assertThat(ndefRecord).isNotNull();
-        assertThat(ndefRecord.getTnf()).isEqualTo(NdefRecord.TNF_MIME_MEDIA);
-    }
-
-    @Test
-    public void testCreateTextRecord() {
-        String languageCode = Locale.getDefault().getLanguage();
-        NdefRecord ndefRecord = NdefRecord.createTextRecord(languageCode, "testdata");
-        assertThat(ndefRecord).isNotNull();
-        assertThat(ndefRecord.getTnf()).isEqualTo(NdefRecord.TNF_WELL_KNOWN);
-        assertThat(ndefRecord.getType()).isEqualTo(NdefRecord.RTD_TEXT);
-    }
-
-}
diff --git a/nfc/tests/src/android/nfc/NfcAntennaInfoTest.java b/nfc/tests/src/android/nfc/NfcAntennaInfoTest.java
deleted file mode 100644
index c24816d..0000000
--- a/nfc/tests/src/android/nfc/NfcAntennaInfoTest.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.mock;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.ArrayList;
-import java.util.List;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class NfcAntennaInfoTest {
-    private NfcAntennaInfo mNfcAntennaInfo;
-
-
-    @Before
-    public void setUp() {
-        AvailableNfcAntenna availableNfcAntenna = mock(AvailableNfcAntenna.class);
-        List<AvailableNfcAntenna> antennas = new ArrayList<>();
-        antennas.add(availableNfcAntenna);
-        mNfcAntennaInfo = new NfcAntennaInfo(1, 1, false, antennas);
-    }
-
-    @After
-    public void tearDown() {
-    }
-
-    @Test
-    public void testGetDeviceHeight() {
-        int height = mNfcAntennaInfo.getDeviceHeight();
-        assertThat(height).isEqualTo(1);
-    }
-
-    @Test
-    public void testGetDeviceWidth() {
-        int width = mNfcAntennaInfo.getDeviceWidth();
-        assertThat(width).isEqualTo(1);
-    }
-
-    @Test
-    public void testIsDeviceFoldable() {
-        boolean foldable = mNfcAntennaInfo.isDeviceFoldable();
-        assertThat(foldable).isFalse();
-    }
-
-    @Test
-    public void testGetAvailableNfcAntennas() {
-        List<AvailableNfcAntenna> antennas = mNfcAntennaInfo.getAvailableNfcAntennas();
-        assertThat(antennas).isNotNull();
-        assertThat(antennas.size()).isEqualTo(1);
-    }
-
-}
diff --git a/nfc/tests/src/android/nfc/NfcControllerAlwaysOnListenerTest.java b/nfc/tests/src/android/nfc/NfcControllerAlwaysOnListenerTest.java
deleted file mode 100644
index 48f4288..0000000
--- a/nfc/tests/src/android/nfc/NfcControllerAlwaysOnListenerTest.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import android.nfc.NfcAdapter.ControllerAlwaysOnListener;
-import android.os.RemoteException;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.Executor;
-
-/**
- * Test of {@link NfcControllerAlwaysOnListener}.
- */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class NfcControllerAlwaysOnListenerTest {
-
-    private INfcAdapter mNfcAdapter = mock(INfcAdapter.class);
-
-    private Throwable mThrowRemoteException = new RemoteException("RemoteException");
-
-    private static Executor getExecutor() {
-        return new Executor() {
-            @Override
-            public void execute(Runnable command) {
-                command.run();
-            }
-        };
-    }
-
-    private static void verifyListenerInvoked(ControllerAlwaysOnListener listener) {
-        verify(listener, times(1)).onControllerAlwaysOnChanged(anyBoolean());
-    }
-
-    @Test
-    public void testRegister_RegisterUnregisterWhenNotSupported() throws RemoteException {
-        // isControllerAlwaysOnSupported() returns false, not supported.
-        doReturn(false).when(mNfcAdapter).isControllerAlwaysOnSupported();
-        NfcControllerAlwaysOnListener mListener =
-                new NfcControllerAlwaysOnListener(mNfcAdapter);
-        ControllerAlwaysOnListener mockListener1 = mock(ControllerAlwaysOnListener.class);
-        ControllerAlwaysOnListener mockListener2 = mock(ControllerAlwaysOnListener.class);
-
-        // Verify that the state listener will not registered with the NFC Adapter
-        mListener.register(getExecutor(), mockListener1);
-        verify(mNfcAdapter, times(0)).registerControllerAlwaysOnListener(any());
-
-        // Register a second client and no any call to NFC Adapter
-        mListener.register(getExecutor(), mockListener2);
-        verify(mNfcAdapter, times(0)).registerControllerAlwaysOnListener(any());
-
-        // Unregister first listener, and no any call to NFC Adapter
-        mListener.unregister(mockListener1);
-        verify(mNfcAdapter, times(0)).registerControllerAlwaysOnListener(any());
-        verify(mNfcAdapter, times(0)).unregisterControllerAlwaysOnListener(any());
-
-        // Unregister second listener, and no any call to NFC Adapter
-        mListener.unregister(mockListener2);
-        verify(mNfcAdapter, times(0)).registerControllerAlwaysOnListener(any());
-        verify(mNfcAdapter, times(0)).unregisterControllerAlwaysOnListener(any());
-    }
-
-    @Test
-    public void testRegister_RegisterUnregister() throws RemoteException {
-        doReturn(true).when(mNfcAdapter).isControllerAlwaysOnSupported();
-        NfcControllerAlwaysOnListener mListener =
-                new NfcControllerAlwaysOnListener(mNfcAdapter);
-        ControllerAlwaysOnListener mockListener1 = mock(ControllerAlwaysOnListener.class);
-        ControllerAlwaysOnListener mockListener2 = mock(ControllerAlwaysOnListener.class);
-
-        // Verify that the state listener registered with the NFC Adapter
-        mListener.register(getExecutor(), mockListener1);
-        verify(mNfcAdapter, times(1)).registerControllerAlwaysOnListener(any());
-
-        // Register a second client and no new call to NFC Adapter
-        mListener.register(getExecutor(), mockListener2);
-        verify(mNfcAdapter, times(1)).registerControllerAlwaysOnListener(any());
-
-        // Unregister first listener
-        mListener.unregister(mockListener1);
-        verify(mNfcAdapter, times(1)).registerControllerAlwaysOnListener(any());
-        verify(mNfcAdapter, times(0)).unregisterControllerAlwaysOnListener(any());
-
-        // Unregister second listener and the state listener registered with the NFC Adapter
-        mListener.unregister(mockListener2);
-        verify(mNfcAdapter, times(1)).registerControllerAlwaysOnListener(any());
-        verify(mNfcAdapter, times(1)).unregisterControllerAlwaysOnListener(any());
-    }
-
-    @Test
-    public void testRegister_FirstRegisterFails() throws RemoteException {
-        doReturn(true).when(mNfcAdapter).isControllerAlwaysOnSupported();
-        NfcControllerAlwaysOnListener mListener =
-                new NfcControllerAlwaysOnListener(mNfcAdapter);
-        ControllerAlwaysOnListener mockListener1 = mock(ControllerAlwaysOnListener.class);
-        ControllerAlwaysOnListener mockListener2 = mock(ControllerAlwaysOnListener.class);
-
-        // Throw a remote exception whenever first registering
-        doThrow(mThrowRemoteException).when(mNfcAdapter).registerControllerAlwaysOnListener(
-                any());
-
-        mListener.register(getExecutor(), mockListener1);
-        verify(mNfcAdapter, times(1)).registerControllerAlwaysOnListener(any());
-
-        // No longer throw an exception, instead succeed
-        doNothing().when(mNfcAdapter).registerControllerAlwaysOnListener(any());
-
-        // Register a different listener
-        mListener.register(getExecutor(), mockListener2);
-        verify(mNfcAdapter, times(2)).registerControllerAlwaysOnListener(any());
-
-        // Ensure first and second listener were invoked
-        mListener.onControllerAlwaysOnChanged(true);
-        verifyListenerInvoked(mockListener1);
-        verifyListenerInvoked(mockListener2);
-    }
-
-    @Test
-    public void testRegister_RegisterSameListenerTwice() throws RemoteException {
-        doReturn(true).when(mNfcAdapter).isControllerAlwaysOnSupported();
-        NfcControllerAlwaysOnListener mListener =
-                new NfcControllerAlwaysOnListener(mNfcAdapter);
-        ControllerAlwaysOnListener mockListener = mock(ControllerAlwaysOnListener.class);
-
-        // Register the same listener Twice
-        mListener.register(getExecutor(), mockListener);
-        mListener.register(getExecutor(), mockListener);
-        verify(mNfcAdapter, times(1)).registerControllerAlwaysOnListener(any());
-
-        // Invoke a state change and ensure the listener is only called once
-        mListener.onControllerAlwaysOnChanged(true);
-        verifyListenerInvoked(mockListener);
-    }
-
-    @Test
-    public void testNotify_AllListenersNotified() throws RemoteException {
-        doReturn(true).when(mNfcAdapter).isControllerAlwaysOnSupported();
-        NfcControllerAlwaysOnListener listener = new NfcControllerAlwaysOnListener(mNfcAdapter);
-        List<ControllerAlwaysOnListener> mockListeners = new ArrayList<>();
-        for (int i = 0; i < 10; i++) {
-            ControllerAlwaysOnListener mockListener = mock(ControllerAlwaysOnListener.class);
-            listener.register(getExecutor(), mockListener);
-            mockListeners.add(mockListener);
-        }
-
-        // Invoke a state change and ensure all listeners are invoked
-        listener.onControllerAlwaysOnChanged(true);
-        for (ControllerAlwaysOnListener mListener : mockListeners) {
-            verifyListenerInvoked(mListener);
-        }
-    }
-
-    @Test
-    public void testStateChange_CorrectValue() throws RemoteException {
-        doReturn(true).when(mNfcAdapter).isControllerAlwaysOnSupported();
-        runStateChangeValue(true, true);
-        runStateChangeValue(false, false);
-
-    }
-
-    private void runStateChangeValue(boolean isEnabledIn, boolean isEnabledOut) {
-        NfcControllerAlwaysOnListener listener = new NfcControllerAlwaysOnListener(mNfcAdapter);
-        ControllerAlwaysOnListener mockListener = mock(ControllerAlwaysOnListener.class);
-        listener.register(getExecutor(), mockListener);
-        listener.onControllerAlwaysOnChanged(isEnabledIn);
-        verify(mockListener, times(1)).onControllerAlwaysOnChanged(isEnabledOut);
-        verify(mockListener, times(0)).onControllerAlwaysOnChanged(!isEnabledOut);
-    }
-}
diff --git a/nfc/tests/src/android/nfc/NfcManagerTest.java b/nfc/tests/src/android/nfc/NfcManagerTest.java
deleted file mode 100644
index 06314cc..0000000
--- a/nfc/tests/src/android/nfc/NfcManagerTest.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-
-import com.android.dx.mockito.inline.extended.ExtendedMockito;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.mockito.MockitoSession;
-import org.mockito.quality.Strictness;
-
-@RunWith(AndroidJUnit4.class)
-public class NfcManagerTest {
-
-    private MockitoSession mMockitoSession;
-    private NfcManager mNfcManager;
-    @Mock
-    private Context mContext;
-
-    @Before
-    public void setUp() {
-        mMockitoSession = ExtendedMockito.mockitoSession()
-                .mockStatic(NfcAdapter.class)
-                .strictness(Strictness.LENIENT)
-                .startMocking();
-        MockitoAnnotations.initMocks(this);
-
-        when(NfcAdapter.getNfcAdapter(any())).thenReturn(mock(NfcAdapter.class));
-        when(mContext.getApplicationContext()).thenReturn(mContext);
-        mNfcManager = new NfcManager(mContext);
-    }
-
-    @After
-    public void tearDown() {
-        mMockitoSession.finishMocking();
-    }
-
-    @Test
-    public void testGetDefaultAdapter() {
-        NfcAdapter nfcAdapter = mNfcManager.getDefaultAdapter();
-        assertThat(nfcAdapter).isNotNull();
-    }
-}
diff --git a/nfc/tests/src/android/nfc/NfcRoutingTableEntryTest.java b/nfc/tests/src/android/nfc/NfcRoutingTableEntryTest.java
deleted file mode 100644
index a90a716..0000000
--- a/nfc/tests/src/android/nfc/NfcRoutingTableEntryTest.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public final class NfcRoutingTableEntryTest {
-
-    @Test
-    public void testAidEntry_GetAid() {
-        String expectedAid = "A00000061A02";
-        RoutingTableAidEntry entry = new RoutingTableAidEntry(1, expectedAid, 0);
-
-        assertEquals(expectedAid, entry.getAid());
-    }
-
-    @Test
-    public void testProtocolEntry_GetProtocol() {
-        RoutingTableProtocolEntry entry =
-                new RoutingTableProtocolEntry(1, RoutingTableProtocolEntry.PROTOCOL_T1T, 0);
-
-        assertEquals(RoutingTableProtocolEntry.PROTOCOL_T1T, entry.getProtocol());
-    }
-
-    @Test
-    public void testSystemCodeEntry_GetSystemCode() {
-        byte[] expectedSystemCode = {0x01, 0x02, 0x03};
-        RoutingTableSystemCodeEntry entry =
-                new RoutingTableSystemCodeEntry(1, expectedSystemCode, 0);
-
-        assertArrayEquals(expectedSystemCode, entry.getSystemCode());
-    }
-
-    @Test
-    public void testTechnologyEntry_GetTechnology_A() {
-        RoutingTableTechnologyEntry entry =
-                new RoutingTableTechnologyEntry(1, RoutingTableTechnologyEntry.TECHNOLOGY_A, 0);
-
-        assertEquals(RoutingTableTechnologyEntry.TECHNOLOGY_A, entry.getTechnology());
-    }
-}
diff --git a/nfc/tests/src/android/nfc/OemLogItemsTest.java b/nfc/tests/src/android/nfc/OemLogItemsTest.java
deleted file mode 100644
index 21ef804..0000000
--- a/nfc/tests/src/android/nfc/OemLogItemsTest.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.mock;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-import java.time.Instant;
-
-@RunWith(JUnit4.class)
-public final class OemLogItemsTest {
-
-    @Test
-    public void testGetAction() {
-        OemLogItems item = new OemLogItems.Builder(OemLogItems.LOG_ACTION_RF_FIELD_STATE_CHANGED)
-                .build();
-        assertEquals(OemLogItems.LOG_ACTION_RF_FIELD_STATE_CHANGED, item.getAction());
-    }
-
-    @Test
-    public void testGetEvent() {
-        OemLogItems item = new OemLogItems.Builder(OemLogItems.LOG_ACTION_NFC_TOGGLE)
-                .setCallingEvent(OemLogItems.EVENT_ENABLE)
-                .build();
-        assertEquals(OemLogItems.EVENT_ENABLE, item.getEvent());
-    }
-
-    @Test
-    public void testGetCallingPid() {
-        OemLogItems item = new OemLogItems.Builder(OemLogItems.LOG_ACTION_NFC_TOGGLE)
-                .setCallingPid(1234)
-                .build();
-        assertEquals(1234, item.getCallingPid());
-    }
-
-    @Test
-    public void testGetCommandApdu() {
-        byte[] commandApdu = {0x01, 0x02, 0x03};
-        OemLogItems item = new OemLogItems.Builder(OemLogItems.LOG_ACTION_HCE_DATA)
-                .setApduCommand(commandApdu)
-                .build();
-        assertArrayEquals(commandApdu, item.getCommandApdu());
-    }
-
-    @Test
-    public void testGetResponseApdu() {
-        byte[] responseApdu = {0x04, 0x05, 0x06};
-        OemLogItems item = new OemLogItems.Builder(OemLogItems.LOG_ACTION_HCE_DATA)
-                .setApduResponse(responseApdu)
-                .build();
-        assertArrayEquals(responseApdu, item.getResponseApdu());
-    }
-
-    @Test
-    public void testGetRfFieldEventTimeMillis() {
-        Instant expectedTime = Instant.ofEpochSecond(1688768000, 123456789);
-        OemLogItems item = new OemLogItems.Builder(OemLogItems.LOG_ACTION_RF_FIELD_STATE_CHANGED)
-                .setRfFieldOnTime(expectedTime)
-                .build();
-        assertEquals(expectedTime, item.getRfFieldEventTimeMillis());
-    }
-
-    @Test
-    public void testGetTag() {
-        Tag mockTag = mock(Tag.class);
-        OemLogItems item = new OemLogItems.Builder(OemLogItems.LOG_ACTION_TAG_DETECTED)
-                .setTag(mockTag)
-                .build();
-        assertEquals(mockTag, item.getTag());
-    }
-}
diff --git a/nfc/tests/src/android/nfc/TechListParcelTest.java b/nfc/tests/src/android/nfc/TechListParcelTest.java
deleted file mode 100644
index a12bbbc..0000000
--- a/nfc/tests/src/android/nfc/TechListParcelTest.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.os.Parcel;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.Arrays;
-
-@RunWith(AndroidJUnit4.class)
-public class TechListParcelTest {
-
-    private static final String[] TECH_LIST_1 = new String[] { "tech1.1", "tech1.2" };
-    private static final String[] TECH_LIST_2 = new String[] { "tech2.1" };
-    private static final String[] TECH_LIST_EMPTY = new String[] {};
-
-    @Test
-    public void testWriteParcel() {
-        TechListParcel techListParcel = new TechListParcel(TECH_LIST_1, TECH_LIST_2);
-
-        Parcel parcel = Parcel.obtain();
-        techListParcel.writeToParcel(parcel, 0);
-        parcel.setDataPosition(0);
-        TechListParcel actualTechList =
-                TechListParcel.CREATOR.createFromParcel(parcel);
-        parcel.recycle();
-
-        assertThat(actualTechList.getTechLists().length).isEqualTo(2);
-        assertThat(Arrays.equals(actualTechList.getTechLists()[0], TECH_LIST_1)).isTrue();
-        assertThat(Arrays.equals(actualTechList.getTechLists()[1], TECH_LIST_2)).isTrue();
-    }
-
-    @Test
-    public void testWriteParcelArrayEmpty() {
-        TechListParcel techListParcel = new TechListParcel();
-
-        Parcel parcel = Parcel.obtain();
-        techListParcel.writeToParcel(parcel, 0);
-        parcel.setDataPosition(0);
-        TechListParcel actualTechList =
-                TechListParcel.CREATOR.createFromParcel(parcel);
-        parcel.recycle();
-
-        assertThat(actualTechList.getTechLists().length).isEqualTo(0);
-    }
-
-    @Test
-    public void testWriteParcelElementEmpty() {
-        TechListParcel techListParcel = new TechListParcel(TECH_LIST_EMPTY);
-
-        Parcel parcel = Parcel.obtain();
-        techListParcel.writeToParcel(parcel, 0);
-        parcel.setDataPosition(0);
-        TechListParcel actualTechList =
-                TechListParcel.CREATOR.createFromParcel(parcel);
-        parcel.recycle();
-
-        assertThat(actualTechList.getTechLists().length).isEqualTo(1);
-        assertThat(Arrays.equals(actualTechList.getTechLists()[0], TECH_LIST_EMPTY)).isTrue();
-    }
-
-}
diff --git a/nfc/tests/src/android/nfc/cardemulation/AidGroupTest.java b/nfc/tests/src/android/nfc/cardemulation/AidGroupTest.java
deleted file mode 100644
index 7e00102..0000000
--- a/nfc/tests/src/android/nfc/cardemulation/AidGroupTest.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc.cardemulation;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.ArgumentMatchers.isNull;
-import static org.mockito.Mockito.atLeastOnce;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-import android.os.Parcel;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.xmlpull.v1.XmlSerializer;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class AidGroupTest {
-    private AidGroup mAidGroup;
-
-    @Before
-    public void setUp() {
-        List<String> aids = new ArrayList<>();
-        aids.add("A0000000031010");
-        aids.add("A0000000041010");
-        aids.add("A0000000034710");
-        aids.add("A000000300");
-        mAidGroup = new AidGroup(aids, "payment");
-    }
-
-    @After
-    public void tearDown() {
-    }
-
-    @Test
-    public void testGetCategory() {
-        String category = mAidGroup.getCategory();
-        assertThat(category).isNotNull();
-        assertThat(category).isEqualTo("payment");
-    }
-
-    @Test
-    public void testGetAids() {
-        List<String> aids = mAidGroup.getAids();
-        assertThat(aids).isNotNull();
-        assertThat(aids.size()).isGreaterThan(0);
-        assertThat(aids.get(0)).isEqualTo("A0000000031010");
-    }
-
-    @Test
-    public void testWriteAsXml() throws IOException {
-        XmlSerializer out = mock(XmlSerializer.class);
-        mAidGroup.writeAsXml(out);
-        verify(out, atLeastOnce()).startTag(isNull(), anyString());
-        verify(out, atLeastOnce()).attribute(isNull(), anyString(), anyString());
-        verify(out, atLeastOnce()).endTag(isNull(), anyString());
-    }
-
-    @Test
-    public void testRightToParcel() {
-        Parcel parcel = mock(Parcel.class);
-        mAidGroup.writeToParcel(parcel, 0);
-        verify(parcel).writeString8(anyString());
-        verify(parcel).writeInt(anyInt());
-        verify(parcel).writeStringList(any());
-    }
-}
diff --git a/nfc/tests/src/android/nfc/cardemulation/CardemulationTest.java b/nfc/tests/src/android/nfc/cardemulation/CardemulationTest.java
deleted file mode 100644
index a215835..0000000
--- a/nfc/tests/src/android/nfc/cardemulation/CardemulationTest.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc.cardemulation;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.app.role.RoleManager;
-import android.content.ComponentName;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.nfc.Constants;
-import android.nfc.INfcCardEmulation;
-import android.nfc.NfcAdapter;
-import android.os.RemoteException;
-import android.os.UserHandle;
-import android.provider.Settings;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-
-import com.android.dx.mockito.inline.extended.ExtendedMockito;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.mockito.MockitoSession;
-import org.mockito.quality.Strictness;
-
-@RunWith(AndroidJUnit4.class)
-public class CardemulationTest {
-
-    private CardEmulation mCardEmulation;
-    @Mock
-    private Context mContext;
-    @Mock
-    private INfcCardEmulation mINfcCardEmulation;
-    @Mock
-    private NfcAdapter mNfcAdapter;
-    @Mock
-    private PackageManager mPackageManager;
-    private MockitoSession mMockitoSession;
-
-    @Before
-    public void setUp() {
-        mMockitoSession = ExtendedMockito.mockitoSession()
-                .mockStatic(NfcAdapter.class)
-                .mockStatic(Settings.Secure.class)
-                .strictness(Strictness.LENIENT)
-                .startMocking();
-        MockitoAnnotations.initMocks(this);
-
-        when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION))
-                .thenReturn(true);
-        when(mContext.getApplicationContext()).thenReturn(mContext);
-        when(mContext.getPackageManager()).thenReturn(mPackageManager);
-        assertThat(mNfcAdapter).isNotNull();
-        when(mNfcAdapter.getCardEmulationService()).thenReturn(mINfcCardEmulation);
-        when(mNfcAdapter.getContext()).thenReturn(mContext);
-        mCardEmulation = CardEmulation.getInstance(mNfcAdapter);
-    }
-
-    @After
-    public void tearDown() {
-        mMockitoSession.finishMocking();
-    }
-
-    @Test
-    public void testIsDefaultServiceForCategory() throws RemoteException {
-        ComponentName componentName = mock(ComponentName.class);
-        UserHandle userHandle = mock(UserHandle.class);
-        when(userHandle.getIdentifier()).thenReturn(1);
-        when(mContext.getUser()).thenReturn(userHandle);
-        when(mINfcCardEmulation.isDefaultServiceForCategory(1, componentName,
-                "payment")).thenReturn(true);
-        boolean result = mCardEmulation.isDefaultServiceForCategory(componentName,
-                "payment");
-        assertThat(result).isTrue();
-        verify(mINfcCardEmulation).isDefaultServiceForCategory(1, componentName,
-                "payment");
-
-    }
-
-    @Test
-    public void testIsDefaultServiceForAid() throws RemoteException {
-        ComponentName componentName = mock(ComponentName.class);
-        UserHandle userHandle = mock(UserHandle.class);
-        when(userHandle.getIdentifier()).thenReturn(1);
-        when(mContext.getUser()).thenReturn(userHandle);
-        when(mINfcCardEmulation.isDefaultServiceForAid(1, componentName,
-                "payment")).thenReturn(true);
-        boolean result = mCardEmulation.isDefaultServiceForAid(componentName,
-                "payment");
-        assertThat(result).isTrue();
-        verify(mINfcCardEmulation).isDefaultServiceForAid(1, componentName,
-                "payment");
-    }
-
-    @Test
-    public void testCategoryAllowsForegroundPreference() throws Settings.SettingNotFoundException {
-        when(mContext.createContextAsUser(any(), anyInt())).thenReturn(mContext);
-        RoleManager roleManager = mock(RoleManager.class);
-        when(roleManager.isRoleAvailable(RoleManager.ROLE_WALLET)).thenReturn(false);
-        when(mContext.getSystemService(RoleManager.class)).thenReturn(roleManager);
-        ContentResolver contentResolver = mock(ContentResolver.class);
-        when(mContext.getContentResolver()).thenReturn(contentResolver);
-        when(Settings.Secure.getInt(contentResolver, Constants
-                .SETTINGS_SECURE_NFC_PAYMENT_FOREGROUND)).thenReturn(1);
-        boolean result = mCardEmulation.categoryAllowsForegroundPreference("payment");
-        assertThat(result).isTrue();
-    }
-
-    @Test
-    public void testGetSelectionModeForCategory() throws RemoteException {
-        when(mINfcCardEmulation.isDefaultPaymentRegistered()).thenReturn(true);
-        int result = mCardEmulation.getSelectionModeForCategory("payment");
-        assertThat(result).isEqualTo(0);
-    }
-
-    @Test
-    public void testSetShouldDefaultToObserveModeForService() throws RemoteException {
-        UserHandle userHandle = mock(UserHandle.class);
-        when(userHandle.getIdentifier()).thenReturn(1);
-        when(mContext.getUser()).thenReturn(userHandle);
-        ComponentName componentName = mock(ComponentName.class);
-        when(mINfcCardEmulation.setShouldDefaultToObserveModeForService(1, componentName, true))
-                .thenReturn(true);
-        boolean result = mCardEmulation
-                .setShouldDefaultToObserveModeForService(componentName, true);
-        assertThat(result).isTrue();
-        verify(mINfcCardEmulation).setShouldDefaultToObserveModeForService(1, componentName, true);
-    }
-
-    @Test
-    public void testRegisterPollingLoopFilterForService()throws RemoteException {
-        UserHandle userHandle = mock(UserHandle.class);
-        when(userHandle.getIdentifier()).thenReturn(1);
-        when(mContext.getUser()).thenReturn(userHandle);
-        ComponentName componentName = mock(ComponentName.class);
-        when(mINfcCardEmulation.registerPollingLoopFilterForService(anyInt(),
-                any(), anyString(), anyBoolean())).thenReturn(true);
-        boolean result = mCardEmulation.registerPollingLoopFilterForService(componentName,
-                "A0000000041010", true);
-        assertThat(result).isTrue();
-        verify(mINfcCardEmulation)
-                .registerPollingLoopFilterForService(anyInt(), any(), anyString(), anyBoolean());
-    }
-
-    @Test
-    public void testRemovePollingLoopFilterForService()throws RemoteException {
-        UserHandle userHandle = mock(UserHandle.class);
-        when(userHandle.getIdentifier()).thenReturn(1);
-        when(mContext.getUser()).thenReturn(userHandle);
-        ComponentName componentName = mock(ComponentName.class);
-        when(mINfcCardEmulation.removePollingLoopFilterForService(anyInt(), any(), anyString()))
-                .thenReturn(true);
-        boolean result = mCardEmulation
-                .removePollingLoopFilterForService(componentName, "A0000000041010");
-        assertThat(result).isTrue();
-        verify(mINfcCardEmulation).removePollingLoopFilterForService(anyInt(), any(), anyString());
-    }
-}
diff --git a/nfc/tests/src/android/nfc/dta/NfcDtaTest.java b/nfc/tests/src/android/nfc/dta/NfcDtaTest.java
deleted file mode 100644
index 38fb7ef..0000000
--- a/nfc/tests/src/android/nfc/dta/NfcDtaTest.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc.dta;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.nfc.INfcDta;
-import android.nfc.NfcAdapter;
-import android.os.RemoteException;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-public class NfcDtaTest {
-    private final String mServiceName = "serviceName";
-    private final int mServiceSap = 1;
-    private final int mMiu = 1;
-    private final int mRwSize = 1;
-    private final int mTestCaseId = 1;
-    @Mock
-    private NfcAdapter mMockNfcAdapter;
-    @Mock
-    private INfcDta mMockService;
-    @Mock
-    private Context mMockContext;
-
-    private NfcDta mNfcDta;
-
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-        when(mMockNfcAdapter.getContext()).thenReturn(mMockContext);
-        when(mMockNfcAdapter.getNfcDtaInterface()).thenReturn(mMockService);
-
-        mNfcDta = NfcDta.getInstance(mMockNfcAdapter);
-    }
-
-    @Test
-    public void testEnableData() throws RemoteException {
-        assertTrue(mNfcDta.enableDta());
-        verify(mMockService).enableDta();
-    }
-
-    @Test
-    public void testEnableDataWithRemoteException() throws RemoteException {
-        doThrow(new RemoteException()).when(mMockService).enableDta();
-
-        assertFalse(mNfcDta.enableDta());
-        verify(mMockService).enableDta();
-    }
-
-    @Test
-    public void testDisableData() throws RemoteException {
-        assertTrue(mNfcDta.disableDta());
-        verify(mMockService).disableDta();
-    }
-
-    @Test
-    public void testDisableDataWithRemoteException() throws RemoteException {
-        doThrow(new RemoteException()).when(mMockService).disableDta();
-
-        assertFalse(mNfcDta.disableDta());
-        verify(mMockService).disableDta();
-    }
-
-    @Test
-    public void testEnableServer() throws RemoteException {
-        when(mMockService.enableServer(mServiceName, mServiceSap, mMiu, mRwSize,
-                mTestCaseId)).thenReturn(true);
-
-        mNfcDta.enableServer(mServiceName, mServiceSap, mMiu, mRwSize, mTestCaseId);
-        verify(mMockService).enableServer(mServiceName, mServiceSap, mMiu, mRwSize, mTestCaseId);
-    }
-
-    @Test
-    public void testEnableServerWithRemoteException() throws RemoteException {
-        doThrow(new RemoteException()).when(mMockService).enableServer(mServiceName, mServiceSap,
-                mMiu,
-                mRwSize, mTestCaseId);
-
-        mNfcDta.enableServer(mServiceName, mServiceSap, mMiu, mRwSize, mTestCaseId);
-        verify(mMockService).enableServer(mServiceName, mServiceSap, mMiu, mRwSize, mTestCaseId);
-    }
-
-    @Test
-    public void testDisableServer() throws RemoteException {
-        assertTrue(mNfcDta.disableServer());
-        verify(mMockService).disableServer();
-    }
-
-    @Test
-    public void testDisableServerWithRemoteException() throws RemoteException {
-        doThrow(new RemoteException()).when(mMockService).disableServer();
-
-        assertFalse(mNfcDta.disableServer());
-        verify(mMockService).disableServer();
-    }
-
-    @Test
-    public void testEnableClient() throws RemoteException {
-        when(mMockService.enableClient(mServiceName, mMiu, mRwSize, mTestCaseId)).thenReturn(true);
-
-        mNfcDta.enableClient(mServiceName, mMiu, mRwSize, mTestCaseId);
-        verify(mMockService).enableClient(mServiceName, mMiu, mRwSize, mTestCaseId);
-    }
-
-    @Test
-    public void testEnableClientWithRemoteException() throws RemoteException {
-        doThrow(new RemoteException()).when(mMockService).enableClient(mServiceName, mMiu, mRwSize,
-                mTestCaseId);
-
-        mNfcDta.enableClient(mServiceName, mMiu, mRwSize, mTestCaseId);
-        verify(mMockService).enableClient(mServiceName, mMiu, mRwSize, mTestCaseId);
-    }
-
-    @Test
-    public void testDisableClient() throws RemoteException {
-        assertTrue(mNfcDta.disableClient());
-        verify(mMockService).disableClient();
-    }
-
-    @Test
-    public void testDisableClientWithRemoteException() throws RemoteException {
-        doThrow(new RemoteException()).when(mMockService).disableClient();
-
-        assertFalse(mNfcDta.disableClient());
-        verify(mMockService).disableClient();
-    }
-
-    @Test
-    public void testRegisterMessageService() throws RemoteException {
-        String msgServiceName = "sampleServiceName";
-        when(mMockService.registerMessageService(msgServiceName)).thenReturn(true);
-
-        mNfcDta.registerMessageService(msgServiceName);
-        verify(mMockService).registerMessageService(msgServiceName);
-    }
-
-    @Test
-    public void testRegisterMessageServiceWithRemoteException() throws RemoteException {
-        String msgServiceName = "sampleServiceName";
-        doThrow(new RemoteException()).when(mMockService).registerMessageService(msgServiceName);
-
-        assertFalse(mNfcDta.registerMessageService(msgServiceName));
-    }
-
-    @Test(expected = NullPointerException.class)
-    public void testGetInstanceWithNullPointerException() {
-        NfcDta.getInstance(null);
-    }
-
-    @Test(expected = UnsupportedOperationException.class)
-    public void testGetInstanceWithUnsupportedOperationExceptionForNfcAdapterContext() {
-        when(mMockNfcAdapter.getContext()).thenReturn(null);
-
-        NfcDta.getInstance(mMockNfcAdapter);
-    }
-}
diff --git a/nfc/tests/src/android/nfc/tech/NfcATest.java b/nfc/tests/src/android/nfc/tech/NfcATest.java
deleted file mode 100644
index 40076eb..0000000
--- a/nfc/tests/src/android/nfc/tech/NfcATest.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc.tech;
-
-import static android.nfc.tech.NfcA.EXTRA_ATQA;
-import static android.nfc.tech.NfcA.EXTRA_SAK;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertThrows;
-import static org.junit.Assert.fail;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.nfc.ErrorCodes;
-import android.nfc.INfcTag;
-import android.nfc.Tag;
-import android.nfc.TransceiveResult;
-import android.os.Bundle;
-import android.os.RemoteException;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.io.IOException;
-
-public class NfcATest {
-    @Mock
-    private Tag mMockTag;
-    @Mock
-    private INfcTag mMockTagService;
-    @Mock
-    private Bundle mMockBundle;
-    private NfcA mNfcA;
-    private final byte[] mSampleArray = new byte[] {1, 2, 3};
-
-    @Before
-    public void setUp() throws RemoteException {
-        MockitoAnnotations.initMocks(this);
-        when(mMockBundle.getShort(EXTRA_SAK)).thenReturn((short) 1);
-        when(mMockBundle.getByteArray(EXTRA_ATQA)).thenReturn(mSampleArray);
-        when(mMockTag.getTechExtras(TagTechnology.NFC_A)).thenReturn(mMockBundle);
-
-        mNfcA = new NfcA(mMockTag);
-    }
-
-    @Test
-    public void testGetNfcAWithTech() {
-        Tag mockTag = mock(Tag.class);
-        when(mockTag.getTechExtras(TagTechnology.NFC_A)).thenReturn(mMockBundle);
-        when(mockTag.hasTech(TagTechnology.NFC_A)).thenReturn(true);
-
-        assertNotNull(NfcA.get(mockTag));
-        verify(mockTag).getTechExtras(TagTechnology.NFC_A);
-        verify(mockTag).hasTech(TagTechnology.NFC_A);
-    }
-
-    @Test
-    public void testGetNfcAWithoutTech() {
-        when(mMockTag.hasTech(TagTechnology.NFC_A)).thenReturn(false);
-        assertNull(NfcA.get(mMockTag));
-    }
-
-    @Test
-    public void testGetAtga() {
-        assertNotNull(mNfcA.getAtqa());
-    }
-
-    @Test
-    public void testGetSak() {
-        assertEquals((short) 1, mNfcA.getSak());
-    }
-
-    @Test
-    public void testTransceive() throws IOException, RemoteException {
-        TransceiveResult mockTransceiveResult = mock(TransceiveResult.class);
-        when(mMockTag.getConnectedTechnology()).thenReturn(TagTechnology.NFC_A);
-        when(mMockTag.getTagService()).thenReturn(mMockTagService);
-        when(mMockTag.getServiceHandle()).thenReturn(1);
-        when(mMockTagService.transceive(1, mSampleArray, true))
-                .thenReturn(mockTransceiveResult);
-        when(mockTransceiveResult.getResponseOrThrow()).thenReturn(mSampleArray);
-
-        mNfcA.transceive(mSampleArray);
-        verify(mMockTag).getTagService();
-        verify(mMockTag).getServiceHandle();
-    }
-
-    @Test
-    public void testGetMaxTransceiveLength() throws RemoteException {
-        when(mMockTag.getTagService()).thenReturn(mMockTagService);
-        when(mMockTagService.getMaxTransceiveLength(TagTechnology.NFC_A)).thenReturn(1);
-
-        mNfcA.getMaxTransceiveLength();
-        verify(mMockTag).getTagService();
-    }
-
-    @Test
-    public void testSetTimeout() {
-        when(mMockTag.getTagService()).thenReturn(mMockTagService);
-        try {
-            when(mMockTagService.setTimeout(TagTechnology.NFC_A, 1000)).thenReturn(
-                    ErrorCodes.SUCCESS);
-
-            mNfcA.setTimeout(1000);
-            verify(mMockTag).getTagService();
-            verify(mMockTagService).setTimeout(TagTechnology.NFC_A, 1000);
-        } catch (Exception e) {
-            fail("Unexpected exception during valid setTimeout: " + e.getMessage());
-        }
-    }
-
-    @Test
-    public void testSetTimeoutInvalidTimeout() {
-        when(mMockTag.getTagService()).thenReturn(mMockTagService);
-        try {
-            when(mMockTagService.setTimeout(TagTechnology.NFC_A, -1)).thenReturn(
-                    ErrorCodes.ERROR_TIMEOUT);
-
-            assertThrows(IllegalArgumentException.class, () -> mNfcA.setTimeout(-1));
-        } catch (Exception e) {
-            fail("Unexpected exception during invalid setTimeout: " + e.getMessage());
-        }
-    }
-
-    @Test
-    public void testSetTimeoutRemoteException() {
-        when(mMockTag.getTagService()).thenReturn(mMockTagService);
-        try {
-            when(mMockTagService.setTimeout(TagTechnology.NFC_A, 1000)).thenThrow(
-                    new RemoteException());
-
-            mNfcA.setTimeout(1000); // Should not throw an exception but log it
-            verify(mMockTag).getTagService();
-            verify(mMockTagService).setTimeout(TagTechnology.NFC_A, 1000);
-        } catch (Exception e) {
-            fail("Unexpected exception during RemoteException in setTimeout: " + e.getMessage());
-        }
-
-    }
-
-    @Test
-    public void testGetTimeout() {
-        when(mMockTag.getTagService()).thenReturn(mMockTagService);
-        try {
-            when(mMockTagService.getTimeout(TagTechnology.NFC_A)).thenReturn(2000);
-
-            assertEquals(2000, mNfcA.getTimeout());
-            verify(mMockTag).getTagService();
-            verify(mMockTagService).getTimeout(TagTechnology.NFC_A);
-        } catch (Exception e) {
-            fail("Unexpected exception during valid getTimeout: " + e.getMessage());
-        }
-    }
-
-    @Test
-    public void testGetTimeoutRemoteException() {
-        when(mMockTag.getTagService()).thenReturn(mMockTagService);
-        try {
-            when(mMockTagService.getTimeout(TagTechnology.NFC_A)).thenThrow(new RemoteException());
-
-            assertEquals(0, mNfcA.getTimeout());
-        } catch (Exception e) {
-            fail("Unexpected exception during RemoteException in getTimeout: " + e.getMessage());
-        }
-    }
-}
diff --git a/nfc/tests/src/android/nfc/tech/NfcBTest.java b/nfc/tests/src/android/nfc/tech/NfcBTest.java
deleted file mode 100644
index 98d6070..0000000
--- a/nfc/tests/src/android/nfc/tech/NfcBTest.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc.tech;
-
-import static android.nfc.tech.NfcB.EXTRA_APPDATA;
-import static android.nfc.tech.NfcB.EXTRA_PROTINFO;
-
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.nfc.INfcTag;
-import android.nfc.Tag;
-import android.nfc.TransceiveResult;
-import android.os.Bundle;
-import android.os.RemoteException;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.io.IOException;
-
-public class NfcBTest {
-    private final byte[] mSampleAppDate = new byte[] {1, 2, 3};
-    private final byte[] mSampleProtInfo = new byte[] {3, 2, 1};
-    @Mock
-    private Tag mMockTag;
-    @Mock
-    private Bundle mMockBundle;
-    @Mock
-    private INfcTag mMockTagService;
-    private NfcB mNfcB;
-
-    @Before
-    public void setUp() throws RemoteException {
-        MockitoAnnotations.initMocks(this);
-        when(mMockBundle.getByteArray(EXTRA_APPDATA)).thenReturn(mSampleAppDate);
-        when(mMockBundle.getByteArray(EXTRA_PROTINFO)).thenReturn(mSampleProtInfo);
-        when(mMockTag.getTechExtras(TagTechnology.NFC_B)).thenReturn(mMockBundle);
-
-        mNfcB = new NfcB(mMockTag);
-    }
-
-    @Test
-    public void testGetApplicationData() {
-        assertNotNull(mNfcB.getApplicationData());
-    }
-
-    @Test
-    public void testGetProtocolInfo() {
-        assertNotNull(mNfcB.getProtocolInfo());
-    }
-
-    @Test
-    public void testGetNfcBInstance() {
-        Tag tag = mock(Tag.class);
-        when(tag.hasTech(TagTechnology.NFC_B)).thenReturn(true);
-        when(tag.getTechExtras(TagTechnology.NFC_B)).thenReturn(mMockBundle);
-
-        assertNotNull(NfcB.get(tag));
-        verify(tag).hasTech(TagTechnology.NFC_B);
-        verify(tag).getTechExtras(TagTechnology.NFC_B);
-    }
-
-    @Test
-    public void testGetNfcBNullInstance() {
-        Tag tag = mock(Tag.class);
-        when(tag.hasTech(TagTechnology.NFC_B)).thenReturn(false);
-
-        assertNull(NfcB.get(tag));
-        verify(tag).hasTech(TagTechnology.NFC_B);
-        verify(tag, never()).getTechExtras(TagTechnology.NFC_B);
-    }
-
-
-    @Test
-    public void testTransceive() throws IOException, RemoteException {
-        byte[] sampleData = new byte[] {1, 2, 3, 4, 5};
-        TransceiveResult mockTransceiveResult = mock(TransceiveResult.class);
-        when(mMockTag.getConnectedTechnology()).thenReturn(TagTechnology.NFC_B);
-        when(mMockTag.getTagService()).thenReturn(mMockTagService);
-        when(mMockTag.getServiceHandle()).thenReturn(1);
-        when(mMockTagService.transceive(1, sampleData, true))
-                .thenReturn(mockTransceiveResult);
-        when(mockTransceiveResult.getResponseOrThrow()).thenReturn(sampleData);
-
-        mNfcB.transceive(sampleData);
-        verify(mMockTag).getTagService();
-        verify(mMockTag).getServiceHandle();
-    }
-
-    @Test
-    public void testGetMaxTransceiveLength() throws RemoteException {
-        when(mMockTag.getTagService()).thenReturn(mMockTagService);
-        when(mMockTagService.getMaxTransceiveLength(TagTechnology.NFC_B)).thenReturn(1);
-
-        mNfcB.getMaxTransceiveLength();
-        verify(mMockTag).getTagService();
-    }
-}
diff --git a/nfc/tests/src/android/nfc/tech/NfcFTest.java b/nfc/tests/src/android/nfc/tech/NfcFTest.java
deleted file mode 100644
index 31a6943..0000000
--- a/nfc/tests/src/android/nfc/tech/NfcFTest.java
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc.tech;
-
-import static android.nfc.tech.NfcF.EXTRA_PMM;
-import static android.nfc.tech.NfcF.EXTRA_SC;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertThrows;
-import static org.junit.Assert.fail;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.nfc.ErrorCodes;
-import android.nfc.INfcTag;
-import android.nfc.Tag;
-import android.nfc.TransceiveResult;
-import android.os.Bundle;
-import android.os.RemoteException;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.io.IOException;
-
-public class NfcFTest {
-    private final byte[] mSampleSystemCode = new byte[] {1, 2, 3};
-    private final byte[] mSampleManufacturer = new byte[] {3, 2, 1};
-    @Mock
-    private Tag mMockTag;
-    @Mock
-    private INfcTag mMockTagService;
-    @Mock
-    private Bundle mMockBundle;
-    private NfcF mNfcF;
-
-    @Before
-    public void setUp() throws RemoteException {
-        MockitoAnnotations.initMocks(this);
-        when(mMockBundle.getByteArray(EXTRA_SC)).thenReturn(mSampleSystemCode);
-        when(mMockBundle.getByteArray(EXTRA_PMM)).thenReturn(mSampleManufacturer);
-        when(mMockTag.getTechExtras(TagTechnology.NFC_F)).thenReturn(mMockBundle);
-
-        mNfcF = new NfcF(mMockTag);
-    }
-
-    @Test
-    public void testGetSystemCode() {
-        assertNotNull(mNfcF.getSystemCode());
-    }
-
-    @Test
-    public void testGetManufacturer() {
-        assertNotNull(mNfcF.getManufacturer());
-    }
-
-    @Test
-    public void testGetNfcFInstanceWithTech() {
-        Tag tag = mock(Tag.class);
-        when(tag.getTechExtras(TagTechnology.NFC_F)).thenReturn(mMockBundle);
-        when(tag.hasTech(TagTechnology.NFC_F)).thenReturn(true);
-
-        assertNotNull(NfcF.get(tag));
-        verify(tag).getTechExtras(TagTechnology.NFC_F);
-        verify(tag).hasTech(TagTechnology.NFC_F);
-    }
-
-    @Test
-    public void testGetNfcFInstanceWithoutTech() {
-        Tag tag = mock(Tag.class);
-        when(tag.hasTech(TagTechnology.NFC_F)).thenReturn(false);
-
-        assertNull(NfcF.get(tag));
-        verify(tag).hasTech(TagTechnology.NFC_F);
-        verify(tag, never()).getTechExtras(TagTechnology.NFC_F);
-    }
-
-    @Test
-    public void testTransceive() throws IOException, RemoteException {
-        byte[] sampleData = new byte[]{1, 2, 3, 4, 5};
-        TransceiveResult mockTransceiveResult = mock(TransceiveResult.class);
-        when(mMockTag.getConnectedTechnology()).thenReturn(TagTechnology.NFC_F);
-        when(mMockTag.getTagService()).thenReturn(mMockTagService);
-        when(mMockTag.getServiceHandle()).thenReturn(1);
-        when(mMockTagService.transceive(1, sampleData, true))
-                .thenReturn(mockTransceiveResult);
-        when(mockTransceiveResult.getResponseOrThrow()).thenReturn(sampleData);
-
-        mNfcF.transceive(sampleData);
-        verify(mMockTag).getTagService();
-        verify(mMockTag).getServiceHandle();
-    }
-
-    @Test
-    public void testGetMaxTransceiveLength() throws RemoteException {
-        when(mMockTag.getTagService()).thenReturn(mMockTagService);
-        when(mMockTagService.getMaxTransceiveLength(TagTechnology.NFC_F)).thenReturn(1);
-
-        mNfcF.getMaxTransceiveLength();
-        verify(mMockTag).getTagService();
-    }
-
-    @Test
-    public void testGetTimeout() {
-        when(mMockTag.getTagService()).thenReturn(mMockTagService);
-        try {
-            when(mMockTagService.getTimeout(TagTechnology.NFC_F)).thenReturn(2000);
-
-            assertEquals(2000, mNfcF.getTimeout());
-            verify(mMockTag).getTagService();
-            verify(mMockTagService).getTimeout(TagTechnology.NFC_F);
-        } catch (Exception e) {
-            fail("Unexpected exception during valid getTimeout: " + e.getMessage());
-        }
-    }
-
-    @Test
-    public void testGetTimeoutRemoteException() {
-        when(mMockTag.getTagService()).thenReturn(mMockTagService);
-        try {
-            when(mMockTagService.getTimeout(TagTechnology.NFC_F)).thenThrow(new RemoteException());
-
-            assertEquals(0, mNfcF.getTimeout());
-        } catch (Exception e) {
-            fail("Unexpected exception during RemoteException in getTimeout: " + e.getMessage());
-        }
-    }
-
-    @Test
-    public void testSetTimeout() {
-        when(mMockTag.getTagService()).thenReturn(mMockTagService);
-        try {
-            when(mMockTagService.setTimeout(TagTechnology.NFC_F, 1000)).thenReturn(
-                    ErrorCodes.SUCCESS);
-
-            mNfcF.setTimeout(1000);
-            verify(mMockTag).getTagService();
-            verify(mMockTagService).setTimeout(TagTechnology.NFC_F, 1000);
-        } catch (Exception e) {
-            fail("Unexpected exception during valid setTimeout: " + e.getMessage());
-        }
-    }
-
-    @Test
-    public void testSetTimeoutInvalidTimeout() {
-        when(mMockTag.getTagService()).thenReturn(mMockTagService);
-        try {
-            when(mMockTagService.setTimeout(TagTechnology.NFC_F, -1)).thenReturn(
-                    ErrorCodes.ERROR_TIMEOUT);
-
-            assertThrows(IllegalArgumentException.class, () -> mNfcF.setTimeout(-1));
-        } catch (Exception e) {
-            fail("Unexpected exception during invalid setTimeout: " + e.getMessage());
-        }
-    }
-
-    @Test
-    public void testSetTimeoutRemoteException() {
-        when(mMockTag.getTagService()).thenReturn(mMockTagService);
-        try {
-            when(mMockTagService.setTimeout(TagTechnology.NFC_F, 1000)).thenThrow(
-                    new RemoteException());
-
-            mNfcF.setTimeout(1000);
-            verify(mMockTag).getTagService();
-            verify(mMockTagService).setTimeout(TagTechnology.NFC_F, 1000);
-        } catch (Exception e) {
-            fail("Unexpected exception during RemoteException in setTimeout: " + e.getMessage());
-        }
-    }
-}
diff --git a/ravenwood/scripts/extract-last-soong-commands.py b/ravenwood/scripts/extract-last-soong-commands.py
index c08d4aa..0629b77 100755
--- a/ravenwood/scripts/extract-last-soong-commands.py
+++ b/ravenwood/scripts/extract-last-soong-commands.py
@@ -32,7 +32,7 @@
 HEADER = r'''#!/bin/bash
 
 set -e # Stop on a failed command
-
+set -x # Print command line before executing
 cd "${ANDROID_BUILD_TOP:?}"
 
 '''
@@ -65,16 +65,8 @@
                     command = m.groups()[0]
 
                     count += 1
-                    out.write(f'### Command {count} ========\n')
-
-                    # Show the full command line before executing it.
-                    out.write('#echo ' + shlex.quote(command) + '\n')
-                    out.write('\n')
-
-                    # Execute the command.
-                    out.write('#' + command + '\n')
-
-                    out.write('\n')
+                    out.write(f'### Command {count} ========\n\n')
+                    out.write('#' + command + '\n\n')
 
                     continue
 
