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 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 46ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna // TODO: is mServiceRunning needed or can we just use mIsRunning or check if mService is null? 47ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna private boolean mServiceRunning = false; 48257f2ecc97d294e95b069547466d2054926d960fBrian Colonna // TODO: now that the code has been restructure to do almost all operations from a handler, this 49257f2ecc97d294e95b069547466d2054926d960fBrian Colonna // lock may no longer be necessary. 50ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna private final Object mServiceRunningLock = new Object(); 519431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private IFaceLockInterface mService; 529431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private boolean mBoundToService = false; 53ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna private View mFaceUnlockView; 549431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 559431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private Handler mHandler; 5661413b5ed215accd7b4f3eaf80edeab2f330aa49Danielle Millett private final int MSG_SERVICE_CONNECTED = 0; 5761413b5ed215accd7b4f3eaf80edeab2f330aa49Danielle Millett private final int MSG_SERVICE_DISCONNECTED = 1; 5861413b5ed215accd7b4f3eaf80edeab2f330aa49Danielle Millett private final int MSG_UNLOCK = 2; 5961413b5ed215accd7b4f3eaf80edeab2f330aa49Danielle Millett private final int MSG_CANCEL = 3; 6061413b5ed215accd7b4f3eaf80edeab2f330aa49Danielle Millett private final int MSG_REPORT_FAILED_ATTEMPT = 4; 61667b5d58b9e8b77221c87811c5c9aab1bfe44ffaBrian Colonna private final int MSG_POKE_WAKELOCK = 5; 629431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 63ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna // TODO: This was added for the purpose of adhering to what the biometric interface expects 64ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna // the isRunning() function to return. However, it is probably not necessary to have both 65ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna // mRunning and mServiceRunning. I'd just rather wait to change that logic. 66257f2ecc97d294e95b069547466d2054926d960fBrian Colonna private volatile boolean mIsRunning = false; 679431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 68ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna // So the user has a consistent amount of time when brought to the backup method from Face 69ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna // Unlock 709431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private final int BACKUP_LOCK_TIMEOUT = 5000; 719431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 72dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller KeyguardSecurityCallback mKeyguardScreenCallback; 739431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 74257f2ecc97d294e95b069547466d2054926d960fBrian Colonna /** 75257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Stores some of the structures that Face Unlock will need to access and creates the handler 76257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * will be used to execute messages on the UI thread. 77257f2ecc97d294e95b069547466d2054926d960fBrian Colonna */ 78000464ac012471d301c6e48a8228291519915e17Jim Miller public FaceUnlock(Context context) { 799431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mContext = context; 80dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mLockPatternUtils = new LockPatternUtils(context); 819431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mHandler = new Handler(this); 829431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 839431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 84000464ac012471d301c6e48a8228291519915e17Jim Miller public void setKeyguardCallback(KeyguardSecurityCallback keyguardScreenCallback) { 85000464ac012471d301c6e48a8228291519915e17Jim Miller mKeyguardScreenCallback = keyguardScreenCallback; 86000464ac012471d301c6e48a8228291519915e17Jim Miller } 87000464ac012471d301c6e48a8228291519915e17Jim Miller 88ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 89ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * Stores and displays the view that Face Unlock is allowed to draw within. 90ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * TODO: since the layout object will eventually be shared by multiple biometric unlock 91ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * methods, we will have to add our other views (background, cancel button) here. 92ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 93ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna public void initializeView(View biometricUnlockView) { 94257f2ecc97d294e95b069547466d2054926d960fBrian Colonna Log.d(TAG, "initializeView()"); 95ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna mFaceUnlockView = biometricUnlockView; 96ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna } 97ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna 98ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 99ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * Indicates whether Face Unlock is currently running. 100ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 1013223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna public boolean isRunning() { 102ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna return mIsRunning; 1033223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna } 1043223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna 105ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 10661413b5ed215accd7b4f3eaf80edeab2f330aa49Danielle Millett * Dismisses face unlock and goes to the backup lock 107ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 10861413b5ed215accd7b4f3eaf80edeab2f330aa49Danielle Millett public void stopAndShowBackup() { 10961413b5ed215accd7b4f3eaf80edeab2f330aa49Danielle Millett if (DEBUG) Log.d(TAG, "stopAndShowBackup()"); 11061413b5ed215accd7b4f3eaf80edeab2f330aa49Danielle Millett mHandler.sendEmptyMessage(MSG_CANCEL); 1113223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna } 1123223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna 113ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 114ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * Binds to the Face Unlock service. Face Unlock will be started when the bind completes. The 115257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Face Unlock view is displayed to hide the backup lock while the service is starting up. 11622001c1f96984655f7205ecbc93dd982c47b4e97Brian Colonna * Called on the UI thread. 117ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 118ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna public boolean start() { 119257f2ecc97d294e95b069547466d2054926d960fBrian Colonna if (DEBUG) Log.d(TAG, "start()"); 12022001c1f96984655f7205ecbc93dd982c47b4e97Brian Colonna if (mHandler.getLooper() != Looper.myLooper()) { 12122001c1f96984655f7205ecbc93dd982c47b4e97Brian Colonna Log.e(TAG, "start() called off of the UI thread"); 12222001c1f96984655f7205ecbc93dd982c47b4e97Brian Colonna } 12322001c1f96984655f7205ecbc93dd982c47b4e97Brian Colonna 124ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna if (mIsRunning) { 125ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna Log.w(TAG, "start() called when already running"); 126ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna } 127ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna 128ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna if (!mBoundToService) { 1294b4b954ddf34af51576441f0e3eca6d19150aadaAmith Yamasani Log.d(TAG, "Binding to Face Unlock service for user=" 1304b4b954ddf34af51576441f0e3eca6d19150aadaAmith Yamasani + mLockPatternUtils.getCurrentUser()); 13127b89e6658a0d233a53f5d7ca20dc57fec82d955Amith Yamasani mContext.bindServiceAsUser(new Intent(IFaceLockInterface.class.getName()), 132ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna mConnection, 133ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna Context.BIND_AUTO_CREATE, 13427b89e6658a0d233a53f5d7ca20dc57fec82d955Amith Yamasani new UserHandle(mLockPatternUtils.getCurrentUser())); 135ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna mBoundToService = true; 136ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna } else { 137ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna Log.w(TAG, "Attempt to bind to Face Unlock when already bound"); 138ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna } 139ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna 140ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna mIsRunning = true; 141ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna return true; 142ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna } 143ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna 144ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 14522001c1f96984655f7205ecbc93dd982c47b4e97Brian Colonna * Stops Face Unlock and unbinds from the service. Called on the UI thread. 146ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 1473223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna public boolean stop() { 148257f2ecc97d294e95b069547466d2054926d960fBrian Colonna if (DEBUG) Log.d(TAG, "stop()"); 14922001c1f96984655f7205ecbc93dd982c47b4e97Brian Colonna if (mHandler.getLooper() != Looper.myLooper()) { 150a71984f3da47c6e6e3164c170735362a3222d3adJim Miller Log.e(TAG, "stop() called from non-UI thread"); 15122001c1f96984655f7205ecbc93dd982c47b4e97Brian Colonna } 15222001c1f96984655f7205ecbc93dd982c47b4e97Brian Colonna 153025fb93e3e5518b7db5fec049d285cfb2d28a074Steven Ross // Clearing any old service connected messages. 154025fb93e3e5518b7db5fec049d285cfb2d28a074Steven Ross mHandler.removeMessages(MSG_SERVICE_CONNECTED); 155025fb93e3e5518b7db5fec049d285cfb2d28a074Steven Ross 156ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna boolean mWasRunning = mIsRunning; 1571108a2cb412b054cc9e4acc48182c46c45180c0cDanielle Millett 158c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna stopUi(); 159c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna 160c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna if (mBoundToService) { 161c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna if (mService != null) { 162c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna try { 163ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna mService.unregisterCallback(mFaceUnlockCallback); 164c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna } catch (RemoteException e) { 165c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna // Not much we can do 1663223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna } 1679431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 168257f2ecc97d294e95b069547466d2054926d960fBrian Colonna Log.d(TAG, "Unbinding from Face Unlock service"); 169c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna mContext.unbindService(mConnection); 170c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna mBoundToService = false; 171c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna } else { 172c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna // This is usually not an error when this happens. Sometimes we will tell it to 173c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna // unbind multiple times because it's called from both onWindowFocusChanged and 174c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna // onDetachedFromWindow. 175ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna if (DEBUG) Log.d(TAG, "Attempt to unbind from Face Unlock when not bound"); 1769431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 177ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna mIsRunning = false; 178ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna return mWasRunning; 1799431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 1809431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 1813223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna /** 182ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * Frees up resources used by Face Unlock and stops it if it is still running. 1833223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna */ 1843223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna public void cleanUp() { 185257f2ecc97d294e95b069547466d2054926d960fBrian Colonna if (DEBUG) Log.d(TAG, "cleanUp()"); 1863223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna if (mService != null) { 1873223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna try { 188ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna mService.unregisterCallback(mFaceUnlockCallback); 1893223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna } catch (RemoteException e) { 1903223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna // Not much we can do 1913223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna } 1923223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna stopUi(); 1933223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna mService = null; 1949431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 1953223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna } 1963223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna 197ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 198ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * Returns the Device Policy Manager quality for Face Unlock, which is BIOMETRIC_WEAK. 199ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 2003223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna public int getQuality() { 2013223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna return DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK; 2029431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 2039431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 204ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 205257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Handles messages such that everything happens on the UI thread in a deterministic order. 206257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Calls from the Face Unlock service come from binder threads. Calls from lockscreen typically 207257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * come from the UI thread. This makes sure there are no race conditions between those calls. 208ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 2099431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public boolean handleMessage(Message msg) { 2109431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna switch (msg.what) { 211257f2ecc97d294e95b069547466d2054926d960fBrian Colonna case MSG_SERVICE_CONNECTED: 212257f2ecc97d294e95b069547466d2054926d960fBrian Colonna handleServiceConnected(); 213257f2ecc97d294e95b069547466d2054926d960fBrian Colonna break; 214257f2ecc97d294e95b069547466d2054926d960fBrian Colonna case MSG_SERVICE_DISCONNECTED: 215257f2ecc97d294e95b069547466d2054926d960fBrian Colonna handleServiceDisconnected(); 216257f2ecc97d294e95b069547466d2054926d960fBrian Colonna break; 217257f2ecc97d294e95b069547466d2054926d960fBrian Colonna case MSG_UNLOCK: 2185eb83aa8965835f75b13a535eafe7f6311e4f790Brian Colonna handleUnlock(msg.arg1); 219257f2ecc97d294e95b069547466d2054926d960fBrian Colonna break; 220257f2ecc97d294e95b069547466d2054926d960fBrian Colonna case MSG_CANCEL: 221257f2ecc97d294e95b069547466d2054926d960fBrian Colonna handleCancel(); 222257f2ecc97d294e95b069547466d2054926d960fBrian Colonna break; 223257f2ecc97d294e95b069547466d2054926d960fBrian Colonna case MSG_REPORT_FAILED_ATTEMPT: 224257f2ecc97d294e95b069547466d2054926d960fBrian Colonna handleReportFailedAttempt(); 225257f2ecc97d294e95b069547466d2054926d960fBrian Colonna break; 226257f2ecc97d294e95b069547466d2054926d960fBrian Colonna case MSG_POKE_WAKELOCK: 227dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez handlePokeWakelock(msg.arg1); 228257f2ecc97d294e95b069547466d2054926d960fBrian Colonna break; 229257f2ecc97d294e95b069547466d2054926d960fBrian Colonna default: 230257f2ecc97d294e95b069547466d2054926d960fBrian Colonna Log.e(TAG, "Unhandled message"); 231257f2ecc97d294e95b069547466d2054926d960fBrian Colonna return false; 2329431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 2339431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna return true; 2349431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 2359431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 236ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 237257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Tells the service to start its UI via an AIDL interface. Called when the 238257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * onServiceConnected() callback is received. 239257f2ecc97d294e95b069547466d2054926d960fBrian Colonna */ 240257f2ecc97d294e95b069547466d2054926d960fBrian Colonna void handleServiceConnected() { 241c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna Log.d(TAG, "handleServiceConnected()"); 242c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna 243c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna // It is possible that an unbind has occurred in the time between the bind and when this 244c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna // function is reached. If an unbind has already occurred, proceeding on to call startUi() 245c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna // can result in a fatal error. Note that the onServiceConnected() callback is 246c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna // asynchronous, so this possibility would still exist if we executed this directly in 247c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna // onServiceConnected() rather than using a handler. 248c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna if (!mBoundToService) { 249c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna Log.d(TAG, "Dropping startUi() in handleServiceConnected() because no longer bound"); 250c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna return; 251c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna } 252c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna 253257f2ecc97d294e95b069547466d2054926d960fBrian Colonna try { 254257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mService.registerCallback(mFaceUnlockCallback); 255257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } catch (RemoteException e) { 256257f2ecc97d294e95b069547466d2054926d960fBrian Colonna Log.e(TAG, "Caught exception connecting to Face Unlock: " + e.toString()); 257257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mService = null; 258257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mBoundToService = false; 259257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mIsRunning = false; 260257f2ecc97d294e95b069547466d2054926d960fBrian Colonna return; 261257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } 262257f2ecc97d294e95b069547466d2054926d960fBrian Colonna 263257f2ecc97d294e95b069547466d2054926d960fBrian Colonna if (mFaceUnlockView != null) { 264257f2ecc97d294e95b069547466d2054926d960fBrian Colonna IBinder windowToken = mFaceUnlockView.getWindowToken(); 265257f2ecc97d294e95b069547466d2054926d960fBrian Colonna if (windowToken != null) { 266dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez // When switching between portrait and landscape view while Face Unlock is running, 267dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez // the screen will eventually go dark unless we poke the wakelock when Face Unlock 268dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez // is restarted. 269dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mKeyguardScreenCallback.userActivity(0); 270dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez 271257f2ecc97d294e95b069547466d2054926d960fBrian Colonna int[] position; 272257f2ecc97d294e95b069547466d2054926d960fBrian Colonna position = new int[2]; 273257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mFaceUnlockView.getLocationInWindow(position); 274257f2ecc97d294e95b069547466d2054926d960fBrian Colonna startUi(windowToken, position[0], position[1], mFaceUnlockView.getWidth(), 275257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mFaceUnlockView.getHeight()); 276257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } else { 277257f2ecc97d294e95b069547466d2054926d960fBrian Colonna Log.e(TAG, "windowToken is null in handleServiceConnected()"); 278257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } 279257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } 280257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } 281257f2ecc97d294e95b069547466d2054926d960fBrian Colonna 282257f2ecc97d294e95b069547466d2054926d960fBrian Colonna /** 283257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Called when the onServiceDisconnected() callback is received. This should not happen during 284257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * normal operation. It indicates an error has occurred. 285257f2ecc97d294e95b069547466d2054926d960fBrian Colonna */ 286257f2ecc97d294e95b069547466d2054926d960fBrian Colonna void handleServiceDisconnected() { 287257f2ecc97d294e95b069547466d2054926d960fBrian Colonna Log.e(TAG, "handleServiceDisconnected()"); 288257f2ecc97d294e95b069547466d2054926d960fBrian Colonna // TODO: this lock may no longer be needed now that everything is being called from a 289257f2ecc97d294e95b069547466d2054926d960fBrian Colonna // handler 290257f2ecc97d294e95b069547466d2054926d960fBrian Colonna synchronized (mServiceRunningLock) { 291257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mService = null; 292257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mServiceRunning = false; 293257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } 294257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mBoundToService = false; 295257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mIsRunning = false; 296257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } 297257f2ecc97d294e95b069547466d2054926d960fBrian Colonna 298257f2ecc97d294e95b069547466d2054926d960fBrian Colonna /** 29961413b5ed215accd7b4f3eaf80edeab2f330aa49Danielle Millett * Stops the Face Unlock service and tells the device to grant access to the user. 300257f2ecc97d294e95b069547466d2054926d960fBrian Colonna */ 3015eb83aa8965835f75b13a535eafe7f6311e4f790Brian Colonna void handleUnlock(int authenticatedUserId) { 302257f2ecc97d294e95b069547466d2054926d960fBrian Colonna if (DEBUG) Log.d(TAG, "handleUnlock()"); 303257f2ecc97d294e95b069547466d2054926d960fBrian Colonna stop(); 3045eb83aa8965835f75b13a535eafe7f6311e4f790Brian Colonna int currentUserId = mLockPatternUtils.getCurrentUser(); 3055eb83aa8965835f75b13a535eafe7f6311e4f790Brian Colonna if (authenticatedUserId == currentUserId) { 3065eb83aa8965835f75b13a535eafe7f6311e4f790Brian Colonna if (DEBUG) Log.d(TAG, "Unlocking for user " + authenticatedUserId); 3075eb83aa8965835f75b13a535eafe7f6311e4f790Brian Colonna mKeyguardScreenCallback.reportSuccessfulUnlockAttempt(); 3085eb83aa8965835f75b13a535eafe7f6311e4f790Brian Colonna mKeyguardScreenCallback.dismiss(true); 3095eb83aa8965835f75b13a535eafe7f6311e4f790Brian Colonna } else { 3105eb83aa8965835f75b13a535eafe7f6311e4f790Brian Colonna Log.d(TAG, "Ignoring unlock for authenticated user (" + authenticatedUserId + 3115eb83aa8965835f75b13a535eafe7f6311e4f790Brian Colonna ") because the current user is " + currentUserId); 3125eb83aa8965835f75b13a535eafe7f6311e4f790Brian Colonna } 313257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } 314257f2ecc97d294e95b069547466d2054926d960fBrian Colonna 315257f2ecc97d294e95b069547466d2054926d960fBrian Colonna /** 31661413b5ed215accd7b4f3eaf80edeab2f330aa49Danielle Millett * Stops the Face Unlock service and goes to the backup lock. 317257f2ecc97d294e95b069547466d2054926d960fBrian Colonna */ 318257f2ecc97d294e95b069547466d2054926d960fBrian Colonna void handleCancel() { 319257f2ecc97d294e95b069547466d2054926d960fBrian Colonna if (DEBUG) Log.d(TAG, "handleCancel()"); 320667b5d58b9e8b77221c87811c5c9aab1bfe44ffaBrian Colonna // We are going to the backup method, so we don't want to see Face Unlock again until the 321667b5d58b9e8b77221c87811c5c9aab1bfe44ffaBrian Colonna // next time the user visits keyguard. 322667b5d58b9e8b77221c87811c5c9aab1bfe44ffaBrian Colonna KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(false); 323667b5d58b9e8b77221c87811c5c9aab1bfe44ffaBrian Colonna 32461413b5ed215accd7b4f3eaf80edeab2f330aa49Danielle Millett mKeyguardScreenCallback.showBackupSecurity(); 325257f2ecc97d294e95b069547466d2054926d960fBrian Colonna stop(); 326dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mKeyguardScreenCallback.userActivity(BACKUP_LOCK_TIMEOUT); 327257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } 328257f2ecc97d294e95b069547466d2054926d960fBrian Colonna 329257f2ecc97d294e95b069547466d2054926d960fBrian Colonna /** 3307019325e183ba1abf1869ccffc4b1ecd8c771a44Brian Colonna * Increments the number of failed Face Unlock attempts. 331257f2ecc97d294e95b069547466d2054926d960fBrian Colonna */ 332257f2ecc97d294e95b069547466d2054926d960fBrian Colonna void handleReportFailedAttempt() { 333257f2ecc97d294e95b069547466d2054926d960fBrian Colonna if (DEBUG) Log.d(TAG, "handleReportFailedAttempt()"); 334667b5d58b9e8b77221c87811c5c9aab1bfe44ffaBrian Colonna // We are going to the backup method, so we don't want to see Face Unlock again until the 335667b5d58b9e8b77221c87811c5c9aab1bfe44ffaBrian Colonna // next time the user visits keyguard. 336667b5d58b9e8b77221c87811c5c9aab1bfe44ffaBrian Colonna KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(false); 337257f2ecc97d294e95b069547466d2054926d960fBrian Colonna 338667b5d58b9e8b77221c87811c5c9aab1bfe44ffaBrian Colonna mKeyguardScreenCallback.reportFailedUnlockAttempt(); 339257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } 340257f2ecc97d294e95b069547466d2054926d960fBrian Colonna 341257f2ecc97d294e95b069547466d2054926d960fBrian Colonna /** 342acbe41fc1316cf16f03de80c84ea311cc4f55ffbSteven Ross * If the screen is on, pokes the wakelock to keep the screen alive and active for a specific 343acbe41fc1316cf16f03de80c84ea311cc4f55ffbSteven Ross * amount of time. 344257f2ecc97d294e95b069547466d2054926d960fBrian Colonna */ 345dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez void handlePokeWakelock(int millis) { 346acbe41fc1316cf16f03de80c84ea311cc4f55ffbSteven Ross PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); 347acbe41fc1316cf16f03de80c84ea311cc4f55ffbSteven Ross if (powerManager.isScreenOn()) { 348dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller mKeyguardScreenCallback.userActivity(millis); 349acbe41fc1316cf16f03de80c84ea311cc4f55ffbSteven Ross } 350257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } 351257f2ecc97d294e95b069547466d2054926d960fBrian Colonna 352257f2ecc97d294e95b069547466d2054926d960fBrian Colonna /** 353257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Implements service connection methods. 354257f2ecc97d294e95b069547466d2054926d960fBrian Colonna */ 3559431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private ServiceConnection mConnection = new ServiceConnection() { 356ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 357257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Called when the Face Unlock service connects after calling bind(). 358ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 3599431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public void onServiceConnected(ComponentName className, IBinder iservice) { 360257f2ecc97d294e95b069547466d2054926d960fBrian Colonna Log.d(TAG, "Connected to Face Unlock service"); 3619431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mService = IFaceLockInterface.Stub.asInterface(iservice); 362257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mHandler.sendEmptyMessage(MSG_SERVICE_CONNECTED); 3639431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 3649431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 365ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 366257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Called if the Face Unlock service unexpectedly disconnects. This indicates an error. 367ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 3689431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public void onServiceDisconnected(ComponentName className) { 369257f2ecc97d294e95b069547466d2054926d960fBrian Colonna Log.e(TAG, "Unexpected disconnect from Face Unlock service"); 370257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mHandler.sendEmptyMessage(MSG_SERVICE_DISCONNECTED); 3719431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 3729431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna }; 3739431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 374ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 375257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Tells the Face Unlock service to start displaying its UI and start processing. 376ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 3773223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna private void startUi(IBinder windowToken, int x, int y, int w, int h) { 378c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna if (DEBUG) Log.d(TAG, "startUi()"); 379c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna synchronized (mServiceRunningLock) { 380c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna if (!mServiceRunning) { 381c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna Log.d(TAG, "Starting Face Unlock"); 382c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna try { 3834fa995a932d876b98c393c909c4eb2e303783e59Uriel Rodriguez mService.startUi(windowToken, x, y, w, h, 3844fa995a932d876b98c393c909c4eb2e303783e59Uriel Rodriguez mLockPatternUtils.isBiometricWeakLivelinessEnabled()); 385c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna } catch (RemoteException e) { 386ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna Log.e(TAG, "Caught exception starting Face Unlock: " + e.toString()); 387c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna return; 3889431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 389c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna mServiceRunning = true; 390c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna } else { 391257f2ecc97d294e95b069547466d2054926d960fBrian Colonna Log.w(TAG, "startUi() attempted while running"); 3929431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 3939431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 3949431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 3959431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 396ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 397257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Tells the Face Unlock service to stop displaying its UI and stop processing. 398ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 3993223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna private void stopUi() { 400257f2ecc97d294e95b069547466d2054926d960fBrian Colonna if (DEBUG) Log.d(TAG, "stopUi()"); 401ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna // Note that attempting to stop Face Unlock when it's not running is not an issue. 402ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna // Face Unlock can return, which stops it and then we try to stop it when the 403c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna // screen is turned off. That's why we check. 404c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna synchronized (mServiceRunningLock) { 405c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna if (mServiceRunning) { 406c266070aec3d99c9a4d422325fbceae44c37a4d3Brian Colonna Log.d(TAG, "Stopping Face Unlock"); 407c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna try { 408c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna mService.stopUi(); 409c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna } catch (RemoteException e) { 410ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna Log.e(TAG, "Caught exception stopping Face Unlock: " + e.toString()); 4119431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 412c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna mServiceRunning = false; 413257f2ecc97d294e95b069547466d2054926d960fBrian Colonna } else { 414257f2ecc97d294e95b069547466d2054926d960fBrian Colonna // This is usually not an error when this happens. Sometimes we will tell it to 415257f2ecc97d294e95b069547466d2054926d960fBrian Colonna // stop multiple times because it's called from both onWindowFocusChanged and 416257f2ecc97d294e95b069547466d2054926d960fBrian Colonna // onDetachedFromWindow. 417257f2ecc97d294e95b069547466d2054926d960fBrian Colonna if (DEBUG) Log.d(TAG, "stopUi() attempted while not running"); 4189431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 4199431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 4209431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 4219431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 422ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 423257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Implements the AIDL biometric unlock service callback interface. 424ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 425ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna private final IFaceLockCallback mFaceUnlockCallback = new IFaceLockCallback.Stub() { 426ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 427257f2ecc97d294e95b069547466d2054926d960fBrian Colonna * Called when Face Unlock wants to grant access to the user. 428ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 4299431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public void unlock() { 430ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna if (DEBUG) Log.d(TAG, "unlock()"); 4315eb83aa8965835f75b13a535eafe7f6311e4f790Brian Colonna Message message = mHandler.obtainMessage(MSG_UNLOCK, UserHandle.getCallingUserId(), -1); 4325eb83aa8965835f75b13a535eafe7f6311e4f790Brian Colonna mHandler.sendMessage(message); 4339431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 4349431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 435ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 4367019325e183ba1abf1869ccffc4b1ecd8c771a44Brian Colonna * Called when Face Unlock wants to go to the backup. 437ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 4389431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public void cancel() { 439ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna if (DEBUG) Log.d(TAG, "cancel()"); 440257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mHandler.sendEmptyMessage(MSG_CANCEL); 4419431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 4429431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 443ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 4447019325e183ba1abf1869ccffc4b1ecd8c771a44Brian Colonna * Called when Face Unlock wants to increment the number of failed attempts. 445ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 4469431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public void reportFailedAttempt() { 447ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna if (DEBUG) Log.d(TAG, "reportFailedAttempt()"); 448257f2ecc97d294e95b069547466d2054926d960fBrian Colonna mHandler.sendEmptyMessage(MSG_REPORT_FAILED_ATTEMPT); 4499431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 4509431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 451ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 452dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez * Called when Face Unlock wants to keep the screen alive and active for a specific amount 453dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez * of time. 454ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 455dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez public void pokeWakelock(int millis) { 456dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez if (DEBUG) Log.d(TAG, "pokeWakelock() for " + millis + "ms"); 457dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez Message message = mHandler.obtainMessage(MSG_POKE_WAKELOCK, millis, -1); 458dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez mHandler.sendMessage(message); 4599431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 460dff307697d7a7482efe4c10cb3b07b9249524a42Uriel Rodriguez 4619431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna }; 4629431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna} 463