summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNick Pelly <npelly@google.com>2011-03-08 11:43:30 -0800
committerNick Pelly <npelly@google.com>2011-03-10 16:03:46 -0800
commit367f41f8f61126c2ab34a34cc676756a9fc23ac2 (patch)
tree263a6f3501d1d435dd3da49a0c8cca8787edf544
parentdfcb8c511635431d536fd3ef1894378f4424ef1a (diff)
downloadframeworks_base-367f41f8f61126c2ab34a34cc676756a9fc23ac2.zip
frameworks_base-367f41f8f61126c2ab34a34cc676756a9fc23ac2.tar.gz
frameworks_base-367f41f8f61126c2ab34a34cc676756a9fc23ac2.tar.bz2
Implement new NFC-EE API's as shared library (frameworks/base).
Change-Id: I45c4eaf59ec78167fc236fdd59676465a5e1bcb7
-rw-r--r--Android.mk2
-rw-r--r--CleanSpec.mk1
-rw-r--r--core/java/android/nfc/INfcAdapter.aidl11
-rwxr-xr-xcore/java/android/nfc/INfcAdapterExtras.aidl (renamed from core/java/android/nfc/INfcSecureElement.aidl)18
-rw-r--r--core/java/android/nfc/NfcAdapter.java65
-rwxr-xr-xcore/java/android/nfc/NfcSecureElement.java138
-rw-r--r--core/res/AndroidManifest.xml4
-rw-r--r--nfc-extras/Android.mk11
-rw-r--r--nfc-extras/com.android.nfc_extras.xml20
-rw-r--r--nfc-extras/java/com/android/nfc_extras/NfcAdapterExtras.java180
-rw-r--r--nfc-extras/java/com/android/nfc_extras/NfcExecutionEnvironment.java125
11 files changed, 357 insertions, 218 deletions
diff --git a/Android.mk b/Android.mk
index 009c80c..09e471f 100644
--- a/Android.mk
+++ b/Android.mk
@@ -121,10 +121,10 @@ LOCAL_SRC_FILES += \
core/java/android/nfc/ILlcpServiceSocket.aidl \
core/java/android/nfc/ILlcpSocket.aidl \
core/java/android/nfc/INfcAdapter.aidl \
+ core/java/android/nfc/INfcAdapterExtras.aidl \
core/java/android/nfc/INfcTag.aidl \
core/java/android/nfc/IP2pInitiator.aidl \
core/java/android/nfc/IP2pTarget.aidl \
- core/java/android/nfc/INfcSecureElement.aidl \
core/java/android/os/IHardwareService.aidl \
core/java/android/os/IMessenger.aidl \
core/java/android/os/INetworkManagementService.aidl \
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 2ee8f31..8c3b17e 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -73,6 +73,7 @@ $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/androi
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/com/trustedlogic)
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates/src/com/trustedlogic)
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/nfc/INdefTag.java)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/nfc)
# ************************************************
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
diff --git a/core/java/android/nfc/INfcAdapter.aidl b/core/java/android/nfc/INfcAdapter.aidl
index d439a48..870127c 100644
--- a/core/java/android/nfc/INfcAdapter.aidl
+++ b/core/java/android/nfc/INfcAdapter.aidl
@@ -28,7 +28,7 @@ import android.nfc.ILlcpConnectionlessSocket;
import android.nfc.INfcTag;
import android.nfc.IP2pTarget;
import android.nfc.IP2pInitiator;
-import android.nfc.INfcSecureElement;
+import android.nfc.INfcAdapterExtras;
/**
* @hide
@@ -41,13 +41,12 @@ interface INfcAdapter
INfcTag getNfcTagInterface();
IP2pTarget getP2pTargetInterface();
IP2pInitiator getP2pInitiatorInterface();
- INfcSecureElement getNfcSecureElementInterface();
+ INfcAdapterExtras getNfcAdapterExtrasInterface();
// NfcAdapter-class related methods
boolean isEnabled();
NdefMessage localGet();
void localSet(in NdefMessage message);
- void openTagConnection(in Tag tag);
void enableForegroundDispatch(in ComponentName activity, in PendingIntent intent,
in IntentFilter[] filters, in TechListParcel techLists);
void disableForegroundDispatch(in ComponentName activity);
@@ -59,12 +58,8 @@ interface INfcAdapter
int createLlcpConnectionlessSocket(int sap);
int createLlcpServiceSocket(int sap, String sn, int miu, int rw, int linearBufferLength);
int createLlcpSocket(int sap, int miu, int rw, int linearBufferLength);
- int deselectSecureElement();
boolean disable();
boolean enable();
String getProperties(String param);
- int[] getSecureElementList();
- int getSelectedSecureElement();
- int selectSecureElement(int seId);
int setProperties(String param, String value);
-} \ No newline at end of file
+}
diff --git a/core/java/android/nfc/INfcSecureElement.aidl b/core/java/android/nfc/INfcAdapterExtras.aidl
index aa98dd2..ab5c1a6 100755
--- a/core/java/android/nfc/INfcSecureElement.aidl
+++ b/core/java/android/nfc/INfcAdapterExtras.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 The Android Open Source Project
+ * 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.
@@ -16,13 +16,15 @@
package android.nfc;
+import android.os.Bundle;
+
/**
* {@hide}
*/
-interface INfcSecureElement {
- int openSecureElementConnection();
- int closeSecureElementConnection(int nativeHandle);
- byte[] exchangeAPDU(int nativeHandle, in byte[] data);
- int[] getSecureElementTechList(int nativeHandle);
- byte[] getSecureElementUid(int nativeHandle);
-} \ No newline at end of file
+interface INfcAdapterExtras {
+ Bundle open(IBinder b);
+ Bundle close();
+ Bundle transceive(in byte[] data_in);
+ int getCardEmulationRoute();
+ void setCardEmulationRoute(int route);
+}
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index 8c56fda..4689804 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -157,31 +157,6 @@ public final class NfcAdapter {
public static final String EXTRA_ID = "android.nfc.extra.ID";
/**
- * Broadcast Action: a transaction with a secure element has been detected.
- * <p>
- * Always contains the extra field
- * {@link android.nfc.NfcAdapter#EXTRA_AID}
- * @hide
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_TRANSACTION_DETECTED =
- "android.nfc.action.TRANSACTION_DETECTED";
-
- /**
- * Broadcast Action: an RF field ON has been detected.
- * @hide
- */
- public static final String ACTION_RF_FIELD_ON_DETECTED =
- "android.nfc.action.RF_FIELD_ON_DETECTED";
-
- /**
- * Broadcast Action: an RF Field OFF has been detected.
- * @hide
- */
- public static final String ACTION_RF_FIELD_OFF_DETECTED =
- "android.nfc.action.RF_FIELD_OFF_DETECTED";
-
- /**
* Broadcast Action: an adapter's state changed between enabled and disabled.
*
* The new value is stored in the extra EXTRA_NEW_BOOLEAN_STATE and just contains
@@ -201,15 +176,6 @@ public final class NfcAdapter {
public static final String EXTRA_NEW_BOOLEAN_STATE = "android.nfc.isEnabled";
/**
- * Mandatory byte array extra field in
- * {@link android.nfc.NfcAdapter#ACTION_TRANSACTION_DETECTED}.
- * <p>
- * Contains the AID of the applet involved in the transaction.
- * @hide
- */
- public static final String EXTRA_AID = "android.nfc.extra.AID";
-
- /**
* LLCP link status: The LLCP link is activated.
* @hide
*/
@@ -691,39 +657,14 @@ public final class NfcAdapter {
}
/**
- * Create an Nfc Secure Element Connection
* @hide
*/
- public NfcSecureElement createNfcSecureElementConnection() {
+ public INfcAdapterExtras getNfcAdapterExtrasInterface() {
try {
- return new NfcSecureElement(sService.getNfcSecureElementInterface());
+ return sService.getNfcAdapterExtrasInterface();
} catch (RemoteException e) {
- Log.e(TAG, "createNfcSecureElementConnection failed", e);
+ attemptDeadServiceRecovery(e);
return null;
}
}
-
- /**
- * To change the Secure Element Card Emulation state (ON/OFF)
- * @hide
- */
- public void changeNfcSecureElementCardEmulationState(boolean state)
- {
- int seId = 11259375;
- if(state){
- /* Enable card emulation */
- try {
- sService.selectSecureElement(seId);
- } catch (RemoteException e) {
- Log.e(TAG, "Enable card emulation failed", e);
- }
- }else{
- /* Disable card emulation */
- try {
- sService.deselectSecureElement();
- } catch (RemoteException e) {
- Log.e(TAG, " card emulation failed", e);
- }
- }
- }
}
diff --git a/core/java/android/nfc/NfcSecureElement.java b/core/java/android/nfc/NfcSecureElement.java
deleted file mode 100755
index 3b5f39e..0000000
--- a/core/java/android/nfc/NfcSecureElement.java
+++ /dev/null
@@ -1,138 +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.tech.TagTechnology;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.io.IOException;
-
-//import android.util.Log;
-
-/**
- * This class provides the primary API for managing all aspects Secure Element.
- * Get an instance of this class by calling
- * Context.getSystemService(Context.NFC_SERVICE).
- * @hide
- */
-public final class NfcSecureElement {
-
- private static final String TAG = "NfcSecureElement";
-
- private INfcSecureElement mService;
-
-
- /**
- * @hide
- */
- public NfcSecureElement(INfcSecureElement mSecureElementService) {
- mService = mSecureElementService;
- }
-
- public int openSecureElementConnection(String seType) throws IOException {
- if (seType.equals("SmartMX")) {
- try {
- int handle = mService.openSecureElementConnection();
- // Handle potential errors
- if (handle != 0) {
- return handle;
- } else {
- throw new IOException("SmartMX connection not allowed");
- }
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in openSecureElementConnection(): ", e);
- return 0;
- }
-
- } else if (seType.equals("UICC")) {
- return 0;
- } else {
- throw new IOException("Wrong Secure Element type");
- }
- }
-
-
- public byte [] exchangeAPDU(int handle,byte [] data) throws IOException {
-
-
- // Perform exchange APDU
- try {
- byte[] response = mService.exchangeAPDU(handle, data);
- // Handle potential errors
- if (response == null) {
- throw new IOException("Exchange APDU failed");
- }
- return response;
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in exchangeAPDU(): ", e);
- return null;
- }
- }
-
- public void closeSecureElementConnection(int handle) throws IOException {
-
- try {
- int status = mService.closeSecureElementConnection(handle);
- // Handle potential errors
- if (ErrorCodes.isError(status)) {
- throw new IOException("Error during the conection close");
- };
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in closeSecureElement(): ", e);
- }
- }
-
-
- /**
- * Returns target type. constants.
- *
- * @return Secure Element technology type. The possible values are defined in
- * {@link TagTechnology}
- *
- */
- public int[] getSecureElementTechList(int handle) throws IOException {
- try {
- return mService.getSecureElementTechList(handle);
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in getType(): ", e);
- return null;
- }
- }
-
- /**
- * Returns Secure Element UID.
- *
- * @return Secure Element UID.
- */
- public byte[] getSecureElementUid(int handle) throws IOException {
-
- byte[] uid = null;
- try {
- uid = mService.getSecureElementUid(handle);
- // Handle potential errors
- if (uid == null) {
- throw new IOException("Get Secure Element UID failed");
- }
- return uid;
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in getType(): ", e);
- return null;
- }
- }
-
-}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 56ca057..c8295d7 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -87,7 +87,9 @@
<protected-broadcast android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" />
<protected-broadcast android:name="android.nfc.action.LLCP_LINK_STATE_CHANGED" />
- <protected-broadcast android:name="android.nfc.action.TRANSACTION_DETECTED" />
+ <protected-broadcast android:name="com.android.nfc_extras.action.RF_FIELD_ON_DETECTED" />
+ <protected-broadcast android:name="com.android.nfc_extras.action.RF_FIELD_OFF_DETECTED" />
+ <protected-broadcast android:name="com.android.nfc_extras.action.AID_SELECTED" />
<!-- ====================================== -->
<!-- Permissions for things that cost money -->
diff --git a/nfc-extras/Android.mk b/nfc-extras/Android.mk
new file mode 100644
index 0000000..330e2d4
--- /dev/null
+++ b/nfc-extras/Android.mk
@@ -0,0 +1,11 @@
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_MODULE:= com.android.nfc_extras
+
+include $(BUILD_JAVA_LIBRARY)
diff --git a/nfc-extras/com.android.nfc_extras.xml b/nfc-extras/com.android.nfc_extras.xml
new file mode 100644
index 0000000..370145d
--- /dev/null
+++ b/nfc-extras/com.android.nfc_extras.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<permissions>
+ <library name="com.android.nfc_extras"
+ file="/system/framework/com.android.nfc_extras.jar" />
+</permissions>
diff --git a/nfc-extras/java/com/android/nfc_extras/NfcAdapterExtras.java b/nfc-extras/java/com/android/nfc_extras/NfcAdapterExtras.java
new file mode 100644
index 0000000..cf38bd1
--- /dev/null
+++ b/nfc-extras/java/com/android/nfc_extras/NfcAdapterExtras.java
@@ -0,0 +1,180 @@
+/*
+ * 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 com.android.nfc_extras;
+
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
+import android.nfc.INfcAdapterExtras;
+import android.nfc.NfcAdapter;
+import android.os.RemoteException;
+import android.util.Log;
+
+/**
+ * Provides additional methods on an {@link NfcAdapter} for Card Emulation
+ * and management of {@link NfcExecutionEnvironment}'s.
+ *
+ * There is a 1-1 relationship between an {@link NfcAdapterExtras} object and
+ * a {@link NfcAdapter} object.
+ */
+public final class NfcAdapterExtras {
+ private static final String TAG = "NfcAdapterExtras";
+
+ /**
+ * Broadcast Action: an RF field ON has been detected.
+ *
+ * <p class="note">This is an unreliable signal, and will be removed.
+ * <p class="note">
+ * Requires the {@link android.Manifest.permission#WRITE_SECURE_SETTINGS} permission
+ * to receive.
+ */
+ public static final String ACTION_RF_FIELD_ON_DETECTED =
+ "com.android.nfc_extras.action.RF_FIELD_ON_DETECTED";
+
+ /**
+ * Broadcast Action: an RF field OFF has been detected.
+ *
+ * <p class="note">This is an unreliable signal, and will be removed.
+ * <p class="note">
+ * Requires the {@link android.Manifest.permission#WRITE_SECURE_SETTINGS} permission
+ * to receive.
+ */
+ public static final String ACTION_RF_FIELD_OFF_DETECTED =
+ "com.android.nfc_extras.action.RF_FIELD_OFF_DETECTED";
+
+ // protected by NfcAdapterExtras.class, and final after first construction
+ private static INfcAdapterExtras sService;
+ private static boolean sIsInitialized = false;
+ private static NfcAdapterExtras sSingleton;
+ private static NfcExecutionEnvironment sEmbeddedEe;
+ private static CardEmulationRoute sRouteOff;
+ private static CardEmulationRoute sRouteOnWhenScreenOn;
+
+ /**
+ * Get the {@link NfcAdapterExtras} for the given {@link NfcAdapter}.
+ *
+ * <p class="note">
+ * Requires the {@link android.Manifest.permission#WRITE_SECURE_SETTINGS} permission.
+ *
+ * @param adapter a {@link NfcAdapter}, must not be null
+ * @return the {@link NfcAdapterExtras} object for the given {@link NfcAdapter}
+ */
+ public static NfcAdapterExtras get(NfcAdapter adapter) {
+ synchronized(NfcAdapterExtras.class) {
+ if (!sIsInitialized) {
+ sIsInitialized = true;
+ sService = adapter.getNfcAdapterExtrasInterface();
+ sEmbeddedEe = new NfcExecutionEnvironment(sService);
+ sRouteOff = new CardEmulationRoute(CardEmulationRoute.ROUTE_OFF, null);
+ sRouteOnWhenScreenOn = new CardEmulationRoute(
+ CardEmulationRoute.ROUTE_ON_WHEN_SCREEN_ON, sEmbeddedEe);
+ sSingleton = new NfcAdapterExtras();
+ }
+ return sSingleton;
+ }
+ }
+
+ private NfcAdapterExtras() {}
+
+ /**
+ * Immutable data class that describes a card emulation route.
+ */
+ public final static class CardEmulationRoute {
+ /**
+ * Card Emulation is turned off on this NfcAdapter.
+ * <p>This is the default routing state after boot.
+ */
+ public static final int ROUTE_OFF = 1;
+
+ /**
+ * Card Emulation is routed to {@link #nfcEe} only when the screen is on,
+ * otherwise it is turned off.
+ */
+ public static final int ROUTE_ON_WHEN_SCREEN_ON = 2;
+
+ /**
+ * A route such as {@link #ROUTE_OFF} or {@link #ROUTE_ON_WHEN_SCREEN_ON}.
+ */
+ public final int route;
+
+ /**
+ * The {@link NFcExecutionEnvironment} that is Card Emulation is routed to.
+ * <p>null if {@link #route} is {@link #ROUTE_OFF}, otherwise not null.
+ */
+ public final NfcExecutionEnvironment nfcEe;
+
+ public CardEmulationRoute(int route, NfcExecutionEnvironment nfcEe) {
+ if (route == ROUTE_OFF && nfcEe != null) {
+ throw new IllegalArgumentException("must not specifiy a NFC-EE with ROUTE_OFF");
+ } else if (route != ROUTE_OFF && nfcEe == null) {
+ throw new IllegalArgumentException("must specifiy a NFC-EE for this route");
+ }
+ this.route = route;
+ this.nfcEe = nfcEe;
+ }
+ }
+
+ /**
+ * Get the routing state of this NFC EE.
+ *
+ * <p class="note">
+ * Requires the {@link android.Manifest.permission#WRITE_SECURE_SETTINGS} permission.
+ *
+ * @return
+ */
+ public CardEmulationRoute getCardEmulationRoute() {
+ try {
+ int route = sService.getCardEmulationRoute();
+ return route == CardEmulationRoute.ROUTE_OFF ?
+ sRouteOff :
+ sRouteOnWhenScreenOn;
+ } catch (RemoteException e) {
+ Log.e(TAG, "", e);
+ return sRouteOff;
+ }
+ }
+
+ /**
+ * Set the routing state of this NFC EE.
+ *
+ * <p>This routing state is not persisted across reboot.
+ *
+ * <p class="note">
+ * Requires the {@link android.Manifest.permission#WRITE_SECURE_SETTINGS} permission.
+ *
+ * @param route a {@link #CardEmulationRoute}
+ */
+ public void setCardEmulationRoute(CardEmulationRoute route) {
+ try {
+ sService.setCardEmulationRoute(route.route);
+ } catch (RemoteException e) {
+ Log.e(TAG, "", e);
+ }
+ }
+
+ /**
+ * Get the {@link NfcExecutionEnvironment} that is embedded with the
+ * {@link NFcAdapter}.
+ *
+ * <p class="note">
+ * Requires the {@link android.Manifest.permission#WRITE_SECURE_SETTINGS} permission.
+ *
+ * @return a {@link NfcExecutionEnvironment}, or null if there is no embedded NFC-EE
+ */
+ public NfcExecutionEnvironment getEmbeddedExecutionEnvironment() {
+ return sEmbeddedEe;
+ }
+}
diff --git a/nfc-extras/java/com/android/nfc_extras/NfcExecutionEnvironment.java b/nfc-extras/java/com/android/nfc_extras/NfcExecutionEnvironment.java
new file mode 100644
index 0000000..3efe492
--- /dev/null
+++ b/nfc-extras/java/com/android/nfc_extras/NfcExecutionEnvironment.java
@@ -0,0 +1,125 @@
+/*
+ * 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 com.android.nfc_extras;
+
+import java.io.IOException;
+
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
+import android.content.Context;
+import android.nfc.INfcAdapterExtras;
+import android.nfc.NfcAdapter;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.RemoteException;
+
+public class NfcExecutionEnvironment {
+ private final INfcAdapterExtras mService;
+
+ /**
+ * Broadcast Action: An ISO-DEP AID was selected.
+ *
+ * <p>This happens as the result of a 'SELECT AID' command from an
+ * external NFC reader/writer.
+ *
+ * <p>Always contains the extra field {@link #EXTRA_AID}
+ *
+ * <p class="note">
+ * Requires the {@link android.Manifest.permission#WRITE_SECURE_SETTINGS} permission
+ * to receive.
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_AID_SELECTED =
+ "com.android.nfc_extras.action.AID_SELECTED";
+
+ /**
+ * Mandatory byte array extra field in {@link #ACTION_AID_SELECTED}.
+ *
+ * <p>Contains the AID selected.
+ * @hide
+ */
+ public static final String EXTRA_AID = "com.android.nfc_extras.extra.AID";
+
+ NfcExecutionEnvironment(INfcAdapterExtras service) {
+ mService = service;
+ }
+
+ /**
+ * Open the NFC Execution Environment on its contact interface.
+ *
+ * <p>Only one process may open the secure element at a time. If it is
+ * already open, an {@link IOException} is thrown.
+ *
+ * <p>All other NFC functionality is disabled while the NFC-EE is open
+ * on its contact interface, so make sure to call {@link #close} once complete.
+ *
+ * <p class="note">
+ * Requires the {@link android.Manifest.permission#WRITE_SECURE_SETTINGS} permission.
+ *
+ * @throws IOException if the NFC-EE is already open, or some other error occurs
+ */
+ public void open() throws IOException {
+ try {
+ Bundle b = mService.open(new Binder());
+ throwBundle(b);
+ } catch (RemoteException e) {
+ return;
+ }
+ }
+
+ /**
+ * Close the NFC Execution Environment on its contact interface.
+ *
+ * <p class="note">
+ * Requires the {@link android.Manifest.permission#WRITE_SECURE_SETTINGS} permission.
+ *
+ * @throws IOException if the NFC-EE is already open, or some other error occurs
+ */
+ public void close() throws IOException {
+ try {
+ throwBundle(mService.close());
+ } catch (RemoteException e) {
+ return;
+ }
+ }
+
+ /**
+ * Send raw commands to the NFC-EE and receive the response.
+ *
+ * <p class="note">
+ * Requires the {@link android.Manifest.permission#WRITE_SECURE_SETTINGS} permission.
+ *
+ * @throws IOException if the NFC-EE is not open, or some other error occurs
+ */
+ public byte[] transceive(byte[] in) throws IOException {
+ Bundle b;
+ try {
+ b = mService.transceive(in);
+ } catch (RemoteException e) {
+ throw new IOException(e.getMessage());
+ }
+ throwBundle(b);
+ return b.getByteArray("out");
+ }
+
+ private static void throwBundle(Bundle b) throws IOException {
+ if (b.getInt("e") == -1) {
+ throw new IOException(b.getString("m"));
+ }
+ }
+}