Skip to content

Commit 6233fbe

Browse files
author
Brian Colonna
committed
Fix 5514230: preventing null window token from occurring
Sometimes the lockscreen view is recreated even though it has already been created (and therefore Face Unlock is already running). One example of this is when the lockscreen momentarily displays in landscape mode and then corrects itself into portrait mode. When lockscreen recreates itself, it removes the view and then later re-adds the view. During that time the window token is null and may be passed to Face Unlock when it tries to restart. The reason this doesn't happen *every* time the view is recreated is because the onServiceConnected() callback starts Face Unlock, and usually it runs after the view is re-added, but sometimes it runs before the view is re-added, resulting in this bug. An earlier fix put null-token checking inside of the Face Unlock service, which prevented crashing but Face Unlock was still unable to run. This fix makes the null token case not happen so Face Unlock can run every time. It accomplishes this by simply not restarting Face Unlock until the view has been re-added. This fix also replaces checking two flags everywhere to see if Face Unlock is being used and instead uses a single function call. Change-Id: Ib46f25f2a58ab2e70470337861c25ee81a858873
1 parent e4ca924 commit 6233fbe

File tree

1 file changed

+27
-27
lines changed

1 file changed

+27
-27
lines changed

policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -360,8 +360,7 @@ public void takeEmergencyCallAction() {
360360
mHasOverlay = true;
361361

362362
// Continue showing FaceLock area until dialer comes up or call is resumed
363-
if (mLockPatternUtils.usingBiometricWeak() &&
364-
mLockPatternUtils.isBiometricWeakInstalled() && mFaceLockServiceRunning) {
363+
if (usingFaceLock() && mFaceLockServiceRunning) {
365364
showFaceLockAreaWithTimeout(FACELOCK_VIEW_AREA_EMERGENCY_DIALER_TIMEOUT);
366365
}
367366

@@ -582,8 +581,7 @@ private void activateFaceLockIfAble() {
582581
bindToFaceLock();
583582
// Show FaceLock area, but only for a little bit so lockpattern will become visible if
584583
// FaceLock fails to start or crashes
585-
if (mLockPatternUtils.usingBiometricWeak() &&
586-
mLockPatternUtils.isBiometricWeakInstalled()) {
584+
if (usingFaceLock()) {
587585
showFaceLockAreaWithTimeout(FACELOCK_VIEW_AREA_SERVICE_TIMEOUT);
588586
}
589587
} else {
@@ -653,11 +651,10 @@ public void show() {
653651
((KeyguardScreen) mUnlockScreen).onResume();
654652
}
655653

656-
if (mLockPatternUtils.usingBiometricWeak() &&
657-
mLockPatternUtils.isBiometricWeakInstalled() && !mHasOverlay) {
654+
if (usingFaceLock() && !mHasOverlay) {
658655
// Note that show() gets called before the screen turns off to set it up for next time
659656
// it is turned on. We don't want to set a timeout on the FaceLock area here because it
660-
// may be gone by the time the screen is turned on again. We set the timout when the
657+
// may be gone by the time the screen is turned on again. We set the timeout when the
661658
// screen turns on instead.
662659
showFaceLockArea();
663660
} else {
@@ -854,7 +851,9 @@ private void updateScreen(Mode mode, boolean force) {
854851
if (mode == Mode.UnlockScreen) {
855852
final UnlockMode unlockMode = getUnlockMode();
856853
if (force || mUnlockScreen == null || unlockMode != mUnlockScreenMode) {
854+
boolean restartFaceLock = stopFaceLockIfRunning();
857855
recreateUnlockScreen(unlockMode);
856+
if (restartFaceLock) activateFaceLockIfAble();
858857
}
859858
}
860859

@@ -1147,28 +1146,33 @@ public int getMinimumHeight() {
11471146

11481147
// Everything below pertains to FaceLock - might want to separate this out
11491148

1150-
// Take care of FaceLock area when layout is created
1149+
// Indicates whether FaceLock is in use
1150+
private boolean usingFaceLock() {
1151+
return (mLockPatternUtils.usingBiometricWeak() &&
1152+
mLockPatternUtils.isBiometricWeakInstalled());
1153+
}
1154+
1155+
// Takes care of FaceLock area when layout is created
11511156
private void initializeFaceLockAreaView(View view) {
1152-
if (mLockPatternUtils.usingBiometricWeak() &&
1153-
mLockPatternUtils.isBiometricWeakInstalled()) {
1157+
if (usingFaceLock()) {
11541158
mFaceLockAreaView = view.findViewById(R.id.faceLockAreaView);
11551159
if (mFaceLockAreaView == null) {
11561160
Log.e(TAG, "Layout does not have faceLockAreaView and FaceLock is enabled");
1157-
} else {
1158-
if (mBoundToFaceLockService) {
1159-
// If we are creating a layout when we are already bound to FaceLock, then we
1160-
// are undergoing an orientation change. Stop FaceLock and restart it in the
1161-
// new location.
1162-
if (DEBUG) Log.d(TAG, "Restarting FL - creating view while already bound");
1163-
stopAndUnbindFromFaceLock();
1164-
activateFaceLockIfAble();
1165-
}
11661161
}
11671162
} else {
11681163
mFaceLockAreaView = null; // Set to null if not using FaceLock
11691164
}
11701165
}
11711166

1167+
// Stops FaceLock if it is running and reports back whether it was running or not
1168+
private boolean stopFaceLockIfRunning() {
1169+
if (usingFaceLock() && mBoundToFaceLockService) {
1170+
stopAndUnbindFromFaceLock();
1171+
return true;
1172+
}
1173+
return false;
1174+
}
1175+
11721176
// Handles covering or exposing FaceLock area on the client side when FaceLock starts or stops
11731177
// This needs to be done in a handler because the call could be coming from a callback from the
11741178
// FaceLock service that is in a thread that can't modify the UI
@@ -1221,8 +1225,7 @@ private void showFaceLockAreaWithTimeout(long timeoutMillis) {
12211225
// Binds to FaceLock service. This call does not tell it to start, but it causes the service
12221226
// to call the onServiceConnected callback, which then starts FaceLock.
12231227
public void bindToFaceLock() {
1224-
if (mLockPatternUtils.usingBiometricWeak() &&
1225-
mLockPatternUtils.isBiometricWeakInstalled()) {
1228+
if (usingFaceLock()) {
12261229
if (!mBoundToFaceLockService) {
12271230
if (DEBUG) Log.d(TAG, "before bind to FaceLock service");
12281231
mContext.bindService(new Intent(IFaceLockInterface.class.getName()),
@@ -1238,8 +1241,7 @@ public void bindToFaceLock() {
12381241

12391242
// Tells FaceLock to stop and then unbinds from the FaceLock service
12401243
public void stopAndUnbindFromFaceLock() {
1241-
if (mLockPatternUtils.usingBiometricWeak() &&
1242-
mLockPatternUtils.isBiometricWeakInstalled()) {
1244+
if (usingFaceLock()) {
12431245
stopFaceLock();
12441246

12451247
if (mBoundToFaceLockService) {
@@ -1300,8 +1302,7 @@ public void onServiceDisconnected(ComponentName className) {
13001302
// Tells the FaceLock service to start displaying its UI and perform recognition
13011303
public void startFaceLock(IBinder windowToken, int x, int y, int h, int w)
13021304
{
1303-
if (mLockPatternUtils.usingBiometricWeak() &&
1304-
mLockPatternUtils.isBiometricWeakInstalled()) {
1305+
if (usingFaceLock()) {
13051306
synchronized (mFaceLockServiceRunningLock) {
13061307
if (!mFaceLockServiceRunning) {
13071308
if (DEBUG) Log.d(TAG, "Starting FaceLock");
@@ -1322,8 +1323,7 @@ public void startFaceLock(IBinder windowToken, int x, int y, int h, int w)
13221323
// Tells the FaceLock service to stop displaying its UI and stop recognition
13231324
public void stopFaceLock()
13241325
{
1325-
if (mLockPatternUtils.usingBiometricWeak() &&
1326-
mLockPatternUtils.isBiometricWeakInstalled()) {
1326+
if (usingFaceLock()) {
13271327
// Note that attempting to stop FaceLock when it's not running is not an issue.
13281328
// FaceLock can return, which stops it and then we try to stop it when the
13291329
// screen is turned off. That's why we check.

0 commit comments

Comments
 (0)