Only run fp over occluding LS activites on the allowlist

Running fp over occluding activities is guarded behind flag:
  FP_LISTEN_OCCLUDING_APPS

Test: atest KeyguardUpdateMonitorTest
Bug: 283260970
Change-Id: Ic285cd73a33ec8ba21038dda75e026df30e7c6d6
This commit is contained in:
Beverly
2023-06-22 18:31:45 +00:00
parent 59a803957b
commit de61860e2d
5 changed files with 125 additions and 14 deletions

View File

@@ -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>

View File

@@ -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",

View File

@@ -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
@@ -2292,7 +2298,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;
@@ -2334,6 +2342,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
@@ -2549,7 +2563,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));
@@ -3019,7 +3033,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
&& (mOccludingAppRequestingFp
|| isUdfps
|| mAlternateBouncerShowing
|| mFeatureFlags.isEnabled(Flags.FP_LISTEN_OCCLUDING_APPS)
|| mAllowFingerprintOnCurrentOccludingActivity
)
);
@@ -3062,6 +3076,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
System.currentTimeMillis(),
user,
shouldListen,
mAllowFingerprintOnCurrentOccludingActivity,
mAlternateBouncerShowing,
biometricEnabledForUser,
mPrimaryBouncerIsOrWillBeShowing,
@@ -4090,19 +4105,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 ");
}
@@ -4294,7 +4325,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
mUserTracker.removeCallback(mUserChangedCallback);
TaskStackChangeListeners.getInstance().unregisterTaskStackListener(mTaskStackListener);
mTaskStackChangeListeners.unregisterTaskStackListener(mTaskStackListener);
mBroadcastDispatcher.unregisterReceiver(mBroadcastReceiver);
mBroadcastDispatcher.unregisterReceiver(mBroadcastAllReceiver);
@@ -4353,6 +4384,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));

View File

@@ -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,

View File

@@ -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;
@@ -174,6 +180,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
@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;
@@ -263,6 +271,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;
@@ -326,6 +338,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();
@@ -1435,7 +1451,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)
@@ -1443,10 +1460,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);
}
@@ -3142,6 +3185,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);
@@ -3158,7 +3218,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);
}