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

Commit 83eb6bb5 authored by Jorim Jaggi's avatar Jorim Jaggi
Browse files

Improve motion for wake-and-unlocking while pulsing

- Move all fingerprint related to logic in on central class in
SystemUI that knows all the state of the UI so there is exactly ONE
place in which we decide what to do when we acquire a fingerprint.
- When pulsing and we get a valid finger, we fade the contents of the
Keyguard out and fade the scrim out almost the same way as we would do
in a normal wake-and-unlock sequence.
- Hide shadows while dozing, so we don't see the artifacts when we fade
the dozed Keyguard out.

Bug: 23225107
Change-Id: I82f78e61f2530cf7d507ade80f6f0a340c082567
parent 007f0e8f
Loading
Loading
Loading
Loading
+9 −101
Original line number Diff line number Diff line
@@ -94,15 +94,12 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
    private static final String TAG = "KeyguardUpdateMonitor";
    private static final boolean DEBUG = KeyguardConstants.DEBUG;
    private static final boolean DEBUG_SIM_STATES = KeyguardConstants.DEBUG_SIM_STATES;
    private static final boolean DEBUG_FP_WAKELOCK = KeyguardConstants.DEBUG_FP_WAKELOCK;
    private static final int LOW_BATTERY_THRESHOLD = 20;
    private static final long FINGERPRINT_WAKELOCK_TIMEOUT_MS = 15 * 1000;

    private static final String ACTION_FACE_UNLOCK_STARTED
            = "com.android.facelock.FACE_UNLOCK_STARTED";
    private static final String ACTION_FACE_UNLOCK_STOPPED
            = "com.android.facelock.FACE_UNLOCK_STOPPED";
    private static final String FINGERPRINT_WAKE_LOCK_NAME = "wake-and-unlock wakelock";

    private static final String ACTION_STRONG_AUTH_TIMEOUT =
            "com.android.systemui.ACTION_STRONG_AUTH_TIMEOUT";
