diff options
150 files changed, 542 insertions, 19050 deletions
diff --git a/MEMORY_OWNERS b/MEMORY_OWNERS index 89ce5140d8ea..12aa2951bbc9 100644 --- a/MEMORY_OWNERS +++ b/MEMORY_OWNERS @@ -2,5 +2,4 @@ surenb@google.com 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 1a7258a802df..4c3416523b99 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.EOFException; 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 @@ import org.conscrypt.ChannelType; * 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 @@ final class ClientEndpoint { } } + @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 f20b1706129b..9e45c4ae23b5 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.Cipher; 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 @@ public final class ClientSocketPerfTest { 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 @@ public final class ClientSocketPerfTest { 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 @@ public final class ClientSocketPerfTest { 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)); - - 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 = + config.serverFactory() + .newServer( + config.messageSize(), + config.protocol().getProtocols(), + ciphers(config)); + socketPair.server.init(); + + 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 @@ public final class ClientSocketPerfTest { // 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); - - BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); - while (state.keepRunning()) { - while (bytesCounter.get() < config.messageSize()) { - } - bytesCounter.set(0); + try { + reset(); + setup(config); + recording.set(true); + + 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 @@ public final class ClientSocketPerfTest { 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 1e4f12460936..83eaaa1155e4 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 @@ import javax.net.ssl.SSLSocketFactory; /** * 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 @@ final class ServerEndpoint { 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 @@ final class ServerEndpoint { 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 af3c405eab82..90a87ce0c69d 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.JUnitParamsRunner; import junitparams.Parameters; import org.junit.Rule; +import org.junit.After; import org.junit.Test; import org.junit.runner.RunWith; @@ -115,14 +116,33 @@ public final class ServerSocketPerfTest { 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 @@ public final class ServerSocketPerfTest { 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 @@ public final class ServerSocketPerfTest { } }); - 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 @@ public final class ServerSocketPerfTest { 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 @@ public final class ServerSocketPerfTest { 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 b541d86ec43f..609377eeebcf 100644 --- a/core/java/android/content/pm/flags.aconfig +++ b/core/java/android/content/pm/flags.aconfig @@ -152,7 +152,7 @@ flag { 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 f3bb51490f20..727dcbaca4bf 100644 --- a/core/java/android/os/OWNERS +++ b/core/java/android/os/OWNERS @@ -4,6 +4,8 @@ per-file *Vibrator* = file:/services/core/java/com/android/server/vibrator/OWNER # 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 d9cc82a77a85..029b674b6be1 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 @@ public class NetworkSecurityTrustManager extends X509ExtendedTrustManager { /** * 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 @@ public class NetworkSecurityTrustManager extends X509ExtendedTrustManager { 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 85ce3c63f18b..e945ff98a96f 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 58dc4ba8df21..a1bdec5280db 100644 --- a/core/java/android/security/net/config/RootTrustManager.java +++ b/core/java/android/security/net/config/RootTrustManager.java @@ -120,7 +120,7 @@ public class RootTrustManager extends X509ExtendedTrustManager { /** * 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 @@ public class RootTrustManager extends X509ExtendedTrustManager { 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 77550002e3c6..3ed902f69342 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 000000000000..c93a4195c2d9 --- /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 28856c87f7c6..a59149c380e0 100644 --- a/libs/protoutil/Android.bp +++ b/libs/protoutil/Android.bp @@ -59,7 +59,6 @@ cc_library { 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 6d84e7066839..b91a5b57ac6b 100644 --- a/media/java/android/media/FadeManagerConfiguration.java +++ b/media/java/android/media/FadeManagerConfiguration.java @@ -673,6 +673,7 @@ public final class FadeManagerConfiguration implements Parcelable { 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 1fde7d268517..3ea2d3506f31 100644 --- a/native/android/OWNERS +++ b/native/android/OWNERS @@ -29,6 +29,7 @@ per-file surface_texture.cpp = file:/graphics/java/android/graphics/OWNERS # 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 0fdb3bd38db8..000000000000 --- 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 f46dccd97974..000000000000 --- 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 49c778d22038..000000000000 --- 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 c8c479a4d2ad..000000000000 --- 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 ef9aab6e7641..000000000000 --- 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 5ebe91111ec0..000000000000 --- 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 f7f8ee3ddda5..000000000000 --- 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 d802177e249b..000000000000 --- 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 fb82b5ddbb21..000000000000 --- 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 6bd6072a2f43..000000000000 --- 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 c7a618125add..000000000000 --- 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 c6eaa57b6b06..000000000000 --- 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 d802177e249b..000000000000 --- 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 d802177e249b..000000000000 --- 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 63a6a58d8ce2..000000000000 --- 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 f6236b2bfb3b..000000000000 --- 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 027141d99c30..000000000000 --- 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 9d06e2d7d5eb..000000000000 --- 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 e76aeb07f106..000000000000 --- 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 e677998a7970..000000000000 --- 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 59e6c62926c9..000000000000 --- 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 9b11e2d30ed8..000000000000 --- 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 148c4ec86845..000000000000 --- 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 aa5ba58e7179..000000000000 --- 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 d2c81cd27d90..000000000000 --- 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 a57de1e0e21a..000000000000 --- 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 b06bf06d5197..000000000000 --- 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 ac0a5aaaa195..000000000000 --- 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 cde57c58ca1f..000000000000 --- 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 00ceaa9801d8..000000000000 --- 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 1bb7680d2fed..000000000000 --- 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 4cc59271362b..000000000000 --- 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 af1fa2fb2456..000000000000 --- 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 124bfac4f0d0..000000000000 --- 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 e5eac0b4d6fd..000000000000 --- 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 170df71385bb..000000000000 --- 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 e1cace987dc3..000000000000 --- 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 821dc6f6c868..000000000000 --- 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 584eb9a128b4..000000000000 --- 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 b4cda5b022fb..000000000000 --- 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 2a06ff314b22..000000000000 --- 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 378b9d05b385..000000000000 --- 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 553f6c01b016..000000000000 --- 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 10f89d0936e4..000000000000 --- 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 7bf4355d5b35..000000000000 --- 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 909eca7b0c9d..000000000000 --- 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 63397c21b036..000000000000 --- 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> - * <activity android:name=".nfc.TechFilter" android:label="NFC/TechFilter"> - * <!-- Add a technology filter --> - * <intent-filter> - * <action android:name="android.nfc.action.TECH_DISCOVERED" /> - * </intent-filter> - * - * <meta-data android:name="android.nfc.action.TECH_DISCOVERED" - * android:resource="@xml/filter_nfc" - * /> - * </activity></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> - * <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - * <!-- capture anything using NfcF --> - * <tech-list> - * <tech>android.nfc.tech.NfcF</tech> - * </tech-list> - * - * <!-- OR --> - * - * <!-- capture all MIFARE Classics with NDEF payloads --> - * <tech-list> - * <tech>android.nfc.tech.NfcA</tech> - * <tech>android.nfc.tech.MifareClassic</tech> - * <tech>android.nfc.tech.Ndef</tech> - * </tech-list> - * </resources></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> - * <application ...> - * <meta-data android:name="android.nfc.disable_beam_default" - * android:value="true" /> - * </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> - * <application ...> - * <meta-data android:name="android.nfc.disable_beam_default" - * android:value="true" /> - * </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 d5e79fc37282..000000000000 --- 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 c57b2e029cc5..000000000000 --- 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 6ae58fd38cbe..000000000000 --- 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 aff4f52f2bab..000000000000 --- 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 1ab8a1ebd72c..000000000000 --- 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 644e3122774b..000000000000 --- 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 b46e34368e77..000000000000 --- 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 4153779a8ba2..000000000000 --- 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 742d75fe4bc3..000000000000 --- 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 890cb090f587..000000000000 --- 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 3bcb445fc7d2..000000000000 --- 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 4f3e1999f5d3..000000000000 --- 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 3509644ac106..000000000000 --- 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 4a1b1f3cecbc..000000000000 --- 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 be94f9fc117c..000000000000 --- 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 a68d8c167865..000000000000 --- 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 06cc0a5f26f1..000000000000 --- 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 86239ce7a6b2..000000000000 --- 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 05a30aad76fc..000000000000 --- 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 f72f74e8b3b9..000000000000 --- 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 ce67f8f9aea7..000000000000 --- 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 312261ebe76d..000000000000 --- 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 500038f14d9d..000000000000 --- 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 1981d7c0c6e0..000000000000 --- 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 92e646f220f0..000000000000 --- 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 9f01559bd344..000000000000 --- 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 98f92ee03eef..000000000000 --- 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 7992094e6ba1..000000000000 --- 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 7f2ca545007b..000000000000 --- 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 45315f812250..000000000000 --- 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 fee9c5bfa328..000000000000 --- 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 fbf2203b40b4..000000000000 --- 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> <service android:name=".MyHostApduService" android:exported="true" android:permission="android.permission.BIND_NFC_SERVICE"> - * <intent-filter> - * <action android:name="android.nfc.cardemulation.action.HOST_APDU_SERVICE"/> - * </intent-filter> - * <meta-data android:name="android.nfc.cardemulation.host_apdu_service" android:resource="@xml/apduservice"/> - * </service></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> - * <host-apdu-service xmlns:android="http://schemas.android.com/apk/res/android" - * android:description="@string/servicedesc" android:requireDeviceUnlock="false"> - * <aid-group android:description="@string/aiddescription" android:category="other"> - * <aid-filter android:name="F0010203040506"/> - * <aid-filter android:name="F0394148148100"/> - * </aid-group> - * </host-apdu-service> - * </pre> - * - * <p>The {@link android.R.styleable#HostApduService <host-apdu-service>} is required - * to contain a - * {@link android.R.styleable#HostApduService_description <android:description>} - * attribute that contains a user-friendly description of the service that may be shown in UI. - * The - * {@link android.R.styleable#HostApduService_requireDeviceUnlock <requireDeviceUnlock>} - * 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 <host-apdu-service>} must - * contain one or more {@link android.R.styleable#AidGroup <aid-group>} tags. - * Each {@link android.R.styleable#AidGroup <aid-group>} must contain one or - * more {@link android.R.styleable#AidFilter <aid-filter>} 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 65b5ca77de62..000000000000 --- 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 <service> 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> <service android:name=".MyHostNfcFService" android:exported="true" android:permission="android.permission.BIND_NFC_SERVICE"> - * <intent-filter> - * <action android:name="android.nfc.cardemulation.action.HOST_NFCF_SERVICE"/> - * </intent-filter> - * <meta-data android:name="android.nfc.cardemulation.host_nfcf_service" android:resource="@xml/nfcfservice"/> - * </service></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> - * <host-nfcf-service xmlns:android="http://schemas.android.com/apk/res/android" - * android:description="@string/servicedesc"> - * <system-code-filter android:name="4000"/> - * <nfcid2-filter android:name="02FE000000000000"/> - <t3tPmm-filter android:name="FFFFFFFFFFFFFFFF"/> - * </host-nfcf-service> - * </pre> - * - * <p>The {@link android.R.styleable#HostNfcFService <host-nfcf-service>} is required - * to contain a - * {@link android.R.styleable#HostApduService_description <android:description>} - * attribute that contains a user-friendly description of the service that may be shown in UI. - * <p>The {@link android.R.styleable#HostNfcFService <host-nfcf-service>} must - * contain: - * <ul> - * <li>Exactly one {@link android.R.styleable#SystemCodeFilter <system-code-filter>} tag.</li> - * <li>Exactly one {@link android.R.styleable#Nfcid2Filter <nfcid2-filter>} tag.</li> - * <li>Zero or one {@link android.R.styleable#T3tPmmFilter <t3tPmm-filter>} 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 48bbf5b61052..000000000000 --- 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 8d8a17270523..000000000000 --- 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> <service android:name=".MyOffHostApduService" android:exported="true" android:permission="android.permission.BIND_NFC_SERVICE"> - * <intent-filter> - * <action android:name="android.nfc.cardemulation.action.OFF_HOST_APDU_SERVICE"/> - * </intent-filter> - * <meta-data android:name="android.nfc.cardemulation.off_host_apdu_service" android:resource="@xml/apduservice"/> - * </service></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> - * <offhost-apdu-service xmlns:android="http://schemas.android.com/apk/res/android" - * android:description="@string/servicedesc"> - * <aid-group android:description="@string/subscription" android:category="other"> - * <aid-filter android:name="F0010203040506"/> - * <aid-filter android:name="F0394148148100"/> - * </aid-group> - * </offhost-apdu-service> - * </pre> - * - * <p>The {@link android.R.styleable#OffHostApduService <offhost-apdu-service>} is required - * to contain a - * {@link android.R.styleable#OffHostApduService_description <android:description>} - * attribute that contains a user-friendly description of the service that may be shown in UI. - * - * <p>The {@link android.R.styleable#OffHostApduService <offhost-apdu-service>} must - * contain one or more {@link android.R.styleable#AidGroup <aid-group>} tags. - * Each {@link android.R.styleable#AidGroup <aid-group>} must contain one or - * more {@link android.R.styleable#AidFilter <aid-filter>} 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 8e09f8baaff2..000000000000 --- 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 5dcc84ccf8b9..000000000000 --- 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 202e1cfb48f6..000000000000 --- 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 88016623434d..000000000000 --- 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 55c1d1650aa9..000000000000 --- 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 ae468fead7a2..000000000000 --- 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 0ba0c5a8d13b..000000000000 --- 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 26f54e692289..000000000000 --- 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 c0416a39ba76..000000000000 --- 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 7d83f157a314..000000000000 --- 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 2240fe7f7d3b..000000000000 --- 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 7e6648361670..000000000000 --- 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 3ebd47f610c0..000000000000 --- 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 421ba7827cb1..000000000000 --- 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 2ccd38875f07..000000000000 --- 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 186c63bf07fd..000000000000 --- 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 839fe429b338..000000000000 --- 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 a99828f90c5b..000000000000 --- 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 67b496e0baf3..000000000000 --- 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=" && ((pollTechnology & 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=" && ((pollTechnology & 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 & 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 & 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 17fb810c626b..000000000000 --- 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 95646720d3d5..000000000000 --- 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 490d6f5df197..000000000000 --- 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 9ca295da75c3..000000000000 --- 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 044c67448329..000000000000 --- 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 c24816d85517..000000000000 --- 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 48f4288d401e..000000000000 --- 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 a12bbbc6884b..000000000000 --- 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 7e0010247ee7..000000000000 --- 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 40076ebd0a0a..000000000000 --- 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 0d73cb3e63c9..798e2d49ff57 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 @@ class TogglePermissionAppInfoPageTest { @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 38becd4decd2..c3af44b60d0c 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 @@ public final class DeviceConfigService extends Binder { 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 b00c8ade07eb..8a6a0d6dbb99 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 @@ internal fun PredictiveBackHandler( // 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 715d979e116e..2b33224022fc 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.TransitionKey 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 @@ internal suspend fun <T : ContentKey> animateProgress( 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 @@ internal suspend fun <T : ContentKey> animateProgress( } // 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 c08d4aa799a5..0629b77029e0 100755 --- a/ravenwood/scripts/extract-last-soong-commands.py +++ b/ravenwood/scripts/extract-last-soong-commands.py @@ -32,7 +32,7 @@ re_command = re.compile(r''' ^\[.*?\] \s* (.*) ''', re.X) 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 @@ def main(args): 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 3224b27d5803..c234ee479a57 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 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ * 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 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ } 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 c15cf34b8955..6858e2941ff9 100644 --- a/services/core/java/com/android/server/OWNERS +++ b/services/core/java/com/android/server/OWNERS @@ -31,6 +31,7 @@ per-file *Storage* = file:/core/java/android/os/storage/OWNERS 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 2ec1aedd18f9..5bd9c054dbf8 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 @@ public final class PhantomProcessList { 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 @@ public final class PhantomProcessList { 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 @@ public final class PhantomProcessList { } } - 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 @@ public final class PhantomProcessList { 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 4d5bce559a91..fedfe511b747 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 @@ public final class FadeOutManager { 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 @@ public final class FadeOutManager { 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 e80a86d73f90..4fd026a6dc52 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 @@ public final class PowerStatsLogger extends Handler { } 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 8bfef6d5d218..4140c046f968 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 @@ class CameraStateMonitor { } 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 755d4c8c9fc5..6dd7d35856df 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 @@ class PinnedTaskController { * 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 @@ class PinnedTaskController { * 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 ad4faab1e106..e1b6e5d0e706 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 @@ public class ScreenRecordingCallbackController { 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 42ea5a88a09b..83d08cca43ad 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 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> { */ 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 2c0390241593..97ae6be0c2bc 100644 --- a/services/core/jni/Android.bp +++ b/services/core/jni/Android.bp @@ -79,6 +79,7 @@ cc_library_static { ":lib_oomConnection_native", ":lib_anrTimer_native", ":lib_lazilyRegisteredServices_native", + ":lib_phantomProcessList_native", ], include_dirs: [ @@ -264,3 +265,10 @@ filegroup { "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 000000000000..0c5e6d85919a --- /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 df37ec3ef037..a12eb319b9fa 100644 --- a/services/core/jni/onload.cpp +++ b/services/core/jni/onload.cpp @@ -70,6 +70,7 @@ int register_com_android_server_display_DisplayControl(JNIEnv* env); 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 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */) 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 ac95f046f9e6..c80d6db9399c 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -3033,10 +3033,10 @@ public final class SystemServer implements Dumpable { 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 d2c91ff2ef60..232bb83fdf9f 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 @@ class AppIdPermissionPolicy : SchemePolicy() { 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 12370954e9a5..8b357862dcbc 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 @@ class AppIdPermissionPolicyPermissionResetTest : BasePermissionPolicyTest() { } 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 94d4b9522d60..03bd73c52083 100644 --- a/services/tests/mockingservicestests/jni/Android.bp +++ b/services/tests/mockingservicestests/jni/Android.bp @@ -24,6 +24,7 @@ cc_library_shared { ":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 9b4c8178b092..30fa7de94af1 100644 --- a/services/tests/mockingservicestests/jni/onload.cpp +++ b/services/tests/mockingservicestests/jni/onload.cpp @@ -28,6 +28,7 @@ int register_android_server_am_CachedAppOptimizer(JNIEnv* env); 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 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */) 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 d8a9400d5180..69feb1d86983 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 *Gnss* = file:/services/core/java/com/android/server/location/OWNERS 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 a0f2395f5203..d70ffd2ec050 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 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { /** * 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 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { * 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 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { /** * 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 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { // 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 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { // === 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 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { 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 class ShortcutManagerTest1 extends BaseShortcutManagerTest { }); } - public void testAddDynamicShortcuts() { + public void AddDynamicShortcuts() { setCaller(CALLING_PACKAGE_1, USER_0); final ShortcutInfo si1 = makeShortcut("shortcut1"); @@ -402,7 +402,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { }); } - 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 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { 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 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { 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 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { 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 class ShortcutManagerTest1 extends BaseShortcutManagerTest { }); } - public void testPublishWithNoActivity_noMainActivityInPackage() { + public void PublishWithNoActivity_noMainActivityInPackage() { mRunningUsers.put(USER_10, true); runWithCaller(CALLING_PACKAGE_2, USER_10, () -> { @@ -750,7 +750,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { }); } - 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 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { 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 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { 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 class ShortcutManagerTest1 extends BaseShortcutManagerTest { */ } - public void testCleanupDanglingBitmaps() throws Exception { + public void CleanupDanglingBitmaps() throws Exception { assertBitmapDirectories(USER_0, EMPTY_STRINGS); assertBitmapDirectories(USER_10, EMPTY_STRINGS); @@ -1203,7 +1203,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { 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 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { 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 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { 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 class ShortcutManagerTest1 extends BaseShortcutManagerTest { }); } - 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 class ShortcutManagerTest1 extends BaseShortcutManagerTest { }); } - public void testShortcutManagerGetShortcuts_shortcutTypes() { + public void ShortcutManagerGetShortcuts_shortcutTypes() { // Create 3 manifest and 3 dynamic shortcuts addManifestShortcutResource( @@ -1616,7 +1616,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { 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 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { "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 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { 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 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { // === Test for launcher side APIs === - public void testGetShortcuts() { + public void GetShortcuts() { // Set up shortcuts. @@ -1997,7 +1997,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { "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 class ShortcutManagerTest1 extends BaseShortcutManagerTest { }); } - 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 class ShortcutManagerTest1 extends BaseShortcutManagerTest { }); } - 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 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { } // TODO resource - public void testGetShortcutInfo() { + public void GetShortcutInfo() { // Create shortcuts. setCaller(CALLING_PACKAGE_1); final ShortcutInfo s1_1 = makeShortcut( @@ -2279,7 +2279,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { 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 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { * 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 class ShortcutManagerTest1 extends BaseShortcutManagerTest { }); } - 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 class ShortcutManagerTest1 extends BaseShortcutManagerTest { }); } - 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 class ShortcutManagerTest1 extends BaseShortcutManagerTest { }); } - 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 class ShortcutManagerTest1 extends BaseShortcutManagerTest { }); } - 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 class ShortcutManagerTest1 extends BaseShortcutManagerTest { }); } - public void testStartShortcut() { + public void StartShortcut() { // Create some shortcuts. runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { final ShortcutInfo s1_1 = makeShortcut( @@ -3611,7 +3611,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { // 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 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { .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 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { // === Test for persisting === - public void testSaveAndLoadUser_empty() { + public void SaveAndLoadUser_empty() { assertTrue(mManager.setDynamicShortcuts(list())); Log.i(TAG, "Saved state"); @@ -3917,7 +3917,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { /** * 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 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { // 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 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { 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 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { // 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 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { 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 class ShortcutManagerTest1 extends BaseShortcutManagerTest { }); } - 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 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { 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 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { 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 class ShortcutManagerTest1 extends BaseShortcutManagerTest { }); } - public void testHandlePackageDisable() { + public void HandlePackageDisable() { checkHandlePackageDeleteInner((userId, packageName) -> { disablePackage(userId, packageName); mService.mPackageMonitor.onReceive(getTestContext(), @@ -5048,7 +5048,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { } /** 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 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { 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 class ShortcutManagerTest1 extends BaseShortcutManagerTest { }); } - 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 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { /** * 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 class ShortcutManagerTest1 extends BaseShortcutManagerTest { }); } - 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 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { 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 class ShortcutManagerTest1 extends BaseShortcutManagerTest { }); } - 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 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { * - 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 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { checkBackupAndRestore_success(/*firstRestore=*/ true); } - public void testBackupAndRestore_backupRestoreTwice() { + public void BackupAndRestore_backupRestoreTwice() { prepareForBackupTest(); checkBackupAndRestore_success(/*firstRestore=*/ true); @@ -5774,7 +5774,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { 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 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { checkBackupAndRestore_success(/*firstRestore=*/ true); } - public void testBackupAndRestore_restoreToSuperSetSignatures() { + public void BackupAndRestore_restoreToSuperSetSignatures() { prepareForBackupTest(); // Change package signatures. @@ -5980,7 +5980,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { }); } - public void testBackupAndRestore_publisherWrongSignature() { + public void BackupAndRestore_publisherWrongSignature() { prepareForBackupTest(); addPackage(CALLING_PACKAGE_1, CALLING_UID_1, 10, "sigx"); // different signature @@ -5988,7 +5988,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { 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 class ShortcutManagerTest1 extends BaseShortcutManagerTest { }); } - public void testBackupAndRestore_launcherLowerVersion() { + public void BackupAndRestore_launcherLowerVersion() { prepareForBackupTest(); addPackage(LAUNCHER_1, LAUNCHER_UID_1, 0); // Lower version @@ -6126,7 +6126,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { 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 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { checkBackupAndRestore_launcherNotRestored(true); } - public void testBackupAndRestore_launcherNoLongerBackupTarget() { + public void BackupAndRestore_launcherNoLongerBackupTarget() { prepareForBackupTest(); updatePackageInfo(LAUNCHER_1, @@ -6239,7 +6239,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { }); } - public void testBackupAndRestore_launcherAndPackageNoLongerBackupTarget() { + public void BackupAndRestore_launcherAndPackageNoLongerBackupTarget() { prepareForBackupTest(); updatePackageInfo(CALLING_PACKAGE_1, @@ -6337,7 +6337,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { }); } - public void testBackupAndRestore_disabled() { + public void BackupAndRestore_disabled() { prepareCrossProfileDataSet(); // Before doing backup & restore, disable s1. @@ -6402,7 +6402,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { } - 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 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { * 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 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { /** * 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 class ShortcutManagerTest1 extends BaseShortcutManagerTest { } - public void testSaveAndLoad_crossProfile() { + public void SaveAndLoad_crossProfile() { prepareCrossProfileDataSet(); dumpsysOnLogcat("Before save & load"); @@ -6859,7 +6859,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { .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 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { 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 class ShortcutManagerTest1 extends BaseShortcutManagerTest { }); } - public void testHasShareTargets_permission() { + public void HasShareTargets_permission() { assertExpectException(SecurityException.class, "Missing permission", () -> mManager.hasShareTargets(CALLING_PACKAGE_1)); @@ -6896,7 +6896,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { 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 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { 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 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { 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 class ShortcutManagerTest1 extends BaseShortcutManagerTest { }); } - 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 class ShortcutManagerTest1 extends BaseShortcutManagerTest { }); } - 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 class ShortcutManagerTest1 extends BaseShortcutManagerTest { }); } - 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 class ShortcutManagerTest1 extends BaseShortcutManagerTest { }); } - 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 class ShortcutManagerTest1 extends BaseShortcutManagerTest { }); } - 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 class ShortcutManagerTest1 extends BaseShortcutManagerTest { }); } - 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 class ShortcutManagerTest1 extends BaseShortcutManagerTest { }); } - 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 class ShortcutManagerTest1 extends BaseShortcutManagerTest { }); } - public void testManifestShortcuts_duplicateInTwoActivities() { + public void ManifestShortcuts_duplicateInTwoActivities() { mService.handleUnlockUser(USER_0); // ShortcutActivity has shortcut ms1 @@ -7985,7 +7985,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { /** * 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 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { /** * 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 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { /** * 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 class ShortcutManagerTest1 extends BaseShortcutManagerTest { }); } - 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 class ShortcutManagerTest1 extends BaseShortcutManagerTest { }); } - 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 class ShortcutManagerTest1 extends BaseShortcutManagerTest { }); } - 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 class ShortcutManagerTest1 extends BaseShortcutManagerTest { }); } - public void testShortcutsPushedOutByManifest() { + public void ShortcutsPushedOutByManifest() { // Change the max number of shortcuts. mService.updateConfigurationLocked(ConfigConstants.KEY_MAX_SHORTCUTS + "=3"); @@ -8577,7 +8577,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { }); } - 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 class ShortcutManagerTest1 extends BaseShortcutManagerTest { }); } - public void testIsForegroundDefaultLauncher_true() { + public void IsForegroundDefaultLauncher_true() { final int uid = 1024; setDefaultLauncher(UserHandle.USER_SYSTEM, "default"); @@ -8633,7 +8633,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { } - public void testIsForegroundDefaultLauncher_defaultButNotForeground() { + public void IsForegroundDefaultLauncher_defaultButNotForeground() { final int uid = 1024; setDefaultLauncher(UserHandle.USER_SYSTEM, "default"); @@ -8642,7 +8642,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { 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 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { 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 class ShortcutManagerTest1 extends BaseShortcutManagerTest { } } - 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 class ShortcutManagerTest1 extends BaseShortcutManagerTest { } } - 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 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { 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 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { 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 class ShortcutManagerTest1 extends BaseShortcutManagerTest { }); } - 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 class ShortcutManagerTest1 extends BaseShortcutManagerTest { }); } - public void testPinHiddenShortcuts_ThrowsException() { + public void PinHiddenShortcuts_ThrowsException() { runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { assertThrown(IllegalArgumentException.class, () -> { mManager.requestPinShortcut(makeShortcutExcludedFromLauncher("s1"), null); |