Implement dead service recovery in NFC extras library.
Change-Id: I4f1d714c625470df4cda2c4c9aacb8d27bfabb10
This commit is contained in:
@@ -56,13 +56,21 @@ public final class NfcAdapterExtras {
|
||||
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
|
||||
// protected by NfcAdapterExtras.class, and final after first construction,
|
||||
// except for attemptDeadServiceRecovery() when NFC crashes - we accept a
|
||||
// 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;
|
||||
|
||||
/** get service handles */
|
||||
private static void initService() {
|
||||
sService = sAdapter.getNfcAdapterExtrasInterface();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link NfcAdapterExtras} for the given {@link NfcAdapter}.
|
||||
*
|
||||
@@ -76,12 +84,13 @@ public final class NfcAdapterExtras {
|
||||
synchronized(NfcAdapterExtras.class) {
|
||||
if (sSingleton == null) {
|
||||
try {
|
||||
sService = adapter.getNfcAdapterExtrasInterface();
|
||||
sEmbeddedEe = new NfcExecutionEnvironment(sService);
|
||||
sAdapter = adapter;
|
||||
sRouteOff = new CardEmulationRoute(CardEmulationRoute.ROUTE_OFF, null);
|
||||
sSingleton = new NfcAdapterExtras();
|
||||
sEmbeddedEe = new NfcExecutionEnvironment(sSingleton);
|
||||
sRouteOnWhenScreenOn = new CardEmulationRoute(
|
||||
CardEmulationRoute.ROUTE_ON_WHEN_SCREEN_ON, sEmbeddedEe);
|
||||
sSingleton = new NfcAdapterExtras();
|
||||
initService();
|
||||
} finally {
|
||||
if (sSingleton == null) {
|
||||
sService = null;
|
||||
@@ -135,6 +144,19 @@ public final class NfcAdapterExtras {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* NFC service dead - attempt best effort recovery
|
||||
*/
|
||||
void attemptDeadServiceRecovery(Exception e) {
|
||||
Log.e(TAG, "NFC Adapter Extras dead - attempting to recover");
|
||||
sAdapter.attemptDeadServiceRecovery(e);
|
||||
initService();
|
||||
}
|
||||
|
||||
INfcAdapterExtras getService() {
|
||||
return sService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the routing state of this NFC EE.
|
||||
*
|
||||
@@ -150,7 +172,7 @@ public final class NfcAdapterExtras {
|
||||
sRouteOff :
|
||||
sRouteOnWhenScreenOn;
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "", e);
|
||||
attemptDeadServiceRecovery(e);
|
||||
return sRouteOff;
|
||||
}
|
||||
}
|
||||
@@ -169,7 +191,7 @@ public final class NfcAdapterExtras {
|
||||
try {
|
||||
sService.setCardEmulationRoute(route.route);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "", e);
|
||||
attemptDeadServiceRecovery(e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,7 +212,7 @@ public final class NfcAdapterExtras {
|
||||
try {
|
||||
sService.registerTearDownApdus(packageName, apdus);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "", e);
|
||||
attemptDeadServiceRecovery(e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,7 +220,7 @@ public final class NfcAdapterExtras {
|
||||
try {
|
||||
sService.unregisterTearDownApdus(packageName);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "", e);
|
||||
attemptDeadServiceRecovery(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
|
||||
public class NfcExecutionEnvironment {
|
||||
private final INfcAdapterExtras mService;
|
||||
private final NfcAdapterExtras mExtras;
|
||||
|
||||
/**
|
||||
* Broadcast Action: An ISO-DEP AID was selected.
|
||||
@@ -55,8 +55,8 @@ public class NfcExecutionEnvironment {
|
||||
*/
|
||||
public static final String EXTRA_AID = "com.android.nfc_extras.extra.AID";
|
||||
|
||||
NfcExecutionEnvironment(INfcAdapterExtras service) {
|
||||
mService = service;
|
||||
NfcExecutionEnvironment(NfcAdapterExtras extras) {
|
||||
mExtras = extras;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -75,10 +75,11 @@ public class NfcExecutionEnvironment {
|
||||
*/
|
||||
public void open() throws IOException {
|
||||
try {
|
||||
Bundle b = mService.open(new Binder());
|
||||
Bundle b = mExtras.getService().open(new Binder());
|
||||
throwBundle(b);
|
||||
} catch (RemoteException e) {
|
||||
return;
|
||||
mExtras.attemptDeadServiceRecovery(e);
|
||||
throw new IOException("NFC Service was dead, try again");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,9 +93,10 @@ public class NfcExecutionEnvironment {
|
||||
*/
|
||||
public void close() throws IOException {
|
||||
try {
|
||||
throwBundle(mService.close());
|
||||
throwBundle(mExtras.getService().close());
|
||||
} catch (RemoteException e) {
|
||||
return;
|
||||
mExtras.attemptDeadServiceRecovery(e);
|
||||
throw new IOException("NFC Service was dead");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,9 +111,10 @@ public class NfcExecutionEnvironment {
|
||||
public byte[] transceive(byte[] in) throws IOException {
|
||||
Bundle b;
|
||||
try {
|
||||
b = mService.transceive(in);
|
||||
b = mExtras.getService().transceive(in);
|
||||
} catch (RemoteException e) {
|
||||
throw new IOException(e.getMessage());
|
||||
mExtras.attemptDeadServiceRecovery(e);
|
||||
throw new IOException("NFC Service was dead, need to re-open");
|
||||
}
|
||||
throwBundle(b);
|
||||
return b.getByteArray("out");
|
||||
|
||||
Reference in New Issue
Block a user