@@ -110,29 +107,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {

    private static final String PERMISSION_SELF = "com.android.systemui.permission.SELF";

    /**
     * Mode in which we don't need to wake up the device when we get a fingerprint.
     */
    private static final int FP_WAKE_NONE = 0;

    /**
     * Mode in which we wake up the device, and directly dismiss Keyguard. Active when we acquire
     * a fingerprint while the screen is off and the device was sleeping.
     */
    private static final int FP_WAKE_DIRECT_UNLOCK = 1;

    /**
     * Mode in which we wake up the device, but play the normal dismiss animation. Active when we
     * acquire a fingerprint pulsing in doze mode.
     * */
    private static final int FP_WAKE_TO_BOUNCER = 2;

    /**
     * Mode in which we only wake up the device, and keyguard was not showing when we acquired a
     * fingerprint.
     * */
    private static final int FP_ONLY_WAKE = 3;

    /**
     * Milliseconds after unlocking with fingerprint times out, i.e. the user has to use a
     * strong auth method like password, PIN or pattern.
@@ -202,7 +176,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
    private List<SubscriptionInfo> mSubscriptionInfo;
    private boolean mFingerprintDetectionRunning;
    private TrustManager mTrustManager;
    private PowerManager mPowerManager;

    private final Handler mHandler = new Handler() {
        @Override
@@ -398,22 +371,23 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
        }
    }

    private void onFingerprintAuthenticated(int userId, boolean wakeAndUnlocking) {
    private void onFingerprintAuthenticated(int userId) {
        mUserFingerprintAuthenticated.put(userId, true);
        for (int i = 0; i < mCallbacks.size(); i++) {
            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
            if (cb != null) {
                cb.onFingerprintAuthenticated(userId, wakeAndUnlocking);
                cb.onFingerprintAuthenticated(userId);
            }
        }
    }

    private void handleFingerprintAuthFailed() {
        if (mFpWakeMode == FP_WAKE_DIRECT_UNLOCK) {
            notifyOnFingerprintWakeAndUnlockingFinished();
        for (int i = 0; i < mCallbacks.size(); i++) {
            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
            if (cb != null) {
                cb.onFingerprintAuthFailed();
            }
        }
        mFpWakeMode = FP_WAKE_NONE;
        releaseFingerprintWakeLock();
        handleFingerprintHelp(-1, mContext.getString(R.string.fingerprint_not_recognized));
    }

@@ -421,75 +395,15 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
        if (acquireInfo != FingerprintManager.FINGERPRINT_ACQUIRED_GOOD) {
            return;
        }
        if (!mDeviceInteractive && !mScreenOn) {
            releaseFingerprintWakeLock();
            mWakeLock = mPowerManager.newWakeLock(
                    PowerManager.PARTIAL_WAKE_LOCK, FINGERPRINT_WAKE_LOCK_NAME);
            mWakeLock.acquire();
            mFpWakeMode = mKeyguardIsVisible ? FP_WAKE_DIRECT_UNLOCK : FP_ONLY_WAKE;
            if (DEBUG_FP_WAKELOCK) {
                Log.i(TAG, "fingerprint acquired, grabbing fp wakelock");
            }
            mHandler.postDelayed(mReleaseFingerprintWakeLockRunnable,
                    FINGERPRINT_WAKELOCK_TIMEOUT_MS);
            if (mFpWakeMode == FP_WAKE_DIRECT_UNLOCK) {
                notifyOnFingerprintWakeAndUnlockingStarted();
            }
        } else if (!mDeviceInteractive) {
            mFpWakeMode = FP_WAKE_TO_BOUNCER;
        } else {
            mFpWakeMode = FP_WAKE_NONE;
        }
    }

    private void notifyOnFingerprintWakeAndUnlockingStarted() {
        for (int i = 0; i < mCallbacks.size(); i++) {
            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
            if (cb != null) {
                cb.onFingerprintWakeAndUnlockingStarted();
                cb.onFingerprintAcquired();
            }
        }
    }

    private void notifyOnFingerprintWakeAndUnlockingFinished() {
        for (int i = 0; i < mCallbacks.size(); i++) {
            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
            if (cb != null) {
                cb.onFingerprintWakeAndUnlockingFinished();
            }
        }
    }

    private final Runnable mReleaseFingerprintWakeLockRunnable = new Runnable() {
        @Override
        public void run() {
            if (DEBUG_FP_WAKELOCK) {
                Log.i(TAG, "fp wakelock: TIMEOUT!!");
            }
            releaseFingerprintWakeLock();
        }
    };

    private void releaseFingerprintWakeLock() {
        if (mWakeLock != null) {
            mHandler.removeCallbacks(mReleaseFingerprintWakeLockRunnable);
            if (DEBUG_FP_WAKELOCK) {
                Log.i(TAG, "releasing fp wakelock");
            }
            mWakeLock.release();
            mWakeLock = null;
        }
    }

    private void handleFingerprintAuthenticated() {
        if (mFpWakeMode == FP_WAKE_TO_BOUNCER || mFpWakeMode == FP_WAKE_DIRECT_UNLOCK
                || mFpWakeMode == FP_ONLY_WAKE) {
            if (DEBUG_FP_WAKELOCK) {
                Log.i(TAG, "fp wakelock: Authenticated, waking up...");
            }
            mPowerManager.wakeUp(SystemClock.uptimeMillis());
        }
        releaseFingerprintWakeLock();
        try {
            final int userId;
            try {
@@ -502,7 +416,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
                Log.d(TAG, "Fingerprint disabled by DPM for userId: " + userId);
                return;
            }
            onFingerprintAuthenticated(userId, mFpWakeMode == FP_WAKE_DIRECT_UNLOCK);
            onFingerprintAuthenticated(userId);
        } finally {
            setFingerprintRunningDetectionRunning(false);
        }
@@ -752,7 +666,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
    };
    private CancellationSignal mFingerprintCancelSignal;
    private FingerprintManager mFpm;
    private PowerManager.WakeLock mWakeLock;

    /**
     * When we receive a
@@ -915,10 +828,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
                cb.onScreenTurnedOn();
            }
        }
        if (mFpWakeMode == FP_WAKE_DIRECT_UNLOCK) {
            notifyOnFingerprintWakeAndUnlockingFinished();
        }
        mFpWakeMode = FP_WAKE_NONE;
    }

    private void handleScreenTurnedOff() {
@@ -957,7 +866,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
    private KeyguardUpdateMonitor(Context context) {
        mContext = context;
        mSubscriptionManager = SubscriptionManager.from(context);
        mPowerManager = context.getSystemService(PowerManager.class);
        mAlarmManager = context.getSystemService(AlarmManager.class);
        mDeviceProvisioned = isDeviceProvisionedInSettingsDb();

+10 −10
Original line number Diff line number Diff line
@@ -186,23 +186,23 @@ public class KeyguardUpdateMonitorCallback {
    public void onTrustGrantedWithFlags(int flags, int userId) { }

    /**
     * Called when a fingerprint is recognized.
     * @param userId the user id for which the fingerprint was authenticated
     * @param wakeAndUnlocking whether the authentication woke the device up and thus we'd like to
     *                         dismiss the lockscreen before turning on the screen
     * Called when a finger has been acquired.
     * <p>
     * It is guaranteed that either {@link #onFingerprintAuthenticated} or
     * {@link #onFingerprintAuthFailed()} is called after this method eventually.
     */
    public void onFingerprintAuthenticated(int userId, boolean wakeAndUnlocking) { }
    public void onFingerprintAcquired() { }

    /**
     * Called when we might be starting a wake-and-unlock sequence.
     * Called when a fingerprint couldn't be authenticated.
     */
    public void onFingerprintWakeAndUnlockingStarted() { }
    public void onFingerprintAuthFailed() { }

    /**
     * Called when we're done with the wake-and-unlock sequence. This can either happen when we
     * figure out that the fingerprint didn't match, or when the phone is fully unlocked.
     * Called when a fingerprint is recognized.
     * @param userId the user id for which the fingerprint was authenticated
     */
    public void onFingerprintWakeAndUnlockingFinished() { }
    public void onFingerprintAuthenticated(int userId) { }

    /**
     * Called when fingerprint provides help string (e.g. "Try again")
+1 −0
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@
    <item type="id" name="doze_saved_filter_tag"/>
    <item type="id" name="qs_icon_tag"/>
    <item type="id" name="scrim"/>
    <item type="id" name="scrim_target"/>
    <item type="id" name="hun_scrim_alpha_start"/>
    <item type="id" name="hun_scrim_alpha_end"/>
    <item type="id" name="notification_power"/>
+9 −32
Original line number Diff line number Diff line
@@ -68,6 +68,7 @@ import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.keyguard.ViewMediatorCallback;
import com.android.systemui.SystemUI;
import com.android.systemui.statusbar.phone.FingerprintUnlockController;
import com.android.systemui.statusbar.phone.PhoneStatusBar;
import com.android.systemui.statusbar.phone.ScrimController;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
@@ -176,11 +177,6 @@ public class KeyguardViewMediator extends SystemUI {
     */
    private static final String KEYGUARD_ANALYTICS_SETTING = "keyguard_analytics";

    /**
     * How much faster we collapse the lockscreen when authenticating with fingerprint.
     */
    private static final float FINGERPRINT_COLLAPSE_SPEEDUP_FACTOR = 1.3f;

    /** The stream type that the lock sounds are tied to. */
    private int mUiSoundsStreamType;

@@ -458,31 +454,6 @@ public class KeyguardViewMediator extends SystemUI {
                    break;
            }
        }

        @Override
        public void onFingerprintAuthenticated(int userId, boolean wakeAndUnlocking) {
            boolean unlockingWithFingerprintAllowed =
                    mUpdateMonitor.isUnlockingWithFingerprintAllowed();
            if (mStatusBarKeyguardViewManager.isBouncerShowing()) {
                if (unlockingWithFingerprintAllowed) {
                    mStatusBarKeyguardViewManager.notifyKeyguardAuthenticated(
                            false /* strongAuth */);
                }
            } else {
                if (wakeAndUnlocking && mShowing && unlockingWithFingerprintAllowed) {
                    mWakeAndUnlocking = true;
                    mStatusBarKeyguardViewManager.setWakeAndUnlocking();
                    keyguardDone(true);
                } else if (mShowing) {
                    if (wakeAndUnlocking) {
                        mStatusBarKeyguardViewManager.notifyDeviceWakeUpRequested();
                    }
                    mStatusBarKeyguardViewManager.animateCollapsePanels(
                            FINGERPRINT_COLLAPSE_SPEEDUP_FACTOR);
                }
            }
        };

    };

    ViewMediatorCallback mViewMediatorCallback = new ViewMediatorCallback() {
@@ -1620,11 +1591,17 @@ public class KeyguardViewMediator extends SystemUI {
        }
    }

    public void onWakeAndUnlocking() {
        mWakeAndUnlocking = true;
        keyguardDone(true /* authenticated */);
    }

    public StatusBarKeyguardViewManager registerStatusBar(PhoneStatusBar phoneStatusBar,
            ViewGroup container, StatusBarWindowManager statusBarWindowManager,
            ScrimController scrimController) {
            ScrimController scrimController,
            FingerprintUnlockController fingerprintUnlockController) {
        mStatusBarKeyguardViewManager.registerStatusBar(phoneStatusBar, container,
                statusBarWindowManager, scrimController);
                statusBarWindowManager, scrimController, fingerprintUnlockController);
        return mStatusBarKeyguardViewManager;
    }

+1 −0
Original line number Diff line number Diff line
@@ -350,6 +350,7 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
        } else {
            updateBackground();
        }
        setOutlineAlpha(dark ? 0f : 1f);
     }

    public void setShowingLegacyBackground(boolean showing) {
Loading