FaceUnlock.java revision 4b4b954ddf34af51576441f0e3eca6d19150aada
19431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna/* 2dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller * Copyright (C) 2012 The Android Open Source Project 39431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna * 49431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna * Licensed under the Apache License, Version 2.0 (the "License"); 59431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna * you may not use this file except in compliance with the License. 69431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna * You may obtain a copy of the License at 79431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna * 89431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna * http://www.apache.org/licenses/LICENSE-2.0 99431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna * 109431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna * Unless required by applicable law or agreed to in writing, software 119431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna * distributed under the License is distributed on an "AS IS" BASIS, 129431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna * See the License for the specific language governing permissions and 149431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna * limitations under the License. 159431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna */ 169431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 17dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerpackage com.android.internal.policy.impl.keyguard; 189431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 199431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonnaimport com.android.internal.policy.IFaceLockCallback; 209431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonnaimport com.android.internal.policy.IFaceLockInterface; 219431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonnaimport com.android.internal.widget.LockPatternUtils; 229431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 233223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonnaimport android.app.admin.DevicePolicyManager; 249431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonnaimport android.content.ComponentName; 259431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonnaimport android.content.Context; 269431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonnaimport android.content.Intent; 279431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonnaimport android.content.ServiceConnection; 289431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonnaimport android.os.Handler; 299431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonnaimport android.os.IBinder; 3022001c1f96984655f7205ecbc93dd982c47b4e97Brian Colonnaimport android.os.Looper; 319431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonnaimport android.os.Message; 329431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonnaimport android.os.RemoteException; 339431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonnaimport android.util.Log; 349431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonnaimport android.view.View; 359431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 363223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonnapublic class FaceUnlock implements BiometricSensorUnlock, Handler.Callback { 379431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 389431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private static final boolean DEBUG = false; 399431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private static final String TAG = "FULLockscreen"; 409431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 419431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private final Context mContext; 42ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna private final LockPatternUtils mLockPatternUtils; 439431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 44ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna // TODO: is mServiceRunning needed or can we just use mIsRunning or check if mService is null? 45ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna private boolean mServiceRunning = false; 46257f2ecc97d294e95b069547466d2054926d960fBrian Colonna // TODO: now that the code has been restructure to do almost all operations from a handler, this 47257f2ecc97d294e95b069547466d2054926d960fBrian Colonna // lock may no longer be necessary. 48ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna private final Object mServiceRunningLock = new Object(); 499431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private IFaceLockInterface mService; 509431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private boolean mBoundToService = false; 51ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna private View mFaceUnlockView; 529431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 539431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private Handler mHandler; 54257f2ecc97d294e95b069547466d2054926d960fBrian Colonna private final int MSG_SHOW_FACE_UNLOCK_VIEW = 0; 55257f2ecc97d294e95b069547466d2054926d960fBrian Colonna private final int MSG_HIDE_FACE_UNLOCK_VIEW = 1; 56257f2ecc97d294e95b069547466d2054926d960fBrian Colonna private final int MSG_SERVICE_CONNECTED = 2; 57257f2ecc97d294e95b069547466d2054926d960fBrian Colonna private final int MSG_SERVICE_DISCONNECTED = 3; 58257f2ecc97d294e95b069547466d2054926d960fBrian Colonna private final int MSG_UNLOCK = 4; 59257f2ecc97d294e95b069547466d2054926d960fBrian Colonna private final int MSG_CANCEL = 5; 60257f2ecc97d294e95b069547466d2054926d960fBrian Colonna private final int MSG_REPORT_FAILED_ATTEMPT = 6; 61257f2ecc97d294e95b069547466d2054926d960fBrian Colonna private final int MSG_EXPOSE_FALLBACK = 7; 62257f2ecc97d294e95b069547466d2054926d960fBrian Colonna private final int MSG_POKE_WAKELOCK = 8; 639431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 64ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna // TODO: This was added for the purpose of adhering to what the biometric interface expects 65ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna // the isRunning() function to return. However, it is probably not necessary to have both 66ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna // mRunning and mServiceRunning. I'd just rather wait to change that logic. 67257f2ecc97d294e95b069547466d2054926d960fBrian Colonna private volatile boolean mIsRunning = false; 689431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 699431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // Long enough to stay visible while the service starts 709431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // Short enough to not have to wait long for backup if service fails to start or crashes 719431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // The service can take a couple of seconds to start on the first try after boot 72257f2ecc97d294e95b069547466d2054926d960fBrian Colonna private final int SERVICE_STARTUP_VIEW_TIMEOUT = 3000; 739431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 74ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna // So the user has a consistent amount of time when brought to the backup method from Face 75ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna // Unlock 769431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private final int BACKUP_LOCK_TIMEOUT = 5000; 779431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 78dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller KeyguardSecurityCallback mKeyguardScreenCallback; 799431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 80257f2ecc97d294e95b069547466d2054926d960fBrian Colonna /** 81257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Stores some of the structures that Face Unlock will need to access and creates the handler 82257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * will be used to execute messages on the UI thread. 83257f2ecc97d294e95b069547466d2054926d960fBrian Colonna */ 84000464ac012471d301c6e48a8228291519915e17Jim Miller public FaceUnlock(Context context) { 859431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mContext = context; 86dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mLockPatternUtils = new LockPatternUtils(context); 879431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mHandler = new Handler(this); 889431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 899431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 90000464ac012471d301c6e48a8228291519915e17Jim Miller public void setKeyguardCallback(KeyguardSecurityCallback keyguardScreenCallback) { 91000464ac012471d301c6e48a8228291519915e17Jim Miller mKeyguardScreenCallback = keyguardScreenCallback; 92000464ac012471d301c6e48a8228291519915e17Jim Miller } 93000464ac012471d301c6e48a8228291519915e17Jim Miller 94ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 95ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * Stores and displays the view that Face Unlock is allowed to draw within. 96ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * TODO: since the layout object will eventually be shared by multiple biometric unlock 97ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * methods, we will have to add our other views (background, cancel button) here. 98ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 99ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna public void initializeView(View biometricUnlockView) { 100257f2ecc97d294e95b069547466d2054926d960fBrian Colonna Log.d(TAG, "initializeView()"); 101ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna mFaceUnlockView = biometricUnlockView; 102ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna } 103ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna 104ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 105ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * Indicates whether Face Unlock is currently running. 106ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 1073223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna public boolean isRunning() { 108ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna return mIsRunning; 1093223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna } 1103223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna 111ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 112ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * Sets the Face Unlock view to visible, hiding it after the specified amount of time. If 11322001c1f96984655f7205ecbc93dd982c47b4e97Brian Colonna * timeoutMillis is 0, no hide is performed. Called on the UI thread. 114ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 1153223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna public void show(long timeoutMillis) { 116257f2ecc97d294e95b069547466d2054926d960fBrian Colonna if (DEBUG) Log.d(TAG, "show()"); 11722001c1f96984655f7205ecbc93dd982c47b4e97Brian Colonna if (mHandler.getLooper() != Looper.myLooper()) { 11822001c1f96984655f7205ecbc93dd982c47b4e97Brian Colonna Log.e(TAG, "show() called off of the UI thread"); 11922001c1f96984655f7205ecbc93dd982c47b4e97Brian Colonna } 120257f2ecc97d294e95b069547466d2054926d960fBrian Colonna removeDisplayMessages(); 121ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna if (timeoutMillis > 0) { 122257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mHandler.sendEmptyMessageDelayed(MSG_HIDE_FACE_UNLOCK_VIEW, timeoutMillis); 123ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna } 1243223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna } 1253223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna 126ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 127ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * Hides the Face Unlock view. 128ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 1293223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna public void hide() { 130257f2ecc97d294e95b069547466d2054926d960fBrian Colonna if (DEBUG) Log.d(TAG, "hide()"); 1313223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna // Remove messages to prevent a delayed show message from undo-ing the hide 132257f2ecc97d294e95b069547466d2054926d960fBrian Colonna removeDisplayMessages(); 133257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mHandler.sendEmptyMessage(MSG_HIDE_FACE_UNLOCK_VIEW); 1343223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna } 1353223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna 136ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 137ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * Binds to the Face Unlock service. Face Unlock will be started when the bind completes. The 138257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Face Unlock view is displayed to hide the backup lock while the service is starting up. 13922001c1f96984655f7205ecbc93dd982c47b4e97Brian Colonna * Called on the UI thread. 140ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 141ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna public boolean start() { 142257f2ecc97d294e95b069547466d2054926d960fBrian Colonna if (DEBUG) Log.d(TAG, "start()"); 14322001c1f96984655f7205ecbc93dd982c47b4e97Brian Colonna if (mHandler.getLooper() != Looper.myLooper()) { 14422001c1f96984655f7205ecbc93dd982c47b4e97Brian Colonna Log.e(TAG, "start() called off of the UI thread"); 14522001c1f96984655f7205ecbc93dd982c47b4e97Brian Colonna } 14622001c1f96984655f7205ecbc93dd982c47b4e97Brian Colonna 147ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna if (mIsRunning) { 148ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna Log.w(TAG, "start() called when already running"); 149ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna } 150ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna 151ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna // Show Face Unlock view, but only for a little bit so lockpattern will become visible if 152ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna // Face Unlock fails to start or crashes 153ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna // This must show before bind to guarantee that Face Unlock has a place to display 154257f2ecc97d294e95b069547466d2054926d960fBrian Colonna show(SERVICE_STARTUP_VIEW_TIMEOUT); 155ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna if (!mBoundToService) { 1564b4b954ddf34af51576441f0e3eca6d19150aadaAmith Yamasani Log.d(TAG, "Binding to Face Unlock service for user=" 1574b4b954ddf34af51576441f0e3eca6d19150aadaAmith Yamasani + mLockPatternUtils.getCurrentUser()); 158ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna mContext.bindService(new Intent(IFaceLockInterface.class.getName()), 159ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna mConnection, 160ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna Context.BIND_AUTO_CREATE, 161ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna mLockPatternUtils.getCurrentUser()); 162ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna mBoundToService = true; 163ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna } else { 164ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna Log.w(TAG, "Attempt to bind to Face Unlock when already bound"); 165ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna } 166ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna 167ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna mIsRunning = true; 168ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna return true; 169ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna } 170ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna 171ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 17222001c1f96984655f7205ecbc93dd982c47b4e97Brian Colonna * Stops Face Unlock and unbinds from the service. Called on the UI thread. 173ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 1743223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna public boolean stop() { 175257f2ecc97d294e95b069547466d2054926d960fBrian Colonna if (DEBUG) Log.d(TAG, "stop()"); 17622001c1f96984655f7205ecbc93dd982c47b4e97Brian Colonna if (mHandler.getLooper() != Looper.myLooper()) { 17722001c1f96984655f7205ecbc93dd982c47b4e97Brian Colonna Log.e(TAG, "stop() called off of the UI thread"); 17822001c1f96984655f7205ecbc93dd982c47b4e97Brian Colonna } 17922001c1f96984655f7205ecbc93dd982c47b4e97Brian Colonna 180ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna boolean mWasRunning = mIsRunning; 181c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna stopUi(); 182c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna 183c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna if (mBoundToService) { 184c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna if (mService != null) { 185c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna try { 186ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna mService.unregisterCallback(mFaceUnlockCallback); 187c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna } catch (RemoteException e) { 188c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna // Not much we can do 1893223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna } 1909431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 191257f2ecc97d294e95b069547466d2054926d960fBrian Colonna Log.d(TAG, "Unbinding from Face Unlock service"); 192c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna mContext.unbindService(mConnection); 193c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna mBoundToService = false; 194c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna } else { 195c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna // This is usually not an error when this happens. Sometimes we will tell it to 196c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna // unbind multiple times because it's called from both onWindowFocusChanged and 197c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna // onDetachedFromWindow. 198ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna if (DEBUG) Log.d(TAG, "Attempt to unbind from Face Unlock when not bound"); 1999431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 200ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna mIsRunning = false; 201ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna return mWasRunning; 2029431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 2039431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 2043223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna /** 205ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * Frees up resources used by Face Unlock and stops it if it is still running. 2063223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna */ 2073223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna public void cleanUp() { 208257f2ecc97d294e95b069547466d2054926d960fBrian Colonna if (DEBUG) Log.d(TAG, "cleanUp()"); 2093223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna if (mService != null) { 2103223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna try { 211ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna mService.unregisterCallback(mFaceUnlockCallback); 2123223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna } catch (RemoteException e) { 2133223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna // Not much we can do 2143223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna } 2153223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna stopUi(); 2163223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna mService = null; 2179431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 2183223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna } 2193223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna 220ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 221ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * Returns the Device Policy Manager quality for Face Unlock, which is BIOMETRIC_WEAK. 222ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 2233223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna public int getQuality() { 2243223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna return DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK; 2259431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 2269431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 227ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 228257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Handles messages such that everything happens on the UI thread in a deterministic order. 229257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Calls from the Face Unlock service come from binder threads. Calls from lockscreen typically 230257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * come from the UI thread. This makes sure there are no race conditions between those calls. 231ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 2329431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public boolean handleMessage(Message msg) { 2339431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna switch (msg.what) { 234257f2ecc97d294e95b069547466d2054926d960fBrian Colonna case MSG_SHOW_FACE_UNLOCK_VIEW: 235257f2ecc97d294e95b069547466d2054926d960fBrian Colonna handleShowFaceUnlockView(); 236257f2ecc97d294e95b069547466d2054926d960fBrian Colonna break; 237257f2ecc97d294e95b069547466d2054926d960fBrian Colonna case MSG_HIDE_FACE_UNLOCK_VIEW: 238257f2ecc97d294e95b069547466d2054926d960fBrian Colonna handleHideFaceUnlockView(); 239257f2ecc97d294e95b069547466d2054926d960fBrian Colonna break; 240257f2ecc97d294e95b069547466d2054926d960fBrian Colonna case MSG_SERVICE_CONNECTED: 241257f2ecc97d294e95b069547466d2054926d960fBrian Colonna handleServiceConnected(); 242257f2ecc97d294e95b069547466d2054926d960fBrian Colonna break; 243257f2ecc97d294e95b069547466d2054926d960fBrian Colonna case MSG_SERVICE_DISCONNECTED: 244257f2ecc97d294e95b069547466d2054926d960fBrian Colonna handleServiceDisconnected(); 245257f2ecc97d294e95b069547466d2054926d960fBrian Colonna break; 246257f2ecc97d294e95b069547466d2054926d960fBrian Colonna case MSG_UNLOCK: 247257f2ecc97d294e95b069547466d2054926d960fBrian Colonna handleUnlock(); 248257f2ecc97d294e95b069547466d2054926d960fBrian Colonna break; 249257f2ecc97d294e95b069547466d2054926d960fBrian Colonna case MSG_CANCEL: 250257f2ecc97d294e95b069547466d2054926d960fBrian Colonna handleCancel(); 251257f2ecc97d294e95b069547466d2054926d960fBrian Colonna break; 252257f2ecc97d294e95b069547466d2054926d960fBrian Colonna case MSG_REPORT_FAILED_ATTEMPT: 253257f2ecc97d294e95b069547466d2054926d960fBrian Colonna handleReportFailedAttempt(); 254257f2ecc97d294e95b069547466d2054926d960fBrian Colonna break; 255257f2ecc97d294e95b069547466d2054926d960fBrian Colonna case MSG_EXPOSE_FALLBACK: 256257f2ecc97d294e95b069547466d2054926d960fBrian Colonna handleExposeFallback(); 257257f2ecc97d294e95b069547466d2054926d960fBrian Colonna break; 258257f2ecc97d294e95b069547466d2054926d960fBrian Colonna case MSG_POKE_WAKELOCK: 259dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez handlePokeWakelock(msg.arg1); 260257f2ecc97d294e95b069547466d2054926d960fBrian Colonna break; 261257f2ecc97d294e95b069547466d2054926d960fBrian Colonna default: 262257f2ecc97d294e95b069547466d2054926d960fBrian Colonna Log.e(TAG, "Unhandled message"); 263257f2ecc97d294e95b069547466d2054926d960fBrian Colonna return false; 2649431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 2659431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna return true; 2669431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 2679431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 268ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 269257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Sets the Face Unlock view to visible, thus covering the backup lock. 270257f2ecc97d294e95b069547466d2054926d960fBrian Colonna */ 271257f2ecc97d294e95b069547466d2054926d960fBrian Colonna void handleShowFaceUnlockView() { 272257f2ecc97d294e95b069547466d2054926d960fBrian Colonna if (DEBUG) Log.d(TAG, "handleShowFaceUnlockView()"); 273000464ac012471d301c6e48a8228291519915e17Jim Miller // Not required 274257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } 275257f2ecc97d294e95b069547466d2054926d960fBrian Colonna 276257f2ecc97d294e95b069547466d2054926d960fBrian Colonna /** 277000464ac012471d301c6e48a8228291519915e17Jim Miller * Hide face unlock and show backup 278257f2ecc97d294e95b069547466d2054926d960fBrian Colonna */ 279257f2ecc97d294e95b069547466d2054926d960fBrian Colonna void handleHideFaceUnlockView() { 280257f2ecc97d294e95b069547466d2054926d960fBrian Colonna if (DEBUG) Log.d(TAG, "handleHideFaceUnlockView()"); 281000464ac012471d301c6e48a8228291519915e17Jim Miller mKeyguardScreenCallback.showBackupSecurity(); 282257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } 283257f2ecc97d294e95b069547466d2054926d960fBrian Colonna 284257f2ecc97d294e95b069547466d2054926d960fBrian Colonna /** 285257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Tells the service to start its UI via an AIDL interface. Called when the 286257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * onServiceConnected() callback is received. 287257f2ecc97d294e95b069547466d2054926d960fBrian Colonna */ 288257f2ecc97d294e95b069547466d2054926d960fBrian Colonna void handleServiceConnected() { 289c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna Log.d(TAG, "handleServiceConnected()"); 290c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna 291c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna // It is possible that an unbind has occurred in the time between the bind and when this 292c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna // function is reached. If an unbind has already occurred, proceeding on to call startUi() 293c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna // can result in a fatal error. Note that the onServiceConnected() callback is 294c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna // asynchronous, so this possibility would still exist if we executed this directly in 295c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna // onServiceConnected() rather than using a handler. 296c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna if (!mBoundToService) { 297c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna Log.d(TAG, "Dropping startUi() in handleServiceConnected() because no longer bound"); 298c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna return; 299c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna } 300c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna 301257f2ecc97d294e95b069547466d2054926d960fBrian Colonna try { 302257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mService.registerCallback(mFaceUnlockCallback); 303257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } catch (RemoteException e) { 304257f2ecc97d294e95b069547466d2054926d960fBrian Colonna Log.e(TAG, "Caught exception connecting to Face Unlock: " + e.toString()); 305257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mService = null; 306257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mBoundToService = false; 307257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mIsRunning = false; 308257f2ecc97d294e95b069547466d2054926d960fBrian Colonna return; 309257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } 310257f2ecc97d294e95b069547466d2054926d960fBrian Colonna 311257f2ecc97d294e95b069547466d2054926d960fBrian Colonna if (mFaceUnlockView != null) { 312257f2ecc97d294e95b069547466d2054926d960fBrian Colonna IBinder windowToken = mFaceUnlockView.getWindowToken(); 313257f2ecc97d294e95b069547466d2054926d960fBrian Colonna if (windowToken != null) { 314dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez // When switching between portrait and landscape view while Face Unlock is running, 315dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez // the screen will eventually go dark unless we poke the wakelock when Face Unlock 316dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez // is restarted. 317dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mKeyguardScreenCallback.userActivity(0); 318dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez 319257f2ecc97d294e95b069547466d2054926d960fBrian Colonna int[] position; 320257f2ecc97d294e95b069547466d2054926d960fBrian Colonna position = new int[2]; 321257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mFaceUnlockView.getLocationInWindow(position); 322257f2ecc97d294e95b069547466d2054926d960fBrian Colonna startUi(windowToken, position[0], position[1], mFaceUnlockView.getWidth(), 323257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mFaceUnlockView.getHeight()); 324257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } else { 325257f2ecc97d294e95b069547466d2054926d960fBrian Colonna Log.e(TAG, "windowToken is null in handleServiceConnected()"); 326257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } 327257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } 328257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } 329257f2ecc97d294e95b069547466d2054926d960fBrian Colonna 330257f2ecc97d294e95b069547466d2054926d960fBrian Colonna /** 331257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Called when the onServiceDisconnected() callback is received. This should not happen during 332257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * normal operation. It indicates an error has occurred. 333257f2ecc97d294e95b069547466d2054926d960fBrian Colonna */ 334257f2ecc97d294e95b069547466d2054926d960fBrian Colonna void handleServiceDisconnected() { 335257f2ecc97d294e95b069547466d2054926d960fBrian Colonna Log.e(TAG, "handleServiceDisconnected()"); 336257f2ecc97d294e95b069547466d2054926d960fBrian Colonna // TODO: this lock may no longer be needed now that everything is being called from a 337257f2ecc97d294e95b069547466d2054926d960fBrian Colonna // handler 338257f2ecc97d294e95b069547466d2054926d960fBrian Colonna synchronized (mServiceRunningLock) { 339257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mService = null; 340257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mServiceRunning = false; 341257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } 342257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mBoundToService = false; 343257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mIsRunning = false; 344257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } 345257f2ecc97d294e95b069547466d2054926d960fBrian Colonna 346257f2ecc97d294e95b069547466d2054926d960fBrian Colonna /** 347257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Stops the Face Unlock service and tells the device to grant access to the user. Shows the 348257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Face Unlock view to keep the backup lock covered while the device unlocks. 349257f2ecc97d294e95b069547466d2054926d960fBrian Colonna */ 350257f2ecc97d294e95b069547466d2054926d960fBrian Colonna void handleUnlock() { 351257f2ecc97d294e95b069547466d2054926d960fBrian Colonna if (DEBUG) Log.d(TAG, "handleUnlock()"); 352257f2ecc97d294e95b069547466d2054926d960fBrian Colonna removeDisplayMessages(); 353257f2ecc97d294e95b069547466d2054926d960fBrian Colonna stop(); 354257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mKeyguardScreenCallback.reportSuccessfulUnlockAttempt(); 355dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mKeyguardScreenCallback.dismiss(true); 356257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } 357257f2ecc97d294e95b069547466d2054926d960fBrian Colonna 358257f2ecc97d294e95b069547466d2054926d960fBrian Colonna /** 3597019325e183ba1abf1869ccffc4b1ecd8c771a44Brian Colonna * Stops the Face Unlock service and exposes the backup lock. 360257f2ecc97d294e95b069547466d2054926d960fBrian Colonna */ 361257f2ecc97d294e95b069547466d2054926d960fBrian Colonna void handleCancel() { 362257f2ecc97d294e95b069547466d2054926d960fBrian Colonna if (DEBUG) Log.d(TAG, "handleCancel()"); 363000464ac012471d301c6e48a8228291519915e17Jim Miller mKeyguardScreenCallback.dismiss(false); 364257f2ecc97d294e95b069547466d2054926d960fBrian Colonna stop(); 365dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mKeyguardScreenCallback.userActivity(BACKUP_LOCK_TIMEOUT); 366257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } 367257f2ecc97d294e95b069547466d2054926d960fBrian Colonna 368257f2ecc97d294e95b069547466d2054926d960fBrian Colonna /** 3697019325e183ba1abf1869ccffc4b1ecd8c771a44Brian Colonna * Increments the number of failed Face Unlock attempts. 370257f2ecc97d294e95b069547466d2054926d960fBrian Colonna */ 371257f2ecc97d294e95b069547466d2054926d960fBrian Colonna void handleReportFailedAttempt() { 372257f2ecc97d294e95b069547466d2054926d960fBrian Colonna if (DEBUG) Log.d(TAG, "handleReportFailedAttempt()"); 373dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mKeyguardScreenCallback.reportFailedUnlockAttempt(); 374257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } 375257f2ecc97d294e95b069547466d2054926d960fBrian Colonna 376257f2ecc97d294e95b069547466d2054926d960fBrian Colonna /** 377257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Hides the Face Unlock view to expose the backup lock. Called when the Face Unlock service UI 378257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * is started, indicating there is no need to continue displaying the underlying view because 379257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * the service UI is now covering the backup lock. 380257f2ecc97d294e95b069547466d2054926d960fBrian Colonna */ 381257f2ecc97d294e95b069547466d2054926d960fBrian Colonna void handleExposeFallback() { 382257f2ecc97d294e95b069547466d2054926d960fBrian Colonna if (DEBUG) Log.d(TAG, "handleExposeFallback()"); 383000464ac012471d301c6e48a8228291519915e17Jim Miller // No longer required because face unlock doesn't cover backup unlock. 384257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } 385257f2ecc97d294e95b069547466d2054926d960fBrian Colonna 386257f2ecc97d294e95b069547466d2054926d960fBrian Colonna /** 387dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez * Pokes the wakelock to keep the screen alive and active for a specific amount of time. 388257f2ecc97d294e95b069547466d2054926d960fBrian Colonna */ 389dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez void handlePokeWakelock(int millis) { 390dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mKeyguardScreenCallback.userActivity(millis); 391257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } 392257f2ecc97d294e95b069547466d2054926d960fBrian Colonna 393257f2ecc97d294e95b069547466d2054926d960fBrian Colonna /** 394257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Removes show and hide messages from the message queue. Called to prevent delayed show/hide 395257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * messages from undoing a new message. 396ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 397257f2ecc97d294e95b069547466d2054926d960fBrian Colonna private void removeDisplayMessages() { 398257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mHandler.removeMessages(MSG_SHOW_FACE_UNLOCK_VIEW); 399257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mHandler.removeMessages(MSG_HIDE_FACE_UNLOCK_VIEW); 4009431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 4019431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 402257f2ecc97d294e95b069547466d2054926d960fBrian Colonna /** 403257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Implements service connection methods. 404257f2ecc97d294e95b069547466d2054926d960fBrian Colonna */ 4059431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private ServiceConnection mConnection = new ServiceConnection() { 406ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 407257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Called when the Face Unlock service connects after calling bind(). 408ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 4099431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public void onServiceConnected(ComponentName className, IBinder iservice) { 410257f2ecc97d294e95b069547466d2054926d960fBrian Colonna Log.d(TAG, "Connected to Face Unlock service"); 4119431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mService = IFaceLockInterface.Stub.asInterface(iservice); 412257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mHandler.sendEmptyMessage(MSG_SERVICE_CONNECTED); 4139431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 4149431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 415ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 416257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Called if the Face Unlock service unexpectedly disconnects. This indicates an error. 417ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 4189431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public void onServiceDisconnected(ComponentName className) { 419257f2ecc97d294e95b069547466d2054926d960fBrian Colonna Log.e(TAG, "Unexpected disconnect from Face Unlock service"); 420257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mHandler.sendEmptyMessage(MSG_SERVICE_DISCONNECTED); 4219431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 4229431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna }; 4239431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 424ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 425257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Tells the Face Unlock service to start displaying its UI and start processing. 426ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 4273223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna private void startUi(IBinder windowToken, int x, int y, int w, int h) { 428c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna if (DEBUG) Log.d(TAG, "startUi()"); 429c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna synchronized (mServiceRunningLock) { 430c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna if (!mServiceRunning) { 431c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna Log.d(TAG, "Starting Face Unlock"); 432c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna try { 4334fa995a932d876b98c393c909c4eb2e303783e59Uriel Rodriguez mService.startUi(windowToken, x, y, w, h, 4344fa995a932d876b98c393c909c4eb2e303783e59Uriel Rodriguez mLockPatternUtils.isBiometricWeakLivelinessEnabled()); 435c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna } catch (RemoteException e) { 436ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna Log.e(TAG, "Caught exception starting Face Unlock: " + e.toString()); 437c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna return; 4389431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 439c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna mServiceRunning = true; 440c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna } else { 441257f2ecc97d294e95b069547466d2054926d960fBrian Colonna Log.w(TAG, "startUi() attempted while running"); 4429431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 4439431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 4449431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 4459431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 446ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 447257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Tells the Face Unlock service to stop displaying its UI and stop processing. 448ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 4493223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna private void stopUi() { 450257f2ecc97d294e95b069547466d2054926d960fBrian Colonna if (DEBUG) Log.d(TAG, "stopUi()"); 451ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna // Note that attempting to stop Face Unlock when it's not running is not an issue. 452ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna // Face Unlock can return, which stops it and then we try to stop it when the 453c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna // screen is turned off. That's why we check. 454c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna synchronized (mServiceRunningLock) { 455c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna if (mServiceRunning) { 456c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna Log.d(TAG, "Stopping Face Unlock"); 457c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna try { 458c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna mService.stopUi(); 459c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna } catch (RemoteException e) { 460ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna Log.e(TAG, "Caught exception stopping Face Unlock: " + e.toString()); 4619431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 462c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna mServiceRunning = false; 463257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } else { 464257f2ecc97d294e95b069547466d2054926d960fBrian Colonna // This is usually not an error when this happens. Sometimes we will tell it to 465257f2ecc97d294e95b069547466d2054926d960fBrian Colonna // stop multiple times because it's called from both onWindowFocusChanged and 466257f2ecc97d294e95b069547466d2054926d960fBrian Colonna // onDetachedFromWindow. 467257f2ecc97d294e95b069547466d2054926d960fBrian Colonna if (DEBUG) Log.d(TAG, "stopUi() attempted while not running"); 4689431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 4699431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 4709431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 4719431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 472ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 473257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Implements the AIDL biometric unlock service callback interface. 474ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 475ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna private final IFaceLockCallback mFaceUnlockCallback = new IFaceLockCallback.Stub() { 476ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 477257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Called when Face Unlock wants to grant access to the user. 478ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 4799431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public void unlock() { 480ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna if (DEBUG) Log.d(TAG, "unlock()"); 481257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mHandler.sendEmptyMessage(MSG_UNLOCK); 4829431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 4839431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 484ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 4857019325e183ba1abf1869ccffc4b1ecd8c771a44Brian Colonna * Called when Face Unlock wants to go to the backup. 486ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 4879431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public void cancel() { 488ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna if (DEBUG) Log.d(TAG, "cancel()"); 489257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mHandler.sendEmptyMessage(MSG_CANCEL); 4909431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 4919431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 492ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 4937019325e183ba1abf1869ccffc4b1ecd8c771a44Brian Colonna * Called when Face Unlock wants to increment the number of failed attempts. 494ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 4959431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public void reportFailedAttempt() { 496ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna if (DEBUG) Log.d(TAG, "reportFailedAttempt()"); 497257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mHandler.sendEmptyMessage(MSG_REPORT_FAILED_ATTEMPT); 4989431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 4999431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 500ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 501257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Called when the Face Unlock service starts displaying the UI, indicating that the backup 502257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * unlock can be exposed because the Face Unlock service is now covering the backup with its 503257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * UI. 504ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna **/ 5059431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public void exposeFallback() { 506ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna if (DEBUG) Log.d(TAG, "exposeFallback()"); 507257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mHandler.sendEmptyMessage(MSG_EXPOSE_FALLBACK); 5089431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 5099431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 510ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 511dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez * Called when Face Unlock wants to keep the screen alive and active for a specific amount 512dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez * of time. 513ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 514dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez public void pokeWakelock(int millis) { 515dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez if (DEBUG) Log.d(TAG, "pokeWakelock() for " + millis + "ms"); 516dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez Message message = mHandler.obtainMessage(MSG_POKE_WAKELOCK, millis, -1); 517dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez mHandler.sendMessage(message); 5189431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 519dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez 5209431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna }; 5219431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna} 522