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

Commit 449fb2de authored by Nick Pelly's avatar Nick Pelly Committed by Android Git Automerger
Browse files

am 222f489f: am 6d55e134: Make best effort attempt to recover NFC service when it dies.

parents 936747d6 222f489f
Loading
Loading
Loading
Loading
+8 −8
Original line number Diff line number Diff line
@@ -42,8 +42,8 @@ public class NdefTagConnection extends RawTagConnection {
     * Internal constructor, to be used by NfcAdapter
     * @hide
     */
    /* package private */ NdefTagConnection(INfcAdapter service, NdefTag tag, String target) throws RemoteException {
        super(service, tag);
    /* package private */ NdefTagConnection(NfcAdapter adapter, NdefTag tag, String target) throws RemoteException {
        super(adapter, tag);
        String[] targets = tag.getNdefTargets();
        int i;

@@ -63,8 +63,8 @@ public class NdefTagConnection extends RawTagConnection {
     * Internal constructor, to be used by NfcAdapter
     * @hide
     */
    /* package private */ NdefTagConnection(INfcAdapter service, NdefTag tag) throws RemoteException {
        this(service, tag, tag.getNdefTargets()[0]);
    /* package private */ NdefTagConnection(NfcAdapter adapter, NdefTag tag) throws RemoteException {
        this(adapter, tag, tag.getNdefTargets()[0]);
    }

    /**
@@ -97,7 +97,7 @@ public class NdefTagConnection extends RawTagConnection {
            msgArray[0] = msg;
            return msgArray;
        } catch (RemoteException e) {
            Log.e(TAG, "NFC service died");
            attemptDeadServiceRecovery(e);
            return null;
        }
    }
@@ -134,7 +134,7 @@ public class NdefTagConnection extends RawTagConnection {
                    throw new IOException();
            }
        } catch (RemoteException e) {
            Log.e(TAG, "NFC service died");
            attemptDeadServiceRecovery(e);
        }
    }

@@ -161,7 +161,7 @@ public class NdefTagConnection extends RawTagConnection {
                    throw new IOException();
            }
        } catch (RemoteException e) {
            Log.e(TAG, "NFC service died");
            attemptDeadServiceRecovery(e);
            return false;
        }
    }
@@ -188,7 +188,7 @@ public class NdefTagConnection extends RawTagConnection {
            return result;

        } catch (RemoteException e) {
            Log.e(TAG, "NFC service died");
            attemptDeadServiceRecovery(e);
            return NDEF_MODE_UNKNOWN;
        }
    }
+44 −18
Original line number Diff line number Diff line
@@ -168,7 +168,10 @@ public final class NfcAdapter {
    private static boolean sIsInitialized = false;
    private static NfcAdapter sAdapter;

    private final INfcAdapter mService;
    // Final after construction, except for attemptDeadServiceRecovery()
    // when NFC crashes.
    // Not locked - we accept a best effort attempt when NFC crashes.
    /*package*/ INfcAdapter mService;

    private NfcAdapter(INfcAdapter service) {
        mService = service;
@@ -194,6 +197,16 @@ public final class NfcAdapter {
        }
    }

    /** get handle to NFC service interface */
    private static synchronized INfcAdapter getServiceInterface() {
        /* get a handle to NFC service */
        IBinder b = ServiceManager.getService("nfc");
        if (b == null) {
            return null;
        }
        return INfcAdapter.Stub.asInterface(b);
    }

    /**
     * Get a handle to the default NFC Adapter on this Android device.
     * <p>
@@ -214,18 +227,31 @@ public final class NfcAdapter {
                return null;
            }

            /* get a handle to NFC service */
            IBinder b = ServiceManager.getService("nfc");
            if (b == null) {
            INfcAdapter service = getServiceInterface();
            if (service == null) {
                Log.e(TAG, "could not retrieve NFC service");
                return null;
            }

            sAdapter = new NfcAdapter(INfcAdapter.Stub.asInterface(b));
            sAdapter = new NfcAdapter(service);
            return sAdapter;
        }
    }

    /** NFC service dead - attempt best effort recovery */
    /*package*/ void attemptDeadServiceRecovery(Exception e) {
        Log.e(TAG, "NFC service dead - attempting to recover", e);
        INfcAdapter service = getServiceInterface();
        if (service == null) {
            Log.e(TAG, "could not retrieve NFC service during service recovery");
            return;
        }
        /* assigning to mService is not thread-safe, but this is best-effort code
         * and on a well-behaved system should never happen */
        mService = service;
        return;
    }

    /**
     * Return true if this NFC Adapter has any features enabled.
     * <p>
@@ -241,7 +267,7 @@ public final class NfcAdapter {
        try {
            return mService.isEnabled();
        } catch (RemoteException e) {
            Log.e(TAG, "RemoteException in isEnabled()", e);
            attemptDeadServiceRecovery(e);
            return false;
        }
    }
@@ -258,7 +284,7 @@ public final class NfcAdapter {
        try {
            return mService.enable();
        } catch (RemoteException e) {
            Log.e(TAG, "RemoteException in enable()", e);
            attemptDeadServiceRecovery(e);
            return false;
        }
    }
@@ -277,7 +303,7 @@ public final class NfcAdapter {
        try {
            return mService.disable();
        } catch (RemoteException e) {
            Log.e(TAG, "RemoteException in disable()", e);
            attemptDeadServiceRecovery(e);
            return false;
        }
    }
@@ -303,7 +329,7 @@ public final class NfcAdapter {
        try {
            mService.localSet(message);
        } catch (RemoteException e) {
            Log.e(TAG, "NFC service died", e);
            attemptDeadServiceRecovery(e);
        }
    }

@@ -317,7 +343,7 @@ public final class NfcAdapter {
        try {
            return mService.localGet();
        } catch (RemoteException e) {
            Log.e(TAG, "NFC service died", e);
            attemptDeadServiceRecovery(e);
            return null;
        }
    }
@@ -331,9 +357,9 @@ public final class NfcAdapter {
            throw new IllegalArgumentException("mock tag cannot be used for connections");
        }
        try {
            return new RawTagConnection(mService, tag);
            return new RawTagConnection(this, tag);
        } catch (RemoteException e) {
            Log.e(TAG, "NFC service died", e);
            attemptDeadServiceRecovery(e);
            return null;
        }
    }
@@ -347,9 +373,9 @@ public final class NfcAdapter {
            throw new IllegalArgumentException("mock tag cannot be used for connections");
        }
        try {
            return new RawTagConnection(mService, tag, target);
            return new RawTagConnection(this, tag, target);
        } catch (RemoteException e) {
            Log.e(TAG, "NFC service died", e);
            attemptDeadServiceRecovery(e);
            return null;
        }
    }
@@ -363,9 +389,9 @@ public final class NfcAdapter {
            throw new IllegalArgumentException("mock tag cannot be used for connections");
        }
        try {
            return new NdefTagConnection(mService, tag);
            return new NdefTagConnection(this, tag);
        } catch (RemoteException e) {
            Log.e(TAG, "NFC service died", e);
            attemptDeadServiceRecovery(e);
            return null;
        }
    }
@@ -379,9 +405,9 @@ public final class NfcAdapter {
            throw new IllegalArgumentException("mock tag cannot be used for connections");
        }
        try {
            return new NdefTagConnection(mService, tag, target);
            return new NdefTagConnection(this, tag, target);
        } catch (RemoteException e) {
            Log.e(TAG, "NFC service died", e);
            attemptDeadServiceRecovery(e);
            return null;
        }
    }
+29 −10
Original line number Diff line number Diff line
@@ -35,15 +35,20 @@ import android.util.Log;
 */
public class RawTagConnection {

    /*package*/ final INfcAdapter mService;
    /*package*/ final INfcTag mTagService;
    /*package*/ final Tag mTag;
    /*package*/ boolean mIsConnected;
    /*package*/ String mSelectedTarget;
    private final NfcAdapter mAdapter;

    // Following fields are final after construction, except for
    // during attemptDeadServiceRecovery() when NFC crashes.
    // Not locked - we accept a best effort attempt when NFC crashes.
    /*package*/ INfcAdapter mService;
    /*package*/ INfcTag mTagService;

    private static final String TAG = "NFC";

    /* package private */ RawTagConnection(INfcAdapter service, Tag tag, String target) throws RemoteException {
    /*package*/ RawTagConnection(NfcAdapter adapter, Tag tag, String target) throws RemoteException {
        String[] targets = tag.getRawTargets();
        int i;

@@ -58,14 +63,28 @@ public class RawTagConnection {
            throw new IllegalArgumentException();
        }

        mService = service;
        mTagService = service.getNfcTagInterface();
        mAdapter = adapter;
        mService = mAdapter.mService;
        mTagService = mService.getNfcTagInterface();
        mTag = tag;
        mSelectedTarget = target;
    }

    /* package private */ RawTagConnection(INfcAdapter service, Tag tag) throws RemoteException {
        this(service, tag, tag.getRawTargets()[0]);
    /*package*/ RawTagConnection(NfcAdapter adapter, Tag tag) throws RemoteException {
        this(adapter, tag, tag.getRawTargets()[0]);
    }

    /** NFC service dead - attempt best effort recovery */
    /*package*/ void attemptDeadServiceRecovery(Exception e) {
        mAdapter.attemptDeadServiceRecovery(e);
        /* assigning to mService is not thread-safe, but this is best-effort code
         * and on a well-behaved system should never happen */
        mService = mAdapter.mService;
        try {
            mTagService = mService.getNfcTagInterface();
        } catch (RemoteException e2) {
            Log.e(TAG, "second RemoteException trying to recover from dead NFC service", e2);
        }
    }

    /**
@@ -101,7 +120,7 @@ public class RawTagConnection {
        try {
            return mTagService.isPresent(mTag.mServiceHandle);
        } catch (RemoteException e) {
            Log.e(TAG, "NFC service died", e);
            attemptDeadServiceRecovery(e);
            return false;
        }
    }
@@ -136,7 +155,7 @@ public class RawTagConnection {
        try {
            mTagService.close(mTag.mServiceHandle);
        } catch (RemoteException e) {
            Log.e(TAG, "NFC service died", e);
            attemptDeadServiceRecovery(e);
        }
    }

@@ -159,7 +178,7 @@ public class RawTagConnection {
            }
            return response;
        } catch (RemoteException e) {
            Log.e(TAG, "NFC service died", e);
            attemptDeadServiceRecovery(e);
            throw new IOException("NFC service died");
        }
    }