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

Commit 82f2b2ec authored by Roshan Pius's avatar Roshan Pius
Browse files

nfc: Eliminate boilder plate code for recovering service (contd)

Continuation of ag/28238772. Fixing some API calls that were missed in NfcAdapter and fixing all the ones in CardEmulation.

Also, rethrows the remote exception if the recovery fails instead of silently failing as recommended by the API council. 

Bug: 352128197
Change-Id: I79da716bd1bc74195b52eef8fb62db045b52230a
Test: Ran Cts tests
Flag: EXEMPT refactor
parent 303564b4
Loading
Loading
Loading
Loading
+5 −20
Original line number Diff line number Diff line
@@ -236,11 +236,7 @@ public final class NfcActivityManager extends IAppCallback.Stub

    public void setReaderMode(Binder token, int flags, Bundle extras) {
        if (DBG) Log.d(TAG, "Setting reader mode");
        try {
            NfcAdapter.sService.setReaderMode(token, this, flags, extras);
        } catch (RemoteException e) {
            mAdapter.attemptDeadServiceRecovery(e);
        }
        NfcAdapter.callService(() -> NfcAdapter.sService.setReaderMode(token, this, flags, extras));
    }

    /**
@@ -248,19 +244,11 @@ public final class NfcActivityManager extends IAppCallback.Stub
     * Makes IPC call - do not hold lock.
     */
    void requestNfcServiceCallback() {
        try {
            NfcAdapter.sService.setAppCallback(this);
        } catch (RemoteException e) {
            mAdapter.attemptDeadServiceRecovery(e);
        }
        NfcAdapter.callService(() -> NfcAdapter.sService.setAppCallback(this));
    }

    void verifyNfcPermission() {
        try {
            NfcAdapter.sService.verifyNfcPermission();
        } catch (RemoteException e) {
            mAdapter.attemptDeadServiceRecovery(e);
        }
        NfcAdapter.callService(() -> NfcAdapter.sService.verifyNfcPermission());
    }

    @Override
