Skip to content

Commit 3223e25

Browse files
author
Brian Colonna
committed
Changed FUL calls to more general biometric sensor calls
This is another step toward fix 5460649 - cleanup LockPatternKeyguardView (LPKV). After this change, LPKV has minimal knowledge of FUL. FUL now implements a new BiometricSensorUnlock interface and LPKV talks to that interface. Other biometric sensors can implement the same interface such that LPKV doesn't need to know much about what type of biometric sensor is being used or its implementation. The new interface has better, more general function names, so some function names in FaceUnlock.java were changed. Some of the functions in FaceUnlock.java were also reordered to match the interface. This change should not change the behavior of FUL. There are two places where code functionality was changed: 1) There was a showArea() function and a showAreaWithTimeout() function that were both called from LPKV. To simplify the interface, only a show() function is provided - it takes a timeout and if the timeout is 0 it doesn't do the timeout. 2) There was a stopIfRunning() function that did a check to make sure FUL was running. If FUL was running, it stopped FUL. Then it returned a boolean indicating if it had been running. LPKV sometimes needs to know if FUL was running so it knows if it should restart FUL. To simplify the interface, a single stop() function is provided which returns whether or not it was running. I believe the 'if running' check was redundant and that there was no case where calling stop() when it wasn't running would cause any badness. Change-Id: I717268f360aed823e603df8e687cd107aa69ae11
1 parent 18ec7a9 commit 3223e25

File tree

3 files changed

+206
-150
lines changed

3 files changed

+206
-150
lines changed
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* Copyright (C) 2012 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.android.internal.policy.impl;
18+
19+
import android.view.View;
20+
21+
interface BiometricSensorUnlock {
22+
// Returns 'true' if the biometric sensor is available and is selected by user.
23+
public boolean installedAndSelected();
24+
25+
// Returns 'true' if the biometric sensor has started its unlock procedure but has not yet
26+
// accepted or rejected the user.
27+
public boolean isRunning();
28+
29+
// Show the interface, but don't start the unlock procedure. The interface should disappear
30+
// after the specified timeout. If the timeout is 0, the interface shows until another event,
31+
// such as calling hide(), causes it to disappear.
32+
public void show(long timeoutMilliseconds);
33+
34+
// Hide the interface, if any, exposing the lockscreen.
35+
public void hide();
36+
37+
// Stop the unlock procedure if running. Returns 'true' if it was in fact running.
38+
public boolean stop();
39+
40+
// Start the unlock procedure. Returns ‘false’ if it can’t be started or if the backup should
41+
// be used.
42+
public boolean start(boolean suppressBiometricUnlock);
43+
44+
// Provide a view to work within.
45+
public void initializeAreaView(View topView);
46+
47+
// Clean up any resources used by the biometric unlock.
48+
public void cleanUp();
49+
50+
// Returns the Device Policy Manager quality (e.g. PASSWORD_QUALITY_BIOMETRIC_WEAK).
51+
public int getQuality();
52+
}

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

Lines changed: 89 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import com.android.internal.policy.IFaceLockInterface;
2222
import com.android.internal.widget.LockPatternUtils;
2323

24+
import android.app.admin.DevicePolicyManager;
2425
import android.content.ComponentName;
2526
import android.content.Context;
2627
import android.content.Intent;
@@ -33,7 +34,7 @@
3334
import android.util.Log;
3435
import android.view.View;
3536

