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

Commit f6d0fc19 authored by Danielle Millett's avatar Danielle Millett
Browse files

Handling popups correctly for face unlock

Added a keyguardVisibilityChanged callback to indicate when the
keyguard is covered by something (alarm, phone, etc).  Face unlock
doesn't start if it's not visible and it restarts appropriately when
it gains visibility again.  This mostly fixes b/7362774 and b/7376783,
but there's some jank when face unlock goes away (if it was interrupted
while running).

Change-Id: I7bdf8ef6af687acaa7152d8e61bfdcc1979259ff
parent 31821c5b
Loading
Loading
Loading
Loading
+45 −7
Original line number Diff line number Diff line
@@ -39,6 +39,9 @@ public class KeyguardFaceUnlockView extends LinearLayout implements KeyguardSecu
    private View mFaceUnlockAreaView;
    private ImageButton mCancelButton;

    private boolean mIsShowing = false;
    private final Object mIsShowingLock = new Object();

    public KeyguardFaceUnlockView(Context context) {
        this(context, null);
    }
@@ -112,6 +115,7 @@ public class KeyguardFaceUnlockView extends LinearLayout implements KeyguardSecu
    }

    private void initializeBiometricUnlockView() {
        if (DEBUG) Log.d(TAG, "initializeBiometricUnlockView()");
        mFaceUnlockAreaView = findViewById(R.id.face_unlock_area_view);
        if (mFaceUnlockAreaView != null) {
            mBiometricUnlock = new FaceUnlock(mContext);
@@ -129,9 +133,9 @@ public class KeyguardFaceUnlockView extends LinearLayout implements KeyguardSecu
    }

    /**
     * Starts the biometric unlock if it should be started based on a number of factors including
     * the mSuppressBiometricUnlock flag.  If it should not be started, it hides the biometric
     * unlock area.
     * Starts the biometric unlock if it should be started based on a number of factors.  If it
     * should not be started, it either goes to the back up, or remains showing to prepare for
     * it being started later.
     */
    private void maybeStartBiometricUnlock() {
        if (DEBUG) Log.d(TAG, "maybeStartBiometricUnlock()");
@@ -142,12 +146,25 @@ public class KeyguardFaceUnlockView extends LinearLayout implements KeyguardSecu
                    LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT);
            PowerManager powerManager = (PowerManager) mContext.getSystemService(
                    Context.POWER_SERVICE);

            boolean isShowing;
            synchronized(mIsShowingLock) {
                isShowing = mIsShowing;
            }

            // Don't start it if the screen is off or if it's not showing, but keep this view up
            // because we want it here and ready for when the screen turns on or when it does start
            // showing.
            if (!powerManager.isScreenOn() || !isShowing) {
                mBiometricUnlock.stop(); // It shouldn't be running but calling this can't hurt.
                return;
            }

            // TODO: Some of these conditions are handled in KeyguardSecurityModel and may not be
            // necessary here.
            if (monitor.getPhoneState() == TelephonyManager.CALL_STATE_IDLE
                    && !monitor.getMaxBiometricUnlockAttemptsReached()
                    && !backupIsTimedOut
                    && powerManager.isScreenOn()) {
                    && !backupIsTimedOut) {
                mBiometricUnlock.start();
            } else {
                mBiometricUnlock.stopAndShowBackup();
@@ -161,9 +178,11 @@ public class KeyguardFaceUnlockView extends LinearLayout implements KeyguardSecu
        public void onPhoneStateChanged(int phoneState) {
            if (DEBUG) Log.d(TAG, "onPhoneStateChanged(" + phoneState + ")");
            if (phoneState == TelephonyManager.CALL_STATE_RINGING) {
                if (mBiometricUnlock != null) {
                    mBiometricUnlock.stopAndShowBackup();
                }
            }
        }

        @Override
        public void onUserSwitched(int userId) {
@@ -174,6 +193,25 @@ public class KeyguardFaceUnlockView extends LinearLayout implements KeyguardSecu
            // No longer required; static value set by KeyguardViewMediator
            // mLockPatternUtils.setCurrentUser(userId);
        }

        @Override
        public void onKeyguardVisibilityChanged(boolean showing) {
            if (DEBUG) Log.d(TAG, "onKeyguardVisibilityChanged(" + showing + ")");
            boolean wasShowing = false;
            synchronized(mIsShowingLock) {
                wasShowing = mIsShowing;
                mIsShowing = showing;
            }
            PowerManager powerManager = (PowerManager) mContext.getSystemService(
                    Context.POWER_SERVICE);
            if (mBiometricUnlock != null) {
                if (!showing && wasShowing) {
                    mBiometricUnlock.stop();
                } else if (showing && powerManager.isScreenOn() && !wasShowing) {
                    maybeStartBiometricUnlock();
                }
            }
        }
    };

    @Override
+25 −0
Original line number Diff line number Diff line
@@ -80,6 +80,7 @@ public class KeyguardUpdateMonitor {
    private static final int MSG_DPM_STATE_CHANGED = 309;
    private static final int MSG_USER_SWITCHED = 310;
    private static final int MSG_USER_REMOVED = 311;
    private static final int MSG_KEYGUARD_VISIBILITY_CHANGED = 312;

    private static KeyguardUpdateMonitor sInstance;

@@ -147,6 +148,10 @@ public class KeyguardUpdateMonitor {
                case MSG_USER_REMOVED:
                    handleUserRemoved(msg.arg1);
                    break;
                case MSG_KEYGUARD_VISIBILITY_CHANGED:
                    handleKeyguardVisibilityChanged(msg.arg1);
                    break;

            }
        }
    };
