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

Commit d259f2b0 authored by Joe Bolinger's avatar Joe Bolinger Committed by Automerger Merge Worker
Browse files

Merge "Destroy clients that do not start." into sc-v2-dev am: 978e1ddc am: 9560ce30

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/16332565

Change-Id: I88bcc8a58642016b7ae645a220d50d114a80643a
parents a4cbc58d 9560ce30
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -251,7 +251,7 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T>
                        "Successful background authentication!");
                        "Successful background authentication!");
            }
            }


            mAlreadyDone = true;
            markAlreadyDone();


            if (mTaskStackListener != null) {
            if (mTaskStackListener != null) {
                mActivityTaskManager.unregisterTaskStackListener(mTaskStackListener);
                mActivityTaskManager.unregisterTaskStackListener(mTaskStackListener);
@@ -327,7 +327,7 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T>
            final @LockoutTracker.LockoutMode int lockoutMode =
            final @LockoutTracker.LockoutMode int lockoutMode =
                    handleFailedAttempt(getTargetUserId());
                    handleFailedAttempt(getTargetUserId());
            if (lockoutMode != LockoutTracker.LOCKOUT_NONE) {
            if (lockoutMode != LockoutTracker.LOCKOUT_NONE) {
                mAlreadyDone = true;
                markAlreadyDone();
            }
            }


            final CoexCoordinator coordinator = CoexCoordinator.getInstance();
            final CoexCoordinator coordinator = CoexCoordinator.getInstance();
+21 −10
Original line number Original line Diff line number Diff line
@@ -114,7 +114,7 @@ public abstract class BaseClientMonitor extends LoggableMonitor
    // Currently only used for authentication client. The cookie generated by BiometricService
    // Currently only used for authentication client. The cookie generated by BiometricService
    // is never 0.
    // is never 0.
    private final int mCookie;
    private final int mCookie;
    boolean mAlreadyDone;
    private boolean mAlreadyDone = false;


    // Use an empty callback by default since delayed operations can receive events
    // Use an empty callback by default since delayed operations can receive events
    // before they are started and cause NPE in subclasses that access this field directly.
    // before they are started and cause NPE in subclasses that access this field directly.
@@ -202,11 +202,9 @@ public abstract class BaseClientMonitor extends LoggableMonitor
        return callback;
        return callback;
    }
    }


    public boolean isAlreadyDone() {
    /** Signals this operation has completed its lifecycle and should no longer be used. */
        return mAlreadyDone;
    void destroy() {
    }
        mAlreadyDone = true;

    public void destroy() {
        if (mToken != null) {
        if (mToken != null) {
            try {
            try {
                mToken.unlinkToDeath(this, 0);
                mToken.unlinkToDeath(this, 0);
@@ -218,6 +216,20 @@ public abstract class BaseClientMonitor extends LoggableMonitor
        }
        }
    }
    }


    /**
     * Call while the operation is still active, but nearly done, to prevent any action
     * upon client death (only needed for authentication clients).
     */
    void markAlreadyDone() {
        Slog.d(TAG, "marking operation as done: " + this);
        mAlreadyDone = true;
    }

    /** If this operation has been marked as completely done (or cancelled). */
    public boolean isAlreadyDone() {
        return mAlreadyDone;
    }

    @Override
    @Override
    public void binderDied() {
    public void binderDied() {
        binderDiedInternal(true /* clearListener */);
        binderDiedInternal(true /* clearListener */);
@@ -225,10 +237,9 @@ public abstract class BaseClientMonitor extends LoggableMonitor


    // TODO(b/157790417): Move this to the scheduler
    // TODO(b/157790417): Move this to the scheduler
    void binderDiedInternal(boolean clearListener) {
    void binderDiedInternal(boolean clearListener) {
        Slog.e(TAG, "Binder died, owner: " + getOwnerString()
        Slog.e(TAG, "Binder died, operation: " + this);
                + ", operation: " + this.getClass().getName());


        if (isAlreadyDone()) {
        if (mAlreadyDone) {
            Slog.w(TAG, "Binder died but client is finished, ignoring");
            Slog.w(TAG, "Binder died but client is finished, ignoring");
            return;
            return;
        }
        }
@@ -299,7 +310,7 @@ public abstract class BaseClientMonitor extends LoggableMonitor
    @Override
    @Override
    public String toString() {
    public String toString() {
        return "{[" + mSequentialId + "] "
        return "{[" + mSequentialId + "] "
                + this.getClass().getSimpleName()
                + this.getClass().getName()
                + ", proto=" + getProtoEnum()
                + ", proto=" + getProtoEnum()
                + ", owner=" + getOwnerString()
                + ", owner=" + getOwnerString()
                + ", cookie=" + getCookie()
                + ", cookie=" + getCookie()
+3 −0
Original line number Original line Diff line number Diff line
@@ -605,6 +605,9 @@ public class BiometricScheduler {
        if (operation.mState == Operation.STATE_WAITING_FOR_COOKIE) {
        if (operation.mState == Operation.STATE_WAITING_FOR_COOKIE) {
            Slog.w(getTag(), "Skipping cancellation for non-started operation: " + operation);
            Slog.w(getTag(), "Skipping cancellation for non-started operation: " + operation);
            // We can set it to null immediately, since the HAL was never notified to start.
            // We can set it to null immediately, since the HAL was never notified to start.
            if (mCurrentOperation != null) {
                mCurrentOperation.mClientMonitor.destroy();
            }
            mCurrentOperation = null;
            mCurrentOperation = null;
            startNextOperationIfIdle();
            startNextOperationIfIdle();
            return;
            return;
+19 −35
Original line number Original line Diff line number Diff line
@@ -143,8 +143,8 @@ public class BiometricSchedulerTest {


        final ClientMonitorCallbackConverter listener1 = mock(ClientMonitorCallbackConverter.class);
        final ClientMonitorCallbackConverter listener1 = mock(ClientMonitorCallbackConverter.class);


        final BiometricPromptClientMonitor client1 =
        final TestAuthenticationClient client1 =
                new BiometricPromptClientMonitor(mContext, mToken, lazyDaemon1, listener1);
                new TestAuthenticationClient(mContext, lazyDaemon1, mToken, listener1);
        final TestClientMonitor client2 = new TestClientMonitor(mContext, mToken, lazyDaemon2);
        final TestClientMonitor client2 = new TestClientMonitor(mContext, mToken, lazyDaemon2);


        final BaseClientMonitor.Callback callback1 = mock(BaseClientMonitor.Callback.class);
        final BaseClientMonitor.Callback callback1 = mock(BaseClientMonitor.Callback.class);
@@ -180,8 +180,8 @@ public class BiometricSchedulerTest {
    @Test
    @Test
    public void testCancelNotInvoked_whenOperationWaitingForCookie() {
    public void testCancelNotInvoked_whenOperationWaitingForCookie() {
        final HalClientMonitor.LazyDaemon<Object> lazyDaemon1 = () -> mock(Object.class);
        final HalClientMonitor.LazyDaemon<Object> lazyDaemon1 = () -> mock(Object.class);
        final BiometricPromptClientMonitor client1 = new BiometricPromptClientMonitor(mContext,
        final TestAuthenticationClient client1 = new TestAuthenticationClient(mContext,
                mToken, lazyDaemon1, mock(ClientMonitorCallbackConverter.class));
                lazyDaemon1, mToken, mock(ClientMonitorCallbackConverter.class));
        final BaseClientMonitor.Callback callback1 = mock(BaseClientMonitor.Callback.class);
        final BaseClientMonitor.Callback callback1 = mock(BaseClientMonitor.Callback.class);


        // Schedule a BiometricPrompt authentication request
        // Schedule a BiometricPrompt authentication request
@@ -195,6 +195,8 @@ public class BiometricSchedulerTest {
        // should go back to idle, since in this case the framework has not even requested the HAL
        // should go back to idle, since in this case the framework has not even requested the HAL
        // to authenticate yet.
        // to authenticate yet.
        mScheduler.cancelAuthenticationOrDetection(mToken, 1 /* requestId */);
        mScheduler.cancelAuthenticationOrDetection(mToken, 1 /* requestId */);
        assertTrue(client1.isAlreadyDone());
        assertTrue(client1.mDestroyed);
        assertNull(mScheduler.mCurrentOperation);
        assertNull(mScheduler.mCurrentOperation);
    }
    }


@@ -316,6 +318,10 @@ public class BiometricSchedulerTest {
                eq(BiometricConstants.BIOMETRIC_ERROR_CANCELED),
                eq(BiometricConstants.BIOMETRIC_ERROR_CANCELED),
                eq(0) /* vendorCode */);
                eq(0) /* vendorCode */);
        assertNull(mScheduler.getCurrentClient());
        assertNull(mScheduler.getCurrentClient());
        assertTrue(client1.isAlreadyDone());
        assertTrue(client1.mDestroyed);
        assertTrue(client2.isAlreadyDone());
        assertTrue(client2.mDestroyed);
    }
    }


    @Test
    @Test
@@ -465,39 +471,9 @@ public class BiometricSchedulerTest {
        return BiometricSchedulerProto.parseFrom(mScheduler.dumpProtoState(clearSchedulerBuffer));
        return BiometricSchedulerProto.parseFrom(mScheduler.dumpProtoState(clearSchedulerBuffer));
    }
    }


    private static class BiometricPromptClientMonitor extends AuthenticationClient<Object> {

        public BiometricPromptClientMonitor(@NonNull Context context, @NonNull IBinder token,
                @NonNull LazyDaemon<Object> lazyDaemon, ClientMonitorCallbackConverter listener) {
            super(context, lazyDaemon, token, listener, 0 /* targetUserId */, 0 /* operationId */,
                    false /* restricted */, TAG, 1 /* cookie */, false /* requireConfirmation */,
                    TEST_SENSOR_ID, true /* isStrongBiometric */, 0 /* statsModality */,
                    0 /* statsClient */, null /* taskStackListener */, mock(LockoutTracker.class),
                    false /* isKeyguard */, true /* shouldVibrate */,
                    false /* isKeyguardBypassEnabled */);
        }

        @Override
        protected void stopHalOperation() {
        }

        @Override
        protected void startHalOperation() {
        }

        @Override
        protected void handleLifecycleAfterAuth(boolean authenticated) {

        }

        @Override
        public boolean wasUserDetected() {
            return false;
        }
    }

    private static class TestAuthenticationClient extends AuthenticationClient<Object> {
    private static class TestAuthenticationClient extends AuthenticationClient<Object> {
        int mNumCancels = 0;
        int mNumCancels = 0;
        boolean mDestroyed = false;


        public TestAuthenticationClient(@NonNull Context context,
        public TestAuthenticationClient(@NonNull Context context,
                @NonNull LazyDaemon<Object> lazyDaemon, @NonNull IBinder token,
                @NonNull LazyDaemon<Object> lazyDaemon, @NonNull IBinder token,
@@ -530,6 +506,13 @@ public class BiometricSchedulerTest {
            return false;
            return false;
        }
        }


        @Override
        public void destroy() {
            mDestroyed = true;
            super.destroy();
        }

        @Override
        public void cancel() {
        public void cancel() {
            mNumCancels++;
            mNumCancels++;
            super.cancel();
            super.cancel();
@@ -595,6 +578,7 @@ public class BiometricSchedulerTest {


        @Override
        @Override
        public void destroy() {
        public void destroy() {
            super.destroy();
            mDestroyed = true;
            mDestroyed = true;
        }
        }