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

Commit f136101e authored by Beverly's avatar Beverly Committed by Automerger Merge Worker
Browse files

DO NOT MERGE Update active unlock triggers take #2 am: fe7e9e9a am: 4c2b5546

parents c6d436c0 4c2b5546
Loading
Loading
Loading
Loading
+147 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.keyguard

import android.content.ContentResolver
import android.database.ContentObserver
import android.net.Uri
import android.os.Handler
import android.os.UserHandle
import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL
import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT
import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_WAKE
import com.android.keyguard.KeyguardUpdateMonitor.getCurrentUser
import com.android.systemui.Dumpable
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.dump.DumpManager
import com.android.systemui.util.settings.SecureSettings
import java.io.PrintWriter
import javax.inject.Inject

/**
 * Handles active unlock settings changes.
 */
@SysUISingleton
class ActiveUnlockConfig @Inject constructor(
    @Main private val handler: Handler,
    private val secureSettings: SecureSettings,
    private val contentResolver: ContentResolver,
    dumpManager: DumpManager
) : Dumpable {

    /**
     * Indicates the origin for an active unlock request.
     */
    enum class ACTIVE_UNLOCK_REQUEST_ORIGIN {
        WAKE, UNLOCK_INTENT, BIOMETRIC_FAIL, ASSISTANT
    }

    private var requestActiveUnlockOnWakeup = false
    private var requestActiveUnlockOnUnlockIntent = false
    private var requestActiveUnlockOnBioFail = false

    private val settingsObserver = object : ContentObserver(handler) {
        private val wakeUri: Uri = secureSettings.getUriFor(ACTIVE_UNLOCK_ON_WAKE)
        private val unlockIntentUri: Uri = secureSettings.getUriFor(ACTIVE_UNLOCK_ON_UNLOCK_INTENT)
        private val bioFailUri: Uri = secureSettings.getUriFor(ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL)

        fun register() {
            contentResolver.registerContentObserver(
                    wakeUri,
                    false,
                    this,
                    UserHandle.USER_ALL)
            contentResolver.registerContentObserver(
                    unlockIntentUri,
                    false,
                    this,
                    UserHandle.USER_ALL)
            contentResolver.registerContentObserver(
                    bioFailUri,
                    false,
                    this,
                    UserHandle.USER_ALL)

            onChange(true, ArrayList(), 0, getCurrentUser())
        }

        override fun onChange(
            selfChange: Boolean,
            uris: Collection<Uri>,
            flags: Int,
            userId: Int
        ) {
            if (getCurrentUser() != userId) {
                return
            }

            if (selfChange || uris.contains(wakeUri)) {
                requestActiveUnlockOnWakeup = secureSettings.getIntForUser(
                        ACTIVE_UNLOCK_ON_WAKE, 0, getCurrentUser()) == 1
            }

            if (selfChange || uris.contains(unlockIntentUri)) {
                requestActiveUnlockOnUnlockIntent = secureSettings.getIntForUser(
                        ACTIVE_UNLOCK_ON_UNLOCK_INTENT, 0, getCurrentUser()) == 1
            }

            if (selfChange || uris.contains(bioFailUri)) {
                requestActiveUnlockOnBioFail = secureSettings.getIntForUser(
                        ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL, 0, getCurrentUser()) == 1
            }
        }
    }

    init {
        settingsObserver.register()
        dumpManager.registerDumpable(this)
    }

    /**
     * Whether to trigger active unlock based on where the request is coming from and
     * the current settings.
     */
    fun shouldAllowActiveUnlockFromOrigin(requestOrigin: ACTIVE_UNLOCK_REQUEST_ORIGIN): Boolean {
        return when (requestOrigin) {
            ACTIVE_UNLOCK_REQUEST_ORIGIN.WAKE -> requestActiveUnlockOnWakeup

            ACTIVE_UNLOCK_REQUEST_ORIGIN.UNLOCK_INTENT ->
                requestActiveUnlockOnUnlockIntent || requestActiveUnlockOnWakeup

            ACTIVE_UNLOCK_REQUEST_ORIGIN.BIOMETRIC_FAIL ->
                requestActiveUnlockOnBioFail || requestActiveUnlockOnUnlockIntent ||
                        requestActiveUnlockOnWakeup

            ACTIVE_UNLOCK_REQUEST_ORIGIN.ASSISTANT -> isActiveUnlockEnabled()
        }
    }

    /**
     * If any active unlock triggers are enabled.
     */
    fun isActiveUnlockEnabled(): Boolean {
        return requestActiveUnlockOnWakeup || requestActiveUnlockOnUnlockIntent ||
                requestActiveUnlockOnBioFail
    }

    override fun dump(pw: PrintWriter, args: Array<out String>) {
        pw.println("   requestActiveUnlockOnWakeup=$requestActiveUnlockOnWakeup")
        pw.println("   requestActiveUnlockOnUnlockIntent=$requestActiveUnlockOnUnlockIntent")
        pw.println("   requestActiveUnlockOnBioFail=$requestActiveUnlockOnBioFail")
    }
}
 No newline at end of file
