Loading core/res/res/layout/keyguard_face_unlock_view.xml +3 −2 Original line number Diff line number Diff line Loading @@ -46,13 +46,14 @@ android:background="@color/facelock_spotlight_mask" /> <ImageView android:id="@+id/cancel_button" <ImageButton android:id="@+id/face_unlock_cancel_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="5dip" android:layout_alignParentTop="true" android:layout_alignParentEnd="true" android:background="#00000000" android:src="@drawable/ic_facial_backup" /> Loading core/res/res/values/symbols.xml +1 −0 Original line number Diff line number Diff line Loading @@ -1233,6 +1233,7 @@ <java-symbol type="id" name="eight" /> <java-symbol type="id" name="emergencyCallButton" /> <java-symbol type="id" name="face_unlock_area_view" /> <java-symbol type="id" name="face_unlock_cancel_button" /> <java-symbol type="id" name="five" /> <java-symbol type="id" name="forgotPatternButton" /> <java-symbol type="id" name="four" /> Loading policy/src/com/android/internal/policy/impl/keyguard/BiometricSensorUnlock.java +2 −14 Original line number Diff line number Diff line Loading @@ -37,21 +37,9 @@ interface BiometricSensorUnlock { public boolean isRunning(); /** * Covers the backup unlock mechanism by showing the contents of the view initialized in * {@link BiometricSensorUnlock#initializeView(View)}. The view should disappear after the * specified timeout. If the timeout is 0, the interface shows until another event, such as * calling {@link BiometricSensorUnlock#hide()}, causes it to disappear. Called on the UI * thread. * @param timeoutMilliseconds Amount of time in milliseconds to display the view before * disappearing. A value of 0 means the view should remain visible. */ public void show(long timeoutMilliseconds); /** * Uncovers the backup unlock mechanism by hiding the contents of the view initialized in * {@link BiometricSensorUnlock#initializeView(View)}. * Stops and removes the biometric unlock and shows the backup unlock */ public void hide(); public void stopAndShowBackup(); /** * Binds to the biometric unlock service and starts the unlock procedure. Called on the UI Loading policy/src/com/android/internal/policy/impl/keyguard/FaceUnlock.java +15 −78 Original line number Diff line number Diff line Loading @@ -52,26 +52,19 @@ public class FaceUnlock implements BiometricSensorUnlock, Handler.Callback { private View mFaceUnlockView; private Handler mHandler; private final int MSG_SHOW_FACE_UNLOCK_VIEW = 0; private final int MSG_HIDE_FACE_UNLOCK_VIEW = 1; private final int MSG_SERVICE_CONNECTED = 2; private final int MSG_SERVICE_DISCONNECTED = 3; private final int MSG_UNLOCK = 4; private final int MSG_CANCEL = 5; private final int MSG_REPORT_FAILED_ATTEMPT = 6; private final int MSG_EXPOSE_FALLBACK = 7; private final int MSG_POKE_WAKELOCK = 8; private final int MSG_SERVICE_CONNECTED = 0; private final int MSG_SERVICE_DISCONNECTED = 1; private final int MSG_UNLOCK = 2; private final int MSG_CANCEL = 3; private final int MSG_REPORT_FAILED_ATTEMPT = 4; private final int MSG_EXPOSE_FALLBACK = 5; private final int MSG_POKE_WAKELOCK = 6; // TODO: This was added for the purpose of adhering to what the biometric interface expects // the isRunning() function to return. However, it is probably not necessary to have both // mRunning and mServiceRunning. I'd just rather wait to change that logic. private volatile boolean mIsRunning = false; // Long enough to stay visible while the service starts // Short enough to not have to wait long for backup if service fails to start or crashes // The service can take a couple of seconds to start on the first try after boot private final int SERVICE_STARTUP_VIEW_TIMEOUT = 3000; // So the user has a consistent amount of time when brought to the backup method from Face // Unlock private final int BACKUP_LOCK_TIMEOUT = 5000; Loading Loading @@ -110,30 +103,11 @@ public class FaceUnlock implements BiometricSensorUnlock, Handler.Callback { } /** * Sets the Face Unlock view to visible, hiding it after the specified amount of time. If * timeoutMillis is 0, no hide is performed. Called on the UI thread. * Dismisses face unlock and goes to the backup lock */ public void show(long timeoutMillis) { if (DEBUG) Log.d(TAG, "show()"); if (mHandler.getLooper() != Looper.myLooper()) { Log.e(TAG, "show() called off of the UI thread"); } removeDisplayMessages(); if (timeoutMillis > 0) { mHandler.sendEmptyMessageDelayed(MSG_HIDE_FACE_UNLOCK_VIEW, timeoutMillis); } } /** * Hides the Face Unlock view. */ public void hide() { if (DEBUG) Log.d(TAG, "hide()"); // Removes any wakelock messages to make sure they don't cause the screen to turn back on. mHandler.removeMessages(MSG_POKE_WAKELOCK); // Remove messages to prevent a delayed show message from undo-ing the hide removeDisplayMessages(); mHandler.sendEmptyMessage(MSG_HIDE_FACE_UNLOCK_VIEW); public void stopAndShowBackup() { if (DEBUG) Log.d(TAG, "stopAndShowBackup()"); mHandler.sendEmptyMessage(MSG_CANCEL); } /** Loading @@ -151,10 +125,6 @@ public class FaceUnlock implements BiometricSensorUnlock, Handler.Callback { Log.w(TAG, "start() called when already running"); } // Show Face Unlock view, but only for a little bit so lockpattern will become visible if // Face Unlock fails to start or crashes // This must show before bind to guarantee that Face Unlock has a place to display show(SERVICE_STARTUP_VIEW_TIMEOUT); if (!mBoundToService) { Log.d(TAG, "Binding to Face Unlock service for user=" + mLockPatternUtils.getCurrentUser()); Loading Loading @@ -234,12 +204,6 @@ public class FaceUnlock implements BiometricSensorUnlock, Handler.Callback { */ public boolean handleMessage(Message msg) { switch (msg.what) { case MSG_SHOW_FACE_UNLOCK_VIEW: handleShowFaceUnlockView(); break; case MSG_HIDE_FACE_UNLOCK_VIEW: handleHideFaceUnlockView(); break; case MSG_SERVICE_CONNECTED: handleServiceConnected(); break; Loading Loading @@ -268,22 +232,6 @@ public class FaceUnlock implements BiometricSensorUnlock, Handler.Callback { return true; } /** * Sets the Face Unlock view to visible, thus covering the backup lock. */ void handleShowFaceUnlockView() { if (DEBUG) Log.d(TAG, "handleShowFaceUnlockView()"); // Not required } /** * Hide face unlock and show backup */ void handleHideFaceUnlockView() { if (DEBUG) Log.d(TAG, "handleHideFaceUnlockView()"); mKeyguardScreenCallback.showBackupSecurity(); } /** * Tells the service to start its UI via an AIDL interface. Called when the * onServiceConnected() callback is received. Loading Loading @@ -347,23 +295,21 @@ public class FaceUnlock implements BiometricSensorUnlock, Handler.Callback { } /** * Stops the Face Unlock service and tells the device to grant access to the user. Shows the * Face Unlock view to keep the backup lock covered while the device unlocks. * Stops the Face Unlock service and tells the device to grant access to the user. */ void handleUnlock() { if (DEBUG) Log.d(TAG, "handleUnlock()"); removeDisplayMessages(); stop(); mKeyguardScreenCallback.reportSuccessfulUnlockAttempt(); mKeyguardScreenCallback.dismiss(true); } /** * Stops the Face Unlock service and exposes the backup lock. * Stops the Face Unlock service and goes to the backup lock. */ void handleCancel() { if (DEBUG) Log.d(TAG, "handleCancel()"); mKeyguardScreenCallback.dismiss(false); mKeyguardScreenCallback.showBackupSecurity(); stop(); mKeyguardScreenCallback.userActivity(BACKUP_LOCK_TIMEOUT); } Loading Loading @@ -397,15 +343,6 @@ public class FaceUnlock implements BiometricSensorUnlock, Handler.Callback { } } /** * Removes show and hide messages from the message queue. Called to prevent delayed show/hide * messages from undoing a new message. */ private void removeDisplayMessages() { mHandler.removeMessages(MSG_SHOW_FACE_UNLOCK_VIEW); mHandler.removeMessages(MSG_HIDE_FACE_UNLOCK_VIEW); } /** * Implements service connection methods. */ Loading Loading @@ -508,7 +445,7 @@ public class FaceUnlock implements BiometricSensorUnlock, Handler.Callback { * Called when the Face Unlock service starts displaying the UI, indicating that the backup * unlock can be exposed because the Face Unlock service is now covering the backup with its * UI. **/ */ public void exposeFallback() { if (DEBUG) Log.d(TAG, "exposeFallback()"); mHandler.sendEmptyMessage(MSG_EXPOSE_FALLBACK); Loading policy/src/com/android/internal/policy/impl/keyguard/KeyguardFaceUnlockView.java +24 −9 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.telephony.TelephonyManager; import android.util.AttributeSet; import android.util.Log; import android.view.View; import android.widget.ImageButton; import android.widget.LinearLayout; import com.android.internal.R; Loading @@ -29,11 +30,13 @@ import com.android.internal.widget.LockPatternUtils; public class KeyguardFaceUnlockView extends LinearLayout implements KeyguardSecurityView { private static final String TAG = "KeyguardFaceUnlockView"; private static final boolean DEBUG = false; private KeyguardSecurityCallback mKeyguardSecurityCallback; private LockPatternUtils mLockPatternUtils; private BiometricSensorUnlock mBiometricUnlock; private KeyguardNavigationManager mNavigationManager; private View mFaceUnlockAreaView; private ImageButton mCancelButton; public KeyguardFaceUnlockView(Context context) { this(context, null); Loading Loading @@ -70,25 +73,25 @@ public class KeyguardFaceUnlockView extends LinearLayout implements KeyguardSecu @Override public void onDetachedFromWindow() { if (DEBUG) Log.d(TAG, "onDetachedFromWindow()"); if (mBiometricUnlock != null) { mBiometricUnlock.hide(); mBiometricUnlock.stop(); mBiometricUnlock.stopAndShowBackup(); } } @Override public void onPause() { if (DEBUG) Log.d(TAG, "onPause()"); if (mBiometricUnlock != null) { mBiometricUnlock.hide(); mBiometricUnlock.stop(); mBiometricUnlock.stopAndShowBackup(); } KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mUpdateCallback); } @Override public void onResume() { if (DEBUG) Log.d(TAG, "onResume()"); maybeStartBiometricUnlock(); mBiometricUnlock.show(0); KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mUpdateCallback); } Loading @@ -112,6 +115,14 @@ public class KeyguardFaceUnlockView extends LinearLayout implements KeyguardSecu mFaceUnlockAreaView = findViewById(R.id.face_unlock_area_view); if (mFaceUnlockAreaView != null) { mBiometricUnlock = new FaceUnlock(mContext); mCancelButton = (ImageButton) findViewById(R.id.face_unlock_cancel_button); mCancelButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { mBiometricUnlock.stopAndShowBackup(); } }); } else { Log.w(TAG, "Couldn't find biometric unlock view"); } Loading @@ -123,17 +134,20 @@ public class KeyguardFaceUnlockView extends LinearLayout implements KeyguardSecu * unlock area. */ private void maybeStartBiometricUnlock() { if (DEBUG) Log.d(TAG, "maybeStartBiometricUnlock()"); if (mBiometricUnlock != null) { KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(mContext); final boolean backupIsTimedOut = ( monitor.getFailedUnlockAttempts() >= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT); if (monitor.getPhoneState() == TelephonyManager.CALL_STATE_IDLE // TODO: These max attempts checks are also checked in KeyguardSecurityModel so they // might not be necessary here anymore. if (monitor.getPhoneState() != TelephonyManager.CALL_STATE_RINGING && !monitor.getMaxBiometricUnlockAttemptsReached() && !backupIsTimedOut) { mBiometricUnlock.start(); } else { mBiometricUnlock.hide(); mBiometricUnlock.stopAndShowBackup(); } } } Loading @@ -142,14 +156,15 @@ public class KeyguardFaceUnlockView extends LinearLayout implements KeyguardSecu // We need to stop the biometric unlock when a phone call comes in @Override public void onPhoneStateChanged(int phoneState) { if (DEBUG) Log.d(TAG, "onPhoneStateChanged(" + phoneState + ")"); if (phoneState == TelephonyManager.CALL_STATE_RINGING) { mBiometricUnlock.stop(); mBiometricUnlock.hide(); mBiometricUnlock.stopAndShowBackup(); } } @Override public void onUserSwitched(int userId) { if (DEBUG) Log.d(TAG, "onUserSwitched(" + userId + ")"); if (mBiometricUnlock != null) { mBiometricUnlock.stop(); } Loading Loading
core/res/res/layout/keyguard_face_unlock_view.xml +3 −2 Original line number Diff line number Diff line Loading @@ -46,13 +46,14 @@ android:background="@color/facelock_spotlight_mask" /> <ImageView android:id="@+id/cancel_button" <ImageButton android:id="@+id/face_unlock_cancel_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="5dip" android:layout_alignParentTop="true" android:layout_alignParentEnd="true" android:background="#00000000" android:src="@drawable/ic_facial_backup" /> Loading
core/res/res/values/symbols.xml +1 −0 Original line number Diff line number Diff line Loading @@ -1233,6 +1233,7 @@ <java-symbol type="id" name="eight" /> <java-symbol type="id" name="emergencyCallButton" /> <java-symbol type="id" name="face_unlock_area_view" /> <java-symbol type="id" name="face_unlock_cancel_button" /> <java-symbol type="id" name="five" /> <java-symbol type="id" name="forgotPatternButton" /> <java-symbol type="id" name="four" /> Loading
policy/src/com/android/internal/policy/impl/keyguard/BiometricSensorUnlock.java +2 −14 Original line number Diff line number Diff line Loading @@ -37,21 +37,9 @@ interface BiometricSensorUnlock { public boolean isRunning(); /** * Covers the backup unlock mechanism by showing the contents of the view initialized in * {@link BiometricSensorUnlock#initializeView(View)}. The view should disappear after the * specified timeout. If the timeout is 0, the interface shows until another event, such as * calling {@link BiometricSensorUnlock#hide()}, causes it to disappear. Called on the UI * thread. * @param timeoutMilliseconds Amount of time in milliseconds to display the view before * disappearing. A value of 0 means the view should remain visible. */ public void show(long timeoutMilliseconds); /** * Uncovers the backup unlock mechanism by hiding the contents of the view initialized in * {@link BiometricSensorUnlock#initializeView(View)}. * Stops and removes the biometric unlock and shows the backup unlock */ public void hide(); public void stopAndShowBackup(); /** * Binds to the biometric unlock service and starts the unlock procedure. Called on the UI Loading
policy/src/com/android/internal/policy/impl/keyguard/FaceUnlock.java +15 −78 Original line number Diff line number Diff line Loading @@ -52,26 +52,19 @@ public class FaceUnlock implements BiometricSensorUnlock, Handler.Callback { private View mFaceUnlockView; private Handler mHandler; private final int MSG_SHOW_FACE_UNLOCK_VIEW = 0; private final int MSG_HIDE_FACE_UNLOCK_VIEW = 1; private final int MSG_SERVICE_CONNECTED = 2; private final int MSG_SERVICE_DISCONNECTED = 3; private final int MSG_UNLOCK = 4; private final int MSG_CANCEL = 5; private final int MSG_REPORT_FAILED_ATTEMPT = 6; private final int MSG_EXPOSE_FALLBACK = 7; private final int MSG_POKE_WAKELOCK = 8; private final int MSG_SERVICE_CONNECTED = 0; private final int MSG_SERVICE_DISCONNECTED = 1; private final int MSG_UNLOCK = 2; private final int MSG_CANCEL = 3; private final int MSG_REPORT_FAILED_ATTEMPT = 4; private final int MSG_EXPOSE_FALLBACK = 5; private final int MSG_POKE_WAKELOCK = 6; // TODO: This was added for the purpose of adhering to what the biometric interface expects // the isRunning() function to return. However, it is probably not necessary to have both // mRunning and mServiceRunning. I'd just rather wait to change that logic. private volatile boolean mIsRunning = false; // Long enough to stay visible while the service starts // Short enough to not have to wait long for backup if service fails to start or crashes // The service can take a couple of seconds to start on the first try after boot private final int SERVICE_STARTUP_VIEW_TIMEOUT = 3000; // So the user has a consistent amount of time when brought to the backup method from Face // Unlock private final int BACKUP_LOCK_TIMEOUT = 5000; Loading Loading @@ -110,30 +103,11 @@ public class FaceUnlock implements BiometricSensorUnlock, Handler.Callback { } /** * Sets the Face Unlock view to visible, hiding it after the specified amount of time. If * timeoutMillis is 0, no hide is performed. Called on the UI thread. * Dismisses face unlock and goes to the backup lock */ public void show(long timeoutMillis) { if (DEBUG) Log.d(TAG, "show()"); if (mHandler.getLooper() != Looper.myLooper()) { Log.e(TAG, "show() called off of the UI thread"); } removeDisplayMessages(); if (timeoutMillis > 0) { mHandler.sendEmptyMessageDelayed(MSG_HIDE_FACE_UNLOCK_VIEW, timeoutMillis); } } /** * Hides the Face Unlock view. */ public void hide() { if (DEBUG) Log.d(TAG, "hide()"); // Removes any wakelock messages to make sure they don't cause the screen to turn back on. mHandler.removeMessages(MSG_POKE_WAKELOCK); // Remove messages to prevent a delayed show message from undo-ing the hide removeDisplayMessages(); mHandler.sendEmptyMessage(MSG_HIDE_FACE_UNLOCK_VIEW); public void stopAndShowBackup() { if (DEBUG) Log.d(TAG, "stopAndShowBackup()"); mHandler.sendEmptyMessage(MSG_CANCEL); } /** Loading @@ -151,10 +125,6 @@ public class FaceUnlock implements BiometricSensorUnlock, Handler.Callback { Log.w(TAG, "start() called when already running"); } // Show Face Unlock view, but only for a little bit so lockpattern will become visible if // Face Unlock fails to start or crashes // This must show before bind to guarantee that Face Unlock has a place to display show(SERVICE_STARTUP_VIEW_TIMEOUT); if (!mBoundToService) { Log.d(TAG, "Binding to Face Unlock service for user=" + mLockPatternUtils.getCurrentUser()); Loading Loading @@ -234,12 +204,6 @@ public class FaceUnlock implements BiometricSensorUnlock, Handler.Callback { */ public boolean handleMessage(Message msg) { switch (msg.what) { case MSG_SHOW_FACE_UNLOCK_VIEW: handleShowFaceUnlockView(); break; case MSG_HIDE_FACE_UNLOCK_VIEW: handleHideFaceUnlockView(); break; case MSG_SERVICE_CONNECTED: handleServiceConnected(); break; Loading Loading @@ -268,22 +232,6 @@ public class FaceUnlock implements BiometricSensorUnlock, Handler.Callback { return true; } /** * Sets the Face Unlock view to visible, thus covering the backup lock. */ void handleShowFaceUnlockView() { if (DEBUG) Log.d(TAG, "handleShowFaceUnlockView()"); // Not required } /** * Hide face unlock and show backup */ void handleHideFaceUnlockView() { if (DEBUG) Log.d(TAG, "handleHideFaceUnlockView()"); mKeyguardScreenCallback.showBackupSecurity(); } /** * Tells the service to start its UI via an AIDL interface. Called when the * onServiceConnected() callback is received. Loading Loading @@ -347,23 +295,21 @@ public class FaceUnlock implements BiometricSensorUnlock, Handler.Callback { } /** * Stops the Face Unlock service and tells the device to grant access to the user. Shows the * Face Unlock view to keep the backup lock covered while the device unlocks. * Stops the Face Unlock service and tells the device to grant access to the user. */ void handleUnlock() { if (DEBUG) Log.d(TAG, "handleUnlock()"); removeDisplayMessages(); stop(); mKeyguardScreenCallback.reportSuccessfulUnlockAttempt(); mKeyguardScreenCallback.dismiss(true); } /** * Stops the Face Unlock service and exposes the backup lock. * Stops the Face Unlock service and goes to the backup lock. */ void handleCancel() { if (DEBUG) Log.d(TAG, "handleCancel()"); mKeyguardScreenCallback.dismiss(false); mKeyguardScreenCallback.showBackupSecurity(); stop(); mKeyguardScreenCallback.userActivity(BACKUP_LOCK_TIMEOUT); } Loading Loading @@ -397,15 +343,6 @@ public class FaceUnlock implements BiometricSensorUnlock, Handler.Callback { } } /** * Removes show and hide messages from the message queue. Called to prevent delayed show/hide * messages from undoing a new message. */ private void removeDisplayMessages() { mHandler.removeMessages(MSG_SHOW_FACE_UNLOCK_VIEW); mHandler.removeMessages(MSG_HIDE_FACE_UNLOCK_VIEW); } /** * Implements service connection methods. */ Loading Loading @@ -508,7 +445,7 @@ public class FaceUnlock implements BiometricSensorUnlock, Handler.Callback { * Called when the Face Unlock service starts displaying the UI, indicating that the backup * unlock can be exposed because the Face Unlock service is now covering the backup with its * UI. **/ */ public void exposeFallback() { if (DEBUG) Log.d(TAG, "exposeFallback()"); mHandler.sendEmptyMessage(MSG_EXPOSE_FALLBACK); Loading
policy/src/com/android/internal/policy/impl/keyguard/KeyguardFaceUnlockView.java +24 −9 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.telephony.TelephonyManager; import android.util.AttributeSet; import android.util.Log; import android.view.View; import android.widget.ImageButton; import android.widget.LinearLayout; import com.android.internal.R; Loading @@ -29,11 +30,13 @@ import com.android.internal.widget.LockPatternUtils; public class KeyguardFaceUnlockView extends LinearLayout implements KeyguardSecurityView { private static final String TAG = "KeyguardFaceUnlockView"; private static final boolean DEBUG = false; private KeyguardSecurityCallback mKeyguardSecurityCallback; private LockPatternUtils mLockPatternUtils; private BiometricSensorUnlock mBiometricUnlock; private KeyguardNavigationManager mNavigationManager; private View mFaceUnlockAreaView; private ImageButton mCancelButton; public KeyguardFaceUnlockView(Context context) { this(context, null); Loading Loading @@ -70,25 +73,25 @@ public class KeyguardFaceUnlockView extends LinearLayout implements KeyguardSecu @Override public void onDetachedFromWindow() { if (DEBUG) Log.d(TAG, "onDetachedFromWindow()"); if (mBiometricUnlock != null) { mBiometricUnlock.hide(); mBiometricUnlock.stop(); mBiometricUnlock.stopAndShowBackup(); } } @Override public void onPause() { if (DEBUG) Log.d(TAG, "onPause()"); if (mBiometricUnlock != null) { mBiometricUnlock.hide(); mBiometricUnlock.stop(); mBiometricUnlock.stopAndShowBackup(); } KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mUpdateCallback); } @Override public void onResume() { if (DEBUG) Log.d(TAG, "onResume()"); maybeStartBiometricUnlock(); mBiometricUnlock.show(0); KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mUpdateCallback); } Loading @@ -112,6 +115,14 @@ public class KeyguardFaceUnlockView extends LinearLayout implements KeyguardSecu mFaceUnlockAreaView = findViewById(R.id.face_unlock_area_view); if (mFaceUnlockAreaView != null) { mBiometricUnlock = new FaceUnlock(mContext); mCancelButton = (ImageButton) findViewById(R.id.face_unlock_cancel_button); mCancelButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { mBiometricUnlock.stopAndShowBackup(); } }); } else { Log.w(TAG, "Couldn't find biometric unlock view"); } Loading @@ -123,17 +134,20 @@ public class KeyguardFaceUnlockView extends LinearLayout implements KeyguardSecu * unlock area. */ private void maybeStartBiometricUnlock() { if (DEBUG) Log.d(TAG, "maybeStartBiometricUnlock()"); if (mBiometricUnlock != null) { KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(mContext); final boolean backupIsTimedOut = ( monitor.getFailedUnlockAttempts() >= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT); if (monitor.getPhoneState() == TelephonyManager.CALL_STATE_IDLE // TODO: These max attempts checks are also checked in KeyguardSecurityModel so they // might not be necessary here anymore. if (monitor.getPhoneState() != TelephonyManager.CALL_STATE_RINGING && !monitor.getMaxBiometricUnlockAttemptsReached() && !backupIsTimedOut) { mBiometricUnlock.start(); } else { mBiometricUnlock.hide(); mBiometricUnlock.stopAndShowBackup(); } } } Loading @@ -142,14 +156,15 @@ public class KeyguardFaceUnlockView extends LinearLayout implements KeyguardSecu // We need to stop the biometric unlock when a phone call comes in @Override public void onPhoneStateChanged(int phoneState) { if (DEBUG) Log.d(TAG, "onPhoneStateChanged(" + phoneState + ")"); if (phoneState == TelephonyManager.CALL_STATE_RINGING) { mBiometricUnlock.stop(); mBiometricUnlock.hide(); mBiometricUnlock.stopAndShowBackup(); } } @Override public void onUserSwitched(int userId) { if (DEBUG) Log.d(TAG, "onUserSwitched(" + userId + ")"); if (mBiometricUnlock != null) { mBiometricUnlock.stop(); } Loading