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

Commit e6cafe98 authored by Nicolo' Mazzucato's avatar Nicolo' Mazzucato
Browse files

Show side fps hint on large screen bouncer

This adds an hint regarding the possibility to unlock with the fingerprint while on bouncer, only when sided bouncer is enabled (so only on large screens). The hint is visible while the sensor is running.

Bug: 226610828
Test: atest KeyguardSecurityContainerControllerTest
Change-Id: I961ae6fe67e92620e955a5e297052e255fddd80d
parent 0641bef2
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -336,6 +336,11 @@ public class KeyguardHostViewController extends ViewController<KeyguardHostView>
        mKeyguardSecurityContainerController.onStartingToHide();
    }

    /** Called when bouncer visibility changes. */
    public void onBouncerVisibilityChanged(@View.Visibility int visibility) {
        mKeyguardSecurityContainerController.onBouncerVisibilityChanged(visibility);
    }

    public boolean hasDismissActions() {
        return mDismissAction != null || mCancelAction != null;
    }
+61 −8
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.hardware.biometrics.BiometricSourceType.FINGERPRINT;

import static com.android.keyguard.KeyguardSecurityContainer.BOUNCER_DISMISS_BIOMETRIC;
import static com.android.keyguard.KeyguardSecurityContainer.BOUNCER_DISMISS_EXTENDED_ACCESS;
@@ -32,11 +33,13 @@ import android.app.admin.DevicePolicyManager;
import android.content.Intent;
import android.content.res.ColorStateList;
import android.content.res.Configuration;
import android.hardware.biometrics.BiometricSourceType;
import android.metrics.LogMaker;
import android.os.UserHandle;
import android.util.Log;
import android.util.Slog;
import android.view.MotionEvent;
import android.view.View;

import androidx.annotation.Nullable;

@@ -55,6 +58,7 @@ import com.android.keyguard.dagger.KeyguardBouncerScope;
import com.android.settingslib.utils.ThreadUtils;
import com.android.systemui.Gefingerpoken;
import com.android.systemui.R;
import com.android.systemui.biometrics.SidefpsController;
import com.android.systemui.classifier.FalsingCollector;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.flags.Flags;
@@ -67,6 +71,8 @@ import com.android.systemui.statusbar.policy.UserSwitcherController;
import com.android.systemui.util.ViewController;
import com.android.systemui.util.settings.GlobalSettings;

import java.util.Optional;

import javax.inject.Inject;

/** Controller for {@link KeyguardSecurityContainer} */
@@ -93,6 +99,7 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
    private final GlobalSettings mGlobalSettings;
    private final FeatureFlags mFeatureFlags;
    private final SessionTracker mSessionTracker;
    private final Optional<SidefpsController> mSidefpsController;

    private int mLastOrientation = Configuration.ORIENTATION_UNDEFINED;

@@ -236,12 +243,26 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
                    reloadColors();
                }
            };
    private boolean mBouncerVisible = false;
    private final KeyguardUpdateMonitorCallback mKeyguardUpdateMonitorCallback =
            new KeyguardUpdateMonitorCallback() {
                @Override
                public void onDevicePolicyManagerStateChanged() {
                    showPrimarySecurityScreen(false);
                }

                @Override
                public void onBiometricRunningStateChanged(boolean running,
                        BiometricSourceType biometricSourceType) {
                    if (biometricSourceType == FINGERPRINT) {
                        updateSideFpsVisibility();
                    }
                }

                @Override
                public void onStrongAuthStateChanged(int userId) {
                    updateSideFpsVisibility();
                }
            };

    private KeyguardSecurityContainerController(KeyguardSecurityContainer view,
@@ -260,7 +281,8 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
            UserSwitcherController userSwitcherController,
            FeatureFlags featureFlags,
            GlobalSettings globalSettings,
            SessionTracker sessionTracker) {
            SessionTracker sessionTracker,
            Optional<SidefpsController> sidefpsController) {
        super(view);
        mLockPatternUtils = lockPatternUtils;
        mUpdateMonitor = keyguardUpdateMonitor;
@@ -280,6 +302,7 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
        mFeatureFlags = featureFlags;
        mGlobalSettings = globalSettings;
        mSessionTracker = sessionTracker;
        mSidefpsController = sidefpsController;
    }

    @Override
