FaceUnlock.java revision c266070aec3d99c9a4d422325fbceae44c37a4d3
19431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna/* 29431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna * Copyright (C) 2011 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 179431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonnapackage com.android.internal.policy.impl; 189431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 199431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonnaimport com.android.internal.R; 209431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonnaimport com.android.internal.policy.IFaceLockCallback; 219431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonnaimport com.android.internal.policy.IFaceLockInterface; 229431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonnaimport com.android.internal.widget.LockPatternUtils; 239431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 243223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonnaimport android.app.admin.DevicePolicyManager; 259431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonnaimport android.content.ComponentName; 269431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonnaimport android.content.Context; 279431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonnaimport android.content.Intent; 289431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonnaimport android.content.ServiceConnection; 299431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonnaimport android.os.Handler; 309431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonnaimport android.os.IBinder; 3122001c1f96984655f7205ecbc93dd982c47b4e97Brian Colonnaimport android.os.Looper; 329431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonnaimport android.os.Message; 339431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonnaimport android.os.RemoteException; 349431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonnaimport android.telephony.TelephonyManager; 359431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonnaimport android.util.Log; 369431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonnaimport android.view.View; 379431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 383223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonnapublic class FaceUnlock implements BiometricSensorUnlock, Handler.Callback { 399431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 409431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private static final boolean DEBUG = false; 419431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private static final String TAG = "FULLockscreen"; 429431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 439431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private final Context mContext; 44ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna private final LockPatternUtils mLockPatternUtils; 459431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private final KeyguardUpdateMonitor mUpdateMonitor; 469431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 47ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna // TODO: is mServiceRunning needed or can we just use mIsRunning or check if mService is null? 48ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna private boolean mServiceRunning = false; 49257f2ecc97d294e95b069547466d2054926d960fBrian Colonna // TODO: now that the code has been restructure to do almost all operations from a handler, this 50257f2ecc97d294e95b069547466d2054926d960fBrian Colonna // lock may no longer be necessary. 51ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna private final Object mServiceRunningLock = new Object(); 529431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private IFaceLockInterface mService; 539431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private boolean mBoundToService = false; 54ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna private View mFaceUnlockView; 559431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 569431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private Handler mHandler; 57257f2ecc97d294e95b069547466d2054926d960fBrian Colonna private final int MSG_SHOW_FACE_UNLOCK_VIEW = 0; 58257f2ecc97d294e95b069547466d2054926d960fBrian Colonna private final int MSG_HIDE_FACE_UNLOCK_VIEW = 1; 59257f2ecc97d294e95b069547466d2054926d960fBrian Colonna private final int MSG_SERVICE_CONNECTED = 2; 60257f2ecc97d294e95b069547466d2054926d960fBrian Colonna private final int MSG_SERVICE_DISCONNECTED = 3; 61257f2ecc97d294e95b069547466d2054926d960fBrian Colonna private final int MSG_UNLOCK = 4; 62257f2ecc97d294e95b069547466d2054926d960fBrian Colonna private final int MSG_CANCEL = 5; 63257f2ecc97d294e95b069547466d2054926d960fBrian Colonna private final int MSG_REPORT_FAILED_ATTEMPT = 6; 64257f2ecc97d294e95b069547466d2054926d960fBrian Colonna private final int MSG_EXPOSE_FALLBACK = 7; 65257f2ecc97d294e95b069547466d2054926d960fBrian Colonna private final int MSG_POKE_WAKELOCK = 8; 669431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 67ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna // TODO: This was added for the purpose of adhering to what the biometric interface expects 68ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna // the isRunning() function to return. However, it is probably not necessary to have both 69ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna // mRunning and mServiceRunning. I'd just rather wait to change that logic. 70257f2ecc97d294e95b069547466d2054926d960fBrian Colonna private volatile boolean mIsRunning = false; 719431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 729431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // Long enough to stay visible while the service starts 739431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // Short enough to not have to wait long for backup if service fails to start or crashes 749431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // The service can take a couple of seconds to start on the first try after boot 75257f2ecc97d294e95b069547466d2054926d960fBrian Colonna private final int SERVICE_STARTUP_VIEW_TIMEOUT = 3000; 769431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 77ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna // So the user has a consistent amount of time when brought to the backup method from Face 78ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna // Unlock 799431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private final int BACKUP_LOCK_TIMEOUT = 5000; 809431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 819431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna KeyguardScreenCallback mKeyguardScreenCallback; 829431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 83257f2ecc97d294e95b069547466d2054926d960fBrian Colonna /** 84257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Stores some of the structures that Face Unlock will need to access and creates the handler 85257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * will be used to execute messages on the UI thread. 86257f2ecc97d294e95b069547466d2054926d960fBrian Colonna */ 879431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public FaceUnlock(Context context, KeyguardUpdateMonitor updateMonitor, 889431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna LockPatternUtils lockPatternUtils, KeyguardScreenCallback keyguardScreenCallback) { 899431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mContext = context; 909431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mUpdateMonitor = updateMonitor; 919431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mLockPatternUtils = lockPatternUtils; 929431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mKeyguardScreenCallback = keyguardScreenCallback; 939431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mHandler = new Handler(this); 949431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 959431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 96ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 97ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * Stores and displays the view that Face Unlock is allowed to draw within. 98ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * TODO: since the layout object will eventually be shared by multiple biometric unlock 99ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * methods, we will have to add our other views (background, cancel button) here. 100ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 101ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna public void initializeView(View biometricUnlockView) { 102257f2ecc97d294e95b069547466d2054926d960fBrian Colonna Log.d(TAG, "initializeView()"); 103ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna mFaceUnlockView = biometricUnlockView; 104ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna } 105ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna 106ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 107ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * Indicates whether Face Unlock is currently running. 108ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 1093223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna public boolean isRunning() { 110ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna return mIsRunning; 1113223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna } 1123223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna 113ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 114ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * Sets the Face Unlock view to visible, hiding it after the specified amount of time. If 11522001c1f96984655f7205ecbc93dd982c47b4e97Brian Colonna * timeoutMillis is 0, no hide is performed. Called on the UI thread. 116ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 1173223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna public void show(long timeoutMillis) { 118257f2ecc97d294e95b069547466d2054926d960fBrian Colonna if (DEBUG) Log.d(TAG, "show()"); 11922001c1f96984655f7205ecbc93dd982c47b4e97Brian Colonna if (mHandler.getLooper() != Looper.myLooper()) { 12022001c1f96984655f7205ecbc93dd982c47b4e97Brian Colonna Log.e(TAG, "show() called off of the UI thread"); 12122001c1f96984655f7205ecbc93dd982c47b4e97Brian Colonna } 12222001c1f96984655f7205ecbc93dd982c47b4e97Brian Colonna 123257f2ecc97d294e95b069547466d2054926d960fBrian Colonna removeDisplayMessages(); 124ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna if (mFaceUnlockView != null) { 125ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna mFaceUnlockView.setVisibility(View.VISIBLE); 126ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna } 127ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna if (timeoutMillis > 0) { 128257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mHandler.sendEmptyMessageDelayed(MSG_HIDE_FACE_UNLOCK_VIEW, timeoutMillis); 129ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna } 1303223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna } 1313223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna 132ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 133ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * Hides the Face Unlock view. 134ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 1353223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna public void hide() { 136257f2ecc97d294e95b069547466d2054926d960fBrian Colonna if (DEBUG) Log.d(TAG, "hide()"); 1373223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna // Remove messages to prevent a delayed show message from undo-ing the hide 138257f2ecc97d294e95b069547466d2054926d960fBrian Colonna removeDisplayMessages(); 139257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mHandler.sendEmptyMessage(MSG_HIDE_FACE_UNLOCK_VIEW); 1403223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna } 1413223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna 142ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 143ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * Binds to the Face Unlock service. Face Unlock will be started when the bind completes. The 144257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Face Unlock view is displayed to hide the backup lock while the service is starting up. 14522001c1f96984655f7205ecbc93dd982c47b4e97Brian Colonna * Called on the UI thread. 146ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 147ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna public boolean start() { 148257f2ecc97d294e95b069547466d2054926d960fBrian Colonna if (DEBUG) Log.d(TAG, "start()"); 14922001c1f96984655f7205ecbc93dd982c47b4e97Brian Colonna if (mHandler.getLooper() != Looper.myLooper()) { 15022001c1f96984655f7205ecbc93dd982c47b4e97Brian Colonna Log.e(TAG, "start() called off of the UI thread"); 15122001c1f96984655f7205ecbc93dd982c47b4e97Brian Colonna } 15222001c1f96984655f7205ecbc93dd982c47b4e97Brian Colonna 153ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna if (mIsRunning) { 154ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna Log.w(TAG, "start() called when already running"); 155ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna } 156ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna 157ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna // Show Face Unlock view, but only for a little bit so lockpattern will become visible if 158ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna // Face Unlock fails to start or crashes 159ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna // This must show before bind to guarantee that Face Unlock has a place to display 160257f2ecc97d294e95b069547466d2054926d960fBrian Colonna show(SERVICE_STARTUP_VIEW_TIMEOUT); 161ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna if (!mBoundToService) { 162257f2ecc97d294e95b069547466d2054926d960fBrian Colonna Log.d(TAG, "Binding to Face Unlock service"); 163ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna mContext.bindService(new Intent(IFaceLockInterface.class.getName()), 164ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna mConnection, 165ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna Context.BIND_AUTO_CREATE, 166ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna mLockPatternUtils.getCurrentUser()); 167ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna mBoundToService = true; 168ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna } else { 169ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna Log.w(TAG, "Attempt to bind to Face Unlock when already bound"); 170ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna } 171ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna 172ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna mIsRunning = true; 173ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna return true; 174ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna } 175ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna 176ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 17722001c1f96984655f7205ecbc93dd982c47b4e97Brian Colonna * Stops Face Unlock and unbinds from the service. Called on the UI thread. 178ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 1793223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna public boolean stop() { 180257f2ecc97d294e95b069547466d2054926d960fBrian Colonna if (DEBUG) Log.d(TAG, "stop()"); 18122001c1f96984655f7205ecbc93dd982c47b4e97Brian Colonna if (mHandler.getLooper() != Looper.myLooper()) { 18222001c1f96984655f7205ecbc93dd982c47b4e97Brian Colonna Log.e(TAG, "stop() called off of the UI thread"); 18322001c1f96984655f7205ecbc93dd982c47b4e97Brian Colonna } 18422001c1f96984655f7205ecbc93dd982c47b4e97Brian Colonna 185ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna boolean mWasRunning = mIsRunning; 186c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna stopUi(); 187c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna 188c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna if (mBoundToService) { 189c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna if (mService != null) { 190c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna try { 191ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna mService.unregisterCallback(mFaceUnlockCallback); 192c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna } catch (RemoteException e) { 193c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna // Not much we can do 1943223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna } 1959431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 196257f2ecc97d294e95b069547466d2054926d960fBrian Colonna Log.d(TAG, "Unbinding from Face Unlock service"); 197c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna mContext.unbindService(mConnection); 198c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna mBoundToService = false; 199c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna } else { 200c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna // This is usually not an error when this happens. Sometimes we will tell it to 201c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna // unbind multiple times because it's called from both onWindowFocusChanged and 202c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna // onDetachedFromWindow. 203ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna if (DEBUG) Log.d(TAG, "Attempt to unbind from Face Unlock when not bound"); 2049431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 205ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna mIsRunning = false; 206ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna return mWasRunning; 2079431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 2089431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 2093223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna /** 210ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * Frees up resources used by Face Unlock and stops it if it is still running. 2113223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna */ 2123223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna public void cleanUp() { 213257f2ecc97d294e95b069547466d2054926d960fBrian Colonna if (DEBUG) Log.d(TAG, "cleanUp()"); 2143223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna if (mService != null) { 2153223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna try { 216ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna mService.unregisterCallback(mFaceUnlockCallback); 2173223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna } catch (RemoteException e) { 2183223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna // Not much we can do 2193223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna } 2203223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna stopUi(); 2213223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna mService = null; 2229431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 2233223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna } 2243223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna 225ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 226ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * Returns the Device Policy Manager quality for Face Unlock, which is BIOMETRIC_WEAK. 227ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 2283223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna public int getQuality() { 2293223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna return DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK; 2309431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 2319431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 232ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 233257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Handles messages such that everything happens on the UI thread in a deterministic order. 234257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Calls from the Face Unlock service come from binder threads. Calls from lockscreen typically 235257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * come from the UI thread. This makes sure there are no race conditions between those calls. 236ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 2379431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna @Override 2389431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public boolean handleMessage(Message msg) { 2399431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna switch (msg.what) { 240257f2ecc97d294e95b069547466d2054926d960fBrian Colonna case MSG_SHOW_FACE_UNLOCK_VIEW: 241257f2ecc97d294e95b069547466d2054926d960fBrian Colonna handleShowFaceUnlockView(); 242257f2ecc97d294e95b069547466d2054926d960fBrian Colonna break; 243257f2ecc97d294e95b069547466d2054926d960fBrian Colonna case MSG_HIDE_FACE_UNLOCK_VIEW: 244257f2ecc97d294e95b069547466d2054926d960fBrian Colonna handleHideFaceUnlockView(); 245257f2ecc97d294e95b069547466d2054926d960fBrian Colonna break; 246257f2ecc97d294e95b069547466d2054926d960fBrian Colonna case MSG_SERVICE_CONNECTED: 247257f2ecc97d294e95b069547466d2054926d960fBrian Colonna handleServiceConnected(); 248257f2ecc97d294e95b069547466d2054926d960fBrian Colonna break; 249257f2ecc97d294e95b069547466d2054926d960fBrian Colonna case MSG_SERVICE_DISCONNECTED: 250257f2ecc97d294e95b069547466d2054926d960fBrian Colonna handleServiceDisconnected(); 251257f2ecc97d294e95b069547466d2054926d960fBrian Colonna break; 252257f2ecc97d294e95b069547466d2054926d960fBrian Colonna case MSG_UNLOCK: 253257f2ecc97d294e95b069547466d2054926d960fBrian Colonna handleUnlock(); 254257f2ecc97d294e95b069547466d2054926d960fBrian Colonna break; 255257f2ecc97d294e95b069547466d2054926d960fBrian Colonna case MSG_CANCEL: 256257f2ecc97d294e95b069547466d2054926d960fBrian Colonna handleCancel(); 257257f2ecc97d294e95b069547466d2054926d960fBrian Colonna break; 258257f2ecc97d294e95b069547466d2054926d960fBrian Colonna case MSG_REPORT_FAILED_ATTEMPT: 259257f2ecc97d294e95b069547466d2054926d960fBrian Colonna handleReportFailedAttempt(); 260257f2ecc97d294e95b069547466d2054926d960fBrian Colonna break; 261257f2ecc97d294e95b069547466d2054926d960fBrian Colonna case MSG_EXPOSE_FALLBACK: 262257f2ecc97d294e95b069547466d2054926d960fBrian Colonna handleExposeFallback(); 263257f2ecc97d294e95b069547466d2054926d960fBrian Colonna break; 264257f2ecc97d294e95b069547466d2054926d960fBrian Colonna case MSG_POKE_WAKELOCK: 265dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez handlePokeWakelock(msg.arg1); 266257f2ecc97d294e95b069547466d2054926d960fBrian Colonna break; 267257f2ecc97d294e95b069547466d2054926d960fBrian Colonna default: 268257f2ecc97d294e95b069547466d2054926d960fBrian Colonna Log.e(TAG, "Unhandled message"); 269257f2ecc97d294e95b069547466d2054926d960fBrian Colonna return false; 2709431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 2719431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna return true; 2729431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 2739431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 274ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 275257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Sets the Face Unlock view to visible, thus covering the backup lock. 276257f2ecc97d294e95b069547466d2054926d960fBrian Colonna */ 277257f2ecc97d294e95b069547466d2054926d960fBrian Colonna void handleShowFaceUnlockView() { 278257f2ecc97d294e95b069547466d2054926d960fBrian Colonna if (DEBUG) Log.d(TAG, "handleShowFaceUnlockView()"); 279257f2ecc97d294e95b069547466d2054926d960fBrian Colonna if (mFaceUnlockView != null) { 280257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mFaceUnlockView.setVisibility(View.VISIBLE); 281257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } else { 282257f2ecc97d294e95b069547466d2054926d960fBrian Colonna Log.e(TAG, "mFaceUnlockView is null in handleShowFaceUnlockView()"); 283257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } 284257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } 285257f2ecc97d294e95b069547466d2054926d960fBrian Colonna 286257f2ecc97d294e95b069547466d2054926d960fBrian Colonna /** 287257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Sets the Face Unlock view to invisible, thus exposing the backup lock. 288257f2ecc97d294e95b069547466d2054926d960fBrian Colonna */ 289257f2ecc97d294e95b069547466d2054926d960fBrian Colonna void handleHideFaceUnlockView() { 290257f2ecc97d294e95b069547466d2054926d960fBrian Colonna if (DEBUG) Log.d(TAG, "handleHideFaceUnlockView()"); 291257f2ecc97d294e95b069547466d2054926d960fBrian Colonna if (mFaceUnlockView != null) { 292257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mFaceUnlockView.setVisibility(View.INVISIBLE); 293257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } else { 294257f2ecc97d294e95b069547466d2054926d960fBrian Colonna Log.e(TAG, "mFaceUnlockView is null in handleHideFaceUnlockView()"); 295257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } 296257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } 297257f2ecc97d294e95b069547466d2054926d960fBrian Colonna 298257f2ecc97d294e95b069547466d2054926d960fBrian Colonna /** 299257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Tells the service to start its UI via an AIDL interface. Called when the 300257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * onServiceConnected() callback is received. 301257f2ecc97d294e95b069547466d2054926d960fBrian Colonna */ 302257f2ecc97d294e95b069547466d2054926d960fBrian Colonna void handleServiceConnected() { 303c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna Log.d(TAG, "handleServiceConnected()"); 304c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna 305c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna // It is possible that an unbind has occurred in the time between the bind and when this 306c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna // function is reached. If an unbind has already occurred, proceeding on to call startUi() 307c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna // can result in a fatal error. Note that the onServiceConnected() callback is 308c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna // asynchronous, so this possibility would still exist if we executed this directly in 309c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna // onServiceConnected() rather than using a handler. 310c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna if (!mBoundToService) { 311c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna Log.d(TAG, "Dropping startUi() in handleServiceConnected() because no longer bound"); 312c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna return; 313c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna } 314c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna 315257f2ecc97d294e95b069547466d2054926d960fBrian Colonna try { 316257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mService.registerCallback(mFaceUnlockCallback); 317257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } catch (RemoteException e) { 318257f2ecc97d294e95b069547466d2054926d960fBrian Colonna Log.e(TAG, "Caught exception connecting to Face Unlock: " + e.toString()); 319257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mService = null; 320257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mBoundToService = false; 321257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mIsRunning = false; 322257f2ecc97d294e95b069547466d2054926d960fBrian Colonna return; 323257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } 324257f2ecc97d294e95b069547466d2054926d960fBrian Colonna 325257f2ecc97d294e95b069547466d2054926d960fBrian Colonna if (mFaceUnlockView != null) { 326257f2ecc97d294e95b069547466d2054926d960fBrian Colonna IBinder windowToken = mFaceUnlockView.getWindowToken(); 327257f2ecc97d294e95b069547466d2054926d960fBrian Colonna if (windowToken != null) { 328dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez // When switching between portrait and landscape view while Face Unlock is running, 329dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez // the screen will eventually go dark unless we poke the wakelock when Face Unlock 330dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez // is restarted. 331dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez mKeyguardScreenCallback.pokeWakelock(); 332dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez 333257f2ecc97d294e95b069547466d2054926d960fBrian Colonna int[] position; 334257f2ecc97d294e95b069547466d2054926d960fBrian Colonna position = new int[2]; 335257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mFaceUnlockView.getLocationInWindow(position); 336257f2ecc97d294e95b069547466d2054926d960fBrian Colonna startUi(windowToken, position[0], position[1], mFaceUnlockView.getWidth(), 337257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mFaceUnlockView.getHeight()); 338257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } else { 339257f2ecc97d294e95b069547466d2054926d960fBrian Colonna Log.e(TAG, "windowToken is null in handleServiceConnected()"); 340257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } 341257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } 342257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } 343257f2ecc97d294e95b069547466d2054926d960fBrian Colonna 344257f2ecc97d294e95b069547466d2054926d960fBrian Colonna /** 345257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Called when the onServiceDisconnected() callback is received. This should not happen during 346257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * normal operation. It indicates an error has occurred. 347257f2ecc97d294e95b069547466d2054926d960fBrian Colonna */ 348257f2ecc97d294e95b069547466d2054926d960fBrian Colonna void handleServiceDisconnected() { 349257f2ecc97d294e95b069547466d2054926d960fBrian Colonna Log.e(TAG, "handleServiceDisconnected()"); 350257f2ecc97d294e95b069547466d2054926d960fBrian Colonna // TODO: this lock may no longer be needed now that everything is being called from a 351257f2ecc97d294e95b069547466d2054926d960fBrian Colonna // handler 352257f2ecc97d294e95b069547466d2054926d960fBrian Colonna synchronized (mServiceRunningLock) { 353257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mService = null; 354257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mServiceRunning = false; 355257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } 356257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mBoundToService = false; 357257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mIsRunning = false; 358257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } 359257f2ecc97d294e95b069547466d2054926d960fBrian Colonna 360257f2ecc97d294e95b069547466d2054926d960fBrian Colonna /** 361257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Stops the Face Unlock service and tells the device to grant access to the user. Shows the 362257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Face Unlock view to keep the backup lock covered while the device unlocks. 363257f2ecc97d294e95b069547466d2054926d960fBrian Colonna */ 364257f2ecc97d294e95b069547466d2054926d960fBrian Colonna void handleUnlock() { 365257f2ecc97d294e95b069547466d2054926d960fBrian Colonna if (DEBUG) Log.d(TAG, "handleUnlock()"); 366257f2ecc97d294e95b069547466d2054926d960fBrian Colonna removeDisplayMessages(); 367257f2ecc97d294e95b069547466d2054926d960fBrian Colonna if (mFaceUnlockView != null) { 368257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mFaceUnlockView.setVisibility(View.VISIBLE); 369257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } else { 370257f2ecc97d294e95b069547466d2054926d960fBrian Colonna Log.e(TAG, "mFaceUnlockView is null in handleUnlock()"); 371257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } 372257f2ecc97d294e95b069547466d2054926d960fBrian Colonna stop(); 373257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mKeyguardScreenCallback.keyguardDone(true); 374257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mKeyguardScreenCallback.reportSuccessfulUnlockAttempt(); 375257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } 376257f2ecc97d294e95b069547466d2054926d960fBrian Colonna 377257f2ecc97d294e95b069547466d2054926d960fBrian Colonna /** 378257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Stops the Face Unlock service and exposes the backup lock. Called when the user presses the 379dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez * cancel button to skip Face Unlock, no face is detected or there is an error. 380257f2ecc97d294e95b069547466d2054926d960fBrian Colonna */ 381257f2ecc97d294e95b069547466d2054926d960fBrian Colonna void handleCancel() { 382257f2ecc97d294e95b069547466d2054926d960fBrian Colonna if (DEBUG) Log.d(TAG, "handleCancel()"); 383257f2ecc97d294e95b069547466d2054926d960fBrian Colonna if (mFaceUnlockView != null) { 384257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mFaceUnlockView.setVisibility(View.INVISIBLE); 385257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } else { 386257f2ecc97d294e95b069547466d2054926d960fBrian Colonna Log.e(TAG, "mFaceUnlockView is null in handleCancel()"); 387257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } 388257f2ecc97d294e95b069547466d2054926d960fBrian Colonna stop(); 389257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mKeyguardScreenCallback.pokeWakelock(BACKUP_LOCK_TIMEOUT); 390257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } 391257f2ecc97d294e95b069547466d2054926d960fBrian Colonna 392257f2ecc97d294e95b069547466d2054926d960fBrian Colonna /** 393257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Stops the Face Unlock service and exposes the backup lock, reporting a failed unlock attempt. 394257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Called when Face Unlock denies access to the user. 395257f2ecc97d294e95b069547466d2054926d960fBrian Colonna */ 396257f2ecc97d294e95b069547466d2054926d960fBrian Colonna void handleReportFailedAttempt() { 397257f2ecc97d294e95b069547466d2054926d960fBrian Colonna if (DEBUG) Log.d(TAG, "handleReportFailedAttempt()"); 398257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mUpdateMonitor.reportFailedBiometricUnlockAttempt(); 399257f2ecc97d294e95b069547466d2054926d960fBrian Colonna if (mFaceUnlockView != null) { 400257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mFaceUnlockView.setVisibility(View.INVISIBLE); 401257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } else { 402257f2ecc97d294e95b069547466d2054926d960fBrian Colonna Log.e(TAG, "mFaceUnlockView is null in handleReportFailedAttempt()"); 403257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } 404257f2ecc97d294e95b069547466d2054926d960fBrian Colonna stop(); 405257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mKeyguardScreenCallback.pokeWakelock(BACKUP_LOCK_TIMEOUT); 406257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } 407257f2ecc97d294e95b069547466d2054926d960fBrian Colonna 408257f2ecc97d294e95b069547466d2054926d960fBrian Colonna /** 409257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Hides the Face Unlock view to expose the backup lock. Called when the Face Unlock service UI 410257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * is started, indicating there is no need to continue displaying the underlying view because 411257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * the service UI is now covering the backup lock. 412257f2ecc97d294e95b069547466d2054926d960fBrian Colonna */ 413257f2ecc97d294e95b069547466d2054926d960fBrian Colonna void handleExposeFallback() { 414257f2ecc97d294e95b069547466d2054926d960fBrian Colonna if (DEBUG) Log.d(TAG, "handleExposeFallback()"); 415257f2ecc97d294e95b069547466d2054926d960fBrian Colonna if (mFaceUnlockView != null) { 416257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mFaceUnlockView.setVisibility(View.INVISIBLE); 417257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } else { 418257f2ecc97d294e95b069547466d2054926d960fBrian Colonna Log.e(TAG, "mFaceUnlockView is null in handleExposeFallback()"); 419257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } 420257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } 421257f2ecc97d294e95b069547466d2054926d960fBrian Colonna 422257f2ecc97d294e95b069547466d2054926d960fBrian Colonna /** 423dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez * Pokes the wakelock to keep the screen alive and active for a specific amount of time. 424257f2ecc97d294e95b069547466d2054926d960fBrian Colonna */ 425dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez void handlePokeWakelock(int millis) { 426dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez mKeyguardScreenCallback.pokeWakelock(millis); 427257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } 428257f2ecc97d294e95b069547466d2054926d960fBrian Colonna 429257f2ecc97d294e95b069547466d2054926d960fBrian Colonna /** 430257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Removes show and hide messages from the message queue. Called to prevent delayed show/hide 431257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * messages from undoing a new message. 432ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 433257f2ecc97d294e95b069547466d2054926d960fBrian Colonna private void removeDisplayMessages() { 434257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mHandler.removeMessages(MSG_SHOW_FACE_UNLOCK_VIEW); 435257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mHandler.removeMessages(MSG_HIDE_FACE_UNLOCK_VIEW); 4369431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 4379431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 438257f2ecc97d294e95b069547466d2054926d960fBrian Colonna /** 439257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Implements service connection methods. 440257f2ecc97d294e95b069547466d2054926d960fBrian Colonna */ 4419431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private ServiceConnection mConnection = new ServiceConnection() { 442ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 443257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Called when the Face Unlock service connects after calling bind(). 444ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 4459431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna @Override 4469431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public void onServiceConnected(ComponentName className, IBinder iservice) { 447257f2ecc97d294e95b069547466d2054926d960fBrian Colonna Log.d(TAG, "Connected to Face Unlock service"); 4489431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mService = IFaceLockInterface.Stub.asInterface(iservice); 449257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mHandler.sendEmptyMessage(MSG_SERVICE_CONNECTED); 4509431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 4519431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 452ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 453257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Called if the Face Unlock service unexpectedly disconnects. This indicates an error. 454ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 4559431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna @Override 4569431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public void onServiceDisconnected(ComponentName className) { 457257f2ecc97d294e95b069547466d2054926d960fBrian Colonna Log.e(TAG, "Unexpected disconnect from Face Unlock service"); 458257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mHandler.sendEmptyMessage(MSG_SERVICE_DISCONNECTED); 4599431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 4609431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna }; 4619431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 462ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 463257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Tells the Face Unlock service to start displaying its UI and start processing. 464ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 4653223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna private void startUi(IBinder windowToken, int x, int y, int w, int h) { 466c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna if (DEBUG) Log.d(TAG, "startUi()"); 467c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna synchronized (mServiceRunningLock) { 468c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna if (!mServiceRunning) { 469c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna Log.d(TAG, "Starting Face Unlock"); 470c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna try { 47146bbdec799002a33c5890f70225bef9f23fdef93Danielle Millett mService.startUi(windowToken, x, y, w, h, false); 472c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna } catch (RemoteException e) { 473ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna Log.e(TAG, "Caught exception starting Face Unlock: " + e.toString()); 474c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna return; 4759431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 476c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna mServiceRunning = true; 477c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna } else { 478257f2ecc97d294e95b069547466d2054926d960fBrian Colonna Log.w(TAG, "startUi() attempted while running"); 4799431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 4809431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 4819431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 4829431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 483ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 484257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Tells the Face Unlock service to stop displaying its UI and stop processing. 485ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 4863223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna private void stopUi() { 487257f2ecc97d294e95b069547466d2054926d960fBrian Colonna if (DEBUG) Log.d(TAG, "stopUi()"); 488ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna // Note that attempting to stop Face Unlock when it's not running is not an issue. 489ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna // Face Unlock can return, which stops it and then we try to stop it when the 490c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna // screen is turned off. That's why we check. 491c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna synchronized (mServiceRunningLock) { 492c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna if (mServiceRunning) { 493c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna Log.d(TAG, "Stopping Face Unlock"); 494c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna try { 495c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna mService.stopUi(); 496c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna } catch (RemoteException e) { 497ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna Log.e(TAG, "Caught exception stopping Face Unlock: " + e.toString()); 4989431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 499c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna mServiceRunning = false; 500257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } else { 501257f2ecc97d294e95b069547466d2054926d960fBrian Colonna // This is usually not an error when this happens. Sometimes we will tell it to 502257f2ecc97d294e95b069547466d2054926d960fBrian Colonna // stop multiple times because it's called from both onWindowFocusChanged and 503257f2ecc97d294e95b069547466d2054926d960fBrian Colonna // onDetachedFromWindow. 504257f2ecc97d294e95b069547466d2054926d960fBrian Colonna if (DEBUG) Log.d(TAG, "stopUi() attempted while not running"); 5059431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 5069431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 5079431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 5089431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 509ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 510257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Implements the AIDL biometric unlock service callback interface. 511ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 512ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna private final IFaceLockCallback mFaceUnlockCallback = new IFaceLockCallback.Stub() { 513ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 514257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Called when Face Unlock wants to grant access to the user. 515ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 5169431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna @Override 5179431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public void unlock() { 518ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna if (DEBUG) Log.d(TAG, "unlock()"); 519257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mHandler.sendEmptyMessage(MSG_UNLOCK); 5209431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 5219431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 522ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 523dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez * Called when the user presses cancel to skip Face Unlock, a face cannot be found or 524dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez * there is an error. 525ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 5269431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna @Override 5279431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public void cancel() { 528ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna if (DEBUG) Log.d(TAG, "cancel()"); 529257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mHandler.sendEmptyMessage(MSG_CANCEL); 5309431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 5319431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 532ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 533257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Called when Face Unlock denies access to the user. 534ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 5359431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna @Override 5369431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public void reportFailedAttempt() { 537ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna if (DEBUG) Log.d(TAG, "reportFailedAttempt()"); 538257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mHandler.sendEmptyMessage(MSG_REPORT_FAILED_ATTEMPT); 5399431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 5409431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 541ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 542257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Called when the Face Unlock service starts displaying the UI, indicating that the backup 543257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * unlock can be exposed because the Face Unlock service is now covering the backup with its 544257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * UI. 545ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna **/ 5469431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna @Override 5479431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public void exposeFallback() { 548ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna if (DEBUG) Log.d(TAG, "exposeFallback()"); 549257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mHandler.sendEmptyMessage(MSG_EXPOSE_FALLBACK); 5509431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 5519431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 552ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 553dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez * Called when Face Unlock wants to keep the screen alive and active for a specific amount 554dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez * of time. 555ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 556dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez public void pokeWakelock(int millis) { 557dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez if (DEBUG) Log.d(TAG, "pokeWakelock() for " + millis + "ms"); 558dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez Message message = mHandler.obtainMessage(MSG_POKE_WAKELOCK, millis, -1); 559dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez mHandler.sendMessage(message); 5609431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 561dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez 5629431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna }; 5639431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna} 564