Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cc9ee72b authored by Nick Pelly's avatar Nick Pelly
Browse files

Implement dead service recovery in NFC extras library.

Change-Id: I4f1d714c625470df4cda2c4c9aacb8d27bfabb10
parent d2127c43
Loading
Loading
Loading
Loading
+30 −8
Original line number Diff line number Diff line
@@ -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);
        }
    }
}
+12 −9
Original line number Diff line number Diff line
@@ -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");