36-
public class FaceUnlock implements Handler.Callback {
37+
public class FaceUnlock implements BiometricSensorUnlock, Handler.Callback {
3738

3839
private static final boolean DEBUG = false;
3940
private static final String TAG = "FULLockscreen";
@@ -52,10 +53,6 @@ public class FaceUnlock implements Handler.Callback {
5253
private boolean mServiceRunning = false;
5354
private final Object mServiceRunningLock = new Object();
5455

55-
// Long enough to stay visible while dialer comes up
56-
// Short enough to not be visible if the user goes back immediately
57-
private final int VIEW_AREA_EMERGENCY_DIALER_TIMEOUT = 1000;
58-
5956
// Long enough to stay visible while the service starts
6057
// Short enough to not have to wait long for backup if service fails to start or crashes
6158
// The service can take a couple of seconds to start on the first try after boot
@@ -80,65 +77,97 @@ public FaceUnlock(Context context, KeyguardUpdateMonitor updateMonitor,
8077
mHandler = new Handler(this);
8178
}
8279

83-
public void cleanUp() {
84-
if (mService != null) {
85-
try {
86-
mService.unregisterCallback(mFaceLockCallback);
87-
} catch (RemoteException e) {
88-
// Not much we can do
80+
// Indicates whether FaceLock is in use
81+
public boolean installedAndSelected() {
82+
return (mLockPatternUtils.usingBiometricWeak() &&
83+
mLockPatternUtils.isBiometricWeakInstalled());
84+
}
85+
86+
public boolean isRunning() {
87+
return mServiceRunning;
88+
}
89+
90+
// Shows the FaceLock area for a period of time
91+
public void show(long timeoutMillis) {
92+
showArea();
93+
if (timeoutMillis > 0)
94+
mHandler.sendEmptyMessageDelayed(MSG_HIDE_AREA_VIEW, timeoutMillis);
95+
}
96+
97+
// Hides the FaceLock area immediately
98+
public void hide() {
99+
// Remove messages to prevent a delayed show message from undo-ing the hide
100+
removeAreaDisplayMessages();
101+
mHandler.sendEmptyMessage(MSG_HIDE_AREA_VIEW);
102+
}
103+
104+
// Tells FaceLock to stop and then unbinds from the FaceLock service
105+
public boolean stop() {
106+
boolean wasRunning = false;
107+
if (installedAndSelected()) {
108+
stopUi();
109+
110+
if (mBoundToService) {
111+
wasRunning = true;
112+
if (DEBUG) Log.d(TAG, "before unbind from FaceLock service");
113+
if (mService != null) {
114+
try {
115+
mService.unregisterCallback(mFaceLockCallback);
116+
} catch (RemoteException e) {
117+
// Not much we can do
118+
}
119+
}
120+
mContext.unbindService(mConnection);
121+
if (DEBUG) Log.d(TAG, "after unbind from FaceLock service");
122+
mBoundToService = false;
123+
} else {
124+
// This is usually not an error when this happens. Sometimes we will tell it to
125+
// unbind multiple times because it's called from both onWindowFocusChanged and
126+
// onDetachedFromWindow.
127+
if (DEBUG) Log.d(TAG, "Attempt to unbind from FaceLock when not bound");
89128
}
90-
stop();
91-
mService = null;
92129
}
130+
131+
return wasRunning;
93132
}
94133

95-
/** When screen is turned on and focused, need to bind to FaceLock service if we are using
96-
* FaceLock, but only if we're not dealing with a call
97-
*/
98-
public void activateIfAble(boolean hasOverlay) {
134+
/**
135+
* When screen is turned on and focused, need to bind to FaceLock service if we are using
136+
* FaceLock, but only if we're not dealing with a call
137+
*/
138+
public boolean start(boolean suppressBiometricUnlock) {
99139
final boolean tooManyFaceUnlockTries = mUpdateMonitor.getMaxFaceUnlockAttemptsReached();
100140
final int failedBackupAttempts = mUpdateMonitor.getFailedAttempts();
101141
final boolean backupIsTimedOut =
102142
(failedBackupAttempts >= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT);
103143
if (tooManyFaceUnlockTries) Log.i(TAG, "tooManyFaceUnlockTries: " + tooManyFaceUnlockTries);
104144
if (mUpdateMonitor.getPhoneState() == TelephonyManager.CALL_STATE_IDLE
105145
&& installedAndSelected()
106-
&& !hasOverlay
146+
&& !suppressBiometricUnlock
107147
&& !tooManyFaceUnlockTries
108148
&& !backupIsTimedOut) {
109149
bind();
110150

111151
// Show FaceLock area, but only for a little bit so lockpattern will become visible if
112152
// FaceLock fails to start or crashes
113-
showAreaWithTimeout(VIEW_AREA_SERVICE_TIMEOUT);
153+
show(VIEW_AREA_SERVICE_TIMEOUT);
114154

115155
// When switching between portrait and landscape view while FaceLock is running, the
116156
// screen will eventually go dark unless we poke the wakelock when FaceLock is
117157
// restarted
118158
mKeyguardScreenCallback.pokeWakelock();
119159
} else {
120-
hideArea();
160+
hide();
161+
return false;
121162
}
122-
}
123-
124-
public boolean isServiceRunning() {
125-
return mServiceRunning;
126-
}
127163

128-
public int viewAreaEmergencyDialerTimeout() {
129-
return VIEW_AREA_EMERGENCY_DIALER_TIMEOUT;
130-
}
131-
132-
// Indicates whether FaceLock is in use
133-
public boolean installedAndSelected() {
134-
return (mLockPatternUtils.usingBiometricWeak() &&
135-
mLockPatternUtils.isBiometricWeakInstalled());
164+
return true;
136165
}
137166

138167
// Takes care of FaceLock area when layout is created
139-
public void initializeAreaView(View view) {
168+
public void initializeAreaView(View topView) {
140169
if (installedAndSelected()) {
141-
mAreaView = view.findViewById(R.id.faceLockAreaView);
170+
mAreaView = topView.findViewById(R.id.faceLockAreaView);
142171
if (mAreaView == null) {
143172
Log.e(TAG, "Layout does not have areaView and FaceLock is enabled");
144173
}
@@ -147,13 +176,20 @@ public void initializeAreaView(View view) {
147176
}
148177
}
149178

150-
// Stops FaceLock if it is running and reports back whether it was running or not
151-
public boolean stopIfRunning() {
152-
if (installedAndSelected() && mBoundToService) {
153-
stopAndUnbind();
154-
return true;
179+
public void cleanUp() {
180+
if (mService != null) {
181+
try {
182+
mService.unregisterCallback(mFaceLockCallback);
183+
} catch (RemoteException e) {
184+
// Not much we can do
185+
}
186+
stopUi();
187+
mService = null;
155188
}
156-
return false;
189+
}
190+
191+
public int getQuality() {
192+
return DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK;
157193
}
158194

159195
// Handles covering or exposing FaceLock area on the client side when FaceLock starts or stops
@@ -186,28 +222,15 @@ private void removeAreaDisplayMessages() {
186222
}
187223

188224
// Shows the FaceLock area immediately
189-
public void showArea() {
225+
private void showArea() {
190226
// Remove messages to prevent a delayed hide message from undo-ing the show
191227
removeAreaDisplayMessages();
192228
mHandler.sendEmptyMessage(MSG_SHOW_AREA_VIEW);
193229
}
194230

195-
// Hides the FaceLock area immediately
196-
public void hideArea() {
197-
// Remove messages to prevent a delayed show message from undo-ing the hide
198-
removeAreaDisplayMessages();
199-
mHandler.sendEmptyMessage(MSG_HIDE_AREA_VIEW);
200-
}
201-
202-
// Shows the FaceLock area for a period of time
203-
public void showAreaWithTimeout(long timeoutMillis) {
204-
showArea();
205-
mHandler.sendEmptyMessageDelayed(MSG_HIDE_AREA_VIEW, timeoutMillis);
206-
}
207-
208231
// Binds to FaceLock service. This call does not tell it to start, but it causes the service
209232
// to call the onServiceConnected callback, which then starts FaceLock.
210-
public void bind() {
233+
private void bind() {
211234
if (installedAndSelected()) {
212235
if (!mBoundToService) {
213236
if (DEBUG) Log.d(TAG, "before bind to FaceLock service");
@@ -223,32 +246,6 @@ public void bind() {
223246
}
224247
}
225248

226-
// Tells FaceLock to stop and then unbinds from the FaceLock service
227-
public void stopAndUnbind() {
228-
if (installedAndSelected()) {
229-
stop();
230-
231-
if (mBoundToService) {
232-
if (DEBUG) Log.d(TAG, "before unbind from FaceLock service");
233-
if (mService != null) {
234-
try {
235-
mService.unregisterCallback(mFaceLockCallback);
236-
} catch (RemoteException e) {
237-
// Not much we can do
238-
}
239-
}
240-
mContext.unbindService(mConnection);
241-
if (DEBUG) Log.d(TAG, "after unbind from FaceLock service");
242-
mBoundToService = false;
243-
} else {
244-
// This is usually not an error when this happens. Sometimes we will tell it to
245-
// unbind multiple times because it's called from both onWindowFocusChanged and
246-
// onDetachedFromWindow.
247-
if (DEBUG) Log.d(TAG, "Attempt to unbind from FaceLock when not bound");
248-
}
249-
}
250-
}
251-
252249
private ServiceConnection mConnection = new ServiceConnection() {
253250
// Completes connection, registers callback and starts FaceLock when service is bound
254251
@Override
@@ -268,7 +265,7 @@ public void onServiceConnected(ComponentName className, IBinder iservice) {
268265
int[] position;
269266
position = new int[2];
270267
mAreaView.getLocationInWindow(position);
271-
start(mAreaView.getWindowToken(), position[0], position[1],
268+
startUi(mAreaView.getWindowToken(), position[0], position[1],
272269
mAreaView.getWidth(), mAreaView.getHeight());
273270
}
274271
}
@@ -286,7 +283,7 @@ public void onServiceDisconnected(ComponentName className) {
286283
};
287284

288285
// Tells the FaceLock service to start displaying its UI and perform recognition
289-
public void start(IBinder windowToken, int x, int y, int w, int h) {
286+
private void startUi(IBinder windowToken, int x, int y, int w, int h) {
290287
if (installedAndSelected()) {
291288
synchronized (mServiceRunningLock) {
292289
if (!mServiceRunning) {
@@ -300,14 +297,14 @@ public void start(IBinder windowToken, int x, int y, int w, int h) {
300297
}
301298
mServiceRunning = true;
302299
} else {
303-
if (DEBUG) Log.w(TAG, "start() attempted while running");
300+
if (DEBUG) Log.w(TAG, "startUi() attempted while running");
304301
}
305302
}
306303
}
307304
}
308305

309306
// Tells the FaceLock service to stop displaying its UI and stop recognition
310-
public void stop() {
307+
private void stopUi() {
311308
if (installedAndSelected()) {
312309
// Note that attempting to stop FaceLock when it's not running is not an issue.
313310
// FaceLock can return, which stops it and then we try to stop it when the
@@ -333,7 +330,7 @@ public void stop() {
333330
public void unlock() {
334331
if (DEBUG) Log.d(TAG, "FaceLock unlock()");
335332
showArea(); // Keep fallback covered
336-
stopAndUnbind();
333+
stop();
337334

338335
mKeyguardScreenCallback.keyguardDone(true);
339336
mKeyguardScreenCallback.reportSuccessfulUnlockAttempt();
@@ -344,8 +341,8 @@ public void unlock() {
344341
@Override
345342
public void cancel() {
346343
if (DEBUG) Log.d(TAG, "FaceLock cancel()");
347-
hideArea(); // Expose fallback
348-
stopAndUnbind();
344+
hide(); // Expose fallback
345+
stop();
349346
mKeyguardScreenCallback.pokeWakelock(BACKUP_LOCK_TIMEOUT);
350347
}
351348

@@ -355,16 +352,16 @@ public void cancel() {
355352
public void reportFailedAttempt() {
356353
if (DEBUG) Log.d(TAG, "FaceLock reportFailedAttempt()");
357354
mUpdateMonitor.reportFailedFaceUnlockAttempt();
358-
hideArea(); // Expose fallback
359-
stopAndUnbind();
355+
hide(); // Expose fallback
356+
stop();
360357
mKeyguardScreenCallback.pokeWakelock(BACKUP_LOCK_TIMEOUT);
361358
}
362359

363360
// Removes the black area that covers the backup unlock method
364361
@Override
365362
public void exposeFallback() {
366363
if (DEBUG) Log.d(TAG, "FaceLock exposeFallback()");
367-
hideArea(); // Expose fallback
364+
hide(); // Expose fallback
368365
}
369366

370367
// Allows the Face Unlock service to poke the wake lock to keep the lockscreen alive

0 commit comments

Comments
 (0)