FaceUnlock.java revision 3223e2537d5f4e2eceeb321405dbd6da50df66b6
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; 439431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private final KeyguardUpdateMonitor mUpdateMonitor; 449431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 459431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private IFaceLockInterface mService; 469431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private boolean mBoundToService = false; 479431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private View mAreaView; 489431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 499431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private Handler mHandler; 509431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private final int MSG_SHOW_AREA_VIEW = 0; 519431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private final int MSG_HIDE_AREA_VIEW = 1; 529431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 539431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private boolean mServiceRunning = false; 549431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private final Object mServiceRunningLock = new Object(); 559431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 569431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // Long enough to stay visible while the service starts 579431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // Short enough to not have to wait long for backup if service fails to start or crashes 589431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // The service can take a couple of seconds to start on the first try after boot 599431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private final int VIEW_AREA_SERVICE_TIMEOUT = 3000; 609431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 619431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // So the user has a consistent amount of time when brought to the backup method from FaceLock 629431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private final int BACKUP_LOCK_TIMEOUT = 5000; 639431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 649431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna /** 659431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna * Used to lookup the state of the lock pattern 669431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna */ 679431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private final LockPatternUtils mLockPatternUtils; 689431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 699431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna KeyguardScreenCallback mKeyguardScreenCallback; 709431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 719431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public FaceUnlock(Context context, KeyguardUpdateMonitor updateMonitor, 729431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna LockPatternUtils lockPatternUtils, KeyguardScreenCallback keyguardScreenCallback) { 739431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mContext = context; 749431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mUpdateMonitor = updateMonitor; 759431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mLockPatternUtils = lockPatternUtils; 769431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mKeyguardScreenCallback = keyguardScreenCallback; 779431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mHandler = new Handler(this); 789431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 799431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 803223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna // Indicates whether FaceLock is in use 813223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna public boolean installedAndSelected() { 823223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna return (mLockPatternUtils.usingBiometricWeak() && 833223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna mLockPatternUtils.isBiometricWeakInstalled()); 843223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna } 853223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna 863223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna public boolean isRunning() { 873223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna return mServiceRunning; 883223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna } 893223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna 903223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna // Shows the FaceLock area for a period of time 913223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna public void show(long timeoutMillis) { 923223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna showArea(); 933223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna if (timeoutMillis > 0) 943223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna mHandler.sendEmptyMessageDelayed(MSG_HIDE_AREA_VIEW, timeoutMillis); 953223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna } 963223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna 973223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna // Hides the FaceLock area immediately 983223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna public void hide() { 993223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna // Remove messages to prevent a delayed show message from undo-ing the hide 1003223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna removeAreaDisplayMessages(); 1013223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna mHandler.sendEmptyMessage(MSG_HIDE_AREA_VIEW); 1023223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna } 1033223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna 1043223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna // Tells FaceLock to stop and then unbinds from the FaceLock service 1053223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna public boolean stop() { 1063223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna boolean wasRunning = false; 1073223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna if (installedAndSelected()) { 1083223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna stopUi(); 1093223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna 1103223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna if (mBoundToService) { 1113223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna wasRunning = true; 1123223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna if (DEBUG) Log.d(TAG, "before unbind from FaceLock service"); 1133223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna if (mService != null) { 1143223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna try { 1153223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna mService.unregisterCallback(mFaceLockCallback); 1163223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna } catch (RemoteException e) { 1173223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna // Not much we can do 1183223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna } 1193223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna } 1203223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna mContext.unbindService(mConnection); 1213223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna if (DEBUG) Log.d(TAG, "after unbind from FaceLock service"); 1223223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna mBoundToService = false; 1233223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna } else { 1243223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna // This is usually not an error when this happens. Sometimes we will tell it to 1253223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna // unbind multiple times because it's called from both onWindowFocusChanged and 1263223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna // onDetachedFromWindow. 1273223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna if (DEBUG) Log.d(TAG, "Attempt to unbind from FaceLock when not bound"); 1289431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 1299431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 1303223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna 1313223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna return wasRunning; 1329431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 1339431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 1343223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna /** 1353223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna * When screen is turned on and focused, need to bind to FaceLock service if we are using 1363223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna * FaceLock, but only if we're not dealing with a call 1373223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna */ 1383223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna public boolean start(boolean suppressBiometricUnlock) { 1399431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna final boolean tooManyFaceUnlockTries = mUpdateMonitor.getMaxFaceUnlockAttemptsReached(); 1409431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna final int failedBackupAttempts = mUpdateMonitor.getFailedAttempts(); 1419431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna final boolean backupIsTimedOut = 1429431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna (failedBackupAttempts >= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT); 1439431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna if (tooManyFaceUnlockTries) Log.i(TAG, "tooManyFaceUnlockTries: " + tooManyFaceUnlockTries); 1449431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna if (mUpdateMonitor.getPhoneState() == TelephonyManager.CALL_STATE_IDLE 1459431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna && installedAndSelected() 1463223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna && !suppressBiometricUnlock 1479431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna && !tooManyFaceUnlockTries 1489431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna && !backupIsTimedOut) { 1499431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna bind(); 1509431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 1519431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // Show FaceLock area, but only for a little bit so lockpattern will become visible if 1529431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // FaceLock fails to start or crashes 1533223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna show(VIEW_AREA_SERVICE_TIMEOUT); 1549431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 1559431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // When switching between portrait and landscape view while FaceLock is running, the 1569431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // screen will eventually go dark unless we poke the wakelock when FaceLock is 1579431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // restarted 1589431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mKeyguardScreenCallback.pokeWakelock(); 1599431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } else { 1603223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna hide(); 1613223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna return false; 1629431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 1639431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 1643223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna return true; 1659431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 1669431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 1679431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // Takes care of FaceLock area when layout is created 1683223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna public void initializeAreaView(View topView) { 1699431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna if (installedAndSelected()) { 1703223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna mAreaView = topView.findViewById(R.id.faceLockAreaView); 1719431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna if (mAreaView == null) { 1729431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna Log.e(TAG, "Layout does not have areaView and FaceLock is enabled"); 1739431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 1749431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } else { 1759431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mAreaView = null; // Set to null if not using FaceLock 1769431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 1779431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 1789431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 1793223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna public void cleanUp() { 1803223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna if (mService != null) { 1813223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna try { 1823223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna mService.unregisterCallback(mFaceLockCallback); 1833223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna } catch (RemoteException e) { 1843223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna // Not much we can do 1853223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna } 1863223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna stopUi(); 1873223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna mService = null; 1889431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 1893223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna } 1903223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna 1913223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna public int getQuality() { 1923223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna return DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK; 1939431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 1949431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 1959431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // Handles covering or exposing FaceLock area on the client side when FaceLock starts or stops 1969431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // This needs to be done in a handler because the call could be coming from a callback from the 1979431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // FaceLock service that is in a thread that can't modify the UI 1989431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna @Override 1999431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public boolean handleMessage(Message msg) { 2009431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna switch (msg.what) { 2019431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna case MSG_SHOW_AREA_VIEW: 2029431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna if (mAreaView != null) { 2039431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mAreaView.setVisibility(View.VISIBLE); 2049431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 2059431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna break; 2069431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna case MSG_HIDE_AREA_VIEW: 2079431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna if (mAreaView != null) { 2089431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mAreaView.setVisibility(View.INVISIBLE); 2099431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 2109431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna break; 2119431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna default: 2129431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna Log.w(TAG, "Unhandled message"); 2139431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna return false; 2149431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 2159431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna return true; 2169431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 2179431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 2189431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // Removes show and hide messages from the message queue 2199431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private void removeAreaDisplayMessages() { 2209431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mHandler.removeMessages(MSG_SHOW_AREA_VIEW); 2219431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mHandler.removeMessages(MSG_HIDE_AREA_VIEW); 2229431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 2239431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 2249431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // Shows the FaceLock area immediately 2253223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna private void showArea() { 2269431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // Remove messages to prevent a delayed hide message from undo-ing the show 2279431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna removeAreaDisplayMessages(); 2289431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mHandler.sendEmptyMessage(MSG_SHOW_AREA_VIEW); 2299431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 2309431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 2319431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // Binds to FaceLock service. This call does not tell it to start, but it causes the service 2329431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // to call the onServiceConnected callback, which then starts FaceLock. 2333223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna private void bind() { 2349431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna if (installedAndSelected()) { 2359431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna if (!mBoundToService) { 2369431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna if (DEBUG) Log.d(TAG, "before bind to FaceLock service"); 2379431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mContext.bindService(new Intent(IFaceLockInterface.class.getName()), 2389431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mConnection, 239f882f1ad4edd790483924e7bf485fd7c7240d110Amith Yamasani Context.BIND_AUTO_CREATE, 240f882f1ad4edd790483924e7bf485fd7c7240d110Amith Yamasani mLockPatternUtils.getCurrentUser()); 2419431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna if (DEBUG) Log.d(TAG, "after bind to FaceLock service"); 2429431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mBoundToService = true; 2439431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } else { 2449431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna Log.w(TAG, "Attempt to bind to FaceLock when already bound"); 2459431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 2469431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 2479431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 2489431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 2499431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private ServiceConnection mConnection = new ServiceConnection() { 2509431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // Completes connection, registers callback and starts FaceLock when service is bound 2519431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna @Override 2529431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public void onServiceConnected(ComponentName className, IBinder iservice) { 2539431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mService = IFaceLockInterface.Stub.asInterface(iservice); 2549431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna if (DEBUG) Log.d(TAG, "Connected to FaceLock service"); 2559431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna try { 2569431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mService.registerCallback(mFaceLockCallback); 2579431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } catch (RemoteException e) { 2589431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna Log.e(TAG, "Caught exception connecting to FaceLock: " + e.toString()); 2599431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mService = null; 2609431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mBoundToService = false; 2619431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna return; 2629431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 2639431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 2649431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna if (mAreaView != null) { 2659431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna int[] position; 2669431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna position = new int[2]; 2679431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mAreaView.getLocationInWindow(position); 2683223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna startUi(mAreaView.getWindowToken(), position[0], position[1], 2699431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mAreaView.getWidth(), mAreaView.getHeight()); 2709431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 2719431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 2729431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 2739431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // Cleans up if FaceLock service unexpectedly disconnects 2749431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna @Override 2759431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public void onServiceDisconnected(ComponentName className) { 2769431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna synchronized(mServiceRunningLock) { 2779431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mService = null; 2789431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mServiceRunning = false; 2799431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 2809431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mBoundToService = false; 2819431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna Log.w(TAG, "Unexpected disconnect from FaceLock service"); 2829431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 2839431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna }; 2849431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 2859431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // Tells the FaceLock service to start displaying its UI and perform recognition 2863223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna private void startUi(IBinder windowToken, int x, int y, int w, int h) { 2879431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna if (installedAndSelected()) { 2889431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna synchronized (mServiceRunningLock) { 2899431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna if (!mServiceRunning) { 2909431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna if (DEBUG) Log.d(TAG, "Starting FaceLock"); 2919431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna try { 292f66e930e726f4caf49b7d47c08d160b14628c99fBrian Colonna mService.startUi(windowToken, x, y, w, h, 293f66e930e726f4caf49b7d47c08d160b14628c99fBrian Colonna mLockPatternUtils.isBiometricWeakLivelinessEnabled()); 2949431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } catch (RemoteException e) { 2959431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna Log.e(TAG, "Caught exception starting FaceLock: " + e.toString()); 2969431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna return; 2979431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 2989431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mServiceRunning = true; 2999431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } else { 3003223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna if (DEBUG) Log.w(TAG, "startUi() attempted while running"); 3019431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 3029431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 3039431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 3049431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 3059431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 3069431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // Tells the FaceLock service to stop displaying its UI and stop recognition 3073223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna private void stopUi() { 3089431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna if (installedAndSelected()) { 3099431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // Note that attempting to stop FaceLock when it's not running is not an issue. 3109431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // FaceLock can return, which stops it and then we try to stop it when the 3119431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // screen is turned off. That's why we check. 3129431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna synchronized (mServiceRunningLock) { 3139431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna if (mServiceRunning) { 3149431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna try { 3159431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna if (DEBUG) Log.d(TAG, "Stopping FaceLock"); 3169431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mService.stopUi(); 3179431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } catch (RemoteException e) { 3189431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna Log.e(TAG, "Caught exception stopping FaceLock: " + e.toString()); 3199431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 3209431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mServiceRunning = false; 3219431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 3229431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 3239431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 3249431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 3259431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 3269431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // Implements the FaceLock service callback interface defined in AIDL 3279431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private final IFaceLockCallback mFaceLockCallback = new IFaceLockCallback.Stub() { 3289431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // Stops the FaceLock UI and indicates that the phone should be unlocked 3299431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna @Override 3309431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public void unlock() { 3319431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna if (DEBUG) Log.d(TAG, "FaceLock unlock()"); 3329431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna showArea(); // Keep fallback covered 3333223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna stop(); 3349431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 3359431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mKeyguardScreenCallback.keyguardDone(true); 3369431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mKeyguardScreenCallback.reportSuccessfulUnlockAttempt(); 3379431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 3389431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 3399431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // Stops the FaceLock UI and exposes the backup method without unlocking 3409431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // This means the user has cancelled out 3419431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna @Override 3429431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public void cancel() { 3439431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna if (DEBUG) Log.d(TAG, "FaceLock cancel()"); 3443223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna hide(); // Expose fallback 3453223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna stop(); 3469431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mKeyguardScreenCallback.pokeWakelock(BACKUP_LOCK_TIMEOUT); 3479431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 3489431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 3499431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // Stops the FaceLock UI and exposes the backup method without unlocking 3509431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // This means FaceLock failed to recognize them 3519431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna @Override 3529431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public void reportFailedAttempt() { 3539431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna if (DEBUG) Log.d(TAG, "FaceLock reportFailedAttempt()"); 3549431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mUpdateMonitor.reportFailedFaceUnlockAttempt(); 3553223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna hide(); // Expose fallback 3563223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna stop(); 3579431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mKeyguardScreenCallback.pokeWakelock(BACKUP_LOCK_TIMEOUT); 3589431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 3599431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 3609431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // Removes the black area that covers the backup unlock method 3619431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna @Override 3629431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public void exposeFallback() { 3639431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna if (DEBUG) Log.d(TAG, "FaceLock exposeFallback()"); 3643223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna hide(); // Expose fallback 3659431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 3669431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 3679431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // Allows the Face Unlock service to poke the wake lock to keep the lockscreen alive 3689431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna @Override 3699431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public void pokeWakelock() { 3709431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna if (DEBUG) Log.d(TAG, "FaceLock pokeWakelock()"); 3719431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mKeyguardScreenCallback.pokeWakelock(); 3729431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 3739431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna }; 3749431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna} 375