summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/res/values/config.xml4
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardFingerprintListenModel.kt4
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java55
-rw-r--r--packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt9
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java67
5 files changed, 125 insertions, 14 deletions
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 421f41f60d85..9c864abca9dd 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -698,6 +698,10 @@
-->
<integer name="config_face_auth_supported_posture">0</integer>
+ <!-- Components to allow running fingerprint listening if their activity is occluding the lock screen. -->
+ <string-array name="config_fingerprint_listen_on_occluding_activity_packages" translatable="false">
+ </string-array>
+
<!-- Whether the communal service should be enabled -->
<bool name="config_communalServiceEnabled">false</bool>
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardFingerprintListenModel.kt b/packages/SystemUI/src/com/android/keyguard/KeyguardFingerprintListenModel.kt
index f2685c5200ad..f23ae67992a1 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardFingerprintListenModel.kt
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardFingerprintListenModel.kt
@@ -27,6 +27,7 @@ data class KeyguardFingerprintListenModel(
override var userId: Int = 0,
override var listening: Boolean = false,
// keepSorted
+ var allowOnCurrentOccludingActivity: Boolean = false,
var alternateBouncerShowing: Boolean = false,
var biometricEnabledForUser: Boolean = false,
var bouncerIsOrWillShow: Boolean = false,
@@ -58,6 +59,7 @@ data class KeyguardFingerprintListenModel(
userId.toString(),
listening.toString(),
// keep sorted
+ allowOnCurrentOccludingActivity.toString(),
alternateBouncerShowing.toString(),
biometricEnabledForUser.toString(),
bouncerIsOrWillShow.toString(),
@@ -98,6 +100,7 @@ data class KeyguardFingerprintListenModel(
userId = model.userId
listening = model.listening
// keep sorted
+ allowOnCurrentOccludingActivity = model.allowOnCurrentOccludingActivity
alternateBouncerShowing = model.alternateBouncerShowing
biometricEnabledForUser = model.biometricEnabledForUser
bouncerIsOrWillShow = model.bouncerIsOrWillShow
@@ -144,6 +147,7 @@ data class KeyguardFingerprintListenModel(
"userId",
"listening",
// keep sorted
+ "allowOnCurrentOccludingActivity",
"alternateBouncerShowing",
"biometricAllowedForUser",
"bouncerIsOrWillShow",
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 4b3f2814e410..89ef749f05bf 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -18,6 +18,8 @@ package com.android.keyguard;
import static android.app.StatusBarManager.SESSION_KEYGUARD;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.content.Intent.ACTION_USER_REMOVED;
import static android.content.Intent.ACTION_USER_STOPPED;
@@ -76,9 +78,9 @@ import static com.android.systemui.statusbar.policy.DevicePostureController.DEVI
import android.annotation.AnyThread;
import android.annotation.MainThread;
import android.annotation.SuppressLint;
-import android.app.ActivityTaskManager;
import android.app.ActivityTaskManager.RootTaskInfo;
import android.app.AlarmManager;
+import android.app.IActivityTaskManager;
import android.app.admin.DevicePolicyManager;
import android.app.trust.TrustManager;
import android.content.BroadcastReceiver;
@@ -305,6 +307,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
private final AuthController mAuthController;
private final UiEventLogger mUiEventLogger;
private final Set<Integer> mFaceAcquiredInfoIgnoreList;
+ private final Set<String> mAllowFingerprintOnOccludingActivitiesFromPackage;
private final PackageManager mPackageManager;
private int mStatusBarState;
private final StatusBarStateController.StateListener mStatusBarStateControllerListener =
@@ -346,6 +349,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
private boolean mSecureCameraLaunched;
@VisibleForTesting
protected boolean mTelephonyCapable;
+ private boolean mAllowFingerprintOnCurrentOccludingActivity;
// Device provisioning state
private boolean mDeviceProvisioned;
@@ -389,6 +393,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
private final FaceManager mFaceManager;
@Nullable
private KeyguardFaceAuthInteractor mFaceAuthInteractor;
+ private final TaskStackChangeListeners mTaskStackChangeListeners;
+ private final IActivityTaskManager mActivityTaskManager;
private final LockPatternUtils mLockPatternUtils;
@VisibleForTesting
@DevicePostureInt
@@ -2322,7 +2328,9 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
FaceWakeUpTriggersConfig faceWakeUpTriggersConfig,
DevicePostureController devicePostureController,
Optional<FingerprintInteractiveToAuthProvider> interactiveToAuthProvider,
- FeatureFlags featureFlags) {
+ FeatureFlags featureFlags,
+ TaskStackChangeListeners taskStackChangeListeners,
+ IActivityTaskManager activityTaskManagerService) {
mContext = context;
mSubscriptionManager = subscriptionManager;
mUserTracker = userTracker;
@@ -2364,6 +2372,12 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
mConfigFaceAuthSupportedPosture = mContext.getResources().getInteger(
R.integer.config_face_auth_supported_posture);
mFaceWakeUpTriggersConfig = faceWakeUpTriggersConfig;
+ mAllowFingerprintOnOccludingActivitiesFromPackage = Arrays.stream(
+ mContext.getResources().getStringArray(
+ R.array.config_fingerprint_listen_on_occluding_activity_packages))
+ .collect(Collectors.toSet());
+ mTaskStackChangeListeners = taskStackChangeListeners;
+ mActivityTaskManager = activityTaskManagerService;
mHandler = new Handler(mainLooper) {
@Override
@@ -2579,7 +2593,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
}
updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE, FACE_AUTH_UPDATED_ON_KEYGUARD_INIT);
- TaskStackChangeListeners.getInstance().registerTaskStackListener(mTaskStackListener);
+ mTaskStackChangeListeners.registerTaskStackListener(mTaskStackListener);
mIsSystemUser = mUserManager.isSystemUser();
int user = mUserTracker.getUserId();
mUserIsUnlocked.put(user, mUserManager.isUserUnlocked(user));
@@ -3049,7 +3063,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
&& (mOccludingAppRequestingFp
|| isUdfps
|| mAlternateBouncerShowing
- || mFeatureFlags.isEnabled(Flags.FP_LISTEN_OCCLUDING_APPS)
+ || mAllowFingerprintOnCurrentOccludingActivity
)
);
@@ -3092,6 +3106,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
System.currentTimeMillis(),
user,
shouldListen,
+ mAllowFingerprintOnCurrentOccludingActivity,
mAlternateBouncerShowing,
biometricEnabledForUser,
mPrimaryBouncerIsOrWillBeShowing,
@@ -4120,19 +4135,35 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
return mSimDatas.get(subId).slotId;
}
- private final TaskStackChangeListener
- mTaskStackListener = new TaskStackChangeListener() {
+ private final TaskStackChangeListener mTaskStackListener = new TaskStackChangeListener() {
@Override
public void onTaskStackChangedBackground() {
try {
- RootTaskInfo info = ActivityTaskManager.getService().getRootTaskInfo(
+ if (mFeatureFlags.isEnabled(Flags.FP_LISTEN_OCCLUDING_APPS)) {
+ RootTaskInfo standardTask = mActivityTaskManager.getRootTaskInfo(
+ WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+ final boolean previousState = mAllowFingerprintOnCurrentOccludingActivity;
+ mAllowFingerprintOnCurrentOccludingActivity =
+ standardTask.topActivity != null
+ && !TextUtils.isEmpty(standardTask.topActivity.getPackageName())
+ && mAllowFingerprintOnOccludingActivitiesFromPackage.contains(
+ standardTask.topActivity.getPackageName())
+ && standardTask.visible;
+ if (mAllowFingerprintOnCurrentOccludingActivity != previousState) {
+ mLogger.allowFingerprintOnCurrentOccludingActivityChanged(
+ mAllowFingerprintOnCurrentOccludingActivity);
+ updateFingerprintListeningState(BIOMETRIC_ACTION_UPDATE);
+ }
+ }
+
+ RootTaskInfo assistantTask = mActivityTaskManager.getRootTaskInfo(
WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_ASSISTANT);
- if (info == null) {
+ if (assistantTask == null) {
return;
}
- mLogger.logTaskStackChangedForAssistant(info.visible);
+ mLogger.logTaskStackChangedForAssistant(assistantTask.visible);
mHandler.sendMessage(mHandler.obtainMessage(MSG_ASSISTANT_STACK_CHANGED,
- info.visible));
+ assistantTask.visible));
} catch (RemoteException e) {
mLogger.logException(e, "unable to check task stack ");
}
@@ -4324,7 +4355,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
mUserTracker.removeCallback(mUserChangedCallback);
- TaskStackChangeListeners.getInstance().unregisterTaskStackListener(mTaskStackListener);
+ mTaskStackChangeListeners.unregisterTaskStackListener(mTaskStackListener);
mBroadcastDispatcher.unregisterReceiver(mBroadcastReceiver);
mBroadcastDispatcher.unregisterReceiver(mBroadcastAllReceiver);
@@ -4383,6 +4414,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
pw.println(" enabledByUser=" + mBiometricEnabledForUser.get(userId));
pw.println(" mKeyguardOccluded=" + mKeyguardOccluded);
pw.println(" mIsDreaming=" + mIsDreaming);
+ pw.println(" mFingerprintListenOnOccludingActivitiesFromPackage="
+ + mAllowFingerprintOnOccludingActivitiesFromPackage);
if (isUdfpsSupported()) {
pw.println(" udfpsEnrolled=" + isUdfpsEnrolled());
pw.println(" shouldListenForUdfps=" + shouldListenForFingerprint(true));
diff --git a/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt b/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt
index b5963312cb2d..a192803ea0e8 100644
--- a/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt
+++ b/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt
@@ -601,6 +601,15 @@ constructor(@KeyguardUpdateMonitorLog private val logBuffer: LogBuffer) {
)
}
+ fun allowFingerprintOnCurrentOccludingActivityChanged(allow: Boolean) {
+ logBuffer.log(
+ TAG,
+ VERBOSE,
+ { bool1 = allow },
+ { "allowFingerprintOnCurrentOccludingActivityChanged: $bool1" }
+ )
+ }
+
fun logAssistantVisible(assistantVisible: Boolean) {
logBuffer.log(
TAG,
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index b0576e02f998..901c3fb05b2f 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -17,6 +17,7 @@
package com.android.keyguard;
import static android.app.StatusBarManager.SESSION_KEYGUARD;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ERROR_LOCKOUT;
import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ERROR_LOCKOUT_PERMANENT;
@@ -65,6 +66,8 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.Activity;
+import android.app.ActivityTaskManager;
+import android.app.IActivityTaskManager;
import android.app.admin.DevicePolicyManager;
import android.app.trust.IStrongAuthTracker;
import android.app.trust.TrustManager;
@@ -116,6 +119,7 @@ import android.telephony.TelephonyManager;
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
+import android.text.TextUtils;
import androidx.annotation.NonNull;
@@ -139,6 +143,8 @@ import com.android.systemui.flags.FakeFeatureFlags;
import com.android.systemui.log.SessionTracker;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.settings.UserTracker;
+import com.android.systemui.shared.system.TaskStackChangeListener;
+import com.android.systemui.shared.system.TaskStackChangeListeners;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.policy.DevicePostureController;
@@ -175,6 +181,8 @@ import java.util.concurrent.atomic.AtomicInteger;
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
public class KeyguardUpdateMonitorTest extends SysuiTestCase {
+ private static final String PKG_ALLOWING_FP_LISTEN_ON_OCCLUDING_ACTIVITY =
+ "test_app_fp_listen_on_occluding_activity";
private static final String TEST_CARRIER = "TEST_CARRIER";
private static final String TEST_CARRIER_2 = "TEST_CARRIER_2";
private static final int TEST_CARRIER_ID = 1;
@@ -264,6 +272,10 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
private UsbPortStatus mUsbPortStatus;
@Mock
private Uri mURI;
+ @Mock
+ private TaskStackChangeListeners mTaskStackChangeListeners;
+ @Mock
+ private IActivityTaskManager mActivityTaskManager;
private List<FaceSensorPropertiesInternal> mFaceSensorProperties;
private List<FingerprintSensorPropertiesInternal> mFingerprintSensorProperties;
@@ -327,6 +339,10 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
mDumpManager
);
+ mContext.getOrCreateTestableResources().addOverride(com.android.systemui
+ .R.array.config_fingerprint_listen_on_occluding_activity_packages,
+ new String[]{ PKG_ALLOWING_FP_LISTEN_ON_OCCLUDING_ACTIVITY });
+
mTestableLooper = TestableLooper.get(this);
allowTestableLooperAsMainThread();
mFeatureFlags = new FakeFeatureFlags();
@@ -1560,7 +1576,8 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
}
@Test
- public void testOccludingAppFingerprintListeningState_featureFlagEnabled() {
+ public void listenForFingerprint_whenOccludingAppPkgOnAllowlist()
+ throws RemoteException {
mFeatureFlags.set(FP_LISTEN_OCCLUDING_APPS, true);
// GIVEN keyguard isn't visible (app occluding)
@@ -1568,10 +1585,36 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
mKeyguardUpdateMonitor.setKeyguardShowing(true, true);
when(mStrongAuthTracker.hasUserAuthenticatedSinceBoot()).thenReturn(true);
+ // GIVEN the top activity is from a package that allows fingerprint listening over its
+ // occluding activities
+ setTopStandardActivity(PKG_ALLOWING_FP_LISTEN_ON_OCCLUDING_ACTIVITY);
+ onTaskStackChanged();
+
// THEN we SHOULD listen for non-UDFPS fingerprint
assertThat(mKeyguardUpdateMonitor.shouldListenForFingerprint(false)).isEqualTo(true);
- // THEN we should listen for udfps (hiding of mechanism to actually auth is
+ // THEN we should listen for udfps (hiding mechanism to actually auth is
+ // controlled by UdfpsKeyguardViewController)
+ assertThat(mKeyguardUpdateMonitor.shouldListenForFingerprint(true)).isEqualTo(true);
+ }
+
+ @Test
+ public void doNotListenForFingerprint_whenOccludingAppPkgNotOnAllowlist()
+ throws RemoteException {
+ mFeatureFlags.set(FP_LISTEN_OCCLUDING_APPS, true);
+
+ // GIVEN keyguard isn't visible (app occluding)
+ mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON);
+ mKeyguardUpdateMonitor.setKeyguardShowing(true, true);
+ when(mStrongAuthTracker.hasUserAuthenticatedSinceBoot()).thenReturn(true);
+
+ // GIVEN top activity is not in the allowlist for listening to fp over occluding activities
+ setTopStandardActivity("notInAllowList");
+
+ // THEN we should not listen for non-UDFPS fingerprint
+ assertThat(mKeyguardUpdateMonitor.shouldListenForFingerprint(false)).isEqualTo(false);
+
+ // THEN we should listen for udfps (hiding mechanism to actually auth is
// controlled by UdfpsKeyguardViewController)
assertThat(mKeyguardUpdateMonitor.shouldListenForFingerprint(true)).isEqualTo(true);
}
@@ -3267,6 +3310,23 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
BatteryManager.CHARGING_POLICY_ADAPTIVE_LONGLIFE);
}
+ private void setTopStandardActivity(String pkgName) throws RemoteException {
+ final ActivityTaskManager.RootTaskInfo taskInfo = new ActivityTaskManager.RootTaskInfo();
+ taskInfo.visible = true;
+ taskInfo.topActivity = TextUtils.isEmpty(pkgName)
+ ? null : new ComponentName(pkgName, "testClass");
+ when(mActivityTaskManager.getRootTaskInfo(anyInt(), eq(ACTIVITY_TYPE_STANDARD)))
+ .thenReturn(taskInfo);
+ }
+
+ private void onTaskStackChanged() {
+ ArgumentCaptor<TaskStackChangeListener> taskStackChangeListenerCaptor =
+ ArgumentCaptor.forClass(TaskStackChangeListener.class);
+ verify(mTaskStackChangeListeners).registerTaskStackListener(
+ taskStackChangeListenerCaptor.capture());
+ taskStackChangeListenerCaptor.getValue().onTaskStackChangedBackground();
+ }
+
private class TestableKeyguardUpdateMonitor extends KeyguardUpdateMonitor {
AtomicBoolean mSimStateChanged = new AtomicBoolean(false);
AtomicInteger mCachedSimState = new AtomicInteger(-1);
@@ -3284,7 +3344,8 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
mDreamManager, mDevicePolicyManager, mSensorPrivacyManager, mTelephonyManager,
mPackageManager, mFaceManager, mFingerprintManager, mBiometricManager,
mFaceWakeUpTriggersConfig, mDevicePostureController,
- Optional.of(mInteractiveToAuthProvider), mFeatureFlags);
+ Optional.of(mInteractiveToAuthProvider), mFeatureFlags,
+ mTaskStackChangeListeners, mActivityTaskManager);
setStrongAuthTracker(KeyguardUpdateMonitorTest.this.mStrongAuthTracker);
}