@@ -311,8 +334,23 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
            getCurrentSecurityController().onPause();
        }
        mView.onPause();
        // It might happen that onStartingToHide is not called when the device is locked while on
        // bouncer.
        setBouncerVisible(false);
    }

    private void updateSideFpsVisibility() {
        if (!mSidefpsController.isPresent()) {
            return;
        }
        if (mBouncerVisible && mView.isSidedSecurityMode()
                && mUpdateMonitor.isFingerprintDetectionRunning()
                && !mUpdateMonitor.userNeedsStrongAuth()) {
            mSidefpsController.get().show();
        } else {
            mSidefpsController.get().hide();
        }
    }

    /**
     * Shows the primary security screen for the user. This will be either the multi-selector
@@ -397,6 +435,17 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
        if (mCurrentSecurityMode != SecurityMode.None) {
            getCurrentSecurityController().onStartingToHide();
        }
        setBouncerVisible(false);
    }

    /** Called when the bouncer changes visibility. */
    public void onBouncerVisibilityChanged(@View.Visibility int visibility) {
        setBouncerVisible(visibility == View.VISIBLE);
    }

    private void setBouncerVisible(boolean visible) {
        mBouncerVisible = visible;
        updateSideFpsVisibility();
    }

    /**
@@ -655,6 +704,7 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
        private final FeatureFlags mFeatureFlags;
        private final UserSwitcherController mUserSwitcherController;
        private final SessionTracker mSessionTracker;
        private final Optional<SidefpsController> mSidefpsController;

        @Inject
        Factory(KeyguardSecurityContainer view,
@@ -673,7 +723,8 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
                UserSwitcherController userSwitcherController,
                FeatureFlags featureFlags,
                GlobalSettings globalSettings,
                SessionTracker sessionTracker) {
                SessionTracker sessionTracker,
                Optional<SidefpsController> sidefpsController) {
            mView = view;
            mAdminSecondaryLockScreenControllerFactory = adminSecondaryLockScreenControllerFactory;
            mLockPatternUtils = lockPatternUtils;
@@ -690,6 +741,7 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
            mGlobalSettings = globalSettings;
            mUserSwitcherController = userSwitcherController;
            mSessionTracker = sessionTracker;
            mSidefpsController = sidefpsController;
        }

        public KeyguardSecurityContainerController create(
@@ -699,7 +751,8 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
                    mKeyguardUpdateMonitor, mKeyguardSecurityModel, mMetricsLogger, mUiEventLogger,
                    mKeyguardStateController, securityCallback, mSecurityViewFlipperController,
                    mConfigurationController, mFalsingCollector, mFalsingManager,
                    mUserSwitcherController, mFeatureFlags, mGlobalSettings, mSessionTracker);
                    mUserSwitcherController, mFeatureFlags, mGlobalSettings, mSessionTracker,
                    mSidefpsController);
        }
    }
}
+21 −0
Original line number Diff line number Diff line
@@ -16,6 +16,10 @@

package com.android.keyguard.dagger;

import static com.android.systemui.biometrics.SidefpsControllerKt.hasSideFpsSensor;

import android.annotation.Nullable;
import android.hardware.fingerprint.FingerprintManager;
import android.view.LayoutInflater;
import android.view.ViewGroup;

@@ -23,9 +27,14 @@ import com.android.keyguard.KeyguardHostView;
import com.android.keyguard.KeyguardSecurityContainer;
import com.android.keyguard.KeyguardSecurityViewFlipper;
import com.android.systemui.R;
import com.android.systemui.biometrics.SidefpsController;
import com.android.systemui.dagger.qualifiers.RootView;
import com.android.systemui.statusbar.phone.KeyguardBouncer;

import java.util.Optional;

import javax.inject.Provider;

import dagger.Module;
import dagger.Provides;

@@ -60,4 +69,16 @@ public interface KeyguardBouncerModule {
            KeyguardSecurityContainer containerView) {
        return containerView.findViewById(R.id.view_flipper);
    }

    /** Provides {@link SidefpsController} if the device has the side fingerprint sensor. */
    @Provides
    @KeyguardBouncerScope
    static Optional<SidefpsController> providesOptionalSidefpsController(
            @Nullable FingerprintManager fingerprintManager,
            Provider<SidefpsController> sidefpsControllerProvider) {
        if (!hasSideFpsSensor(fingerprintManager)) {
            return Optional.empty();
        }
        return Optional.of(sidefpsControllerProvider.get());
    }
}
+34 −20
Original line number Diff line number Diff line
@@ -34,16 +34,16 @@ import android.hardware.fingerprint.ISidefpsController
import android.os.Handler
import android.util.Log
import android.util.RotationUtils
import android.view.View.AccessibilityDelegate
import android.view.accessibility.AccessibilityEvent
import android.view.Display
import android.view.Gravity
import android.view.LayoutInflater
import android.view.Surface
import android.view.View
import android.view.View.AccessibilityDelegate
import android.view.ViewPropertyAnimator
import android.view.WindowInsets
import android.view.WindowManager
import android.view.accessibility.AccessibilityEvent
import androidx.annotation.RawRes
import com.airbnb.lottie.LottieAnimationView
import com.airbnb.lottie.LottieProperty
@@ -70,13 +70,12 @@ class SidefpsController @Inject constructor(
    private val activityTaskManager: ActivityTaskManager,
    overviewProxyService: OverviewProxyService,
    displayManager: DisplayManager,
    @Main mainExecutor: DelayableExecutor,
    @Main private val mainExecutor: DelayableExecutor,
    @Main private val handler: Handler
) {
    @VisibleForTesting
    val sensorProps: FingerprintSensorPropertiesInternal = fingerprintManager
        ?.sensorPropertiesInternal
        ?.firstOrNull { it.isAnySidefpsType }
        ?.sideFpsSensorProperties
        ?: throw IllegalStateException("no side fingerprint sensor")

    @VisibleForTesting
@@ -135,23 +134,32 @@ class SidefpsController @Inject constructor(
    }

    init {
        fingerprintManager?.setSidefpsController(object : ISidefpsController.Stub() {
        fingerprintManager?.setSidefpsController(
            object : ISidefpsController.Stub() {
                override fun show(
                    sensorId: Int,
                    @BiometricOverlayConstants.ShowReason reason: Int
            ) = if (reason.isReasonToShow(activityTaskManager)) doShow() else hide(sensorId)
                ) = if (reason.isReasonToShow(activityTaskManager)) show() else hide()

            private fun doShow() = mainExecutor.execute {
                override fun hide(sensorId: Int) = hide()
            })
        overviewProxyService.addCallback(overviewProxyListener)
    }

    /** Shows the side fps overlay if not already shown. */
    fun show() {
        mainExecutor.execute {
            if (overlayView == null) {
                createOverlayForDisplay()
            } else {
                Log.v(TAG, "overlay already shown")
            }
        }
    }

            override fun hide(sensorId: Int) = mainExecutor.execute { overlayView = null }
        })
        overviewProxyService.addCallback(overviewProxyListener)
    /** Hides the fps overlay if shown. */
    fun hide() {
        mainExecutor.execute { overlayView = null }
    }

    private fun onOrientationChanged() {
@@ -266,6 +274,12 @@ class SidefpsController @Inject constructor(
    }
}

private val FingerprintManager?.sideFpsSensorProperties: FingerprintSensorPropertiesInternal?
    get() = this?.sensorPropertiesInternal?.firstOrNull { it.isAnySidefpsType }

/** Returns [True] when the device has a side fingerprint sensor. */
fun FingerprintManager?.hasSideFpsSensor(): Boolean = this?.sideFpsSensorProperties != null

@BiometricOverlayConstants.ShowReason
private fun Int.isReasonToShow(activityTaskManager: ActivityTaskManager): Boolean = when (this) {
    REASON_AUTH_KEYGUARD -> false
+4 −1
Original line number Diff line number Diff line
@@ -266,6 +266,9 @@ public class KeyguardBouncer {

    private void setVisibility(@View.Visibility int visibility) {
        mContainer.setVisibility(visibility);
        if (mKeyguardViewController != null) {
            mKeyguardViewController.onBouncerVisibilityChanged(visibility);
        }
        dispatchVisibilityChanged();
    }

@@ -645,7 +648,7 @@ public class KeyguardBouncer {
        /**
         * Invoked when the bouncer expansion reaches {@link KeyguardBouncer#EXPANSION_VISIBLE}.
         * This is NOT called each time the bouncer is shown, but rather only when the fully
         * shown amount has changed based on the panel expansion. The bouncer is visibility
         * shown amount has changed based on the panel expansion. The bouncer's visibility
         * can still change when the expansion amount hasn't changed.
         * See {@link KeyguardBouncer#isShowing()} for the checks for the bouncer showing state.
         */
Loading