diff --git a/MEMORY_OWNERS b/MEMORY_OWNERS
index 89ce5140..12aa295 100644
--- a/MEMORY_OWNERS
+++ b/MEMORY_OWNERS
@@ -2,5 +2,4 @@
 tjmercier@google.com
 kaleshsingh@google.com
 jyescas@google.com
-carlosgalo@google.com
 jji@google.com
diff --git a/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ClientEndpoint.java b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ClientEndpoint.java
index 1a7258a..4c34165 100644
--- a/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ClientEndpoint.java
+++ b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ClientEndpoint.java
@@ -20,6 +20,7 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.lang.AutoCloseable;
 import java.net.InetAddress;
 import java.net.SocketException;
 import java.nio.channels.ClosedChannelException;
@@ -33,7 +34,7 @@
  * Client-side endpoint. Provides basic services for sending/receiving messages from the client
  * socket.
  */
-final class ClientEndpoint {
+final class ClientEndpoint implements AutoCloseable {
     private final SSLSocket socket;
     private InputStream input;
     private OutputStream output;
@@ -56,6 +57,11 @@
         }
     }
 
+    @Override
+    public void close() {
+        stop();
+    }
+
     void stop() {
         try {
             socket.close();
diff --git a/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ClientSocketPerfTest.java b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ClientSocketPerfTest.java
index f20b170..9e45c4a 100644
--- a/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ClientSocketPerfTest.java
+++ b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ClientSocketPerfTest.java
@@ -44,24 +44,21 @@
 import javax.crypto.NoSuchPaddingException;
 
 import org.junit.Rule;
+import org.junit.After;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import junitparams.JUnitParamsRunner;
 import junitparams.Parameters;
 import android.conscrypt.ServerEndpoint.MessageProcessor;
 
-/**
- * Benchmark for comparing performance of server socket implementations.
- */
+/** Benchmark for comparing performance of server socket implementations. */
 @RunWith(JUnitParamsRunner.class)
 @LargeTest
 public final class ClientSocketPerfTest {
 
     @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
 
-    /**
-     * Provider for the test configuration
-     */
+    /** Provider for the test configuration */
     private class Config {
         EndpointFactory a_clientFactory;
         EndpointFactory b_serverFactory;
@@ -69,19 +66,22 @@
         String d_cipher;
         ChannelType e_channelType;
         PerfTestProtocol f_protocol;
-        Config(EndpointFactory clientFactory,
-            EndpointFactory serverFactory,
-            int messageSize,
-            String cipher,
-            ChannelType channelType,
-            PerfTestProtocol protocol) {
-          a_clientFactory = clientFactory;
-          b_serverFactory = serverFactory;
-          c_messageSize = messageSize;
-          d_cipher = cipher;
-          e_channelType = channelType;
-          f_protocol = protocol;
+
+        Config(
+                EndpointFactory clientFactory,
+                EndpointFactory serverFactory,
+                int messageSize,
+                String cipher,
+                ChannelType channelType,
+                PerfTestProtocol protocol) {
+            a_clientFactory = clientFactory;
+            b_serverFactory = serverFactory;
+            c_messageSize = messageSize;
+            d_cipher = cipher;
+            e_channelType = channelType;
+            f_protocol = protocol;
         }
+
         public EndpointFactory clientFactory() {
             return a_clientFactory;
         }
@@ -112,23 +112,43 @@
         for (EndpointFactory endpointFactory : EndpointFactory.values()) {
             for (ChannelType channelType : ChannelType.values()) {
                 for (PerfTestProtocol protocol : PerfTestProtocol.values()) {
-                    params.add(new Object[] {new Config(endpointFactory,
-                        endpointFactory, 64, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
-                        channelType, protocol)});
-                    params.add(new Object[] {new Config(endpointFactory,
-                        endpointFactory, 512, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
-                        channelType, protocol)});
-                    params.add(new Object[] {new Config(endpointFactory,
-                        endpointFactory, 4096, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
-                        channelType, protocol)});
+                    params.add(
+                            new Object[] {
+                                new Config(
+                                        endpointFactory,
+                                        endpointFactory,
+                                        64,
+                                        "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
+                                        channelType,
+                                        protocol)
+                            });
+                    params.add(
+                            new Object[] {
+                                new Config(
+                                        endpointFactory,
+                                        endpointFactory,
+                                        512,
+                                        "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
+                                        channelType,
+                                        protocol)
+                            });
+                    params.add(
+                            new Object[] {
+                                new Config(
+                                        endpointFactory,
+                                        endpointFactory,
+                                        4096,
+                                        "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
+                                        channelType,
+                                        protocol)
+                            });
                 }
             }
         }
         return params;
     }
 
-    private ClientEndpoint client;
-    private ServerEndpoint server;
+    private SocketPair socketPair = new SocketPair();
     private byte[] message;
     private ExecutorService executor;
     private Future<?> sendingFuture;
@@ -137,46 +157,78 @@
     private static final AtomicLong bytesCounter = new AtomicLong();
     private AtomicBoolean recording = new AtomicBoolean();
 
+    private static class SocketPair implements AutoCloseable {
+        public ClientEndpoint client;
+        public ServerEndpoint server;
+
+        SocketPair() {
+            client = null;
+            server = null;
+        }
+
+        @Override
+        public void close() {
+            if (client != null) {
+                client.stop();
+            }
+            if (server != null) {
+                server.stop();
+            }
+        }
+    }
+
     private void setup(Config config) throws Exception {
         message = newTextMessage(512);
 
         // Always use the same server for consistency across the benchmarks.
-        server = config.serverFactory().newServer(
-                config.messageSize(), config.protocol().getProtocols(),
-                ciphers(config));
+        socketPair.server =
+                config.serverFactory()
+                        .newServer(
+                                config.messageSize(),
+                                config.protocol().getProtocols(),
+                                ciphers(config));
+        socketPair.server.init();
 
-        server.setMessageProcessor(new ServerEndpoint.MessageProcessor() {
-            @Override
-            public void processMessage(byte[] inMessage, int numBytes, OutputStream os) {
-                if (recording.get()) {
-                    // Server received a message, increment the count.
-                    bytesCounter.addAndGet(numBytes);
-                }
-            }
-        });
-        Future<?> connectedFuture = server.start();
+        socketPair.server.setMessageProcessor(
+                new ServerEndpoint.MessageProcessor() {
+                    @Override
+                    public void processMessage(byte[] inMessage, int numBytes, OutputStream os) {
+                        if (recording.get()) {
+                            // Server received a message, increment the count.
+                            bytesCounter.addAndGet(numBytes);
+                        }
+                    }
+                });
+        Future<?> connectedFuture = socketPair.server.start();
 
-        client = config.clientFactory().newClient(
-            config.channelType(), server.port(), config.protocol().getProtocols(), ciphers(config));
-        client.start();
+        socketPair.client =
+                config.clientFactory()
+                        .newClient(
+                                config.channelType(),
+                                socketPair.server.port(),
+                                config.protocol().getProtocols(),
+                                ciphers(config));
+        socketPair.client.start();
 
         // Wait for the initial connection to complete.
         connectedFuture.get(5, TimeUnit.SECONDS);
 
         executor = Executors.newSingleThreadExecutor();
-        sendingFuture = executor.submit(new Runnable() {
-            @Override
-            public void run() {
-                try {
-                    Thread thread = Thread.currentThread();
-                    while (!stopping && !thread.isInterrupted()) {
-                        client.sendMessage(message);
-                    }
-                } finally {
-                    client.flush();
-                }
-            }
-        });
+        sendingFuture =
+                executor.submit(
+                        new Runnable() {
+                            @Override
+                            public void run() {
+                                try {
+                                    Thread thread = Thread.currentThread();
+                                    while (!stopping && !thread.isInterrupted()) {
+                                        socketPair.client.sendMessage(message);
+                                    }
+                                } finally {
+                                    socketPair.client.flush();
+                                }
+                            }
+                        });
     }
 
     void close() throws Exception {
@@ -185,29 +237,37 @@
         // Wait for the sending thread to stop.
         sendingFuture.get(5, TimeUnit.SECONDS);
 
-        client.stop();
-        server.stop();
-        executor.shutdown();
-        executor.awaitTermination(5, TimeUnit.SECONDS);
+        if (socketPair != null) {
+            socketPair.close();
+        }
+        if (executor != null) {
+            executor.shutdown();
+            executor.awaitTermination(5, TimeUnit.SECONDS);
+        }
     }
 
-    /**
-     * Simple benchmark for the amount of time to send a given number of messages
-     */
+    /** Simple benchmark for the amount of time to send a given number of messages */
     @Test
     @Parameters(method = "getParams")
     public void time(Config config) throws Exception {
-        reset();
-        setup(config);
-        recording.set(true);
+        try {
+            reset();
+            setup(config);
+            recording.set(true);
 
-        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
-        while (state.keepRunning()) {
-          while (bytesCounter.get() < config.messageSize()) {
-          }
-          bytesCounter.set(0);
+            BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+            while (state.keepRunning()) {
+                while (bytesCounter.get() < config.messageSize()) {}
+                bytesCounter.set(0);
+            }
+            recording.set(false);
+        } finally {
+            close();
         }
-        recording.set(false);
+    }
+
+    @After
+    public void tearDown() throws Exception {
         close();
     }
 
@@ -219,4 +279,4 @@
     private String[] ciphers(Config config) {
         return new String[] {config.cipher()};
     }
-}
\ No newline at end of file
+}
diff --git a/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ServerEndpoint.java b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ServerEndpoint.java
index 1e4f124..83eaaa1 100644
--- a/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ServerEndpoint.java
+++ b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ServerEndpoint.java
@@ -16,10 +16,14 @@
 
 package android.conscrypt;
 
+import static org.conscrypt.TestUtils.getLoopbackAddress;
+
 import java.io.EOFException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.lang.AutoCloseable;
+import java.net.InetSocketAddress;
 import java.net.ServerSocket;
 import java.net.SocketException;
 import java.nio.channels.ClosedChannelException;
@@ -37,7 +41,7 @@
 /**
  * A simple socket-based test server.
  */
-final class ServerEndpoint {
+final class ServerEndpoint implements AutoCloseable {
     /**
      * A processor for receipt of a single message.
      */
@@ -82,7 +86,11 @@
         this.messageSize = messageSize;
         this.protocols = protocols;
         this.cipherSuites = cipherSuites;
-        buffer = new byte[messageSize];
+        this.buffer = new byte[messageSize];
+    }
+
+    void init() throws IOException {
+        serverSocket.bind(new InetSocketAddress(getLoopbackAddress(), 0));
     }
 
     void setMessageProcessor(MessageProcessor messageProcessor) {
@@ -94,6 +102,11 @@
         return executor.submit(new AcceptTask());
     }
 
+    @Override
+    public void close() {
+        stop();
+    }
+
     void stop() {
         try {
             stopping = true;
diff --git a/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ServerSocketPerfTest.java b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ServerSocketPerfTest.java
index af3c405..90a87ce 100644
--- a/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ServerSocketPerfTest.java
+++ b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ServerSocketPerfTest.java
@@ -44,6 +44,7 @@
 import junitparams.Parameters;
 
 import org.junit.Rule;
+import org.junit.After;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -115,14 +116,33 @@
         return params;
     }
 
-    private ClientEndpoint client;
-    private ServerEndpoint server;
+    private SocketPair socketPair = new SocketPair();
     private ExecutorService executor;
     private Future<?> receivingFuture;
     private volatile boolean stopping;
     private static final AtomicLong bytesCounter = new AtomicLong();
     private AtomicBoolean recording = new AtomicBoolean();
 
+    private static class SocketPair implements AutoCloseable {
+        public ClientEndpoint client;
+        public ServerEndpoint server;
+
+        SocketPair() {
+            client = null;
+            server = null;
+        }
+
+        @Override
+        public void close() {
+            if (client != null) {
+                client.stop();
+            }
+            if (server != null) {
+                server.stop();
+            }
+        }
+    }
+
     private void setup(final Config config) throws Exception {
         recording.set(false);
 
@@ -130,9 +150,10 @@
 
         final ChannelType channelType = config.channelType();
 
-        server = config.serverFactory().newServer(config.messageSize(),
+        socketPair.server = config.serverFactory().newServer(config.messageSize(),
             new String[] {"TLSv1.3", "TLSv1.2"}, ciphers(config));
-        server.setMessageProcessor(new MessageProcessor() {
+        socketPair.server.init();
+        socketPair.server.setMessageProcessor(new MessageProcessor() {
             @Override
             public void processMessage(byte[] inMessage, int numBytes, OutputStream os) {
                 try {
@@ -151,20 +172,20 @@
             }
         });
 
-        Future<?> connectedFuture = server.start();
+        Future<?> connectedFuture = socketPair.server.start();
 
         // Always use the same client for consistency across the benchmarks.
-        client = config.clientFactory().newClient(
-                ChannelType.CHANNEL, server.port(),
+        socketPair.client = config.clientFactory().newClient(
+                ChannelType.CHANNEL, socketPair.server.port(),
                 new String[] {"TLSv1.3", "TLSv1.2"}, ciphers(config));
-        client.start();
+        socketPair.client.start();
 
         // Wait for the initial connection to complete.
         connectedFuture.get(5, TimeUnit.SECONDS);
 
         // Start the server-side streaming by sending a message to the server.
-        client.sendMessage(message);
-        client.flush();
+        socketPair.client.sendMessage(message);
+        socketPair.client.flush();
 
         executor = Executors.newSingleThreadExecutor();
         receivingFuture = executor.submit(new Runnable() {
@@ -173,7 +194,7 @@
                 Thread thread = Thread.currentThread();
                 byte[] buffer = new byte[config.messageSize()];
                 while (!stopping && !thread.isInterrupted()) {
-                    int numBytes = client.readMessage(buffer);
+                    int numBytes = socketPair.client.readMessage(buffer);
                     if (numBytes < 0) {
                         return;
                     }
@@ -191,25 +212,38 @@
     void close() throws Exception {
         stopping = true;
         // Stop and wait for sending to complete.
-        server.stop();
-        client.stop();
-        executor.shutdown();
-        receivingFuture.get(5, TimeUnit.SECONDS);
-        executor.awaitTermination(5, TimeUnit.SECONDS);
+        if (socketPair != null) {
+            socketPair.close();
+        }
+        if (executor != null) {
+            executor.shutdown();
+            executor.awaitTermination(5, TimeUnit.SECONDS);
+        }
+        if (receivingFuture != null) {
+            receivingFuture.get(5, TimeUnit.SECONDS);
+        }
     }
 
     @Test
     @Parameters(method = "getParams")
     public void throughput(Config config) throws Exception {
-        setup(config);
-        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
-        while (state.keepRunning()) {
-          recording.set(true);
-          while (bytesCounter.get() < config.messageSize()) {
-          }
-          bytesCounter.set(0);
-          recording.set(false);
+        try {
+            setup(config);
+            BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+            while (state.keepRunning()) {
+                recording.set(true);
+                while (bytesCounter.get() < config.messageSize()) {
+                }
+                bytesCounter.set(0);
+                recording.set(false);
+            }
+        } finally {
+            close();
         }
+    }
+
+    @After
+    public void tearDown() throws Exception {
         close();
     }
 
diff --git a/core/java/android/content/pm/flags.aconfig b/core/java/android/content/pm/flags.aconfig
index b541d86..609377e 100644
--- a/core/java/android/content/pm/flags.aconfig
+++ b/core/java/android/content/pm/flags.aconfig
@@ -152,7 +152,7 @@
     name: "cache_sdk_system_features"
     namespace: "system_performance"
     description: "Feature flag to enable optimized cache for SDK-defined system feature lookups."
-    bug: "375000483"
+    bug: "326623529"
 }
 
 flag {
diff --git a/core/java/android/os/OWNERS b/core/java/android/os/OWNERS
index f3bb514..727dcba 100644
--- a/core/java/android/os/OWNERS
+++ b/core/java/android/os/OWNERS
@@ -4,6 +4,8 @@
 
 # PowerManager
 per-file IPowerManager.aidl = file:/services/core/java/com/android/server/power/OWNERS
+per-file IScreenTimeoutPolicyListener.aidl = file:/services/core/java/com/android/server/power/OWNERS
+per-file IWakeLockCallback.aidl = file:/services/core/java/com/android/server/power/OWNERS
 per-file PowerManager.java = file:/services/core/java/com/android/server/power/OWNERS
 per-file PowerManagerInternal.java = file:/services/core/java/com/android/server/power/OWNERS
 
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/OWNERS b/core/java/android/security/net/config/OWNERS
index 85ce3c6..e945ff9 100644
--- a/core/java/android/security/net/config/OWNERS
+++ b/core/java/android/security/net/config/OWNERS
@@ -1,5 +1,6 @@
-# Bug component: 36824
-set noparent
+# Bug component: 1479456
 
-cbrubaker@google.com
+bessiej@google.com
 brambonne@google.com
+sandrom@google.com
+tweek@google.com
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/java/com/android/internal/util/LATENCY_TRACKER_OWNERS b/core/java/com/android/internal/util/LATENCY_TRACKER_OWNERS
index 7755000..3ed902f 100644
--- a/core/java/com/android/internal/util/LATENCY_TRACKER_OWNERS
+++ b/core/java/com/android/internal/util/LATENCY_TRACKER_OWNERS
@@ -1,3 +1,5 @@
 # TODO(b/274465475): Migrate LatencyTracker testing to its own module
 marcinoc@google.com
 ilkos@google.com
+jjaggi@google.com
+nicomazz@google.com
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/libs/protoutil/Android.bp b/libs/protoutil/Android.bp
index 28856c8..a59149c 100644
--- a/libs/protoutil/Android.bp
+++ b/libs/protoutil/Android.bp
@@ -59,7 +59,6 @@
     apex_available: [
         "//apex_available:platform",
         "com.android.os.statsd",
-        "test_com.android.os.statsd",
     ],
 }
 
diff --git a/media/java/android/media/FadeManagerConfiguration.java b/media/java/android/media/FadeManagerConfiguration.java
index 6d84e70..b91a5b5 100644
--- a/media/java/android/media/FadeManagerConfiguration.java
+++ b/media/java/android/media/FadeManagerConfiguration.java
@@ -673,6 +673,7 @@
         return config != null ? config.getDuration() : DURATION_NOT_SET;
     }
 
+    @Nullable
     private VolumeShaper.Configuration getVolumeShaperConfigFromWrapper(
             FadeVolumeShaperConfigsWrapper wrapper, boolean isFadeIn) {
         // if no volume shaper config is available, return null
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/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/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/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppInfoPageTest.kt b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppInfoPageTest.kt
index 0d73cb3..798e2d4 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppInfoPageTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppInfoPageTest.kt
@@ -160,23 +160,25 @@
     @Test
     fun infoPage_whenChangeableAndClick() {
         val listModel = TestTogglePermissionAppListModel(isAllowed = false, isChangeable = true)
+        val switchTitle = context.getString(listModel.switchTitleResId)
 
         setTogglePermissionAppInfoPage(listModel)
-        composeTestRule.onNodeWithText(context.getString(listModel.switchTitleResId)).performClick()
+        composeTestRule.waitUntilExists(hasText(switchTitle))
+        composeTestRule.onNodeWithText(switchTitle).performClick()
 
-        composeTestRule.waitUntilExists(
-            hasText(context.getString(listModel.switchTitleResId)) and isOn())
+        composeTestRule.waitUntilExists(hasText(switchTitle) and isOn())
     }
 
     @Test
     fun infoPage_whenNotChangeableAndClick() {
         val listModel = TestTogglePermissionAppListModel(isAllowed = false, isChangeable = false)
+        val switchTitle = context.getString(listModel.switchTitleResId)
 
         setTogglePermissionAppInfoPage(listModel)
-        composeTestRule.onNodeWithText(context.getString(listModel.switchTitleResId)).performClick()
+        composeTestRule.waitUntilExists(hasText(switchTitle))
+        composeTestRule.onNodeWithText(switchTitle).performClick()
 
-        composeTestRule.waitUntilExists(
-            hasText(context.getString(listModel.switchTitleResId)) and isOff())
+        composeTestRule.waitUntilExists(hasText(switchTitle) and isOff())
     }
 
     @Test
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java b/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java
index 38becd4..c3af44b 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java
@@ -119,27 +119,7 @@
         for (String line : MyShellCommand.listAll(iprovider)) {
             pw.println(line);
         }
-
-        ArrayList<String> missingFiles = new ArrayList<String>();
-        for (String fileName : sAconfigTextProtoFilesOnDevice) {
-            File aconfigFile = new File(fileName);
-            if (!aconfigFile.exists()) {
-                missingFiles.add(fileName);
-            }
-        }
-
-        if (missingFiles.isEmpty()) {
-            pw.println("\nAconfig flags:");
-            for (String name : MyShellCommand.listAllAconfigFlags(iprovider)) {
-                pw.println(name);
-            }
-        } else {
-            pw.println("\nFailed to dump aconfig flags due to missing files:");
-            for (String fileName : missingFiles) {
-                pw.println(fileName);
-            }
-        }
-    }
+   }
 
     private static HashSet<String> getAconfigFlagNamesInDeviceConfig() {
         HashSet<String> nameSet = new HashSet<String>();
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/PredictiveBackHandler.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/PredictiveBackHandler.kt
index b00c8ad..8a6a0d6 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/PredictiveBackHandler.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/PredictiveBackHandler.kt
@@ -70,6 +70,7 @@
             // The predictive back APIs will automatically animate the progress for us in this case
             // so there is no need to animate it.
             cancelSpec = snap(),
+            animationScope = layoutImpl.animationScope,
         )
     }
 }
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transition/Seek.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transition/Seek.kt
index 715d979..2b33224 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transition/Seek.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transition/Seek.kt
@@ -30,6 +30,8 @@
 import com.android.compose.animation.scene.UserActionResult
 import com.android.compose.animation.scene.createSwipeAnimation
 import kotlin.coroutines.cancellation.CancellationException
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Job
 import kotlinx.coroutines.coroutineScope
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.collectLatest
@@ -141,6 +143,7 @@
     progress: Flow<Float>,
     commitSpec: AnimationSpec<Float>?,
     cancelSpec: AnimationSpec<Float>?,
+    animationScope: CoroutineScope? = null,
 ) {
     fun animateOffset(targetContent: T, spec: AnimationSpec<Float>?) {
         if (state.transitionState != animation.contentTransition || animation.isAnimatingOffset()) {
@@ -176,12 +179,20 @@
         }
 
         // Start the transition.
-        state.startTransition(animation.contentTransition)
+        animationScope?.launch { startTransition(state, animation, collectionJob) }
+            ?: startTransition(state, animation, collectionJob)
+    }
+}
 
-        // The transition is done. Cancel the collection in case the transition was finished because
-        // it was interrupted by another transition.
-        if (collectionJob.isActive) {
-            collectionJob.cancel()
-        }
+private suspend fun <T : ContentKey> startTransition(
+    state: MutableSceneTransitionLayoutStateImpl,
+    animation: SwipeAnimation<T>,
+    progressCollectionJob: Job,
+) {
+    state.startTransition(animation.contentTransition)
+    // The transition is done. Cancel the collection in case the transition was finished
+    // because it was interrupted by another transition.
+    if (progressCollectionJob.isActive) {
+        progressCollectionJob.cancel()
     }
 }
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
 
diff --git a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
index 3224b27..c234ee4 100644
--- a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
+++ b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
@@ -1616,7 +1616,13 @@
      * lock because this calls out to WindowManagerService.
      */
     void addWindowTokensForAllDisplays() {
-        final Display[] displays = mDisplayManager.getDisplays();
+        Display[] displays = {};
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            displays = mDisplayManager.getDisplays();
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
         for (int i = 0; i < displays.length; i++) {
             final int displayId = displays[i].getDisplayId();
             addWindowTokenForDisplay(displayId);
@@ -1652,7 +1658,13 @@
     }
 
     public void onRemoved() {
-        final Display[] displays = mDisplayManager.getDisplays();
+        Display[] displays = {};
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            displays = mDisplayManager.getDisplays();
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
         for (int i = 0; i < displays.length; i++) {
             final int displayId = displays[i].getDisplayId();
             onDisplayRemoved(displayId);
diff --git a/services/core/java/com/android/server/OWNERS b/services/core/java/com/android/server/OWNERS
index c15cf34..6858e29 100644
--- a/services/core/java/com/android/server/OWNERS
+++ b/services/core/java/com/android/server/OWNERS
@@ -31,6 +31,7 @@
 per-file *TimeUpdate* = file:/services/core/java/com/android/server/timezonedetector/OWNERS
 per-file DynamicSystemService.java = file:/packages/DynamicSystemInstallationService/OWNERS
 per-file GestureLauncherService.java = file:platform/packages/apps/EmergencyInfo:/OWNERS
+per-file GestureLauncherService.java = file:/INPUT_OWNERS
 per-file MmsServiceBroker.java = file:/telephony/OWNERS
 per-file NetIdManager.java = file:/services/core/java/com/android/server/net/OWNERS
 per-file PackageWatchdog.java = file:/services/core/java/com/android/server/crashrecovery/OWNERS
diff --git a/services/core/java/com/android/server/am/PhantomProcessList.java b/services/core/java/com/android/server/am/PhantomProcessList.java
index 2ec1aed..5bd9c05 100644
--- a/services/core/java/com/android/server/am/PhantomProcessList.java
+++ b/services/core/java/com/android/server/am/PhantomProcessList.java
@@ -112,23 +112,10 @@
     private final ActivityManagerService mService;
     private final Handler mKillHandler;
 
-    private static final int CGROUP_V1 = 0;
-    private static final int CGROUP_V2 = 1;
-    private static final String[] CGROUP_PATH_PREFIXES = {
-        "/acct/uid_" /* cgroup v1 */,
-        "/sys/fs/cgroup/uid_" /* cgroup v2 */
-    };
-    private static final String CGROUP_PID_PREFIX = "/pid_";
-    private static final String CGROUP_PROCS = "/cgroup.procs";
-
-    @VisibleForTesting
-    int mCgroupVersion = CGROUP_V1;
-
     PhantomProcessList(final ActivityManagerService service) {
         mService = service;
         mKillHandler = service.mProcessList.sKillHandler;
         mInjector = new Injector();
-        probeCgroupVersion();
     }
 
     @VisibleForTesting
@@ -157,9 +144,15 @@
         final int appPid = app.getPid();
         InputStream input = mCgroupProcsFds.get(appPid);
         if (input == null) {
-            final String path = getCgroupFilePath(app.info.uid, appPid);
+            String path = null;
             try {
+                path = getCgroupFilePath(app.info.uid, appPid);
                 input = mInjector.openCgroupProcs(path);
+            } catch (IllegalArgumentException e) {
+                if (DEBUG_PROCESSES) {
+                    Slog.w(TAG, "Unable to obtain cgroup.procs path ", e);
+                }
+                return;
             } catch (FileNotFoundException | SecurityException e) {
                 if (DEBUG_PROCESSES) {
                     Slog.w(TAG, "Unable to open " + path, e);
@@ -207,18 +200,9 @@
         }
     }
 
-    private void probeCgroupVersion() {
-        for (int i = CGROUP_PATH_PREFIXES.length - 1; i >= 0; i--) {
-            if ((new File(CGROUP_PATH_PREFIXES[i] + Process.SYSTEM_UID)).exists()) {
-                mCgroupVersion = i;
-                break;
-            }
-        }
-    }
-
     @VisibleForTesting
     String getCgroupFilePath(int uid, int pid) {
-        return CGROUP_PATH_PREFIXES[mCgroupVersion] + uid + CGROUP_PID_PREFIX + pid + CGROUP_PROCS;
+        return nativeGetCgroupProcsPath(uid, pid);
     }
 
     static String getProcessName(int pid) {
@@ -605,4 +589,7 @@
             return PhantomProcessList.getProcessName(pid);
         }
     }
+
+    private static native String nativeGetCgroupProcsPath(int uid, int pid)
+            throws IllegalArgumentException;
 }
diff --git a/services/core/java/com/android/server/audio/FadeOutManager.java b/services/core/java/com/android/server/audio/FadeOutManager.java
index 4d5bce5..fedfe51 100644
--- a/services/core/java/com/android/server/audio/FadeOutManager.java
+++ b/services/core/java/com/android/server/audio/FadeOutManager.java
@@ -199,7 +199,9 @@
             for (AudioPlaybackConfiguration apc : players) {
                 final VolumeShaper.Configuration volShaper =
                         mFadeConfigurations.getFadeOutVolumeShaperConfig(apc.getAudioAttributes());
-                fa.addFade(apc, /* skipRamp= */ false, volShaper);
+                if (volShaper != null) {
+                    fa.addFade(apc, /* skipRamp= */ false, volShaper);
+                }
             }
         }
     }
@@ -249,7 +251,7 @@
             final VolumeShaper.Configuration volShaper =
                     mFadeConfigurations.getFadeOutVolumeShaperConfig(apc.getAudioAttributes());
             final FadedOutApp fa = mUidToFadedAppsMap.get(apc.getClientUid());
-            if (fa == null) {
+            if (fa == null || volShaper == null) {
                 return;
             }
             fa.addFade(apc, /* skipRamp= */ true, volShaper);
diff --git a/services/core/java/com/android/server/powerstats/PowerStatsLogger.java b/services/core/java/com/android/server/powerstats/PowerStatsLogger.java
index e80a86d..4fd026a 100644
--- a/services/core/java/com/android/server/powerstats/PowerStatsLogger.java
+++ b/services/core/java/com/android/server/powerstats/PowerStatsLogger.java
@@ -285,14 +285,20 @@
     }
 
     private void updateCacheFile(String cacheFilename, byte[] data) {
+        AtomicFile atomicCachedFile = null;
+        FileOutputStream fos = null;
         try {
-            final AtomicFile atomicCachedFile =
+            atomicCachedFile =
                     new AtomicFile(new File(mDataStoragePath, cacheFilename));
-            final FileOutputStream fos = atomicCachedFile.startWrite();
+            fos = atomicCachedFile.startWrite();
             fos.write(data);
             atomicCachedFile.finishWrite(fos);
         } catch (IOException e) {
             Slog.e(TAG, "Failed to write current data to cached file", e);
+            if (fos != null) {
+                atomicCachedFile.failWrite(fos);
+            }
+            return;
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/CameraStateMonitor.java b/services/core/java/com/android/server/wm/CameraStateMonitor.java
index 8bfef6d..4140c04 100644
--- a/services/core/java/com/android/server/wm/CameraStateMonitor.java
+++ b/services/core/java/com/android/server/wm/CameraStateMonitor.java
@@ -106,8 +106,10 @@
     }
 
     void startListeningToCameraState() {
-        mCameraManager.registerAvailabilityCallback(
-                mWmService.mContext.getMainExecutor(), mAvailabilityCallback);
+        if (mCameraManager != null) {
+            mCameraManager.registerAvailabilityCallback(
+                    mWmService.mContext.getMainExecutor(), mAvailabilityCallback);
+        }
         mIsRunning = true;
     }
 
diff --git a/services/core/java/com/android/server/wm/PinnedTaskController.java b/services/core/java/com/android/server/wm/PinnedTaskController.java
index 755d4c8..6dd7d35 100644
--- a/services/core/java/com/android/server/wm/PinnedTaskController.java
+++ b/services/core/java/com/android/server/wm/PinnedTaskController.java
@@ -348,12 +348,14 @@
      * Notifies listeners that the PIP needs to be adjusted for the IME.
      */
     private void notifyImeVisibilityChanged(boolean imeVisible, int imeHeight) {
-        if (mPinnedTaskListener != null) {
-            try {
-                mPinnedTaskListener.onImeVisibilityChanged(imeVisible, imeHeight);
-            } catch (RemoteException e) {
-                Slog.e(TAG_WM, "Error delivering bounds changed event.", e);
-            }
+        if (mPinnedTaskListener == null) {
+            return;
+        }
+
+        try {
+            mPinnedTaskListener.onImeVisibilityChanged(imeVisible, imeHeight);
+        } catch (RemoteException e) {
+            Slog.e(TAG_WM, "Error delivering ime visibility changed event.", e);
         }
     }
 
@@ -361,15 +363,14 @@
      * Notifies listeners that the PIP movement bounds have changed.
      */
     private void notifyMovementBoundsChanged(boolean fromImeAdjustment) {
-        synchronized (mService.mGlobalLock) {
-            if (mPinnedTaskListener == null) {
-                return;
-            }
-            try {
-                mPinnedTaskListener.onMovementBoundsChanged(fromImeAdjustment);
-            } catch (RemoteException e) {
-                Slog.e(TAG_WM, "Error delivering actions changed event.", e);
-            }
+        if (mPinnedTaskListener == null) {
+            return;
+        }
+
+        try {
+            mPinnedTaskListener.onMovementBoundsChanged(fromImeAdjustment);
+        } catch (RemoteException e) {
+            Slog.e(TAG_WM, "Error delivering movement bounds changed event.", e);
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/ScreenRecordingCallbackController.java b/services/core/java/com/android/server/wm/ScreenRecordingCallbackController.java
index ad4faab..e1b6e5d 100644
--- a/services/core/java/com/android/server/wm/ScreenRecordingCallbackController.java
+++ b/services/core/java/com/android/server/wm/ScreenRecordingCallbackController.java
@@ -95,8 +95,9 @@
         if (mediaProjectionInfo.getLaunchCookie() == null) {
             mRecordedWC = (WindowContainer) mWms.mRoot.getDefaultDisplay();
         } else {
-            mRecordedWC = mWms.mRoot.getActivity(activity -> activity.mLaunchCookie
-                    == mediaProjectionInfo.getLaunchCookie().binder).getTask();
+            final ActivityRecord matchingActivity = mWms.mRoot.getActivity(activity ->
+                    activity.mLaunchCookie == mediaProjectionInfo.getLaunchCookie().binder);
+            mRecordedWC = matchingActivity != null ? matchingActivity.getTask() : null;
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java
index 42ea5a8..83d08cc 100644
--- a/services/core/java/com/android/server/wm/TaskDisplayArea.java
+++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java
@@ -843,7 +843,7 @@
      */
     void positionTaskBehindHome(Task task) {
         final Task home = getOrCreateRootHomeTask();
-        final WindowContainer homeParent = home.getParent();
+        final WindowContainer homeParent = home != null ? home.getParent() : null;
         final Task homeParentTask = homeParent != null ? homeParent.asTask() : null;
         if (homeParentTask == null) {
             // reparent throws if parent didn't change...
diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp
index 2c03902..97ae6be 100644
--- a/services/core/jni/Android.bp
+++ b/services/core/jni/Android.bp
@@ -79,6 +79,7 @@
         ":lib_oomConnection_native",
         ":lib_anrTimer_native",
         ":lib_lazilyRegisteredServices_native",
+        ":lib_phantomProcessList_native",
     ],
 
     include_dirs: [
@@ -264,3 +265,10 @@
         "com_android_server_vr_VrManagerService.cpp",
     ],
 }
+
+filegroup {
+    name: "lib_phantomProcessList_native",
+    srcs: [
+        "com_android_server_am_PhantomProcessList.cpp",
+    ],
+}
diff --git a/services/core/jni/com_android_server_am_PhantomProcessList.cpp b/services/core/jni/com_android_server_am_PhantomProcessList.cpp
new file mode 100644
index 0000000..0c5e6d8
--- /dev/null
+++ b/services/core/jni/com_android_server_am_PhantomProcessList.cpp
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+
+#include <jni.h>
+#include <nativehelper/JNIHelp.h>
+#include <processgroup/processgroup.h>
+
+namespace android {
+namespace {
+
+jstring getCgroupProcsPath(JNIEnv* env, jobject clazz, jint uid, jint pid) {
+    if (uid < 0) {
+        jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", "uid is negative: %d", uid);
+        return nullptr;
+    }
+
+    std::string path;
+    if (!CgroupGetAttributePathForProcess("CgroupProcs", uid, pid, path)) {
+        path.clear();
+    }
+
+    return env->NewStringUTF(path.c_str());
+}
+
+const JNINativeMethod sMethods[] = {
+        {"nativeGetCgroupProcsPath", "(II)Ljava/lang/String;", (void*)getCgroupProcsPath},
+};
+
+} // anonymous namespace
+
+int register_android_server_am_PhantomProcessList(JNIEnv* env) {
+    const char* className = "com/android/server/am/PhantomProcessList";
+    return jniRegisterNativeMethods(env, className, sMethods, NELEM(sMethods));
+}
+
+} // namespace android
\ No newline at end of file
diff --git a/services/core/jni/onload.cpp b/services/core/jni/onload.cpp
index df37ec3..a12eb31 100644
--- a/services/core/jni/onload.cpp
+++ b/services/core/jni/onload.cpp
@@ -70,6 +70,7 @@
 int register_com_android_server_SystemClockTime(JNIEnv* env);
 int register_android_server_display_smallAreaDetectionController(JNIEnv* env);
 int register_com_android_server_accessibility_BrailleDisplayConnection(JNIEnv* env);
+int register_android_server_am_PhantomProcessList(JNIEnv* env);
 
 // Note: Consider adding new JNI entrypoints for optional services to
 // LazyJniRegistrar instead, and relying on lazy registration.
@@ -135,5 +136,6 @@
     register_com_android_server_SystemClockTime(env);
     register_android_server_display_smallAreaDetectionController(env);
     register_com_android_server_accessibility_BrailleDisplayConnection(env);
+    register_android_server_am_PhantomProcessList(env);
     return JNI_VERSION_1_4;
 }
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index ac95f04..c80d6db 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -3033,10 +3033,10 @@
         if (com.android.ranging.flags.Flags.rangingStackEnabled()) {
             if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_UWB)
                     || context.getPackageManager().hasSystemFeature(
-                            PackageManager.FEATURE_WIFI_RTT)
+                            PackageManager.FEATURE_WIFI_AWARE)
                     || (com.android.ranging.flags.Flags.rangingCsEnabled()
                             && context.getPackageManager().hasSystemFeature(
-                                    PackageManager.FEATURE_BLUETOOTH_LE_CHANNEL_SOUNDING))) {
+                                    PackageManager.FEATURE_BLUETOOTH_LE))) {
                 t.traceBegin("RangingService");
                 // TODO: b/375264320 - Remove after RELEASE_RANGING_STACK is ramped to next.
                 try {
diff --git a/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionPolicy.kt b/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionPolicy.kt
index d2c91ff..232bb83 100644
--- a/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionPolicy.kt
+++ b/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionPolicy.kt
@@ -286,14 +286,21 @@
                 return@forEach
             }
             var newFlags = oldFlags
+            val isSystemOrInstalled =
+                packageState.isSystem || packageState.getUserStateOrDefault(userId).isInstalled
             newFlags =
                 if (
-                    newFlags.hasBits(PermissionFlags.ROLE) ||
-                        newFlags.hasBits(PermissionFlags.PREGRANT)
+                    isSystemOrInstalled && (
+                        newFlags.hasBits(PermissionFlags.ROLE) ||
+                            newFlags.hasBits(PermissionFlags.PREGRANT)
+                    )
                 ) {
                     newFlags or PermissionFlags.RUNTIME_GRANTED
                 } else {
-                    newFlags andInv PermissionFlags.RUNTIME_GRANTED
+                    newFlags andInv (
+                        PermissionFlags.RUNTIME_GRANTED or PermissionFlags.ROLE or
+                            PermissionFlags.PREGRANT
+                    )
                 }
             newFlags = newFlags andInv USER_SETTABLE_MASK
             if (newFlags.hasBits(PermissionFlags.LEGACY_GRANTED)) {
diff --git a/services/tests/PermissionServiceMockingTests/src/com/android/server/permission/test/AppIdPermissionPolicyPermissionResetTest.kt b/services/tests/PermissionServiceMockingTests/src/com/android/server/permission/test/AppIdPermissionPolicyPermissionResetTest.kt
index 1237095..8b357862d 100644
--- a/services/tests/PermissionServiceMockingTests/src/com/android/server/permission/test/AppIdPermissionPolicyPermissionResetTest.kt
+++ b/services/tests/PermissionServiceMockingTests/src/com/android/server/permission/test/AppIdPermissionPolicyPermissionResetTest.kt
@@ -72,7 +72,8 @@
         } else {
             mockPackageState(
                 APP_ID_1,
-                mockAndroidPackage(PACKAGE_NAME_1, requestedPermissions = setOf(PERMISSION_NAME_0))
+                mockAndroidPackage(PACKAGE_NAME_1, requestedPermissions = setOf(PERMISSION_NAME_0)),
+                true
             )
         }
         setPermissionFlags(APP_ID_1, USER_ID_0, PERMISSION_NAME_0, oldFlags)
diff --git a/services/tests/mockingservicestests/jni/Android.bp b/services/tests/mockingservicestests/jni/Android.bp
index 94d4b95..03bd73c 100644
--- a/services/tests/mockingservicestests/jni/Android.bp
+++ b/services/tests/mockingservicestests/jni/Android.bp
@@ -24,6 +24,7 @@
         ":lib_freezer_native",
         ":lib_oomConnection_native",
         ":lib_lazilyRegisteredServices_native",
+        ":lib_phantomProcessList_native",
         "onload.cpp",
     ],
 
diff --git a/services/tests/mockingservicestests/jni/onload.cpp b/services/tests/mockingservicestests/jni/onload.cpp
index 9b4c817..30fa7de 100644
--- a/services/tests/mockingservicestests/jni/onload.cpp
+++ b/services/tests/mockingservicestests/jni/onload.cpp
@@ -28,6 +28,7 @@
 int register_android_server_am_Freezer(JNIEnv* env);
 int register_android_server_am_OomConnection(JNIEnv* env);
 int register_android_server_utils_LazyJniRegistrar(JNIEnv* env);
+int register_android_server_am_PhantomProcessList(JNIEnv* env);
 };
 
 using namespace android;
@@ -46,5 +47,6 @@
     register_android_server_am_Freezer(env);
     register_android_server_am_OomConnection(env);
     register_android_server_utils_LazyJniRegistrar(env);
+    register_android_server_am_PhantomProcessList(env);
     return JNI_VERSION_1_4;
 }
diff --git a/services/tests/servicestests/src/com/android/server/OWNERS b/services/tests/servicestests/src/com/android/server/OWNERS
index d8a9400..69feb1d 100644
--- a/services/tests/servicestests/src/com/android/server/OWNERS
+++ b/services/tests/servicestests/src/com/android/server/OWNERS
@@ -6,5 +6,6 @@
 per-file *Network* = file:/services/core/java/com/android/server/net/OWNERS
 per-file BatteryServiceTest.java = file:platform/hardware/interfaces:/health/OWNERS
 per-file GestureLauncherServiceTest.java = file:platform/packages/apps/EmergencyInfo:/OWNERS
+per-file GestureLauncherServiceTest.java = file:/INPUT_OWNERS
 per-file PinnerServiceTest.java = file:/apct-tests/perftests/OWNERS
 per-file SecurityStateTest.java = file:/SECURITY_STATE_OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
index a0f2395..d70ffd2 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
@@ -159,7 +159,7 @@
     /**
      * Test for the first launch path, no settings file available.
      */
-    public void testFirstInitialize() {
+    public void FirstInitialize() {
         assertResetTimes(START_TIME, START_TIME + INTERVAL);
     }
 
@@ -167,7 +167,7 @@
      * Test for {@link ShortcutService#getLastResetTimeLocked()} and
      * {@link ShortcutService#getNextResetTimeLocked()}.
      */
-    public void testUpdateAndGetNextResetTimeLocked() {
+    public void UpdateAndGetNextResetTimeLocked() {
         assertResetTimes(START_TIME, START_TIME + INTERVAL);
 
         // Advance clock.
@@ -196,7 +196,7 @@
     /**
      * Test for the restoration from saved file.
      */
-    public void testInitializeFromSavedFile() {
+    public void InitializeFromSavedFile() {
 
         mInjectedCurrentTimeMillis = START_TIME + 4 * INTERVAL + 50;
         assertResetTimes(START_TIME + 4 * INTERVAL, START_TIME + 5 * INTERVAL);
@@ -220,7 +220,7 @@
         // TODO Add various broken cases.
     }
 
-    public void testLoadConfig() {
+    public void LoadConfig() {
         mService.updateConfigurationLocked(
                 ConfigConstants.KEY_RESET_INTERVAL_SEC + "=123,"
                         + ConfigConstants.KEY_MAX_SHORTCUTS + "=4,"
@@ -261,22 +261,22 @@
     // === Test for app side APIs ===
 
     /** Test for {@link android.content.pm.ShortcutManager#getMaxShortcutCountForActivity()} */
-    public void testGetMaxDynamicShortcutCount() {
+    public void GetMaxDynamicShortcutCount() {
         assertEquals(MAX_SHORTCUTS, mManager.getMaxShortcutCountForActivity());
     }
 
     /** Test for {@link android.content.pm.ShortcutManager#getRemainingCallCount()} */
-    public void testGetRemainingCallCount() {
+    public void GetRemainingCallCount() {
         assertEquals(MAX_UPDATES_PER_INTERVAL, mManager.getRemainingCallCount());
     }
 
-    public void testGetIconMaxDimensions() {
+    public void GetIconMaxDimensions() {
         assertEquals(MAX_ICON_DIMENSION, mManager.getIconMaxWidth());
         assertEquals(MAX_ICON_DIMENSION, mManager.getIconMaxHeight());
     }
 
     /** Test for {@link android.content.pm.ShortcutManager#getRateLimitResetTime()} */
-    public void testGetRateLimitResetTime() {
+    public void GetRateLimitResetTime() {
         assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime());
 
         mInjectedCurrentTimeMillis = START_TIME + 4 * INTERVAL + 50;
@@ -284,7 +284,7 @@
         assertEquals(START_TIME + 5 * INTERVAL, mManager.getRateLimitResetTime());
     }
 
-    public void testSetDynamicShortcuts() {
+    public void SetDynamicShortcuts() {
         setCaller(CALLING_PACKAGE_1, USER_0);
 
         final Icon icon1 = Icon.createWithResource(getTestContext(), R.drawable.icon1);
@@ -354,7 +354,7 @@
         });
     }
 
-    public void testAddDynamicShortcuts() {
+    public void AddDynamicShortcuts() {
         setCaller(CALLING_PACKAGE_1, USER_0);
 
         final ShortcutInfo si1 = makeShortcut("shortcut1");
@@ -402,7 +402,7 @@
         });
     }
 
-    public void testPushDynamicShortcut() {
+    public void PushDynamicShortcut() {
         // Change the max number of shortcuts.
         mService.updateConfigurationLocked(ConfigConstants.KEY_MAX_SHORTCUTS + "=5,"
                 + ShortcutService.ConfigConstants.KEY_SAVE_DELAY_MILLIS + "=1");
@@ -543,7 +543,7 @@
                 eq(CALLING_PACKAGE_1), eq("s9"), eq(USER_0));
     }
 
-    public void testPushDynamicShortcut_CallsToUsageStatsManagerAreThrottled()
+    public void PushDynamicShortcut_CallsToUsageStatsManagerAreThrottled()
             throws InterruptedException {
         mService.updateConfigurationLocked(
                 ShortcutService.ConfigConstants.KEY_SAVE_DELAY_MILLIS + "=500");
@@ -594,7 +594,7 @@
                 eq(CALLING_PACKAGE_2), any(), eq(USER_0));
     }
 
-    public void testUnlimitedCalls() {
+    public void UnlimitedCalls() {
         setCaller(CALLING_PACKAGE_1, USER_0);
 
         final ShortcutInfo si1 = makeShortcut("shortcut1");
@@ -625,7 +625,7 @@
         assertEquals(3, mManager.getRemainingCallCount());
     }
 
-    public void testPublishWithNoActivity() {
+    public void PublishWithNoActivity() {
         // If activity is not explicitly set, use the default one.
 
         mRunningUsers.put(USER_10, true);
@@ -731,7 +731,7 @@
         });
     }
 
-    public void testPublishWithNoActivity_noMainActivityInPackage() {
+    public void PublishWithNoActivity_noMainActivityInPackage() {
         mRunningUsers.put(USER_10, true);
 
         runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
@@ -750,7 +750,7 @@
         });
     }
 
-    public void testDeleteDynamicShortcuts() {
+    public void DeleteDynamicShortcuts() {
         final ShortcutInfo si1 = makeShortcut("shortcut1");
         final ShortcutInfo si2 = makeShortcut("shortcut2");
         final ShortcutInfo si3 = makeShortcut("shortcut3");
@@ -791,7 +791,7 @@
         assertEquals(2, mManager.getRemainingCallCount());
     }
 
-    public void testDeleteAllDynamicShortcuts() {
+    public void DeleteAllDynamicShortcuts() {
         final ShortcutInfo si1 = makeShortcut("shortcut1");
         final ShortcutInfo si2 = makeShortcut("shortcut2");
         final ShortcutInfo si3 = makeShortcut("shortcut3");
@@ -820,7 +820,7 @@
         assertEquals(1, mManager.getRemainingCallCount());
     }
 
-    public void testIcons() throws IOException {
+    public void Icons() throws IOException {
         final Icon res32x32 = Icon.createWithResource(getTestContext(), R.drawable.black_32x32);
         final Icon res64x64 = Icon.createWithResource(getTestContext(), R.drawable.black_64x64);
         final Icon res512x512 = Icon.createWithResource(getTestContext(), R.drawable.black_512x512);
@@ -1034,7 +1034,7 @@
 */
     }
 
-    public void testCleanupDanglingBitmaps() throws Exception {
+    public void CleanupDanglingBitmaps() throws Exception {
         assertBitmapDirectories(USER_0, EMPTY_STRINGS);
         assertBitmapDirectories(USER_10, EMPTY_STRINGS);
 
@@ -1203,7 +1203,7 @@
                         maxSize));
     }
 
-    public void testShrinkBitmap() {
+    public void ShrinkBitmap() {
         checkShrinkBitmap(32, 32, R.drawable.black_512x512, 32);
         checkShrinkBitmap(511, 511, R.drawable.black_512x512, 511);
         checkShrinkBitmap(512, 512, R.drawable.black_512x512, 512);
@@ -1226,7 +1226,7 @@
         return out.getFile();
     }
 
-    public void testOpenIconFileForWrite() throws IOException {
+    public void OpenIconFileForWrite() throws IOException {
         mInjectedCurrentTimeMillis = 1000;
 
         final File p10_1_1 = openIconFileForWriteAndGetPath(10, CALLING_PACKAGE_1);
@@ -1300,7 +1300,7 @@
         assertFalse(p11_1_3.getName().contains("_"));
     }
 
-    public void testUpdateShortcuts() {
+    public void UpdateShortcuts() {
         runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> {
             assertTrue(mManager.setDynamicShortcuts(list(
                     makeShortcut("s1"),
@@ -1431,7 +1431,7 @@
         });
     }
 
-    public void testUpdateShortcuts_icons() {
+    public void UpdateShortcuts_icons() {
         runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> {
             assertTrue(mManager.setDynamicShortcuts(list(
                     makeShortcut("s1")
@@ -1525,7 +1525,7 @@
         });
     }
 
-    public void testShortcutManagerGetShortcuts_shortcutTypes() {
+    public void ShortcutManagerGetShortcuts_shortcutTypes() {
 
         // Create 3 manifest and 3 dynamic shortcuts
         addManifestShortcutResource(
@@ -1616,7 +1616,7 @@
         assertShortcutIds(mManager.getShortcuts(ShortcutManager.FLAG_MATCH_CACHED), "s1", "s2");
     }
 
-    public void testCachedShortcuts() {
+    public void CachedShortcuts() {
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
             assertTrue(mManager.setDynamicShortcuts(list(makeShortcut("s1"),
                     makeLongLivedShortcut("s2"), makeLongLivedShortcut("s3"),
@@ -1700,7 +1700,7 @@
                 "s2");
     }
 
-    public void testCachedShortcuts_accessShortcutsPermission() {
+    public void CachedShortcuts_accessShortcutsPermission() {
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
             assertTrue(mManager.setDynamicShortcuts(list(makeShortcut("s1"),
                     makeLongLivedShortcut("s2"), makeLongLivedShortcut("s3"),
@@ -1742,7 +1742,7 @@
         assertShortcutIds(mManager.getShortcuts(ShortcutManager.FLAG_MATCH_CACHED), "s3");
     }
 
-    public void testCachedShortcuts_canPassShortcutLimit() {
+    public void CachedShortcuts_canPassShortcutLimit() {
         // Change the max number of shortcuts.
         mService.updateConfigurationLocked(ConfigConstants.KEY_MAX_SHORTCUTS + "=4");
 
@@ -1780,7 +1780,7 @@
 
     // === Test for launcher side APIs ===
 
-    public void testGetShortcuts() {
+    public void GetShortcuts() {
 
         // Set up shortcuts.
 
@@ -1997,7 +1997,7 @@
                 "s1", "s3");
     }
 
-    public void testGetShortcuts_shortcutKinds() throws Exception {
+    public void GetShortcuts_shortcutKinds() throws Exception {
         // Create 3 manifest and 3 dynamic shortcuts
         addManifestShortcutResource(
                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
@@ -2108,7 +2108,7 @@
         });
     }
 
-    public void testGetShortcuts_resolveStrings() throws Exception {
+    public void GetShortcuts_resolveStrings() throws Exception {
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
             ShortcutInfo si = new ShortcutInfo.Builder(mClientContext)
                     .setId("id")
@@ -2156,7 +2156,7 @@
         });
     }
 
-    public void testGetShortcuts_personsFlag() {
+    public void GetShortcuts_personsFlag() {
         ShortcutInfo s = new ShortcutInfo.Builder(mClientContext, "id")
                 .setShortLabel("label")
                 .setActivity(new ComponentName(mClientContext, ShortcutActivity2.class))
@@ -2204,7 +2204,7 @@
     }
 
     // TODO resource
-    public void testGetShortcutInfo() {
+    public void GetShortcutInfo() {
         // Create shortcuts.
         setCaller(CALLING_PACKAGE_1);
         final ShortcutInfo s1_1 = makeShortcut(
@@ -2279,7 +2279,7 @@
         assertEquals("ABC", findById(list, "s1").getTitle());
     }
 
-    public void testPinShortcutAndGetPinnedShortcuts() {
+    public void PinShortcutAndGetPinnedShortcuts() {
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
             final ShortcutInfo s1_1 = makeShortcutWithTimestamp("s1", 1000);
             final ShortcutInfo s1_2 = makeShortcutWithTimestamp("s2", 2000);
@@ -2360,7 +2360,7 @@
      * This is similar to the above test, except it used "disable" instead of "remove".  It also
      * does "enable".
      */
-    public void testDisableAndEnableShortcuts() {
+    public void DisableAndEnableShortcuts() {
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
             final ShortcutInfo s1_1 = makeShortcutWithTimestamp("s1", 1000);
             final ShortcutInfo s1_2 = makeShortcutWithTimestamp("s2", 2000);
@@ -2485,7 +2485,7 @@
         });
     }
 
-    public void testDisableShortcuts_thenRepublish() {
+    public void DisableShortcuts_thenRepublish() {
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
             assertTrue(mManager.setDynamicShortcuts(list(
                     makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
@@ -2555,7 +2555,7 @@
         });
     }
 
-    public void testPinShortcutAndGetPinnedShortcuts_multi() {
+    public void PinShortcutAndGetPinnedShortcuts_multi() {
         // Create some shortcuts.
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
             assertTrue(mManager.setDynamicShortcuts(list(
@@ -2831,7 +2831,7 @@
         });
     }
 
-    public void testPinShortcutAndGetPinnedShortcuts_assistant() {
+    public void PinShortcutAndGetPinnedShortcuts_assistant() {
         // Create some shortcuts.
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
             assertTrue(mManager.setDynamicShortcuts(list(
@@ -2887,7 +2887,7 @@
         });
     }
 
-    public void testPinShortcutAndGetPinnedShortcuts_crossProfile_plusLaunch() {
+    public void PinShortcutAndGetPinnedShortcuts_crossProfile_plusLaunch() {
         // Create some shortcuts.
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
             assertTrue(mManager.setDynamicShortcuts(list(
@@ -3476,7 +3476,7 @@
         });
     }
 
-    public void testStartShortcut() {
+    public void StartShortcut() {
         // Create some shortcuts.
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
             final ShortcutInfo s1_1 = makeShortcut(
@@ -3611,7 +3611,7 @@
         // TODO Check extra, etc
     }
 
-    public void testLauncherCallback() throws Throwable {
+    public void LauncherCallback() throws Throwable {
         // Disable throttling for this test.
         mService.updateConfigurationLocked(
                 ConfigConstants.KEY_MAX_UPDATES_PER_INTERVAL + "=99999999,"
@@ -3777,7 +3777,7 @@
                 .isEmpty();
     }
 
-    public void testLauncherCallback_crossProfile() throws Throwable {
+    public void LauncherCallback_crossProfile() throws Throwable {
         prepareCrossProfileDataSet();
 
         final Handler h = new Handler(Looper.getMainLooper());
@@ -3900,7 +3900,7 @@
 
     // === Test for persisting ===
 
-    public void testSaveAndLoadUser_empty() {
+    public void SaveAndLoadUser_empty() {
         assertTrue(mManager.setDynamicShortcuts(list()));
 
         Log.i(TAG, "Saved state");
@@ -3917,7 +3917,7 @@
     /**
      * Try save and load, also stop/start the user.
      */
-    public void testSaveAndLoadUser() {
+    public void SaveAndLoadUser() {
         // First, create some shortcuts and save.
         runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> {
             final Icon icon1 = Icon.createWithResource(getTestContext(), R.drawable.black_64x16);
@@ -4058,7 +4058,7 @@
         // TODO Check all other fields
     }
 
-    public void testLoadCorruptedShortcuts() throws Exception {
+    public void LoadCorruptedShortcuts() throws Exception {
         initService();
 
         addPackage("com.android.chrome", 0, 0);
@@ -4072,7 +4072,7 @@
         assertNull(ShortcutPackage.loadFromFile(mService, user, corruptedShortcutPackage, false));
     }
 
-    public void testSaveCorruptAndLoadUser() throws Exception {
+    public void SaveCorruptAndLoadUser() throws Exception {
         // First, create some shortcuts and save.
         runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> {
             final Icon icon1 = Icon.createWithResource(getTestContext(), R.drawable.black_64x16);
@@ -4228,7 +4228,7 @@
         // TODO Check all other fields
     }
 
-    public void testCleanupPackage() {
+    public void CleanupPackage() {
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
             assertTrue(mManager.setDynamicShortcuts(list(
                     makeShortcut("s0_1"))));
@@ -4505,7 +4505,7 @@
         mService.saveDirtyInfo();
     }
 
-    public void testCleanupPackage_republishManifests() {
+    public void CleanupPackage_republishManifests() {
         addManifestShortcutResource(
                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
                 R.xml.shortcut_2);
@@ -4573,7 +4573,7 @@
         });
     }
 
-    public void testHandleGonePackage_crossProfile() {
+    public void HandleGonePackage_crossProfile() {
         // Create some shortcuts.
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
             assertTrue(mManager.setDynamicShortcuts(list(
@@ -4845,7 +4845,7 @@
         assertEquals(expected, spi.canRestoreTo(mService, pi, true));
     }
 
-    public void testCanRestoreTo() {
+    public void CanRestoreTo() {
         addPackage(CALLING_PACKAGE_1, CALLING_UID_1, 10, "sig1");
         addPackage(CALLING_PACKAGE_2, CALLING_UID_2, 10, "sig1", "sig2");
         addPackage(CALLING_PACKAGE_3, CALLING_UID_3, 10, "sig1");
@@ -4908,7 +4908,7 @@
         checkCanRestoreTo(DISABLED_REASON_BACKUP_NOT_SUPPORTED, spi3, true, 10, true, "sig1");
     }
 
-    public void testHandlePackageDelete() {
+    public void HandlePackageDelete() {
         checkHandlePackageDeleteInner((userId, packageName) -> {
             uninstallPackage(userId, packageName);
             mService.mPackageMonitor.onReceive(getTestContext(),
@@ -4916,7 +4916,7 @@
         });
     }
 
-    public void testHandlePackageDisable() {
+    public void HandlePackageDisable() {
         checkHandlePackageDeleteInner((userId, packageName) -> {
             disablePackage(userId, packageName);
             mService.mPackageMonitor.onReceive(getTestContext(),
@@ -5048,7 +5048,7 @@
     }
 
     /** Almost ame as testHandlePackageDelete, except it doesn't uninstall packages. */
-    public void testHandlePackageClearData() {
+    public void HandlePackageClearData() {
         final Icon bmp32x32 = Icon.createWithBitmap(BitmapFactory.decodeResource(
                 getTestContext().getResources(), R.drawable.black_32x32));
         setCaller(CALLING_PACKAGE_1, USER_0);
@@ -5124,7 +5124,7 @@
         assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_10));
     }
 
-    public void testHandlePackageClearData_manifestRepublished() {
+    public void HandlePackageClearData_manifestRepublished() {
 
         mRunningUsers.put(USER_10, true);
 
@@ -5166,7 +5166,7 @@
         });
     }
 
-    public void testHandlePackageUpdate() throws Throwable {
+    public void HandlePackageUpdate() throws Throwable {
         // Set up shortcuts and launchers.
 
         final Icon res32x32 = Icon.createWithResource(getTestContext(), R.drawable.black_32x32);
@@ -5340,7 +5340,7 @@
     /**
      * Test the case where an updated app has resource IDs changed.
      */
-    public void testHandlePackageUpdate_resIdChanged() throws Exception {
+    public void HandlePackageUpdate_resIdChanged() throws Exception {
         final Icon icon1 = Icon.createWithResource(getTestContext(), /* res ID */ 1000);
         final Icon icon2 = Icon.createWithResource(getTestContext(), /* res ID */ 1001);
 
@@ -5415,7 +5415,7 @@
         });
     }
 
-    public void testHandlePackageUpdate_systemAppUpdate() {
+    public void HandlePackageUpdate_systemAppUpdate() {
 
         // Package1 is a system app.  Package 2 is not a system app, so it's not scanned
         // in this test at all.
@@ -5521,7 +5521,7 @@
                 mService.getUserShortcutsLocked(USER_0).getLastAppScanOsFingerprint());
     }
 
-    public void testHandlePackageChanged() {
+    public void HandlePackageChanged() {
         final ComponentName ACTIVITY1 = new ComponentName(CALLING_PACKAGE_1, "act1");
         final ComponentName ACTIVITY2 = new ComponentName(CALLING_PACKAGE_1, "act2");
 
@@ -5651,7 +5651,7 @@
         });
     }
 
-    public void testHandlePackageUpdate_activityNoLongerMain() throws Throwable {
+    public void HandlePackageUpdate_activityNoLongerMain() throws Throwable {
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
             assertTrue(mManager.setDynamicShortcuts(list(
                     makeShortcutWithActivity("s1a",
@@ -5737,7 +5737,7 @@
      * - Unpinned dynamic shortcuts
      * - Bitmaps
      */
-    public void testBackupAndRestore() {
+    public void BackupAndRestore() {
 
         assertFileNotExists("user-0/shortcut_dump/restore-0-start.txt");
         assertFileNotExists("user-0/shortcut_dump/restore-1-payload.xml");
@@ -5758,7 +5758,7 @@
         checkBackupAndRestore_success(/*firstRestore=*/ true);
     }
 
-    public void testBackupAndRestore_backupRestoreTwice() {
+    public void BackupAndRestore_backupRestoreTwice() {
         prepareForBackupTest();
 
         checkBackupAndRestore_success(/*firstRestore=*/ true);
@@ -5774,7 +5774,7 @@
         checkBackupAndRestore_success(/*firstRestore=*/ false);
     }
 
-    public void testBackupAndRestore_restoreToNewVersion() {
+    public void BackupAndRestore_restoreToNewVersion() {
         prepareForBackupTest();
 
         addPackage(CALLING_PACKAGE_1, CALLING_UID_1, 2);
@@ -5783,7 +5783,7 @@
         checkBackupAndRestore_success(/*firstRestore=*/ true);
     }
 
-    public void testBackupAndRestore_restoreToSuperSetSignatures() {
+    public void BackupAndRestore_restoreToSuperSetSignatures() {
         prepareForBackupTest();
 
         // Change package signatures.
@@ -5980,7 +5980,7 @@
         });
     }
 
-    public void testBackupAndRestore_publisherWrongSignature() {
+    public void BackupAndRestore_publisherWrongSignature() {
         prepareForBackupTest();
 
         addPackage(CALLING_PACKAGE_1, CALLING_UID_1, 10, "sigx"); // different signature
@@ -5988,7 +5988,7 @@
         checkBackupAndRestore_publisherNotRestored(ShortcutInfo.DISABLED_REASON_SIGNATURE_MISMATCH);
     }
 
-    public void testBackupAndRestore_publisherNoLongerBackupTarget() {
+    public void BackupAndRestore_publisherNoLongerBackupTarget() {
         prepareForBackupTest();
 
         updatePackageInfo(CALLING_PACKAGE_1,
@@ -6117,7 +6117,7 @@
         });
     }
 
-    public void testBackupAndRestore_launcherLowerVersion() {
+    public void BackupAndRestore_launcherLowerVersion() {
         prepareForBackupTest();
 
         addPackage(LAUNCHER_1, LAUNCHER_UID_1, 0); // Lower version
@@ -6126,7 +6126,7 @@
         checkBackupAndRestore_success(/*firstRestore=*/ true);
     }
 
-    public void testBackupAndRestore_launcherWrongSignature() {
+    public void BackupAndRestore_launcherWrongSignature() {
         prepareForBackupTest();
 
         addPackage(LAUNCHER_1, LAUNCHER_UID_1, 10, "sigx"); // different signature
@@ -6134,7 +6134,7 @@
         checkBackupAndRestore_launcherNotRestored(true);
     }
 
-    public void testBackupAndRestore_launcherNoLongerBackupTarget() {
+    public void BackupAndRestore_launcherNoLongerBackupTarget() {
         prepareForBackupTest();
 
         updatePackageInfo(LAUNCHER_1,
@@ -6239,7 +6239,7 @@
         });
     }
 
-    public void testBackupAndRestore_launcherAndPackageNoLongerBackupTarget() {
+    public void BackupAndRestore_launcherAndPackageNoLongerBackupTarget() {
         prepareForBackupTest();
 
         updatePackageInfo(CALLING_PACKAGE_1,
@@ -6337,7 +6337,7 @@
         });
     }
 
-    public void testBackupAndRestore_disabled() {
+    public void BackupAndRestore_disabled() {
         prepareCrossProfileDataSet();
 
         // Before doing backup & restore, disable s1.
@@ -6402,7 +6402,7 @@
     }
 
 
-    public void testBackupAndRestore_manifestRePublished() {
+    public void BackupAndRestore_manifestRePublished() {
         // Publish two manifest shortcuts.
         addManifestShortcutResource(
                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
@@ -6493,7 +6493,7 @@
      * logcat.
      * - if it has allowBackup=false, we don't touch any of the existing shortcuts.
      */
-    public void testBackupAndRestore_appAlreadyInstalledWhenRestored() {
+    public void BackupAndRestore_appAlreadyInstalledWhenRestored() {
         // Pre-backup.  Same as testBackupAndRestore_manifestRePublished().
 
         // Publish two manifest shortcuts.
@@ -6618,7 +6618,7 @@
     /**
      * Test for restoring the pre-P backup format.
      */
-    public void testBackupAndRestore_api27format() throws Exception {
+    public void BackupAndRestore_api27format() throws Exception {
         final byte[] payload = readTestAsset("shortcut/shortcut_api27_backup.xml").getBytes();
 
         addPackage(CALLING_PACKAGE_1, CALLING_UID_1, 10, "22222");
@@ -6656,7 +6656,7 @@
 
     }
 
-    public void testSaveAndLoad_crossProfile() {
+    public void SaveAndLoad_crossProfile() {
         prepareCrossProfileDataSet();
 
         dumpsysOnLogcat("Before save & load");
@@ -6859,7 +6859,7 @@
                         .getPackageUserId());
     }
 
-    public void testOnApplicationActive_permission() {
+    public void OnApplicationActive_permission() {
         assertExpectException(SecurityException.class, "Missing permission", () ->
                 mManager.onApplicationActive(CALLING_PACKAGE_1, USER_0));
 
@@ -6868,7 +6868,7 @@
         mManager.onApplicationActive(CALLING_PACKAGE_1, USER_0);
     }
 
-    public void testGetShareTargets_permission() {
+    public void GetShareTargets_permission() {
         addPackage(CHOOSER_ACTIVITY_PACKAGE, CHOOSER_ACTIVITY_UID, 10, "sig1");
         mInjectedChooserActivity =
                 ComponentName.createRelative(CHOOSER_ACTIVITY_PACKAGE, ".ChooserActivity");
@@ -6887,7 +6887,7 @@
         });
     }
 
-    public void testHasShareTargets_permission() {
+    public void HasShareTargets_permission() {
         assertExpectException(SecurityException.class, "Missing permission", () ->
                 mManager.hasShareTargets(CALLING_PACKAGE_1));
 
@@ -6896,7 +6896,7 @@
         mManager.hasShareTargets(CALLING_PACKAGE_1);
     }
 
-    public void testisSharingShortcut_permission() throws IntentFilter.MalformedMimeTypeException {
+    public void isSharingShortcut_permission() throws IntentFilter.MalformedMimeTypeException {
         setCaller(LAUNCHER_1, USER_0);
 
         IntentFilter filter_any = new IntentFilter();
@@ -6911,18 +6911,18 @@
         mManager.hasShareTargets(CALLING_PACKAGE_1);
     }
 
-    public void testDumpsys_crossProfile() {
+    public void Dumpsys_crossProfile() {
         prepareCrossProfileDataSet();
         dumpsysOnLogcat("test1", /* force= */ true);
     }
 
-    public void testDumpsys_withIcons() throws IOException {
-        testIcons();
+    public void Dumpsys_withIcons() throws IOException {
+        Icons();
         // Dump after having some icons.
         dumpsysOnLogcat("test1", /* force= */ true);
     }
 
-    public void testManifestShortcut_publishOnUnlockUser() {
+    public void ManifestShortcut_publishOnUnlockUser() {
         addManifestShortcutResource(
                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
                 R.xml.shortcut_1);
@@ -7136,7 +7136,7 @@
         assertNull(mService.getPackageShortcutForTest(LAUNCHER_1, USER_0));
     }
 
-    public void testManifestShortcut_publishOnBroadcast() {
+    public void ManifestShortcut_publishOnBroadcast() {
         // First, no packages are installed.
         uninstallPackage(USER_0, CALLING_PACKAGE_1);
         uninstallPackage(USER_0, CALLING_PACKAGE_2);
@@ -7392,7 +7392,7 @@
         });
     }
 
-    public void testManifestShortcuts_missingMandatoryFields() {
+    public void ManifestShortcuts_missingMandatoryFields() {
         // Start with no apps installed.
         uninstallPackage(USER_0, CALLING_PACKAGE_1);
         uninstallPackage(USER_0, CALLING_PACKAGE_2);
@@ -7461,7 +7461,7 @@
         });
     }
 
-    public void testManifestShortcuts_intentDefinitions() {
+    public void ManifestShortcuts_intentDefinitions() {
         addManifestShortcutResource(
                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
                 R.xml.shortcut_error_4);
@@ -7603,7 +7603,7 @@
         });
     }
 
-    public void testManifestShortcuts_checkAllFields() {
+    public void ManifestShortcuts_checkAllFields() {
         mService.handleUnlockUser(USER_0);
 
         // Package 1 updated, which has one valid manifest shortcut and one invalid.
@@ -7708,7 +7708,7 @@
         });
     }
 
-    public void testManifestShortcuts_localeChange() throws InterruptedException {
+    public void ManifestShortcuts_localeChange() throws InterruptedException {
         mService.handleUnlockUser(USER_0);
 
         // Package 1 updated, which has one valid manifest shortcut and one invalid.
@@ -7812,7 +7812,7 @@
         });
     }
 
-    public void testManifestShortcuts_updateAndDisabled_notPinned() {
+    public void ManifestShortcuts_updateAndDisabled_notPinned() {
         mService.handleUnlockUser(USER_0);
 
         // First, just publish a manifest shortcut.
@@ -7852,7 +7852,7 @@
         });
     }
 
-    public void testManifestShortcuts_updateAndDisabled_pinned() {
+    public void ManifestShortcuts_updateAndDisabled_pinned() {
         mService.handleUnlockUser(USER_0);
 
         // First, just publish a manifest shortcut.
@@ -7908,7 +7908,7 @@
         });
     }
 
-    public void testManifestShortcuts_duplicateInSingleActivity() {
+    public void ManifestShortcuts_duplicateInSingleActivity() {
         mService.handleUnlockUser(USER_0);
 
         // The XML has two shortcuts with the same ID.
@@ -7933,7 +7933,7 @@
         });
     }
 
-    public void testManifestShortcuts_duplicateInTwoActivities() {
+    public void ManifestShortcuts_duplicateInTwoActivities() {
         mService.handleUnlockUser(USER_0);
 
         // ShortcutActivity has shortcut ms1
@@ -7985,7 +7985,7 @@
     /**
      * Manifest shortcuts cannot override shortcuts that were published via the APIs.
      */
-    public void testManifestShortcuts_cannotOverrideNonManifest() {
+    public void ManifestShortcuts_cannotOverrideNonManifest() {
         mService.handleUnlockUser(USER_0);
 
         // Create a non-pinned dynamic shortcut and a non-dynamic pinned shortcut.
@@ -8058,7 +8058,7 @@
     /**
      * Make sure the APIs won't work on manifest shortcuts.
      */
-    public void testManifestShortcuts_immutable() {
+    public void ManifestShortcuts_immutable() {
         mService.handleUnlockUser(USER_0);
 
         // Create a non-pinned manifest shortcut, a pinned shortcut that was originally
@@ -8151,7 +8151,7 @@
     /**
      * Make sure the APIs won't work on manifest shortcuts.
      */
-    public void testManifestShortcuts_tooMany() {
+    public void ManifestShortcuts_tooMany() {
         // Change the max number of shortcuts.
         mService.updateConfigurationLocked(ConfigConstants.KEY_MAX_SHORTCUTS + "=3");
 
@@ -8170,7 +8170,7 @@
         });
     }
 
-    public void testMaxShortcutCount_set() {
+    public void MaxShortcutCount_set() {
         // Change the max number of shortcuts.
         mService.updateConfigurationLocked(ConfigConstants.KEY_MAX_SHORTCUTS + "=3");
 
@@ -8251,7 +8251,7 @@
         });
     }
 
-    public void testMaxShortcutCount_add() {
+    public void MaxShortcutCount_add() {
         // Change the max number of shortcuts.
         mService.updateConfigurationLocked(ConfigConstants.KEY_MAX_SHORTCUTS + "=3");
 
@@ -8378,7 +8378,7 @@
         });
     }
 
-    public void testMaxShortcutCount_update() {
+    public void MaxShortcutCount_update() {
         // Change the max number of shortcuts.
         mService.updateConfigurationLocked(ConfigConstants.KEY_MAX_SHORTCUTS + "=3");
 
@@ -8469,7 +8469,7 @@
         });
     }
 
-    public void testShortcutsPushedOutByManifest() {
+    public void ShortcutsPushedOutByManifest() {
         // Change the max number of shortcuts.
         mService.updateConfigurationLocked(ConfigConstants.KEY_MAX_SHORTCUTS + "=3");
 
@@ -8577,7 +8577,7 @@
         });
     }
 
-    public void testReturnedByServer() {
+    public void ReturnedByServer() {
         // Package 1 updated, with manifest shortcuts.
         addManifestShortcutResource(
                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
@@ -8623,7 +8623,7 @@
         });
     }
 
-    public void testIsForegroundDefaultLauncher_true() {
+    public void IsForegroundDefaultLauncher_true() {
         final int uid = 1024;
 
         setDefaultLauncher(UserHandle.USER_SYSTEM, "default");
@@ -8633,7 +8633,7 @@
     }
 
 
-    public void testIsForegroundDefaultLauncher_defaultButNotForeground() {
+    public void IsForegroundDefaultLauncher_defaultButNotForeground() {
         final int uid = 1024;
 
         setDefaultLauncher(UserHandle.USER_SYSTEM, "default");
@@ -8642,7 +8642,7 @@
         assertFalse(mInternal.isForegroundDefaultLauncher("default", uid));
     }
 
-    public void testIsForegroundDefaultLauncher_foregroundButNotDefault() {
+    public void IsForegroundDefaultLauncher_foregroundButNotDefault() {
         final int uid = 1024;
 
         setDefaultLauncher(UserHandle.USER_SYSTEM, "default");
@@ -8651,7 +8651,7 @@
         assertFalse(mInternal.isForegroundDefaultLauncher("another", uid));
     }
 
-    public void testParseShareTargetsFromManifest() {
+    public void ParseShareTargetsFromManifest() {
         // These values must exactly match the content of shortcuts_share_targets.xml resource
         List<ShareTargetInfo> expectedValues = new ArrayList<>();
         expectedValues.add(new ShareTargetInfo(
@@ -8703,7 +8703,7 @@
         }
     }
 
-    public void testShareTargetInfo_saveToXml() throws IOException, XmlPullParserException {
+    public void ShareTargetInfo_saveToXml() throws IOException, XmlPullParserException {
         List<ShareTargetInfo> expectedValues = new ArrayList<>();
         expectedValues.add(new ShareTargetInfo(
                 new ShareTargetInfo.TargetData[]{new ShareTargetInfo.TargetData(
@@ -8769,7 +8769,7 @@
         }
     }
 
-    public void testIsSharingShortcut() throws IntentFilter.MalformedMimeTypeException {
+    public void IsSharingShortcut() throws IntentFilter.MalformedMimeTypeException {
         addManifestShortcutResource(
                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
                 R.xml.shortcut_share_targets);
@@ -8819,7 +8819,7 @@
                 filter_any));
     }
 
-    public void testIsSharingShortcut_PinnedAndCachedOnlyShortcuts()
+    public void IsSharingShortcut_PinnedAndCachedOnlyShortcuts()
             throws IntentFilter.MalformedMimeTypeException {
         addManifestShortcutResource(
                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
@@ -8876,7 +8876,7 @@
                 filter_any));
     }
 
-    public void testAddingShortcuts_ExcludesHiddenFromLauncherShortcuts() {
+    public void AddingShortcuts_ExcludesHiddenFromLauncherShortcuts() {
         final ShortcutInfo s1 = makeShortcutExcludedFromLauncher("s1");
         final ShortcutInfo s2 = makeShortcutExcludedFromLauncher("s2");
         final ShortcutInfo s3 = makeShortcutExcludedFromLauncher("s3");
@@ -8897,7 +8897,7 @@
         });
     }
 
-    public void testUpdateShortcuts_ExcludesHiddenFromLauncherShortcuts() {
+    public void UpdateShortcuts_ExcludesHiddenFromLauncherShortcuts() {
         final ShortcutInfo s1 = makeShortcut("s1");
         final ShortcutInfo s2 = makeShortcut("s2");
         final ShortcutInfo s3 = makeShortcut("s3");
@@ -8910,7 +8910,7 @@
         });
     }
 
-    public void testPinHiddenShortcuts_ThrowsException() {
+    public void PinHiddenShortcuts_ThrowsException() {
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
             assertThrown(IllegalArgumentException.class, () -> {
                 mManager.requestPinShortcut(makeShortcutExcludedFromLauncher("s1"), null);
