Merge "Changes for access control." into ics-mr1
This commit is contained in:
@@ -32,7 +32,7 @@ import android.nfc.INfcTag;
|
||||
interface INfcAdapter
|
||||
{
|
||||
INfcTag getNfcTagInterface();
|
||||
INfcAdapterExtras getNfcAdapterExtrasInterface();
|
||||
INfcAdapterExtras getNfcAdapterExtrasInterface(in String pkg);
|
||||
|
||||
int getState();
|
||||
boolean disable();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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 NfcAdapter sSingleton; // protected by NfcAdapter.class
|
||||
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;
|
||||
|
||||
/**
|
||||
* 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 (sSingleton == null) {
|
||||
throw new UnsupportedOperationException();
|
||||
if (context == null) {
|
||||
if (sNullContextNfcAdapter == null) {
|
||||
sNullContextNfcAdapter = new NfcAdapter(null);
|
||||
}
|
||||
return sNullContextNfcAdapter;
|
||||
}
|
||||
return sSingleton;
|
||||
NfcAdapter adapter = sNfcAdapters.get(context);
|
||||
if (adapter == null) {
|
||||
adapter = new NfcAdapter(context);
|
||||
sNfcAdapters.put(context, adapter);
|
||||
}
|
||||
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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user