Merge "DO NOT MERGE Update active unlock triggers take #2" into tm-dev
This commit is contained in:
147
packages/SystemUI/src/com/android/keyguard/ActiveUnlockConfig.kt
Normal file
147
packages/SystemUI/src/com/android/keyguard/ActiveUnlockConfig.kt
Normal file
@@ -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")
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -510,7 +510,8 @@ public class KeyguardIndicationController {
|
||||
.setMessage(trustGrantedIndication)
|
||||
.setTextColor(mInitialTextColorState)
|
||||
.build(),
|
||||
false);
|
||||
true);
|
||||
hideBiometricMessage();
|
||||
} else if (!TextUtils.isEmpty(trustManagedIndication)
|
||||
&& mKeyguardUpdateMonitor.getUserTrustIsManaged(userId)
|
||||
&& !userHasTrust) {
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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<>();
|
||||
|
||||
Reference in New Issue
Block a user