diff options
| author | 2022-05-03 13:47:36 +0000 | |
|---|---|---|
| committer | 2022-05-03 13:47:36 +0000 | |
| commit | d9803be1a9ff6cbf690f48a2189c1753e6f40a29 (patch) | |
| tree | 73a70d82ab9efc4de7192c8bc830df94a734d0d9 | |
| parent | 597b031cc5824711ad4f92e78a047867631dc99a (diff) | |
| parent | fe7e9e9a6dfa976abf66614a32321e93d0a3fa49 (diff) | |
Merge "DO NOT MERGE Update active unlock triggers take #2" into tm-dev
10 files changed, 444 insertions, 98 deletions
diff --git a/packages/SystemUI/src/com/android/keyguard/ActiveUnlockConfig.kt b/packages/SystemUI/src/com/android/keyguard/ActiveUnlockConfig.kt new file mode 100644 index 000000000000..f195d2094d6a --- /dev/null +++ b/packages/SystemUI/src/com/android/keyguard/ActiveUnlockConfig.kt @@ -0,0 +1,147 @@ +/* + * 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 diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java index 28a3dbbf6c83..965fcd2653f4 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java @@ -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"); } } }; diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java index a6feedb50a12..bbe9a362b1fa 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -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); } } @@ -1518,10 +1517,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(); } @@ -1580,14 +1578,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) { @@ -1617,10 +1614,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); } } @@ -1628,12 +1626,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 @@ -1749,11 +1741,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) { @@ -1882,7 +1870,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; @@ -1899,18 +1888,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 @@ -2292,11 +2270,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"); } /** @@ -2348,7 +2322,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; @@ -2365,15 +2339,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(), @@ -2383,11 +2372,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()); } /** @@ -2397,9 +2395,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"); } } @@ -3233,8 +3231,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(); @@ -3771,13 +3771,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"); } diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java index 20efafce3cd5..463db5c92554 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java @@ -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) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java index ce6f3e4d29cb..6602f9947051 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java @@ -510,7 +510,8 @@ public class KeyguardIndicationController { .setMessage(trustGrantedIndication) .setTextColor(mInitialTextColorState) .build(), - false); + true); + hideBiometricMessage(); } else if (!TextUtils.isEmpty(trustManagedIndication) && mKeyguardUpdateMonitor.getUserTrustIsManaged(userId) && !userHasTrust) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt index 3e32b64ebe3a..3f8e97f1a1c7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt @@ -21,6 +21,7 @@ import android.content.pm.PackageManager import android.hardware.Sensor import android.hardware.TriggerEvent import android.hardware.TriggerEventListener +import com.android.keyguard.ActiveUnlockConfig import com.android.keyguard.KeyguardUpdateMonitor import com.android.keyguard.KeyguardUpdateMonitorCallback import com.android.systemui.CoreStartable @@ -71,13 +72,9 @@ class KeyguardLiftController @Inject constructor( isListening = false updateListeningState() keyguardUpdateMonitor.requestFaceAuth(true) - if (keyguardUpdateMonitor.mRequestActiveUnlockOnWakeup) { - keyguardUpdateMonitor.requestActiveUnlock("wake-unlock," + - " extra=KeyguardLiftController") - } else if (keyguardUpdateMonitor.mInitiateActiveUnlockOnWakeup) { - keyguardUpdateMonitor.initiateActiveUnlock("wake-initiate," + - " extra=KeyguardLiftController") - } + keyguardUpdateMonitor.requestActiveUnlock( + ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.WAKE, + "KeyguardLiftController") } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java index 98a711d122fc..b5789fb9c634 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java @@ -98,6 +98,7 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.policy.ScreenDecorationsUtils; import com.android.internal.policy.SystemBarUtils; import com.android.internal.util.LatencyTracker; +import com.android.keyguard.ActiveUnlockConfig; import com.android.keyguard.KeyguardStatusView; import com.android.keyguard.KeyguardStatusViewController; import com.android.keyguard.KeyguardUnfoldTransition; @@ -3383,11 +3384,10 @@ public class NotificationPanelViewController extends PanelViewController { .log(LockscreenUiEvent.LOCKSCREEN_LOCK_SHOW_HINT); startUnlockHintAnimation(); } - if (mUpdateMonitor.isFaceEnrolled() - && mUpdateMonitor.mRequestActiveUnlockOnUnlockIntent - && mKeyguardBypassController.canBypass()) { - mUpdateMonitor.requestActiveUnlock("unlock-intent," - + " extra=lockScreenEmptySpaceTap", true); + if (mUpdateMonitor.isFaceEnrolled()) { + mUpdateMonitor.requestActiveUnlock( + ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.UNLOCK_INTENT, + "lockScreenEmptySpaceTap"); } } return true; diff --git a/packages/SystemUI/tests/src/com/android/keyguard/ActiveUnlockConfigTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/ActiveUnlockConfigTest.kt new file mode 100644 index 000000000000..747649006b45 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/keyguard/ActiveUnlockConfigTest.kt @@ -0,0 +1,199 @@ +/* + * 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 +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.dump.DumpManager +import com.android.systemui.util.mockito.capture +import com.android.systemui.util.mockito.eq +import com.android.systemui.util.settings.SecureSettings +import org.junit.Assert.assertFalse +import org.junit.Assert.assertTrue +import org.junit.Before +import org.junit.Test +import org.mockito.ArgumentCaptor +import org.mockito.Captor +import org.mockito.Mock +import org.mockito.Mockito.`when` +import org.mockito.Mockito.verify +import org.mockito.MockitoAnnotations + +@SmallTest +class ActiveUnlockConfigTest : SysuiTestCase() { + private val fakeWakeUri = Uri.Builder().appendPath("wake").build() + private val fakeUnlockIntentUri = Uri.Builder().appendPath("unlock-intent").build() + private val fakeBioFailUri = Uri.Builder().appendPath("bio-fail").build() + + @Mock + private lateinit var secureSettings: SecureSettings + + @Mock + private lateinit var contentResolver: ContentResolver + + @Mock + private lateinit var handler: Handler + + @Mock + private lateinit var dumpManager: DumpManager + + @Captor + private lateinit var settingsObserverCaptor: ArgumentCaptor<ContentObserver> + + private lateinit var activeUnlockConfig: ActiveUnlockConfig + + @Before + fun setUp() { + MockitoAnnotations.initMocks(this) + + `when`(secureSettings.getUriFor(Settings.Secure.ACTIVE_UNLOCK_ON_WAKE)) + .thenReturn(fakeWakeUri) + `when`(secureSettings.getUriFor(Settings.Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT)) + .thenReturn(fakeUnlockIntentUri) + `when`(secureSettings.getUriFor(Settings.Secure.ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL)) + .thenReturn(fakeBioFailUri) + + activeUnlockConfig = ActiveUnlockConfig( + handler, + secureSettings, + contentResolver, + dumpManager + ) + } + + @Test + fun testRegsitersForSettingsChanges() { + verifyRegisterSettingObserver() + } + + @Test + fun testOnWakeupSettingChanged() { + verifyRegisterSettingObserver() + + // GIVEN no active unlock settings enabled + assertFalse( + activeUnlockConfig.shouldAllowActiveUnlockFromOrigin( + ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.WAKE) + ) + + // WHEN unlock on wake is allowed + `when`(secureSettings.getIntForUser(Settings.Secure.ACTIVE_UNLOCK_ON_WAKE, + 0, 0)).thenReturn(1) + settingsObserverCaptor.value.onChange( + false, + listOf(fakeWakeUri), + 0, + 0 + ) + + // THEN active unlock triggers allowed on: wake, unlock-intent, and biometric failure + assertTrue( + activeUnlockConfig.shouldAllowActiveUnlockFromOrigin( + ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.WAKE) + ) + assertTrue( + activeUnlockConfig.shouldAllowActiveUnlockFromOrigin( + ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.UNLOCK_INTENT) + ) + assertTrue( + activeUnlockConfig.shouldAllowActiveUnlockFromOrigin( + ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.BIOMETRIC_FAIL) + ) + } + + @Test + fun testOnUnlockIntentSettingChanged() { + verifyRegisterSettingObserver() + + // GIVEN no active unlock settings enabled + assertFalse( + activeUnlockConfig.shouldAllowActiveUnlockFromOrigin( + ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.UNLOCK_INTENT) + ) + + // WHEN unlock on biometric failed is allowed + `when`(secureSettings.getIntForUser(Settings.Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT, + 0, 0)).thenReturn(1) + settingsObserverCaptor.value.onChange( + false, + listOf(fakeUnlockIntentUri), + 0, + 0 + ) + + // THEN active unlock triggers allowed on: biometric failure ONLY + assertFalse(activeUnlockConfig.shouldAllowActiveUnlockFromOrigin( + ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.WAKE)) + assertTrue(activeUnlockConfig.shouldAllowActiveUnlockFromOrigin( + ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.UNLOCK_INTENT)) + assertTrue(activeUnlockConfig.shouldAllowActiveUnlockFromOrigin( + ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.BIOMETRIC_FAIL)) + } + + @Test + fun testOnBioFailSettingChanged() { + verifyRegisterSettingObserver() + + // GIVEN no active unlock settings enabled + assertFalse(activeUnlockConfig.shouldAllowActiveUnlockFromOrigin( + ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.BIOMETRIC_FAIL)) + + // WHEN unlock on biometric failed is allowed + `when`(secureSettings.getIntForUser(Settings.Secure.ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL, + 0, 0)).thenReturn(1) + settingsObserverCaptor.value.onChange( + false, + listOf(fakeBioFailUri), + 0, + 0 + ) + + // THEN active unlock triggers allowed on: biometric failure ONLY + assertFalse(activeUnlockConfig.shouldAllowActiveUnlockFromOrigin( + ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.WAKE)) + assertFalse(activeUnlockConfig.shouldAllowActiveUnlockFromOrigin( + ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.UNLOCK_INTENT)) + assertTrue(activeUnlockConfig.shouldAllowActiveUnlockFromOrigin( + ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.BIOMETRIC_FAIL)) + } + + private fun verifyRegisterSettingObserver() { + verify(contentResolver).registerContentObserver( + eq(fakeWakeUri), + eq(false), + capture(settingsObserverCaptor), + eq(UserHandle.USER_ALL)) + + verify(contentResolver).registerContentObserver( + eq(fakeUnlockIntentUri), + eq(false), + capture(settingsObserverCaptor), + eq(UserHandle.USER_ALL)) + + verify(contentResolver).registerContentObserver( + eq(fakeBioFailUri), + eq(false), + capture(settingsObserverCaptor), + eq(UserHandle.USER_ALL)) + } +} diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java index 86a4f5ad43b0..2dc066c8a9db 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java @@ -177,6 +177,8 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { private ArgumentCaptor<StatusBarStateController.StateListener> mStatusBarStateListenerCaptor; @Mock private KeyguardUpdateMonitorCallback mTestCallback; + @Mock + private ActiveUnlockConfig mActiveUnlockConfig; // Direct executor private Executor mBackgroundExecutor = Runnable::run; private Executor mMainExecutor = Runnable::run; @@ -1188,7 +1190,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { mBackgroundExecutor, mMainExecutor, mStatusBarStateController, mLockPatternUtils, mAuthController, mTelephonyListenerManager, - mInteractionJankMonitor, mLatencyTracker); + mInteractionJankMonitor, mLatencyTracker, mActiveUnlockConfig); setStrongAuthTracker(KeyguardUpdateMonitorTest.this.mStrongAuthTracker); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java index 7779f42f1a2e..da5939ae4a12 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java @@ -212,6 +212,7 @@ public class UdfpsControllerTest extends SysuiTestCase { .thenReturn(mFpmOtherView); when(mEnrollView.getContext()).thenReturn(mContext); when(mKeyguardStateController.isOccluded()).thenReturn(false); + when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(true); final List<FingerprintSensorPropertiesInternal> props = new ArrayList<>(); final List<ComponentInfoInternal> componentInfo = new ArrayList<>(); |