Skip to content

Commit cc9ee72

Browse files
author
Nick Pelly
committed
Implement dead service recovery in NFC extras library.
Change-Id: I4f1d714c625470df4cda2c4c9aacb8d27bfabb10
1 parent d2127c4 commit cc9ee72

File tree

2 files changed

+42
-17
lines changed

2 files changed

+42
-17
lines changed

nfc-extras/java/com/android/nfc_extras/NfcAdapterExtras.java

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,21 @@ public final class NfcAdapterExtras {
5656
public static final String ACTION_RF_FIELD_OFF_DETECTED =
5757
"com.android.nfc_extras.action.RF_FIELD_OFF_DETECTED";
5858

59-
// protected by NfcAdapterExtras.class, and final after first construction
59+
// protected by NfcAdapterExtras.class, and final after first construction,
60+
// except for attemptDeadServiceRecovery() when NFC crashes - we accept a
61+
// best effort recovery
62+
private static NfcAdapter sAdapter;
6063
private static INfcAdapterExtras sService;
6164
private static NfcAdapterExtras sSingleton;
6265
private static NfcExecutionEnvironment sEmbeddedEe;
6366
private static CardEmulationRoute sRouteOff;
6467
private static CardEmulationRoute sRouteOnWhenScreenOn;
6568

69+
/** get service handles */
70+
private static void initService() {
71+
sService = sAdapter.getNfcAdapterExtrasInterface();
72+
}
73+
6674
/**
6775
* Get the {@link NfcAdapterExtras} for the given {@link NfcAdapter}.
6876
*
@@ -76,12 +84,13 @@ public static NfcAdapterExtras get(NfcAdapter adapter) {
7684
synchronized(NfcAdapterExtras.class) {
7785
if (sSingleton == null) {
7886
try {
79-
sService = adapter.getNfcAdapterExtrasInterface();
80-
sEmbeddedEe = new NfcExecutionEnvironment(sService);
87+
sAdapter = adapter;
8188
sRouteOff = new CardEmulationRoute(CardEmulationRoute.ROUTE_OFF, null);
89+
sSingleton = new NfcAdapterExtras();
90+
sEmbeddedEe = new NfcExecutionEnvironment(sSingleton);
8291
sRouteOnWhenScreenOn = new CardEmulationRoute(
8392
CardEmulationRoute.ROUTE_ON_WHEN_SCREEN_ON, sEmbeddedEe);
84-
sSingleton = new NfcAdapterExtras();
93+
initService();
8594
} finally {
8695
if (sSingleton == null) {
8796
sService = null;
@@ -135,6 +144,19 @@ public CardEmulationRoute(int route, NfcExecutionEnvironment nfcEe) {
135144
}
136145
}
137146

147+
/**
148+
* NFC service dead - attempt best effort recovery
149+
*/
150+
void attemptDeadServiceRecovery(Exception e) {
151+
Log.e(TAG, "NFC Adapter Extras dead - attempting to recover");
152+
sAdapter.attemptDeadServiceRecovery(e);
153+
initService();
154+
}
155+
156+
INfcAdapterExtras getService() {
157+
return sService;
158+
}
159+
138160
/**
139161
* Get the routing state of this NFC EE.
140162
*
@@ -150,7 +172,7 @@ public CardEmulationRoute getCardEmulationRoute() {
150172
sRouteOff :
151173
sRouteOnWhenScreenOn;
152174
} catch (RemoteException e) {
153-
Log.e(TAG, "", e);
175+
attemptDeadServiceRecovery(e);
154176
return sRouteOff;
155177
}
156178
}
@@ -169,7 +191,7 @@ public void setCardEmulationRoute(CardEmulationRoute route) {
169191
try {
170192
sService.setCardEmulationRoute(route.route);
171193
} catch (RemoteException e) {
172-
Log.e(TAG, "", e);
194+
attemptDeadServiceRecovery(e);
173195
}
174196
}
175197

@@ -190,15 +212,15 @@ public void registerTearDownApdus(String packageName, ApduList apdus) {
190212
try {
191213
sService.registerTearDownApdus(packageName, apdus);
192214
} catch (RemoteException e) {
193-
Log.e(TAG, "", e);
215+
attemptDeadServiceRecovery(e);
194216
}
195217
}
196218

197219
public void unregisterTearDownApdus(String packageName) {
198220
try {
199221
sService.unregisterTearDownApdus(packageName);
200222
} catch (RemoteException e) {
201-
Log.e(TAG, "", e);
223+
attemptDeadServiceRecovery(e);
202224
}
203225
}
204226
}

nfc-extras/java/com/android/nfc_extras/NfcExecutionEnvironment.java

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
import android.os.RemoteException;
3030

3131
public class NfcExecutionEnvironment {
32-
private final INfcAdapterExtras mService;
32+
private final NfcAdapterExtras mExtras;
3333

3434
/**
3535
* Broadcast Action: An ISO-DEP AID was selected.
@@ -55,8 +55,8 @@ public class NfcExecutionEnvironment {
5555
*/
5656
public static final String EXTRA_AID = "com.android.nfc_extras.extra.AID";
5757

58-
NfcExecutionEnvironment(INfcAdapterExtras service) {
59-
mService = service;
58+
NfcExecutionEnvironment(NfcAdapterExtras extras) {
59+
mExtras = extras;
6060
}
6161

6262
/**
@@ -75,10 +75,11 @@ public class NfcExecutionEnvironment {
7575
*/
7676
public void open() throws IOException {
7777
try {
78-
Bundle b = mService.open(new Binder());
78+
Bundle b = mExtras.getService().open(new Binder());
7979
throwBundle(b);
8080
} catch (RemoteException e) {
81-
return;
81+
mExtras.attemptDeadServiceRecovery(e);
82+
throw new IOException("NFC Service was dead, try again");
8283
}
8384
}
8485

@@ -92,9 +93,10 @@ public void open() throws IOException {
9293
*/
9394
public void close() throws IOException {
9495
try {
95-
throwBundle(mService.close());
96+
throwBundle(mExtras.getService().close());
9697
} catch (RemoteException e) {
97-
return;
98+
mExtras.attemptDeadServiceRecovery(e);
99+
throw new IOException("NFC Service was dead");
98100
}
99101
}
100102

@@ -109,9 +111,10 @@ public void close() throws IOException {
109111
public byte[] transceive(byte[] in) throws IOException {
110112
Bundle b;
111113
try {
112-
b = mService.transceive(in);
114+
b = mExtras.getService().transceive(in);
113115
} catch (RemoteException e) {
114-
throw new IOException(e.getMessage());
116+
mExtras.attemptDeadServiceRecovery(e);
117+
throw new IOException("NFC Service was dead, need to re-open");
115118
}
116119
throwBundle(b);
117120
return b.getByteArray("out");

0 commit comments

Comments
 (0)