FaceUnlock.java revision ea8441e22a4316cb6e78dd8bf461d3e658545b64
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; 319431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonnaimport android.os.Message; 329431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonnaimport android.os.RemoteException; 339431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonnaimport android.telephony.TelephonyManager; 349431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonnaimport android.util.Log; 359431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonnaimport android.view.View; 369431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 373223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonnapublic class FaceUnlock implements BiometricSensorUnlock, Handler.Callback { 389431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 399431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private static final boolean DEBUG = false; 409431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private static final String TAG = "FULLockscreen"; 419431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 429431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private final Context mContext; 43ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna private final LockPatternUtils mLockPatternUtils; 449431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private final KeyguardUpdateMonitor mUpdateMonitor; 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; 48ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna private final Object mServiceRunningLock = new Object(); 499431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private IFaceLockInterface mService; 509431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private boolean mBoundToService = false; 51ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna private View mFaceUnlockView; 529431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 539431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private Handler mHandler; 549431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private final int MSG_SHOW_AREA_VIEW = 0; 559431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private final int MSG_HIDE_AREA_VIEW = 1; 569431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 57ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna // TODO: This was added for the purpose of adhering to what the biometric interface expects 58ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna // the isRunning() function to return. However, it is probably not necessary to have both 59ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna // mRunning and mServiceRunning. I'd just rather wait to change that logic. 60ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna private boolean mIsRunning = false; 619431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 629431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // Long enough to stay visible while the service starts 639431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // Short enough to not have to wait long for backup if service fails to start or crashes 649431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // The service can take a couple of seconds to start on the first try after boot 659431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private final int VIEW_AREA_SERVICE_TIMEOUT = 3000; 669431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 67ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna // So the user has a consistent amount of time when brought to the backup method from Face 68ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna // Unlock 699431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private final int BACKUP_LOCK_TIMEOUT = 5000; 709431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 719431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 729431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna KeyguardScreenCallback mKeyguardScreenCallback; 739431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 749431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public FaceUnlock(Context context, KeyguardUpdateMonitor updateMonitor, 759431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna LockPatternUtils lockPatternUtils, KeyguardScreenCallback keyguardScreenCallback) { 769431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mContext = context; 779431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mUpdateMonitor = updateMonitor; 789431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mLockPatternUtils = lockPatternUtils; 799431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mKeyguardScreenCallback = keyguardScreenCallback; 809431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mHandler = new Handler(this); 819431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 829431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 83ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 84ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * Stores and displays the view that Face Unlock is allowed to draw within. 85ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * TODO: since the layout object will eventually be shared by multiple biometric unlock 86ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * methods, we will have to add our other views (background, cancel button) here. 87ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 88ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna public void initializeView(View biometricUnlockView) { 89ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna mFaceUnlockView = biometricUnlockView; 90ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna show(0); 91ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna } 92ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna 93ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 94ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * Indicates whether Face Unlock is currently running. 95ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 963223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna public boolean isRunning() { 97ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna return mIsRunning; 983223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna } 993223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna 100ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 101ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * Sets the Face Unlock view to visible, hiding it after the specified amount of time. If 102ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * timeoutMillis is 0, no hide is performed. 103ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 1043223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna public void show(long timeoutMillis) { 105fe444b48bac83bd5472b1102dae87661bafcfccbSteven Ross removeAreaDisplayMessages(); 106ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna if (mFaceUnlockView != null) { 107ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna mFaceUnlockView.setVisibility(View.VISIBLE); 108ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna } 109ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna if (timeoutMillis > 0) { 1103223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna mHandler.sendEmptyMessageDelayed(MSG_HIDE_AREA_VIEW, timeoutMillis); 111ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna } 1123223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna } 1133223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna 114ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 115ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * Hides the Face Unlock view. 116ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 1173223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna public void hide() { 1183223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna // Remove messages to prevent a delayed show message from undo-ing the hide 1193223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna removeAreaDisplayMessages(); 1203223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna mHandler.sendEmptyMessage(MSG_HIDE_AREA_VIEW); 1213223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna } 1223223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna 123ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 124ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * Binds to the Face Unlock service. Face Unlock will be started when the bind completes. The 125ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * Face Unlock area is displayed to hide the backup while the service is starting up. 126ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 127ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna public boolean start() { 128ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna if (mIsRunning) { 129ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna Log.w(TAG, "start() called when already running"); 130ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna } 131ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna 132ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna // Show Face Unlock view, but only for a little bit so lockpattern will become visible if 133ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna // Face Unlock fails to start or crashes 134ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna // This must show before bind to guarantee that Face Unlock has a place to display 135ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna show(VIEW_AREA_SERVICE_TIMEOUT); 136ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna if (!mBoundToService) { 137ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna if (DEBUG) Log.d(TAG, "before bind to Face Unlock service"); 138ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna mContext.bindService(new Intent(IFaceLockInterface.class.getName()), 139ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna mConnection, 140ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna Context.BIND_AUTO_CREATE, 141ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna mLockPatternUtils.getCurrentUser()); 142ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna if (DEBUG) Log.d(TAG, "after bind to Face Unlock service"); 143ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna mBoundToService = true; 144ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna } else { 145ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna Log.w(TAG, "Attempt to bind to Face Unlock when already bound"); 146ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna } 147ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna 148ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna // When switching between portrait and landscape view while Face Unlock is running, the 149ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna // screen will eventually go dark unless we poke the wakelock when Face Unlock is 150ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna // restarted 151ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna mKeyguardScreenCallback.pokeWakelock(); 152ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna 153ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna mIsRunning = true; 154ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna return true; 155ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna } 156ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna 157ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 158ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * Stops Face Unlock and unbinds from the service. 159ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 1603223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna public boolean stop() { 161ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna boolean mWasRunning = mIsRunning; 162c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna stopUi(); 163c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna 164c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna if (mBoundToService) { 165ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna if (DEBUG) Log.d(TAG, "before unbind from Face Unlock service"); 166c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna if (mService != null) { 167c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna try { 168ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna mService.unregisterCallback(mFaceUnlockCallback); 169c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna } catch (RemoteException e) { 170c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna // Not much we can do 1713223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna } 1729431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 173c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna mContext.unbindService(mConnection); 174ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna if (DEBUG) Log.d(TAG, "after unbind from Face Unlock service"); 175c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna mBoundToService = false; 176c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna } else { 177c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna // This is usually not an error when this happens. Sometimes we will tell it to 178c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna // unbind multiple times because it's called from both onWindowFocusChanged and 179c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna // onDetachedFromWindow. 180ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna if (DEBUG) Log.d(TAG, "Attempt to unbind from Face Unlock when not bound"); 1819431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 182ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna mIsRunning = false; 183ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna return mWasRunning; 1849431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 1859431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 1863223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna /** 187ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * Frees up resources used by Face Unlock and stops it if it is still running. 1883223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna */ 1893223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna public void cleanUp() { 1903223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna if (mService != null) { 1913223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna try { 192ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna mService.unregisterCallback(mFaceUnlockCallback); 1933223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna } catch (RemoteException e) { 1943223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna // Not much we can do 1953223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna } 1963223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna stopUi(); 1973223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna mService = null; 1989431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 1993223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna } 2003223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna 201ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 202ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * Returns the Device Policy Manager quality for Face Unlock, which is BIOMETRIC_WEAK. 203ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 2043223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna public int getQuality() { 2053223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna return DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK; 2069431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 2079431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 208ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 209ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * Handles showing the Face Unlock view (hiding the backup lock) and hiding the Face Unlock view 210ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * (exposing the backup lock). In cases where 'show' needs to happen immediately, 211ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * setVisibility() is called directly (without using this handler). This handler is used when 212ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * 'show' needs to happen from a non-UI thread. It also handles hide() messages since they 213ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * often require a delay. 214ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 2159431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna @Override 2169431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public boolean handleMessage(Message msg) { 2179431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna switch (msg.what) { 2189431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna case MSG_SHOW_AREA_VIEW: 219ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna if (mFaceUnlockView != null) { 220ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna mFaceUnlockView.setVisibility(View.VISIBLE); 221ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna } 2229431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna break; 2239431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna case MSG_HIDE_AREA_VIEW: 224ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna if (mFaceUnlockView != null) { 225ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna mFaceUnlockView.setVisibility(View.INVISIBLE); 2269431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 2279431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna break; 2289431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna default: 2299431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna Log.w(TAG, "Unhandled message"); 2309431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna return false; 2319431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 2329431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna return true; 2339431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 2349431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 235ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 236ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * Removes show and hide messages from the message queue 237ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 2389431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private void removeAreaDisplayMessages() { 2399431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mHandler.removeMessages(MSG_SHOW_AREA_VIEW); 2409431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mHandler.removeMessages(MSG_HIDE_AREA_VIEW); 2419431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 2429431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 2439431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private ServiceConnection mConnection = new ServiceConnection() { 244ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 245ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * Completes connection, registers callback, and starts Face Unlock when service is bound 246ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 2479431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna @Override 2489431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public void onServiceConnected(ComponentName className, IBinder iservice) { 2499431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mService = IFaceLockInterface.Stub.asInterface(iservice); 250ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna if (DEBUG) Log.d(TAG, "Connected to Face Unlock service"); 2519431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna try { 252ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna mService.registerCallback(mFaceUnlockCallback); 2539431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } catch (RemoteException e) { 254ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna Log.e(TAG, "Caught exception connecting to Face Unlock: " + e.toString()); 2559431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mService = null; 2569431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mBoundToService = false; 257ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna mIsRunning = false; 2589431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna return; 2599431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 2609431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 261ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna if (mFaceUnlockView != null) { 2629431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna int[] position; 2639431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna position = new int[2]; 264ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna mFaceUnlockView.getLocationInWindow(position); 265ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna startUi(mFaceUnlockView.getWindowToken(), position[0], position[1], 266ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna mFaceUnlockView.getWidth(), mFaceUnlockView.getHeight()); 2679431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 2689431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 2699431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 270ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 271ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * Cleans up if Face Unlock service unexpectedly disconnects 272ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 2739431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna @Override 2749431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public void onServiceDisconnected(ComponentName className) { 2759431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna synchronized(mServiceRunningLock) { 2769431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mService = null; 2779431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mServiceRunning = false; 2789431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 2799431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mBoundToService = false; 280ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna mIsRunning = false; 281ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna Log.w(TAG, "Unexpected disconnect from Face Unlock service"); 2829431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 2839431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna }; 2849431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 285ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 286ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * Tells the Face Unlock service to start displaying its UI and perform recognition 287ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 2883223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna private void startUi(IBinder windowToken, int x, int y, int w, int h) { 289c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna synchronized (mServiceRunningLock) { 290c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna if (!mServiceRunning) { 291ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna if (DEBUG) Log.d(TAG, "Starting Face Unlock"); 292c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna try { 293c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna mService.startUi(windowToken, x, y, w, h, 294c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna mLockPatternUtils.isBiometricWeakLivelinessEnabled()); 295c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna } catch (RemoteException e) { 296ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna Log.e(TAG, "Caught exception starting Face Unlock: " + e.toString()); 297c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna return; 2989431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 299c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna mServiceRunning = true; 300c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna } else { 301c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna if (DEBUG) Log.w(TAG, "startUi() attempted while running"); 3029431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 3039431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 3049431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 3059431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 306ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 307ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * Tells the Face Unlock service to stop displaying its UI and stop recognition 308ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 3093223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna private void stopUi() { 310ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna // Note that attempting to stop Face Unlock when it's not running is not an issue. 311ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna // Face Unlock can return, which stops it and then we try to stop it when the 312c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna // screen is turned off. That's why we check. 313c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna synchronized (mServiceRunningLock) { 314c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna if (mServiceRunning) { 315c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna try { 316ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna if (DEBUG) Log.d(TAG, "Stopping Face Unlock"); 317c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna mService.stopUi(); 318c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna } catch (RemoteException e) { 319ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna Log.e(TAG, "Caught exception stopping Face Unlock: " + e.toString()); 3209431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 321c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna mServiceRunning = false; 3229431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 3239431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 3249431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 3259431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 326ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 327ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * Implements the biometric unlock service callback interface defined in AIDL 328ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 329ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna private final IFaceLockCallback mFaceUnlockCallback = new IFaceLockCallback.Stub() { 330ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 331ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * Stops the Face Unlock UI and indicates that the phone should be unlocked 332ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 3339431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna @Override 3349431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public void unlock() { 335ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna if (DEBUG) Log.d(TAG, "unlock()"); 336fe444b48bac83bd5472b1102dae87661bafcfccbSteven Ross 337fe444b48bac83bd5472b1102dae87661bafcfccbSteven Ross // Keep fallback covered 338fe444b48bac83bd5472b1102dae87661bafcfccbSteven Ross removeAreaDisplayMessages(); 339fe444b48bac83bd5472b1102dae87661bafcfccbSteven Ross mHandler.sendEmptyMessage(MSG_SHOW_AREA_VIEW); 340fe444b48bac83bd5472b1102dae87661bafcfccbSteven Ross 3413223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna stop(); 3429431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 3439431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mKeyguardScreenCallback.keyguardDone(true); 3449431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mKeyguardScreenCallback.reportSuccessfulUnlockAttempt(); 3459431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 3469431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 347ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 348ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * Stops the Face Unlock UI and exposes the backup method without unlocking 349ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * This means the user has cancelled out 350ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 3519431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna @Override 3529431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public void cancel() { 353ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna if (DEBUG) Log.d(TAG, "cancel()"); 3543223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna hide(); // Expose fallback 3553223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna stop(); 3569431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mKeyguardScreenCallback.pokeWakelock(BACKUP_LOCK_TIMEOUT); 3579431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 3589431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 359ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 360ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * Stops the Face Unlock UI and exposes the backup method without unlocking 361ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * This means Face Unlock failed to recognize them 362ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 3639431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna @Override 3649431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public void reportFailedAttempt() { 365ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna if (DEBUG) Log.d(TAG, "reportFailedAttempt()"); 366ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna mUpdateMonitor.reportFailedBiometricUnlockAttempt(); 3673223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna hide(); // Expose fallback 3683223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna stop(); 3699431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mKeyguardScreenCallback.pokeWakelock(BACKUP_LOCK_TIMEOUT); 3709431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 3719431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 372ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 373ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * Removes the black area that covers the backup unlock method 374ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna **/ 3759431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna @Override 3769431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public void exposeFallback() { 377ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna if (DEBUG) Log.d(TAG, "exposeFallback()"); 3783223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna hide(); // Expose fallback 3799431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 3809431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 381ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna /** 382ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna * Allows the Face Unlock service to poke the wake lock to keep the lockscreen alive 383ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna */ 3849431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna @Override 3859431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public void pokeWakelock() { 386ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna if (DEBUG) Log.d(TAG, "pokeWakelock()"); 3879431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mKeyguardScreenCallback.pokeWakelock(); 3889431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 3899431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna }; 3909431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna} 391