summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/nfc/INfcAdapter.aidl2
-rw-r--r--core/java/android/nfc/INfcAdapterExtras.aidl12
-rw-r--r--core/java/android/nfc/NfcAdapter.java78
-rw-r--r--core/java/android/nfc/NfcManager.java3
-rw-r--r--nfc-extras/java/com/android/nfc_extras/NfcAdapterExtras.java69
-rw-r--r--nfc-extras/java/com/android/nfc_extras/NfcExecutionEnvironment.java16
6 files changed, 107 insertions, 73 deletions
diff --git a/core/java/android/nfc/INfcAdapter.aidl b/core/java/android/nfc/INfcAdapter.aidl
index 016af58..0b93ad0 100644
--- a/core/java/android/nfc/INfcAdapter.aidl
+++ b/core/java/android/nfc/INfcAdapter.aidl
@@ -32,7 +32,7 @@ import android.nfc.INfcTag;
interface INfcAdapter
{
INfcTag getNfcTagInterface();
- INfcAdapterExtras getNfcAdapterExtrasInterface();
+ INfcAdapterExtras getNfcAdapterExtrasInterface(in String pkg);
int getState();
boolean disable();
diff --git a/core/java/android/nfc/INfcAdapterExtras.aidl b/core/java/android/nfc/INfcAdapterExtras.aidl
index 0c2a2fd..2b9d4f0 100644
--- a/core/java/android/nfc/INfcAdapterExtras.aidl
+++ b/core/java/android/nfc/INfcAdapterExtras.aidl
@@ -23,10 +23,10 @@ import android.os.Bundle;
* {@hide}
*/
interface INfcAdapterExtras {
- Bundle open(IBinder b);
- Bundle close();
- Bundle transceive(in byte[] data_in);
- int getCardEmulationRoute();
- void setCardEmulationRoute(int route);
- void authenticate(in byte[] token);
+ Bundle open(in String pkg, IBinder b);
+ Bundle close(in String pkg, IBinder b);
+ Bundle transceive(in String pkg, in byte[] data_in);
+ int getCardEmulationRoute(in String pkg);
+ void setCardEmulationRoute(in String pkg, int route);
+ void authenticate(in String pkg, in byte[] token);
}
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index fe0106d..a9f1685 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -16,6 +16,8 @@
package android.nfc;
+import java.util.HashMap;
+
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.app.Activity;
@@ -197,15 +199,21 @@ public final class NfcAdapter {
static INfcTag sTagService;
/**
- * NfcAdapter is currently a singleton, and does not require a context.
- * However all the public API's are future-proofed to require a context.
- * If we start using that then we'll need to keep a HashMap of
- * Context.getApplicationContext() -> NfcAdapter, such that NfcAdapter
- * is a singleton within each application context.
+ * 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 sSingleton; // protected by NfcAdapter.class
+ static NfcAdapter sNullContextNfcAdapter; // protected by NfcAdapter.class
final NfcActivityManager mNfcActivityManager;
+ final Context mContext;
/**
* A callback to be invoked when the system successfully delivers your {@link NdefMessage}
@@ -280,12 +288,12 @@ public final class NfcAdapter {
}
/**
- * Returns the singleton, or throws if NFC is not available.
+ * Returns the NfcAdapter for application context,
+ * or throws if NFC is not available.
+ * @hide
*/
- static synchronized NfcAdapter getSingleton() {
+ public static synchronized NfcAdapter getNfcAdapter(Context context) {
if (!sIsInitialized) {
- sIsInitialized = true;
-
/* is this device meant to have NFC */
if (!hasNfcFeature()) {
Log.v(TAG, "this device does not have NFC support");
@@ -303,12 +311,21 @@ public final class NfcAdapter {
Log.e(TAG, "could not retrieve NFC Tag service");
throw new UnsupportedOperationException();
}
- sSingleton = new NfcAdapter();
+
+ sIsInitialized = true;
+ }
+ if (context == null) {
+ if (sNullContextNfcAdapter == null) {
+ sNullContextNfcAdapter = new NfcAdapter(null);
+ }
+ return sNullContextNfcAdapter;
}
- if (sSingleton == null) {
- throw new UnsupportedOperationException();
+ NfcAdapter adapter = sNfcAdapters.get(context);
+ if (adapter == null) {
+ adapter = new NfcAdapter(context);
+ sNfcAdapters.put(context, adapter);
}
- return sSingleton;
+ return adapter;
}
/** get handle to NFC service interface */
@@ -336,6 +353,10 @@ public final class NfcAdapter {
* @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();
/* use getSystemService() instead of just instantiating to take
* advantage of the context's cached NfcManager & NfcAdapter */
NfcManager manager = (NfcManager) context.getSystemService(Context.NFC_SERVICE);
@@ -343,25 +364,30 @@ public final class NfcAdapter {
}
/**
- * Get a handle to the default NFC Adapter on this Android device.
- * <p>
- * Most Android devices will only have one NFC Adapter (NFC Controller).
- *
- * @return the default NFC adapter, or null if no NFC adapter exists
+ * 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)}
*/
@Deprecated
public static NfcAdapter getDefaultAdapter() {
Log.w(TAG, "WARNING: NfcAdapter.getDefaultAdapter() is deprecated, use " +
"NfcAdapter.getDefaultAdapter(Context) instead", new Exception());
- return getSingleton();
+
+ return NfcAdapter.getNfcAdapter(null);
+ }
+
+ NfcAdapter(Context context) {
+ mContext = context;
+ mNfcActivityManager = new NfcActivityManager(this);
}
/**
- * Does not currently need a context.
+ * @hide
*/
- NfcAdapter() {
- mNfcActivityManager = new NfcActivityManager(this);
+ public Context getContext() {
+ return mContext;
}
/**
@@ -875,8 +901,12 @@ public final class NfcAdapter {
* @hide
*/
public INfcAdapterExtras getNfcAdapterExtrasInterface() {
+ if (mContext == null) {
+ throw new UnsupportedOperationException("You need a context on NfcAdapter to use the "
+ + " NFC extras APIs");
+ }
try {
- return sService.getNfcAdapterExtrasInterface();
+ return sService.getNfcAdapterExtrasInterface(mContext.getPackageName());
} catch (RemoteException e) {
attemptDeadServiceRecovery(e);
return null;
diff --git a/core/java/android/nfc/NfcManager.java b/core/java/android/nfc/NfcManager.java
index 300ab45..6ec2e21 100644
--- a/core/java/android/nfc/NfcManager.java
+++ b/core/java/android/nfc/NfcManager.java
@@ -39,8 +39,9 @@ public final class NfcManager {
*/
public NfcManager(Context context) {
NfcAdapter adapter;
+ context = context.getApplicationContext();
try {
- adapter = NfcAdapter.getSingleton();
+ adapter = NfcAdapter.getNfcAdapter(context);
} catch (UnsupportedOperationException e) {
adapter = null;
}
diff --git a/nfc-extras/java/com/android/nfc_extras/NfcAdapterExtras.java b/nfc-extras/java/com/android/nfc_extras/NfcAdapterExtras.java
index 99cbb86..62213de 100644
--- a/nfc-extras/java/com/android/nfc_extras/NfcAdapterExtras.java
+++ b/nfc-extras/java/com/android/nfc_extras/NfcAdapterExtras.java
@@ -16,8 +16,7 @@
package com.android.nfc_extras;
-import android.annotation.SdkConstant;
-import android.annotation.SdkConstant.SdkConstantType;
+import android.content.Context;
import android.nfc.INfcAdapterExtras;
import android.nfc.NfcAdapter;
import android.os.RemoteException;
@@ -60,10 +59,14 @@ public final class NfcAdapterExtras {
// best effort recovery
private static NfcAdapter sAdapter;
private static INfcAdapterExtras sService;
- private static NfcAdapterExtras sSingleton;
- private static NfcExecutionEnvironment sEmbeddedEe;
- private static CardEmulationRoute sRouteOff;
- private static CardEmulationRoute sRouteOnWhenScreenOn;
+ private static final CardEmulationRoute ROUTE_OFF =
+ new CardEmulationRoute(CardEmulationRoute.ROUTE_OFF, null);
+
+ private final NfcExecutionEnvironment mEmbeddedEe;
+ private final CardEmulationRoute mRouteOnWhenScreenOn;
+
+ final Context mContext;
+ final String mPackageName;
/** get service handles */
private static void initService() {
@@ -84,31 +87,35 @@ public final class NfcAdapterExtras {
* @return the {@link NfcAdapterExtras} object for the given {@link NfcAdapter}
*/
public static NfcAdapterExtras get(NfcAdapter adapter) {
- synchronized(NfcAdapterExtras.class) {
- if (sSingleton == null) {
+ Context context = adapter.getContext();
+ if (context == null) {
+ throw new UnsupportedOperationException(
+ "You must pass a context to your NfcAdapter to use the NFC extras APIs");
+ }
+
+ synchronized (NfcAdapterExtras.class) {
+ if (sService == null) {
try {
sAdapter = adapter;
- sSingleton = new NfcAdapterExtras();
- sEmbeddedEe = new NfcExecutionEnvironment(sSingleton);
- sRouteOff = new CardEmulationRoute(CardEmulationRoute.ROUTE_OFF, null);
- sRouteOnWhenScreenOn = new CardEmulationRoute(
- CardEmulationRoute.ROUTE_ON_WHEN_SCREEN_ON, sEmbeddedEe);
initService();
} finally {
if (sService == null) {
- sRouteOnWhenScreenOn = null;
- sRouteOff = null;
- sEmbeddedEe = null;
- sSingleton = null;
sAdapter = null;
}
}
}
- return sSingleton;
}
+
+ return new NfcAdapterExtras(context);
}
- private NfcAdapterExtras() {}
+ private NfcAdapterExtras(Context context) {
+ mContext = context.getApplicationContext();
+ mPackageName = context.getPackageName();
+ mEmbeddedEe = new NfcExecutionEnvironment(this);
+ mRouteOnWhenScreenOn = new CardEmulationRoute(CardEmulationRoute.ROUTE_ON_WHEN_SCREEN_ON,
+ mEmbeddedEe);
+ }
/**
* Immutable data class that describes a card emulation route.
@@ -166,18 +173,16 @@ public final class NfcAdapterExtras {
*
* <p class="note">
* Requires the {@link android.Manifest.permission#WRITE_SECURE_SETTINGS} permission.
- *
- * @return
*/
public CardEmulationRoute getCardEmulationRoute() {
try {
- int route = sService.getCardEmulationRoute();
+ int route = sService.getCardEmulationRoute(mPackageName);
return route == CardEmulationRoute.ROUTE_OFF ?
- sRouteOff :
- sRouteOnWhenScreenOn;
+ ROUTE_OFF :
+ mRouteOnWhenScreenOn;
} catch (RemoteException e) {
attemptDeadServiceRecovery(e);
- return sRouteOff;
+ return ROUTE_OFF;
}
}
@@ -189,11 +194,11 @@ public final class NfcAdapterExtras {
* <p class="note">
* Requires the {@link android.Manifest.permission#WRITE_SECURE_SETTINGS} permission.
*
- * @param route a {@link #CardEmulationRoute}
+ * @param route a {@link CardEmulationRoute}
*/
public void setCardEmulationRoute(CardEmulationRoute route) {
try {
- sService.setCardEmulationRoute(route.route);
+ sService.setCardEmulationRoute(mPackageName, route.route);
} catch (RemoteException e) {
attemptDeadServiceRecovery(e);
}
@@ -201,7 +206,7 @@ public final class NfcAdapterExtras {
/**
* Get the {@link NfcExecutionEnvironment} that is embedded with the
- * {@link NFcAdapter}.
+ * {@link NfcAdapter}.
*
* <p class="note">
* Requires the {@link android.Manifest.permission#WRITE_SECURE_SETTINGS} permission.
@@ -209,7 +214,7 @@ public final class NfcAdapterExtras {
* @return a {@link NfcExecutionEnvironment}, or null if there is no embedded NFC-EE
*/
public NfcExecutionEnvironment getEmbeddedExecutionEnvironment() {
- return sEmbeddedEe;
+ return mEmbeddedEe;
}
/**
@@ -218,12 +223,12 @@ public final class NfcAdapterExtras {
* Some implementations of NFC Adapter Extras may require applications
* to authenticate with a token, before using other methods.
*
- * @param a implementation specific token
- * @throws a {@link java.lang.SecurityException} if authentication failed
+ * @param token a implementation specific token
+ * @throws java.lang.SecurityException if authentication failed
*/
public void authenticate(byte[] token) {
try {
- sService.authenticate(token);
+ sService.authenticate(mPackageName, token);
} catch (RemoteException e) {
attemptDeadServiceRecovery(e);
}
diff --git a/nfc-extras/java/com/android/nfc_extras/NfcExecutionEnvironment.java b/nfc-extras/java/com/android/nfc_extras/NfcExecutionEnvironment.java
index 63c2de2..f47327a 100644
--- a/nfc-extras/java/com/android/nfc_extras/NfcExecutionEnvironment.java
+++ b/nfc-extras/java/com/android/nfc_extras/NfcExecutionEnvironment.java
@@ -16,20 +16,17 @@
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;
+import java.io.IOException;
+
public class NfcExecutionEnvironment {
private final NfcAdapterExtras mExtras;
+ private final Binder mToken;
/**
* Broadcast Action: An ISO-DEP AID was selected.
@@ -115,6 +112,7 @@ public class NfcExecutionEnvironment {
NfcExecutionEnvironment(NfcAdapterExtras extras) {
mExtras = extras;
+ mToken = new Binder();
}
/**
@@ -133,7 +131,7 @@ public class NfcExecutionEnvironment {
*/
public void open() throws IOException {
try {
- Bundle b = mExtras.getService().open(new Binder());
+ Bundle b = mExtras.getService().open(mExtras.mPackageName, mToken);
throwBundle(b);
} catch (RemoteException e) {
mExtras.attemptDeadServiceRecovery(e);
@@ -151,7 +149,7 @@ public class NfcExecutionEnvironment {
*/
public void close() throws IOException {
try {
- throwBundle(mExtras.getService().close());
+ throwBundle(mExtras.getService().close(mExtras.mPackageName, mToken));
} catch (RemoteException e) {
mExtras.attemptDeadServiceRecovery(e);
throw new IOException("NFC Service was dead");
@@ -169,7 +167,7 @@ public class NfcExecutionEnvironment {
public byte[] transceive(byte[] in) throws IOException {
Bundle b;
try {
- b = mExtras.getService().transceive(in);
+ b = mExtras.getService().transceive(mExtras.mPackageName, in);
} catch (RemoteException e) {
mExtras.attemptDeadServiceRecovery(e);
throw new IOException("NFC Service was dead, need to re-open");