diff options
Diffstat (limited to 'nfc-extras/java/com/android')
-rw-r--r-- | nfc-extras/java/com/android/nfc_extras/NfcAdapterExtras.java | 70 | ||||
-rw-r--r-- | nfc-extras/java/com/android/nfc_extras/NfcExecutionEnvironment.java | 21 |
2 files changed, 70 insertions, 21 deletions
diff --git a/nfc-extras/java/com/android/nfc_extras/NfcAdapterExtras.java b/nfc-extras/java/com/android/nfc_extras/NfcAdapterExtras.java index cf38bd1..6001be9 100644 --- a/nfc-extras/java/com/android/nfc_extras/NfcAdapterExtras.java +++ b/nfc-extras/java/com/android/nfc_extras/NfcAdapterExtras.java @@ -18,6 +18,7 @@ package com.android.nfc_extras; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; +import android.nfc.ApduList; import android.nfc.INfcAdapterExtras; import android.nfc.NfcAdapter; import android.os.RemoteException; @@ -55,14 +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 boolean sIsInitialized = false; 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}. * @@ -74,14 +82,23 @@ public final class NfcAdapterExtras { */ 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(); + if (sSingleton == null) { + try { + 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); + initService(); + } finally { + if (sSingleton == null) { + sService = null; + sEmbeddedEe = null; + sRouteOff = null; + sRouteOnWhenScreenOn = null; + } + } } return sSingleton; } @@ -128,6 +145,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. * * <p class="note"> @@ -142,7 +172,7 @@ public final class NfcAdapterExtras { sRouteOff : sRouteOnWhenScreenOn; } catch (RemoteException e) { - Log.e(TAG, "", e); + attemptDeadServiceRecovery(e); return sRouteOff; } } @@ -161,7 +191,7 @@ public final class NfcAdapterExtras { try { sService.setCardEmulationRoute(route.route); } catch (RemoteException e) { - Log.e(TAG, "", e); + attemptDeadServiceRecovery(e); } } @@ -177,4 +207,20 @@ public final class NfcAdapterExtras { public NfcExecutionEnvironment getEmbeddedExecutionEnvironment() { return sEmbeddedEe; } + + public void registerTearDownApdus(String packageName, ApduList apdus) { + try { + sService.registerTearDownApdus(packageName, apdus); + } catch (RemoteException e) { + attemptDeadServiceRecovery(e); + } + } + + public void unregisterTearDownApdus(String packageName) { + try { + sService.unregisterTearDownApdus(packageName); + } 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 3efe492..eb2f6f8 100644 --- a/nfc-extras/java/com/android/nfc_extras/NfcExecutionEnvironment.java +++ b/nfc-extras/java/com/android/nfc_extras/NfcExecutionEnvironment.java @@ -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"); |