@@ -557,6 +562,19 @@ public class KeyguardUpdateMonitor {
        }
    }

    /**
     * Handle {@link #MSG_KEYGUARD_VISIBILITY_CHANGED}
     */
    private void handleKeyguardVisibilityChanged(int showing) {
        if (DEBUG) Log.d(TAG, "handleKeyguardVisibilityChanged(" + showing + ")");
        for (int i = 0; i < mCallbacks.size(); i++) {
            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
            if (cb != null) {
                cb.onKeyguardVisibilityChanged(showing == 1);
            }
        }
    }

    private static boolean isBatteryUpdateInteresting(BatteryStatus old, BatteryStatus current) {
        final boolean nowPluggedIn = current.isPluggedIn();
        final boolean wasPluggedIn = old.isPluggedIn();
@@ -659,6 +677,13 @@ public class KeyguardUpdateMonitor {
        callback.onSimStateChanged(mSimState);
    }

    public void sendKeyguardVisibilityChanged(boolean showing) {
        if (DEBUG) Log.d(TAG, "sendKeyguardVisibilityChanged(" + showing + ")");
        Message message = mHandler.obtainMessage(MSG_KEYGUARD_VISIBILITY_CHANGED);
        message.arg1 = showing ? 1 : 0;
        message.sendToTarget();
    }

    public void reportClockVisible(boolean visible) {
        mClockVisible = visible;
        mHandler.obtainMessage(MSG_CLOCK_VISIBILITY_CHANGED).sendToTarget();
+6 −0
Original line number Diff line number Diff line
@@ -61,6 +61,12 @@ class KeyguardUpdateMonitorCallback {
     */
    void onPhoneStateChanged(int phoneState) { }

    /**
     * Called when the visibility of the keyguard changes.
     * @param showing Indicates if the keyguard is now visible.
     */
    void onKeyguardVisibilityChanged(boolean showing) { }

    /**
     * Called when visibility of lockscreen clock changes, such as when
     * obscured by a widget.
+1 −0
Original line number Diff line number Diff line
@@ -771,6 +771,7 @@ public class KeyguardViewMediator {
     */
    public void setHidden(boolean isHidden) {
        if (DEBUG) Log.d(TAG, "setHidden " + isHidden);
        mUpdateMonitor.sendKeyguardVisibilityChanged(!isHidden);
        mHandler.removeMessages(SET_HIDDEN);
        Message msg = mHandler.obtainMessage(SET_HIDDEN, (isHidden ? 1 : 0), 0);
        mHandler.sendMessage(msg);