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

Commit cf99bb18 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Only run fp over occluding LS activites on the allowlist" into udc-qpr-dev

parents 5e41ba4c de61860e
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -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>

+4 −0
Original line number Diff line number Diff line
@@ -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",
+44 −11
Original line number Diff line number Diff line
@@ -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));
+9 −0
Original line number Diff line number Diff line
@@ -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,
+64 −3
Original line number Diff line number Diff line
@@ -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);
        }