@@ -406,11 +394,8 @@ public final class NfcActivityManager extends IAppCallback.Stub
    }

    private void changeDiscoveryTech(Binder token, int pollTech, int listenTech) {
        try {
            NfcAdapter.sService.updateDiscoveryTechnology(token, pollTech, listenTech);
        } catch (RemoteException e) {
            mAdapter.attemptDeadServiceRecovery(e);
        }
        NfcAdapter.callService(
            () -> NfcAdapter.sService.updateDiscoveryTechnology(token, pollTech, listenTech));
    }

}
+58 −128
Original line number Diff line number Diff line
@@ -922,8 +922,8 @@ public final class NfcAdapter {
     * @hide
     */
    @UnsupportedAppUsage
    public INfcAdapter getService() {
        isEnabled();  // NOP call to recover sService if it is stale
    public static INfcAdapter getService() {
        isEnabledStatic();  // NOP call to recover sService if it is stale
        return sService;
    }

@@ -931,8 +931,8 @@ public final class NfcAdapter {
     * Returns the binder interface to the tag service.
     * @hide
     */
    public INfcTag getTagService() {
        isEnabled();  // NOP call to recover sTagService if it is stale
    public static INfcTag getTagService() {
        isEnabledStatic();  // NOP call to recover sTagService if it is stale
        return sTagService;
    }

@@ -940,8 +940,8 @@ public final class NfcAdapter {
     * Returns the binder interface to the card emulation service.
     * @hide
     */
    public INfcCardEmulation getCardEmulationService() {
        isEnabled();
    public static INfcCardEmulation getCardEmulationService() {
        isEnabledStatic();
        return sCardEmulationService;
    }

@@ -949,8 +949,8 @@ public final class NfcAdapter {
     * Returns the binder interface to the NFC-F card emulation service.
     * @hide
     */
    public INfcFCardEmulation getNfcFCardEmulationService() {
        isEnabled();
    public static INfcFCardEmulation getNfcFCardEmulationService() {
        isEnabledStatic();
        return sNfcFCardEmulationService;
    }

@@ -973,14 +973,14 @@ public final class NfcAdapter {
     * @hide
     */
    @UnsupportedAppUsage
    public void attemptDeadServiceRecovery(Exception e) {
    public static void attemptDeadServiceRecovery(RemoteException 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");
            // nothing more can be done now, sService is still stale, we'll hit
            // this recovery path again later
            return;
            e.rethrowAsRuntimeException();
        }
        // assigning to sService is not thread-safe, but this is best-effort code
        // and on a well-behaved system should never happen
@@ -993,7 +993,7 @@ public final class NfcAdapter {
                Log.e(TAG, "could not retrieve NFC tag service during service recovery");
                // nothing more can be done now, sService is still stale, we'll hit
                // this recovery path again later
                return;
                ee.rethrowAsRuntimeException();
            }
        }

@@ -1014,24 +1014,27 @@ public final class NfcAdapter {
                        "could not retrieve NFC-F card emulation service during service recovery");
            }
        }

        return;
    }

    private boolean isCardEmulationEnabled() {
    private static boolean isCardEmulationEnabled() {
        if (sHasCeFeature) {
            return (sCardEmulationService != null || sNfcFCardEmulationService != null);
        }
        return false;
    }

    private boolean isTagReadingEnabled() {
    private static boolean isTagReadingEnabled() {
        if (sHasNfcFeature) {
            return sTagService != null;
        }
        return false;
    }

    private static boolean isEnabledStatic() {
        boolean serviceState = callServiceReturn(() -> sService.getState() == STATE_ON, false);
        return serviceState
                && (isTagReadingEnabled() || isCardEmulationEnabled() || sHasNfcWlcFeature);
    }

    /**
     * Return true if this NFC Adapter has any features enabled.
@@ -1046,24 +1049,7 @@ public final class NfcAdapter {
     * @return true if this NFC Adapter has any features enabled
     */
    public boolean isEnabled() {
        boolean serviceState = false;
        try {
            serviceState = sService.getState() == STATE_ON;
        } catch (RemoteException e) {
            attemptDeadServiceRecovery(e);
            // Try one more time
            if (sService == null) {
                Log.e(TAG, "Failed to recover NFC Service.");
                return false;
            }
            try {
                serviceState = sService.getState() == STATE_ON;
            } catch (RemoteException ee) {
                Log.e(TAG, "Failed to recover NFC Service.");
            }
        }
        return serviceState
                && (isTagReadingEnabled() || isCardEmulationEnabled() || sHasNfcWlcFeature);
        return isEnabledStatic();
    }

    /**
@@ -1157,11 +1143,7 @@ public final class NfcAdapter {
     * @hide
     */
    public void pausePolling(int timeoutInMs) {
        try {
            sService.pausePolling(timeoutInMs);
        } catch (RemoteException e) {
            attemptDeadServiceRecovery(e);
        }
        callService(() -> sService.pausePolling(timeoutInMs));
    }


@@ -1222,11 +1204,7 @@ public final class NfcAdapter {
     * @hide
     */
    public void resumePolling() {
        try {
            sService.resumePolling();
        } catch (RemoteException e) {
            attemptDeadServiceRecovery(e);
        }
        callService(() -> sService.resumePolling());
    }

    /**
@@ -1645,15 +1623,10 @@ public final class NfcAdapter {
        if (activity == null || intent == null) {
            throw new NullPointerException();
        }
        try {
            TechListParcel parcel = null;
            if (techLists != null && techLists.length > 0) {
                parcel = new TechListParcel(techLists);
            }
            sService.setForegroundDispatch(intent, filters, parcel);
        } catch (RemoteException e) {
            attemptDeadServiceRecovery(e);
        }
        final TechListParcel parcel = (techLists != null && techLists.length > 0)
            ? new TechListParcel(techLists)
            : null;
        callService(() -> sService.setForegroundDispatch(intent, filters, parcel));
    }

    /**
@@ -1677,11 +1650,7 @@ public final class NfcAdapter {
                throw new UnsupportedOperationException();
            }
        }
        try {
            sService.setForegroundDispatch(null, null, null);
        } catch (RemoteException e) {
            attemptDeadServiceRecovery(e);
        }
        callService(() -> sService.setForegroundDispatch(null, null, null));
    }

    /**
@@ -1762,11 +1731,7 @@ public final class NfcAdapter {
        }
        Binder token = new Binder();
        int flags = enable ? ENABLE_POLLING_FLAGS : DISABLE_POLLING_FLAGS;
        try {
            NfcAdapter.sService.setReaderMode(token, null, flags, null);
        } catch (RemoteException e) {
            attemptDeadServiceRecovery(e);
        }
        callService(() -> sService.setReaderMode(token, null, flags, null));
    }

    /**
@@ -1838,12 +1803,8 @@ public final class NfcAdapter {
                && ((pollTechnology & FLAG_SET_DEFAULT_TECH) == FLAG_SET_DEFAULT_TECH
                || (listenTechnology & FLAG_SET_DEFAULT_TECH) == FLAG_SET_DEFAULT_TECH)) {
            Binder token = new Binder();
            try {
                NfcAdapter.sService.updateDiscoveryTechnology(token,
                        pollTechnology, listenTechnology);
            } catch (RemoteException e) {
                attemptDeadServiceRecovery(e);
            }
            callService( () ->
                sService.updateDiscoveryTechnology(token, pollTechnology, listenTechnology));
        } else {
            mNfcActivityManager.setDiscoveryTech(activity, pollTechnology, listenTechnology);
        }
@@ -2227,11 +2188,7 @@ public final class NfcAdapter {
        if (tag == null) {
            throw new NullPointerException("tag cannot be null");
        }
        try {
            sService.dispatch(tag);
        } catch (RemoteException e) {
            attemptDeadServiceRecovery(e);
        }
        callService(() -> sService.dispatch(tag));
    }

    /**
@@ -2267,8 +2224,10 @@ public final class NfcAdapter {
            synchronized (mLock) {
                if (mNfcUnlockHandlers.containsKey(unlockHandler)) {
                    // update the tag technologies
                    callService(() -> {
                        sService.removeNfcUnlockHandler(mNfcUnlockHandlers.get(unlockHandler));
                        mNfcUnlockHandlers.remove(unlockHandler);
                    });
                }

                INfcUnlockHandler.Stub iHandler = new INfcUnlockHandler.Stub() {
@@ -2277,20 +2236,18 @@ public final class NfcAdapter {
                        return unlockHandler.onUnlockAttempted(tag);
                    }
                };

                sService.addNfcUnlockHandler(iHandler,
                        Tag.getTechCodesFromStrings(tagTechnologies));
                return callServiceReturn(() -> {
                        sService.addNfcUnlockHandler(
                            iHandler, Tag.getTechCodesFromStrings(tagTechnologies));
                        mNfcUnlockHandlers.put(unlockHandler, iHandler);
                        return true;
                    }, false);
            }
        } catch (RemoteException e) {
            attemptDeadServiceRecovery(e);
            return false;
        } catch (IllegalArgumentException e) {
            Log.e(TAG, "Unable to register LockscreenDispatch", e);
            return false;
        }

        return true;
    }

    /**
@@ -2307,17 +2264,14 @@ public final class NfcAdapter {
                throw new UnsupportedOperationException();
            }
        }
        try {
        synchronized (mLock) {
            if (mNfcUnlockHandlers.containsKey(unlockHandler)) {
                return callServiceReturn(() -> {
                    sService.removeNfcUnlockHandler(mNfcUnlockHandlers.remove(unlockHandler));
                }

                    return true;
                }, false);
            }
        } catch (RemoteException e) {
            attemptDeadServiceRecovery(e);
            return false;
            return true;
        }
    }

@@ -2525,26 +2479,8 @@ public final class NfcAdapter {
            Log.e(TAG, "TagIntentAppPreference is not supported");
            throw new UnsupportedOperationException();
        }
        try {
            Map<String, Boolean> result = (Map<String, Boolean>) sService
                     .getTagIntentAppPreferenceForUser(userId);
            return result;
        } catch (RemoteException e) {
            attemptDeadServiceRecovery(e);
            // Try one more time
            if (sService == null) {
                Log.e(TAG, "Failed to recover NFC Service.");
                return Collections.emptyMap();
            }
            try {
                Map<String, Boolean> result = (Map<String, Boolean>) sService
                        .getTagIntentAppPreferenceForUser(userId);
                return result;
            } catch (RemoteException ee) {
                Log.e(TAG, "Failed to recover NFC Service.");
            }
            return Collections.emptyMap();
        }
        return callServiceReturn( () ->
            sService.getTagIntentAppPreferenceForUser(userId), Collections.emptyMap());
    }

    /**
@@ -2590,50 +2526,44 @@ public final class NfcAdapter {
        callService(() ->  sService.notifyTestHceData(technology, data));
    }

    /** @hide */
    interface ServiceCall {
        void call() throws RemoteException;
    }

    void callService(ServiceCall call) {
    /** @hide */
    static void callService(ServiceCall call) {
        try {
            if (sService == null) {
                attemptDeadServiceRecovery(null);
                attemptDeadServiceRecovery(new RemoteException("NFC Service is null"));
            }
            call.call();
        } catch (RemoteException e) {
            attemptDeadServiceRecovery(e);
            // Try one more time
            if (sService == null) {
                Log.e(TAG, "Failed to recover NFC Service.");
                return;
            }
            try {
                call.call();
            } catch (RemoteException ee) {
                Log.e(TAG, "Failed to recover NFC Service.");
                ee.rethrowAsRuntimeException();
            }
        }
    }
    /** @hide */
    interface ServiceCallReturn<T> {
        T call() throws RemoteException;
    }
    <T> T callServiceReturn(ServiceCallReturn<T> call, T defaultReturn) {
    /** @hide */
    static <T> T callServiceReturn(ServiceCallReturn<T> call, T defaultReturn) {
        try {
            if (sService == null) {
                attemptDeadServiceRecovery(null);
                attemptDeadServiceRecovery(new RemoteException("NFC Service is null"));
            }
            return call.call();
        } catch (RemoteException e) {
            attemptDeadServiceRecovery(e);
            // Try one more time
            if (sService == null) {
                Log.e(TAG, "Failed to recover NFC Service.");
                return defaultReturn;
            }
            try {
                return call.call();
            } catch (RemoteException ee) {
                Log.e(TAG, "Failed to recover NFC Service.");
                ee.rethrowAsRuntimeException();
            }
        }
        return defaultReturn;
+7 −23
Original line number Diff line number Diff line
@@ -89,13 +89,11 @@ public final class NfcOemExtension {
                        + "registering");
                throw new IllegalArgumentException();
            }
            try {
            NfcAdapter.callService(() -> {
                NfcAdapter.sService.registerOemExtensionCallback(mOemNfcExtensionCallback);
                mCallback = callback;
                mExecutor = executor;
            } catch (RemoteException e) {
                mAdapter.attemptDeadServiceRecovery(e);
            }
            });
        }
    }

@@ -117,13 +115,11 @@ public final class NfcOemExtension {
                Log.e(TAG, "Callback not registered");
                throw new IllegalArgumentException();
            }
            try {
            NfcAdapter.callService(() -> {
                NfcAdapter.sService.unregisterOemExtensionCallback(mOemNfcExtensionCallback);
                mCallback = null;
                mExecutor = null;
            } catch (RemoteException e) {
                mAdapter.attemptDeadServiceRecovery(e);
            }
            });
        }
    }

@@ -134,11 +130,7 @@ public final class NfcOemExtension {
    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
    public void clearPreference() {
        try {
            NfcAdapter.sService.clearPreference();
        } catch (RemoteException e) {
            mAdapter.attemptDeadServiceRecovery(e);
        }
        NfcAdapter.callService(() -> NfcAdapter.sService.clearPreference());
    }

    /**
@@ -147,11 +139,7 @@ public final class NfcOemExtension {
    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
    public void synchronizeScreenState() {
        try {
            NfcAdapter.sService.setScreenState();
        } catch (RemoteException e) {
            mAdapter.attemptDeadServiceRecovery(e);
        }
        NfcAdapter.callService(() -> NfcAdapter.sService.setScreenState());
    }

    /**
@@ -162,11 +150,7 @@ public final class NfcOemExtension {
    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
    public void maybeTriggerFirmwareUpdate() {
        try {
            NfcAdapter.sService.checkFirmware();
        } catch (RemoteException e) {
            mAdapter.attemptDeadServiceRecovery(e);
        }
        NfcAdapter.callService(() -> NfcAdapter.sService.checkFirmware());
    }

    private final class NfcOemExtensionCallback extends INfcOemExtensionCallback.Stub {
+137 −494

File changed.

Preview size limit exceeded, changes collapsed.