+4 −4
Original line number Diff line number Diff line
@@ -221,10 +221,10 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
                mKeyguardSecurityCallback.userActivity();
                showMessage(null, null);
            }
            if (mUpdateMonitor.isFaceEnrolled()
                    && mUpdateMonitor.mRequestActiveUnlockOnUnlockIntent) {
                mUpdateMonitor.requestActiveUnlock("unlock-intent, reason=swipeUpOnBouncer",
                        true);
            if (mUpdateMonitor.isFaceEnrolled()) {
                mUpdateMonitor.requestActiveUnlock(
                        ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.UNLOCK_INTENT,
                        "swipeUpOnBouncer");
            }
        }
    };
+67 −74
Original line number Diff line number Diff line
@@ -248,12 +248,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
        }
    }

    public final boolean mRequestActiveUnlockOnAssistant;
    public final boolean mRequestActiveUnlockOnWakeup;
    public final boolean mInitiateActiveUnlockOnWakeup;
    public final boolean mRequestActiveUnlockOnUnlockIntent;
    public final boolean mRequestActiveUnlockOnBioFail;

    private final Context mContext;
    private final boolean mIsPrimaryUser;
    private final boolean mIsAutomotive;
@@ -340,6 +334,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
    private int mActiveMobileDataSubscription = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
    private final Executor mBackgroundExecutor;
    private SensorPrivacyManager mSensorPrivacyManager;
    private final ActiveUnlockConfig mActiveUnlockConfig;

    /**
     * Short delay before restarting fingerprint authentication after a successful try. This should
@@ -441,12 +436,12 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
        Assert.isMainThread();
        boolean wasTrusted = mUserHasTrust.get(userId, false);
        mUserHasTrust.put(userId, enabled);
        // If there was no change in trusted state, make sure we are not authenticating.
        // TrustManager sends an onTrustChanged whenever a user unlocks keyguard, for
        // this reason we need to make sure to not authenticate.
        if (wasTrusted == enabled) {
        // If there was no change in trusted state or trust granted, make sure we are not
        // authenticating.  TrustManager sends an onTrustChanged whenever a user unlocks keyguard,
        // for this reason we need to make sure to not authenticate.
        if (wasTrusted == enabled || enabled) {
            updateBiometricListeningState(BIOMETRIC_ACTION_STOP);
        } else if (!enabled) {
        } else {
            updateBiometricListeningState(BIOMETRIC_ACTION_START);
        }

@@ -1364,14 +1359,18 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
                cb.onTrustAgentErrorMessage(message);
            }
        }

    }

    @VisibleForTesting
    void setAssistantVisible(boolean assistantVisible) {
        mAssistantVisible = assistantVisible;
        updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE);
        if (mAssistantVisible && mRequestActiveUnlockOnAssistant) {
            requestActiveUnlock("assistant", false);
        if (mAssistantVisible) {
            requestActiveUnlock(
                    ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.ASSISTANT,
                    "assistant",
                    false);
        }
    }

@@ -1532,10 +1531,9 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab

                @Override
                public void onAuthenticationFailed() {
                    if (mRequestActiveUnlockOnBioFail) {
                        requestActiveUnlock("biometric-failure, extra=fingerprintFailure",
                                true);
                    }
                    requestActiveUnlock(
                            ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.BIOMETRIC_FAIL,
                            "fingerprintFailure");
                    handleFingerprintAuthFailed();
                }

@@ -1600,14 +1598,13 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab

                @Override
                public void onAuthenticationFailed() {
                    if (shouldRequestActiveUnlockOnFaceError()) {
                        String reason =
                                mKeyguardBypassController.canBypass() ? "bypass"
                                        : mUdfpsBouncerShowing ? "udfpsBouncer" :
                                                mBouncerFullyShown ? "bouncer" : "udfpsFpDown";
                        requestActiveUnlock("biometric-failure"
                                + ", extra=faceFailure-" + reason, true);
                    }
                        requestActiveUnlock(
                                ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.BIOMETRIC_FAIL,
                                "faceFailure-" + reason);

                    handleFaceAuthFailed();
                    if (mKeyguardBypassController != null) {
@@ -1637,10 +1634,11 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
                    if (mKeyguardBypassController != null) {
                        mKeyguardBypassController.setUserHasDeviceEntryIntent(false);
                    }
                    if (errMsgId == BiometricFaceConstants.FACE_ERROR_TIMEOUT
                            && shouldRequestActiveUnlockOnFaceError()) {
                        requestActiveUnlock("biometric-failure"
                                + ", extra=faceError-" + errMsgId, true);

                    if (errMsgId == BiometricFaceConstants.FACE_ERROR_TIMEOUT) {
                        requestActiveUnlock(
                                ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.BIOMETRIC_FAIL,
                                "faceError-" + errMsgId);
                    }
                }

@@ -1648,12 +1646,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
                public void onAuthenticationAcquired(int acquireInfo) {
                    handleFaceAcquired(acquireInfo);
                }

                private boolean shouldRequestActiveUnlockOnFaceError() {
                    return mRequestActiveUnlockOnBioFail
                            && (mKeyguardBypassController.canBypass() || mBouncerFullyShown
                            || mUdfpsBouncerShowing || mAuthController.isUdfpsFingerDown());
                }
    };

    @VisibleForTesting
@@ -1769,11 +1761,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
        Trace.beginSection("KeyguardUpdateMonitor#handleStartedWakingUp");
        Assert.isMainThread();
        updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE);
        if (mRequestActiveUnlockOnWakeup) {
            requestActiveUnlock("wake-unlock");
        } else if (mInitiateActiveUnlockOnWakeup) {
            initiateActiveUnlock("wake-initiate");
        }
        requestActiveUnlock(ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.WAKE, "wakingUp");
        for (int i = 0; i < mCallbacks.size(); i++) {
            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
            if (cb != null) {
@@ -1902,7 +1890,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
            AuthController authController,
            TelephonyListenerManager telephonyListenerManager,
            InteractionJankMonitor interactionJankMonitor,
            LatencyTracker latencyTracker) {
            LatencyTracker latencyTracker,
            ActiveUnlockConfig activeUnlockConfiguration) {
        mContext = context;
        mSubscriptionManager = SubscriptionManager.from(context);
        mTelephonyListenerManager = telephonyListenerManager;
@@ -1919,18 +1908,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
        mAuthController = authController;
        dumpManager.registerDumpable(getClass().getName(), this);
        mSensorPrivacyManager = context.getSystemService(SensorPrivacyManager.class);

        // TODO, b/222459888: add official configurable names to Settings.java
        mRequestActiveUnlockOnWakeup = Settings.Global.getInt(
                mContext.getContentResolver(), "wake-unlock", 0) == 1;
        mInitiateActiveUnlockOnWakeup = Settings.Global.getInt(
                mContext.getContentResolver(), "wake-initiate", 1) == 1;
        mRequestActiveUnlockOnUnlockIntent = Settings.Global.getInt(
                mContext.getContentResolver(), "unlock-intent", 0) == 1;
        mRequestActiveUnlockOnBioFail = Settings.Global.getInt(
                mContext.getContentResolver(), "bio-fail", 0) == 1;
        mRequestActiveUnlockOnAssistant = Settings.Global.getInt(
                mContext.getContentResolver(), "assistant", 0) == 1;
        mActiveUnlockConfig = activeUnlockConfiguration;

        mHandler = new Handler(mainLooper) {
            @Override
@@ -2312,11 +2290,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
        }
        mAuthInterruptActive = active;
        updateFaceListeningState(BIOMETRIC_ACTION_UPDATE);
        if (mRequestActiveUnlockOnWakeup) {
            requestActiveUnlock("wake-unlock, extra=onReach");
        } else if (mInitiateActiveUnlockOnWakeup) {
            initiateActiveUnlock("wake-initiate, extra=onReach");
        }
        requestActiveUnlock(ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.WAKE, "onReach");
    }

    /**
@@ -2368,7 +2342,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
    /**
     * Initiates active unlock to get the unlock token ready.
     */
    public void initiateActiveUnlock(String reason) {
    private void initiateActiveUnlock(String reason) {
        // If this message exists, FP has already authenticated, so wait until that is handled
        if (mHandler.hasMessages(MSG_BIOMETRIC_AUTHENTICATION_CONTINUE)) {
            return;
@@ -2385,15 +2359,30 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
    /**
     * Attempts to trigger active unlock from trust agent.
     */
    public void requestActiveUnlock(String reason, boolean dismissKeyguard) {
    private void requestActiveUnlock(
            ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN requestOrigin,
            String reason,
            boolean dismissKeyguard
    ) {
        // If this message exists, FP has already authenticated, so wait until that is handled
        if (mHandler.hasMessages(MSG_BIOMETRIC_AUTHENTICATION_CONTINUE)) {
            return;
        }

        if (shouldTriggerActiveUnlock()) {
        final boolean allowRequest =
                mActiveUnlockConfig.shouldAllowActiveUnlockFromOrigin(requestOrigin);
        if (requestOrigin == ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.WAKE
                && !allowRequest && mActiveUnlockConfig.isActiveUnlockEnabled()) {
            // instead of requesting the active unlock, initiate the unlock
            initiateActiveUnlock(reason);
            return;
        }

        if (allowRequest && shouldTriggerActiveUnlock()) {
            if (DEBUG) {
                Log.d("ActiveUnlock", "reportUserRequestedUnlock triggerReason=" + reason
                Log.d("ActiveUnlock", "reportUserRequestedUnlock"
                        + " origin=" + requestOrigin.name()
                        + " reason=" + reason
                        + " dismissKeyguard=" + dismissKeyguard);
            }
            mTrustManager.reportUserRequestedUnlock(KeyguardUpdateMonitor.getCurrentUser(),
@@ -2403,11 +2392,20 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab

    /**
     * Attempts to trigger active unlock from trust agent.
     * Only dismisses the keyguard if only face is enrolled (no FP) and bypass is enabled.
     * Only dismisses the keyguard under certain conditions.
     */
    public void requestActiveUnlock(String reason) {
        requestActiveUnlock(reason, isFaceEnrolled() && !isUdfpsEnrolled()
                && mKeyguardBypassController.getBypassEnabled());
    public void requestActiveUnlock(
            ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN requestOrigin,
            String extraReason
    ) {
        final boolean canFaceBypass = isFaceEnrolled() && mKeyguardBypassController != null
                && mKeyguardBypassController.canBypass();
        requestActiveUnlock(
                requestOrigin,
                extraReason, canFaceBypass
                        || mUdfpsBouncerShowing
                        || mBouncerFullyShown
                        || mAuthController.isUdfpsFingerDown());
    }

    /**
@@ -2417,9 +2415,9 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
        mUdfpsBouncerShowing = showing;
        if (mUdfpsBouncerShowing) {
            updateFaceListeningState(BIOMETRIC_ACTION_START);
            if (mRequestActiveUnlockOnUnlockIntent) {
                requestActiveUnlock("unlock-intent, extra=udfpsBouncer", true);
            }
            requestActiveUnlock(
                    ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.UNLOCK_INTENT,
                    "udfpsBouncer");
        }
    }

@@ -3253,8 +3251,10 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
        }

        if (wasBouncerFullyShown != mBouncerFullyShown) {
            if (mBouncerFullyShown && mRequestActiveUnlockOnUnlockIntent) {
                requestActiveUnlock("unlock-intent, reason=bouncerFullyShown", true);
            if (mBouncerFullyShown) {
                requestActiveUnlock(
                        ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.UNLOCK_INTENT,
                        "bouncerFullyShown");
            }
            for (int i = 0; i < mCallbacks.size(); i++) {
                KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
@@ -3791,13 +3791,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
        }
        mListenModels.print(pw);

        pw.println("Enabled active unlock triggers:");
        pw.println("   mRequestActiveUnlockOnWakeup=" + mRequestActiveUnlockOnWakeup);
        pw.println("   mInitiateActiveUnlockOnWakeup=" + mInitiateActiveUnlockOnWakeup);
        pw.println("   mRequestActiveUnlockOnUnlockIntent=" + mRequestActiveUnlockOnUnlockIntent);
        pw.println("   mRequestActiveUnlockOnBiometricFail=" + mRequestActiveUnlockOnBioFail);
        pw.println("   mRequestActiveUnlockOnAssistant=" + mRequestActiveUnlockOnAssistant);

        if (mIsAutomotive) {
            pw.println("  Running on Automotive build");
        }
+12 −6
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@ import android.view.accessibility.AccessibilityManager;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.LatencyTracker;
import com.android.keyguard.ActiveUnlockConfig;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.animation.ActivityLaunchAnimator;
import com.android.systemui.dagger.SysUISingleton;
@@ -658,9 +659,15 @@ public class UdfpsController implements DozeReceiver {
        mExecution.assertIsMainThread();

        mOverlay = overlay;
        final int requestReason = overlay.getRequestReason();
        if (requestReason == REASON_AUTH_KEYGUARD
                && !mKeyguardUpdateMonitor.isFingerprintDetectionRunning()) {
            Log.d(TAG, "Attempting to showUdfpsOverlay when fingerprint detection"
                    + " isn't running on keyguard. Skip show.");
            return;
        }
        if (overlay.show(this, mOverlayParams)) {
            Log.v(TAG, "showUdfpsOverlay | adding window reason="
                    + overlay.getRequestReason());
            Log.v(TAG, "showUdfpsOverlay | adding window reason=" + requestReason);
            mOnFingerDown = false;
            mAttemptedToDismissKeyguard = false;
            mOrientationListener.enable();
@@ -791,10 +798,9 @@ public class UdfpsController implements DozeReceiver {
                mKeyguardUpdateMonitor.requestFaceAuth(/* userInitiatedRequest */ false);
            }

            if (mKeyguardUpdateMonitor.mRequestActiveUnlockOnUnlockIntent) {
                mKeyguardUpdateMonitor.requestActiveUnlock("unlock-intent extra=udfpsFingerDown",
                        true);
            }
            mKeyguardUpdateMonitor.requestActiveUnlock(
                    ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.UNLOCK_INTENT,
                    "udfpsFingerDown");
        }
        mOnFingerDown = true;
        if (mAlternateTouchProvider != null) {
+2 −1
Original line number Diff line number Diff line
@@ -510,7 +510,8 @@ public class KeyguardIndicationController {
                            .setMessage(trustGrantedIndication)
                            .setTextColor(mInitialTextColorState)
                            .build(),
                    false);
                    true);
            hideBiometricMessage();
        } else if (!TextUtils.isEmpty(trustManagedIndication)
                && mKeyguardUpdateMonitor.getUserTrustIsManaged(userId)
                && !userHasTrust) {
Loading