FaceUnlock.java revision 5cf17879a31b7b78c09ec50b727f921840dcf783
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 175ecd81154fa039961f65bb4e36d18ac555b0d1d6Jim Millerpackage com.android.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; 32acbe41fc1316cf16f03de80c84ea311cc4f55ffbSteven Rossimport android.os.PowerManager; 339431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonnaimport android.os.RemoteException; 345eb83aa8965835f75b13a535eafe7f6311e4f790Brian Colonnaimport android.os.UserHandle; 359431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonnaimport android.util.Log; 369431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonnaimport android.view.View; 379431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 383223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonnapublic class FaceUnlock implements BiometricSensorUnlock, Handler.Callback { 399431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 405cf17879a31b7b78c09ec50b727f921840dcf783Jorim Jaggi private static final boolean DEBUG = KeyguardConstants.DEBUG; 419431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private static final String TAG = "FULLockscreen"; 425cf17879a31b7b78c09ec50b727f921840dcf783Jorim Jaggi private static final String FACE_LOCK_PACKAGE = "com.android.facelock"; 439431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 449431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private final Context mContext; 45ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna private final LockPatternUtils mLockPatternUtils; 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; 5761413b5ed215accd7b4f3eaf80edeab2f330aa49Danielle Millett private final int MSG_SERVICE_CONNECTED = 0; 5861413b5ed215accd7b4f3eaf80edeab2f330aa49Danielle Millett private final int MSG_SERVICE_DISCONNECTED = 1; 5961413b5ed215accd7b4f3eaf80edeab2f330aa49Danielle Millett private final int MSG_UNLOCK = 2; 6061413b5ed215accd7b4f3eaf80edeab2f330aa49Danielle Millett private final int MSG_CANCEL = 3; 6161413b5ed215accd7b4f3eaf80edeab2f330aa49Danielle Millett private final int MSG_REPORT_FAILED_ATTEMPT = 4; 62667b5d58b9e8b77221c87811c5c9aab1bfe44ffaBrian Colonna private final int MSG_POKE_WAKELOCK = 5; 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 69ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna // So the user has a consistent amount of time when brought to the backup method from Face 70ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna // Unlock 719431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private final int BACKUP_LOCK_TIMEOUT = 5000; 729431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 73dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller KeyguardSecurityCallback mKeyguardScreenCallback; 749431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 75257f2ecc97d294e95b069547466d2054926d960fBrian Colonna /** 76257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Stores some of the structures that Face Unlock will need to access and creates the handler 77257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * will be used to execute messages on the UI thread. 78257f2ecc97d294e95b069547466d2054926d960fBrian Colonna */ 79000464ac012471d301c6e48a8228291519915e17Jim Miller public FaceUnlock(Context context) { 809431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mContext = context; 81dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mLockPatternUtils = new LockPatternUtils(context); 829431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mHandler = new Handler(this); 839431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 849431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 85000464ac012471d301c6e48a8228291519915e17Jim Miller public void setKeyguardCallback(KeyguardSecurityCallback keyguardScreenCallback) { 86000464ac012471d301c6e48a8228291519915e17Jim Miller mKeyguardScreenCallback = keyguardScreenCallback; 87000464ac012471d301c6e48a8228291519915e17Jim Miller } 88000464ac012471d301c6e48a8228291519915e17Jim Miller 89ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 90ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * Stores and displays the view that Face Unlock is allowed to draw within. 91ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * TODO: since the layout object will eventually be shared by multiple biometric unlock 92ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * methods, we will have to add our other views (background, cancel button) here. 93ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 94ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna public void initializeView(View biometricUnlockView) { 95257f2ecc97d294e95b069547466d2054926d960fBrian Colonna Log.d(TAG, "initializeView()"); 96ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna mFaceUnlockView = biometricUnlockView; 97ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna } 98ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna 99ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 100ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * Indicates whether Face Unlock is currently running. 101ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 1023223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna public boolean isRunning() { 103ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna return mIsRunning; 1043223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna } 1053223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna 106ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 10761413b5ed215accd7b4f3eaf80edeab2f330aa49Danielle Millett * Dismisses face unlock and goes to the backup lock 108ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 10961413b5ed215accd7b4f3eaf80edeab2f330aa49Danielle Millett public void stopAndShowBackup() { 11061413b5ed215accd7b4f3eaf80edeab2f330aa49Danielle Millett if (DEBUG) Log.d(TAG, "stopAndShowBackup()"); 11161413b5ed215accd7b4f3eaf80edeab2f330aa49Danielle Millett mHandler.sendEmptyMessage(MSG_CANCEL); 1123223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna } 1133223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna 114ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 115ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * Binds to the Face Unlock service. Face Unlock will be started when the bind completes. The 116257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Face Unlock view is displayed to hide the backup lock while the service is starting up. 11722001c1f96984655f7205ecbc93dd982c47b4e97Brian Colonna * Called on the UI thread. 118ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 119ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna public boolean start() { 120257f2ecc97d294e95b069547466d2054926d960fBrian Colonna if (DEBUG) Log.d(TAG, "start()"); 12122001c1f96984655f7205ecbc93dd982c47b4e97Brian Colonna if (mHandler.getLooper() != Looper.myLooper()) { 12222001c1f96984655f7205ecbc93dd982c47b4e97Brian Colonna Log.e(TAG, "start() called off of the UI thread"); 12322001c1f96984655f7205ecbc93dd982c47b4e97Brian Colonna } 12422001c1f96984655f7205ecbc93dd982c47b4e97Brian Colonna 125ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna if (mIsRunning) { 126ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna Log.w(TAG, "start() called when already running"); 127ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna } 128ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna 129ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna if (!mBoundToService) { 1304b4b954ddf34af51576441f0e3eca6d19150aadaAmith Yamasani Log.d(TAG, "Binding to Face Unlock service for user=" 1314b4b954ddf34af51576441f0e3eca6d19150aadaAmith Yamasani + mLockPatternUtils.getCurrentUser()); 1325cf17879a31b7b78c09ec50b727f921840dcf783Jorim Jaggi mContext.bindServiceAsUser( 1335cf17879a31b7b78c09ec50b727f921840dcf783Jorim Jaggi new Intent(IFaceLockInterface.class.getName()).setPackage(FACE_LOCK_PACKAGE), 134ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna mConnection, 135ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna Context.BIND_AUTO_CREATE, 13627b89e6658a0d233a53f5d7ca20dc57fec82d955Amith Yamasani new UserHandle(mLockPatternUtils.getCurrentUser())); 137ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna mBoundToService = true; 138ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna } else { 139ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna Log.w(TAG, "Attempt to bind to Face Unlock when already bound"); 140ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna } 141ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna 142ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna mIsRunning = true; 143ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna return true; 144ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna } 145ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna 146ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 14722001c1f96984655f7205ecbc93dd982c47b4e97Brian Colonna * Stops Face Unlock and unbinds from the service. Called on the UI thread. 148ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 1493223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna public boolean stop() { 150257f2ecc97d294e95b069547466d2054926d960fBrian Colonna if (DEBUG) Log.d(TAG, "stop()"); 15122001c1f96984655f7205ecbc93dd982c47b4e97Brian Colonna if (mHandler.getLooper() != Looper.myLooper()) { 152a71984f3da47c6e6e3164c170735362a3222d3adJim Miller Log.e(TAG, "stop() called from non-UI thread"); 15322001c1f96984655f7205ecbc93dd982c47b4e97Brian Colonna } 15422001c1f96984655f7205ecbc93dd982c47b4e97Brian Colonna 155025fb93e3e5518b7db5fec049d285cfb2d28a074Steven Ross // Clearing any old service connected messages. 156025fb93e3e5518b7db5fec049d285cfb2d28a074Steven Ross mHandler.removeMessages(MSG_SERVICE_CONNECTED); 157025fb93e3e5518b7db5fec049d285cfb2d28a074Steven Ross 158ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna boolean mWasRunning = mIsRunning; 1591108a2cb412b054cc9e4acc48182c46c45180c0cDanielle Millett 160c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna stopUi(); 161c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna 162c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna if (mBoundToService) { 163c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna if (mService != null) { 164c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna try { 165ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna mService.unregisterCallback(mFaceUnlockCallback); 166c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna } catch (RemoteException e) { 167c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna // Not much we can do 1683223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna } 1699431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 170257f2ecc97d294e95b069547466d2054926d960fBrian Colonna Log.d(TAG, "Unbinding from Face Unlock service"); 171c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna mContext.unbindService(mConnection); 172c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna mBoundToService = false; 173c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna } else { 174c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna // This is usually not an error when this happens. Sometimes we will tell it to 175c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna // unbind multiple times because it's called from both onWindowFocusChanged and 176c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna // onDetachedFromWindow. 177ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna if (DEBUG) Log.d(TAG, "Attempt to unbind from Face Unlock when not bound"); 1789431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 179ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna mIsRunning = false; 180ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna return mWasRunning; 1819431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 1829431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 1833223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna /** 184ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * Frees up resources used by Face Unlock and stops it if it is still running. 1853223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna */ 1863223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna public void cleanUp() { 187257f2ecc97d294e95b069547466d2054926d960fBrian Colonna if (DEBUG) Log.d(TAG, "cleanUp()"); 1883223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna if (mService != null) { 1893223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna try { 190ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna mService.unregisterCallback(mFaceUnlockCallback); 1913223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna } catch (RemoteException e) { 1923223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna // Not much we can do 1933223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna } 1943223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna stopUi(); 1953223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna mService = null; 1969431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 1973223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna } 1983223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna 199ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 200ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * Returns the Device Policy Manager quality for Face Unlock, which is BIOMETRIC_WEAK. 201ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 2023223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna public int getQuality() { 2033223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna return DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK; 2049431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 2059431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 206ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 207257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Handles messages such that everything happens on the UI thread in a deterministic order. 208257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Calls from the Face Unlock service come from binder threads. Calls from lockscreen typically 209257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * come from the UI thread. This makes sure there are no race conditions between those calls. 210ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 2119431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public boolean handleMessage(Message msg) { 2129431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna switch (msg.what) { 213257f2ecc97d294e95b069547466d2054926d960fBrian Colonna case MSG_SERVICE_CONNECTED: 214257f2ecc97d294e95b069547466d2054926d960fBrian Colonna handleServiceConnected(); 215257f2ecc97d294e95b069547466d2054926d960fBrian Colonna break; 216257f2ecc97d294e95b069547466d2054926d960fBrian Colonna case MSG_SERVICE_DISCONNECTED: 217257f2ecc97d294e95b069547466d2054926d960fBrian Colonna handleServiceDisconnected(); 218257f2ecc97d294e95b069547466d2054926d960fBrian Colonna break; 219257f2ecc97d294e95b069547466d2054926d960fBrian Colonna case MSG_UNLOCK: 2205eb83aa8965835f75b13a535eafe7f6311e4f790Brian Colonna handleUnlock(msg.arg1); 221257f2ecc97d294e95b069547466d2054926d960fBrian Colonna break; 222257f2ecc97d294e95b069547466d2054926d960fBrian Colonna case MSG_CANCEL: 223257f2ecc97d294e95b069547466d2054926d960fBrian Colonna handleCancel(); 224257f2ecc97d294e95b069547466d2054926d960fBrian Colonna break; 225257f2ecc97d294e95b069547466d2054926d960fBrian Colonna case MSG_REPORT_FAILED_ATTEMPT: 226257f2ecc97d294e95b069547466d2054926d960fBrian Colonna handleReportFailedAttempt(); 227257f2ecc97d294e95b069547466d2054926d960fBrian Colonna break; 228257f2ecc97d294e95b069547466d2054926d960fBrian Colonna case MSG_POKE_WAKELOCK: 229dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez handlePokeWakelock(msg.arg1); 230257f2ecc97d294e95b069547466d2054926d960fBrian Colonna break; 231257f2ecc97d294e95b069547466d2054926d960fBrian Colonna default: 232257f2ecc97d294e95b069547466d2054926d960fBrian Colonna Log.e(TAG, "Unhandled message"); 233257f2ecc97d294e95b069547466d2054926d960fBrian Colonna return false; 2349431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 2359431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna return true; 2369431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 2379431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 238ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 239257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Tells the service to start its UI via an AIDL interface. Called when the 240257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * onServiceConnected() callback is received. 241257f2ecc97d294e95b069547466d2054926d960fBrian Colonna */ 242257f2ecc97d294e95b069547466d2054926d960fBrian Colonna void handleServiceConnected() { 243c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna Log.d(TAG, "handleServiceConnected()"); 244c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna 245c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna // It is possible that an unbind has occurred in the time between the bind and when this 246c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna // function is reached. If an unbind has already occurred, proceeding on to call startUi() 247c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna // can result in a fatal error. Note that the onServiceConnected() callback is 248c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna // asynchronous, so this possibility would still exist if we executed this directly in 249c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna // onServiceConnected() rather than using a handler. 250c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna if (!mBoundToService) { 251c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna Log.d(TAG, "Dropping startUi() in handleServiceConnected() because no longer bound"); 252c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna return; 253c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna } 254c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna 255257f2ecc97d294e95b069547466d2054926d960fBrian Colonna try { 256257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mService.registerCallback(mFaceUnlockCallback); 257257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } catch (RemoteException e) { 258257f2ecc97d294e95b069547466d2054926d960fBrian Colonna Log.e(TAG, "Caught exception connecting to Face Unlock: " + e.toString()); 259257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mService = null; 260257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mBoundToService = false; 261257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mIsRunning = false; 262257f2ecc97d294e95b069547466d2054926d960fBrian Colonna return; 263257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } 264257f2ecc97d294e95b069547466d2054926d960fBrian Colonna 265257f2ecc97d294e95b069547466d2054926d960fBrian Colonna if (mFaceUnlockView != null) { 266257f2ecc97d294e95b069547466d2054926d960fBrian Colonna IBinder windowToken = mFaceUnlockView.getWindowToken(); 267257f2ecc97d294e95b069547466d2054926d960fBrian Colonna if (windowToken != null) { 268dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez // When switching between portrait and landscape view while Face Unlock is running, 269dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez // the screen will eventually go dark unless we poke the wakelock when Face Unlock 270dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez // is restarted. 271dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mKeyguardScreenCallback.userActivity(0); 272dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez 273257f2ecc97d294e95b069547466d2054926d960fBrian Colonna int[] position; 274257f2ecc97d294e95b069547466d2054926d960fBrian Colonna position = new int[2]; 275257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mFaceUnlockView.getLocationInWindow(position); 276257f2ecc97d294e95b069547466d2054926d960fBrian Colonna startUi(windowToken, position[0], position[1], mFaceUnlockView.getWidth(), 277257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mFaceUnlockView.getHeight()); 278257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } else { 279257f2ecc97d294e95b069547466d2054926d960fBrian Colonna Log.e(TAG, "windowToken is null in handleServiceConnected()"); 280257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } 281257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } 282257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } 283257f2ecc97d294e95b069547466d2054926d960fBrian Colonna 284257f2ecc97d294e95b069547466d2054926d960fBrian Colonna /** 285257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Called when the onServiceDisconnected() callback is received. This should not happen during 286257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * normal operation. It indicates an error has occurred. 287257f2ecc97d294e95b069547466d2054926d960fBrian Colonna */ 288257f2ecc97d294e95b069547466d2054926d960fBrian Colonna void handleServiceDisconnected() { 289257f2ecc97d294e95b069547466d2054926d960fBrian Colonna Log.e(TAG, "handleServiceDisconnected()"); 290257f2ecc97d294e95b069547466d2054926d960fBrian Colonna // TODO: this lock may no longer be needed now that everything is being called from a 291257f2ecc97d294e95b069547466d2054926d960fBrian Colonna // handler 292257f2ecc97d294e95b069547466d2054926d960fBrian Colonna synchronized (mServiceRunningLock) { 293257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mService = null; 294257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mServiceRunning = false; 295257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } 296257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mBoundToService = false; 297257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mIsRunning = false; 298257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } 299257f2ecc97d294e95b069547466d2054926d960fBrian Colonna 300257f2ecc97d294e95b069547466d2054926d960fBrian Colonna /** 30161413b5ed215accd7b4f3eaf80edeab2f330aa49Danielle Millett * Stops the Face Unlock service and tells the device to grant access to the user. 302257f2ecc97d294e95b069547466d2054926d960fBrian Colonna */ 3035eb83aa8965835f75b13a535eafe7f6311e4f790Brian Colonna void handleUnlock(int authenticatedUserId) { 304257f2ecc97d294e95b069547466d2054926d960fBrian Colonna if (DEBUG) Log.d(TAG, "handleUnlock()"); 305257f2ecc97d294e95b069547466d2054926d960fBrian Colonna stop(); 3065eb83aa8965835f75b13a535eafe7f6311e4f790Brian Colonna int currentUserId = mLockPatternUtils.getCurrentUser(); 3075eb83aa8965835f75b13a535eafe7f6311e4f790Brian Colonna if (authenticatedUserId == currentUserId) { 3085eb83aa8965835f75b13a535eafe7f6311e4f790Brian Colonna if (DEBUG) Log.d(TAG, "Unlocking for user " + authenticatedUserId); 3097751ff6cd079e59e3c1f2404198774cd371ea69fJim Miller mKeyguardScreenCallback.reportUnlockAttempt(true); 3105eb83aa8965835f75b13a535eafe7f6311e4f790Brian Colonna mKeyguardScreenCallback.dismiss(true); 3115eb83aa8965835f75b13a535eafe7f6311e4f790Brian Colonna } else { 3125eb83aa8965835f75b13a535eafe7f6311e4f790Brian Colonna Log.d(TAG, "Ignoring unlock for authenticated user (" + authenticatedUserId + 3135eb83aa8965835f75b13a535eafe7f6311e4f790Brian Colonna ") because the current user is " + currentUserId); 3145eb83aa8965835f75b13a535eafe7f6311e4f790Brian Colonna } 315257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } 316257f2ecc97d294e95b069547466d2054926d960fBrian Colonna 317257f2ecc97d294e95b069547466d2054926d960fBrian Colonna /** 31861413b5ed215accd7b4f3eaf80edeab2f330aa49Danielle Millett * Stops the Face Unlock service and goes to the backup lock. 319257f2ecc97d294e95b069547466d2054926d960fBrian Colonna */ 320257f2ecc97d294e95b069547466d2054926d960fBrian Colonna void handleCancel() { 321257f2ecc97d294e95b069547466d2054926d960fBrian Colonna if (DEBUG) Log.d(TAG, "handleCancel()"); 322667b5d58b9e8b77221c87811c5c9aab1bfe44ffaBrian Colonna // We are going to the backup method, so we don't want to see Face Unlock again until the 323667b5d58b9e8b77221c87811c5c9aab1bfe44ffaBrian Colonna // next time the user visits keyguard. 324667b5d58b9e8b77221c87811c5c9aab1bfe44ffaBrian Colonna KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(false); 325667b5d58b9e8b77221c87811c5c9aab1bfe44ffaBrian Colonna 32661413b5ed215accd7b4f3eaf80edeab2f330aa49Danielle Millett mKeyguardScreenCallback.showBackupSecurity(); 327257f2ecc97d294e95b069547466d2054926d960fBrian Colonna stop(); 328dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mKeyguardScreenCallback.userActivity(BACKUP_LOCK_TIMEOUT); 329257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } 330257f2ecc97d294e95b069547466d2054926d960fBrian Colonna 331257f2ecc97d294e95b069547466d2054926d960fBrian Colonna /** 3327019325e183ba1abf1869ccffc4b1ecd8c771a44Brian Colonna * Increments the number of failed Face Unlock attempts. 333257f2ecc97d294e95b069547466d2054926d960fBrian Colonna */ 334257f2ecc97d294e95b069547466d2054926d960fBrian Colonna void handleReportFailedAttempt() { 335257f2ecc97d294e95b069547466d2054926d960fBrian Colonna if (DEBUG) Log.d(TAG, "handleReportFailedAttempt()"); 336667b5d58b9e8b77221c87811c5c9aab1bfe44ffaBrian Colonna // We are going to the backup method, so we don't want to see Face Unlock again until the 337667b5d58b9e8b77221c87811c5c9aab1bfe44ffaBrian Colonna // next time the user visits keyguard. 338667b5d58b9e8b77221c87811c5c9aab1bfe44ffaBrian Colonna KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(false); 339257f2ecc97d294e95b069547466d2054926d960fBrian Colonna 3407751ff6cd079e59e3c1f2404198774cd371ea69fJim Miller mKeyguardScreenCallback.reportUnlockAttempt(false); 341257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } 342257f2ecc97d294e95b069547466d2054926d960fBrian Colonna 343257f2ecc97d294e95b069547466d2054926d960fBrian Colonna /** 344acbe41fc1316cf16f03de80c84ea311cc4f55ffbSteven Ross * If the screen is on, pokes the wakelock to keep the screen alive and active for a specific 345acbe41fc1316cf16f03de80c84ea311cc4f55ffbSteven Ross * amount of time. 346257f2ecc97d294e95b069547466d2054926d960fBrian Colonna */ 347dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez void handlePokeWakelock(int millis) { 348acbe41fc1316cf16f03de80c84ea311cc4f55ffbSteven Ross PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); 349acbe41fc1316cf16f03de80c84ea311cc4f55ffbSteven Ross if (powerManager.isScreenOn()) { 350dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mKeyguardScreenCallback.userActivity(millis); 351acbe41fc1316cf16f03de80c84ea311cc4f55ffbSteven Ross } 352257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } 353257f2ecc97d294e95b069547466d2054926d960fBrian Colonna 354257f2ecc97d294e95b069547466d2054926d960fBrian Colonna /** 355257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Implements service connection methods. 356257f2ecc97d294e95b069547466d2054926d960fBrian Colonna */ 3579431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private ServiceConnection mConnection = new ServiceConnection() { 358ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 359257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Called when the Face Unlock service connects after calling bind(). 360ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 3619431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public void onServiceConnected(ComponentName className, IBinder iservice) { 362257f2ecc97d294e95b069547466d2054926d960fBrian Colonna Log.d(TAG, "Connected to Face Unlock service"); 3639431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mService = IFaceLockInterface.Stub.asInterface(iservice); 364257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mHandler.sendEmptyMessage(MSG_SERVICE_CONNECTED); 3659431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 3669431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 367ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 368257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Called if the Face Unlock service unexpectedly disconnects. This indicates an error. 369ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 3709431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public void onServiceDisconnected(ComponentName className) { 371257f2ecc97d294e95b069547466d2054926d960fBrian Colonna Log.e(TAG, "Unexpected disconnect from Face Unlock service"); 372257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mHandler.sendEmptyMessage(MSG_SERVICE_DISCONNECTED); 3739431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 3749431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna }; 3759431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 376ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 377257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Tells the Face Unlock service to start displaying its UI and start processing. 378ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 3793223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna private void startUi(IBinder windowToken, int x, int y, int w, int h) { 380c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna if (DEBUG) Log.d(TAG, "startUi()"); 381c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna synchronized (mServiceRunningLock) { 382c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna if (!mServiceRunning) { 383c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna Log.d(TAG, "Starting Face Unlock"); 384c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna try { 3854fa995a932d876b98c393c909c4eb2e303783e59Uriel Rodriguez mService.startUi(windowToken, x, y, w, h, 3864fa995a932d876b98c393c909c4eb2e303783e59Uriel Rodriguez mLockPatternUtils.isBiometricWeakLivelinessEnabled()); 387c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna } catch (RemoteException e) { 388ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna Log.e(TAG, "Caught exception starting Face Unlock: " + e.toString()); 389c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna return; 3909431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 391c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna mServiceRunning = true; 392c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna } else { 393257f2ecc97d294e95b069547466d2054926d960fBrian Colonna Log.w(TAG, "startUi() attempted while running"); 3949431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 3959431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 3969431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 3979431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 398ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 399257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Tells the Face Unlock service to stop displaying its UI and stop processing. 400ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 4013223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna private void stopUi() { 402257f2ecc97d294e95b069547466d2054926d960fBrian Colonna if (DEBUG) Log.d(TAG, "stopUi()"); 403ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna // Note that attempting to stop Face Unlock when it's not running is not an issue. 404ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna // Face Unlock can return, which stops it and then we try to stop it when the 405c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna // screen is turned off. That's why we check. 406c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna synchronized (mServiceRunningLock) { 407c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna if (mServiceRunning) { 408c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna Log.d(TAG, "Stopping Face Unlock"); 409c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna try { 410c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna mService.stopUi(); 411c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna } catch (RemoteException e) { 412ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna Log.e(TAG, "Caught exception stopping Face Unlock: " + e.toString()); 4139431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 414c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna mServiceRunning = false; 415257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } else { 416257f2ecc97d294e95b069547466d2054926d960fBrian Colonna // This is usually not an error when this happens. Sometimes we will tell it to 417257f2ecc97d294e95b069547466d2054926d960fBrian Colonna // stop multiple times because it's called from both onWindowFocusChanged and 418257f2ecc97d294e95b069547466d2054926d960fBrian Colonna // onDetachedFromWindow. 419257f2ecc97d294e95b069547466d2054926d960fBrian Colonna if (DEBUG) Log.d(TAG, "stopUi() attempted while not running"); 4209431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 4219431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 4229431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 4239431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 424ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 425257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Implements the AIDL biometric unlock service callback interface. 426ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 427ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna private final IFaceLockCallback mFaceUnlockCallback = new IFaceLockCallback.Stub() { 428ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 429257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Called when Face Unlock wants to grant access to the user. 430ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 4319431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public void unlock() { 432ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna if (DEBUG) Log.d(TAG, "unlock()"); 4335eb83aa8965835f75b13a535eafe7f6311e4f790Brian Colonna Message message = mHandler.obtainMessage(MSG_UNLOCK, UserHandle.getCallingUserId(), -1); 4345eb83aa8965835f75b13a535eafe7f6311e4f790Brian Colonna mHandler.sendMessage(message); 4359431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 4369431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 437ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 4387019325e183ba1abf1869ccffc4b1ecd8c771a44Brian Colonna * Called when Face Unlock wants to go to the backup. 439ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 4409431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public void cancel() { 441ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna if (DEBUG) Log.d(TAG, "cancel()"); 442257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mHandler.sendEmptyMessage(MSG_CANCEL); 4439431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 4449431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 445ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 4467019325e183ba1abf1869ccffc4b1ecd8c771a44Brian Colonna * Called when Face Unlock wants to increment the number of failed attempts. 447ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 4489431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public void reportFailedAttempt() { 449ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna if (DEBUG) Log.d(TAG, "reportFailedAttempt()"); 450257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mHandler.sendEmptyMessage(MSG_REPORT_FAILED_ATTEMPT); 4519431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 4529431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 453ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 454dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez * Called when Face Unlock wants to keep the screen alive and active for a specific amount 455dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez * of time. 456ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 457dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez public void pokeWakelock(int millis) { 458dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez if (DEBUG) Log.d(TAG, "pokeWakelock() for " + millis + "ms"); 459dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez Message message = mHandler.obtainMessage(MSG_POKE_WAKELOCK, millis, -1); 460dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez mHandler.sendMessage(message); 4619431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 462dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez 4639431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna }; 4649431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna} 465