FaceUnlock.java revision 9431366ecb4b6e4a87c0047c36548aa0bc23f2b1
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 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; 309431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonnaimport android.os.Message; 319431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonnaimport android.os.RemoteException; 329431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonnaimport android.telephony.TelephonyManager; 339431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonnaimport android.util.Log; 349431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonnaimport android.view.View; 359431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 369431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonnapublic class FaceUnlock implements Handler.Callback { 379431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 389431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private static final boolean DEBUG = false; 399431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private static final String TAG = "FULLockscreen"; 409431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 419431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private final Context mContext; 429431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private final KeyguardUpdateMonitor mUpdateMonitor; 439431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 449431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private IFaceLockInterface mService; 459431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private boolean mBoundToService = false; 469431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private View mAreaView; 479431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 489431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private Handler mHandler; 499431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private final int MSG_SHOW_AREA_VIEW = 0; 509431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private final int MSG_HIDE_AREA_VIEW = 1; 519431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 529431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private boolean mServiceRunning = false; 539431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private final Object mServiceRunningLock = new Object(); 549431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 559431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // Long enough to stay visible while dialer comes up 569431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // Short enough to not be visible if the user goes back immediately 579431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private final int VIEW_AREA_EMERGENCY_DIALER_TIMEOUT = 1000; 589431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 599431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // Long enough to stay visible while the service starts 609431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // Short enough to not have to wait long for backup if service fails to start or crashes 619431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // The service can take a couple of seconds to start on the first try after boot 629431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private final int VIEW_AREA_SERVICE_TIMEOUT = 3000; 639431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 649431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // So the user has a consistent amount of time when brought to the backup method from FaceLock 659431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private final int BACKUP_LOCK_TIMEOUT = 5000; 669431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 679431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna /** 689431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna * Used to lookup the state of the lock pattern 699431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna */ 709431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private final LockPatternUtils mLockPatternUtils; 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 839431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public void cleanUp() { 849431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna if (mService != null) { 859431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna try { 869431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mService.unregisterCallback(mFaceLockCallback); 879431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } catch (RemoteException e) { 889431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // Not much we can do 899431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 909431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna stop(); 919431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mService = null; 929431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 939431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 949431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 959431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna /** When screen is turned on and focused, need to bind to FaceLock service if we are using 969431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna * FaceLock, but only if we're not dealing with a call 979431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna */ 989431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public void activateIfAble(boolean hasOverlay) { 999431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna final boolean tooManyFaceUnlockTries = mUpdateMonitor.getMaxFaceUnlockAttemptsReached(); 1009431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna final int failedBackupAttempts = mUpdateMonitor.getFailedAttempts(); 1019431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna final boolean backupIsTimedOut = 1029431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna (failedBackupAttempts >= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT); 1039431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna if (tooManyFaceUnlockTries) Log.i(TAG, "tooManyFaceUnlockTries: " + tooManyFaceUnlockTries); 1049431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna if (mUpdateMonitor.getPhoneState() == TelephonyManager.CALL_STATE_IDLE 1059431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna && installedAndSelected() 1069431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna && !hasOverlay 1079431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna && !tooManyFaceUnlockTries 1089431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna && !backupIsTimedOut) { 1099431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna bind(); 1109431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 1119431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // Show FaceLock area, but only for a little bit so lockpattern will become visible if 1129431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // FaceLock fails to start or crashes 1139431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna showAreaWithTimeout(VIEW_AREA_SERVICE_TIMEOUT); 1149431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 1159431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // When switching between portrait and landscape view while FaceLock is running, the 1169431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // screen will eventually go dark unless we poke the wakelock when FaceLock is 1179431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // restarted 1189431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mKeyguardScreenCallback.pokeWakelock(); 1199431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } else { 1209431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna hideArea(); 1219431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 1229431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 1239431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 1249431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public boolean isServiceRunning() { 1259431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna return mServiceRunning; 1269431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 1279431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 1289431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public int viewAreaEmergencyDialerTimeout() { 1299431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna return VIEW_AREA_EMERGENCY_DIALER_TIMEOUT; 1309431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 1319431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 1329431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // Indicates whether FaceLock is in use 1339431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public boolean installedAndSelected() { 1349431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna return (mLockPatternUtils.usingBiometricWeak() && 1359431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mLockPatternUtils.isBiometricWeakInstalled()); 1369431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 1379431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 1389431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // Takes care of FaceLock area when layout is created 1399431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public void initializeAreaView(View view) { 1409431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna if (installedAndSelected()) { 1419431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mAreaView = view.findViewById(R.id.faceLockAreaView); 1429431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna if (mAreaView == null) { 1439431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna Log.e(TAG, "Layout does not have areaView and FaceLock is enabled"); 1449431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 1459431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } else { 1469431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mAreaView = null; // Set to null if not using FaceLock 1479431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 1489431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 1499431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 1509431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // Stops FaceLock if it is running and reports back whether it was running or not 1519431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public boolean stopIfRunning() { 1529431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna if (installedAndSelected() && mBoundToService) { 1539431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna stopAndUnbind(); 1549431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna return true; 1559431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 1569431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna return false; 1579431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 1589431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 1599431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // Handles covering or exposing FaceLock area on the client side when FaceLock starts or stops 1609431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // This needs to be done in a handler because the call could be coming from a callback from the 1619431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // FaceLock service that is in a thread that can't modify the UI 1629431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna @Override 1639431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public boolean handleMessage(Message msg) { 1649431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna switch (msg.what) { 1659431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna case MSG_SHOW_AREA_VIEW: 1669431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna if (mAreaView != null) { 1679431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mAreaView.setVisibility(View.VISIBLE); 1689431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 1699431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna break; 1709431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna case MSG_HIDE_AREA_VIEW: 1719431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna if (mAreaView != null) { 1729431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mAreaView.setVisibility(View.INVISIBLE); 1739431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 1749431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna break; 1759431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna default: 1769431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna Log.w(TAG, "Unhandled message"); 1779431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna return false; 1789431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 1799431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna return true; 1809431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 1819431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 1829431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // Removes show and hide messages from the message queue 1839431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private void removeAreaDisplayMessages() { 1849431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mHandler.removeMessages(MSG_SHOW_AREA_VIEW); 1859431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mHandler.removeMessages(MSG_HIDE_AREA_VIEW); 1869431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 1879431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 1889431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // Shows the FaceLock area immediately 1899431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public void showArea() { 1909431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // Remove messages to prevent a delayed hide message from undo-ing the show 1919431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna removeAreaDisplayMessages(); 1929431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mHandler.sendEmptyMessage(MSG_SHOW_AREA_VIEW); 1939431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 1949431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 1959431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // Hides the FaceLock area immediately 1969431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public void hideArea() { 1979431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // Remove messages to prevent a delayed show message from undo-ing the hide 1989431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna removeAreaDisplayMessages(); 1999431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mHandler.sendEmptyMessage(MSG_HIDE_AREA_VIEW); 2009431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 2019431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 2029431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // Shows the FaceLock area for a period of time 2039431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public void showAreaWithTimeout(long timeoutMillis) { 2049431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna showArea(); 2059431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mHandler.sendEmptyMessageDelayed(MSG_HIDE_AREA_VIEW, timeoutMillis); 2069431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 2079431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 2089431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // Binds to FaceLock service. This call does not tell it to start, but it causes the service 2099431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // to call the onServiceConnected callback, which then starts FaceLock. 2109431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public void bind() { 2119431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna if (installedAndSelected()) { 2129431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna if (!mBoundToService) { 2139431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna if (DEBUG) Log.d(TAG, "before bind to FaceLock service"); 2149431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mContext.bindService(new Intent(IFaceLockInterface.class.getName()), 2159431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mConnection, 2169431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna Context.BIND_AUTO_CREATE); 2179431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna if (DEBUG) Log.d(TAG, "after bind to FaceLock service"); 2189431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mBoundToService = true; 2199431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } else { 2209431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna Log.w(TAG, "Attempt to bind to FaceLock when already bound"); 2219431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 2229431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 2239431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 2249431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 2259431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // Tells FaceLock to stop and then unbinds from the FaceLock service 2269431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public void stopAndUnbind() { 2279431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna if (installedAndSelected()) { 2289431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna stop(); 2299431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 2309431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna if (mBoundToService) { 2319431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna if (DEBUG) Log.d(TAG, "before unbind from FaceLock service"); 2329431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna if (mService != null) { 2339431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna try { 2349431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mService.unregisterCallback(mFaceLockCallback); 2359431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } catch (RemoteException e) { 2369431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // Not much we can do 2379431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 2389431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 2399431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mContext.unbindService(mConnection); 2409431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna if (DEBUG) Log.d(TAG, "after unbind from FaceLock service"); 2419431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mBoundToService = false; 2429431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } else { 2439431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // This is usually not an error when this happens. Sometimes we will tell it to 2449431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // unbind multiple times because it's called from both onWindowFocusChanged and 2459431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // onDetachedFromWindow. 2469431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna if (DEBUG) Log.d(TAG, "Attempt to unbind from FaceLock when not bound"); 2479431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 2489431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 2499431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 2509431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 2519431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private ServiceConnection mConnection = new ServiceConnection() { 2529431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // Completes connection, registers callback and starts FaceLock when service is bound 2539431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna @Override 2549431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public void onServiceConnected(ComponentName className, IBinder iservice) { 2559431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mService = IFaceLockInterface.Stub.asInterface(iservice); 2569431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna if (DEBUG) Log.d(TAG, "Connected to FaceLock service"); 2579431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna try { 2589431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mService.registerCallback(mFaceLockCallback); 2599431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } catch (RemoteException e) { 2609431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna Log.e(TAG, "Caught exception connecting to FaceLock: " + e.toString()); 2619431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mService = null; 2629431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mBoundToService = false; 2639431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna return; 2649431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 2659431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 2669431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna if (mAreaView != null) { 2679431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna int[] position; 2689431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna position = new int[2]; 2699431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mAreaView.getLocationInWindow(position); 2709431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna start(mAreaView.getWindowToken(), position[0], position[1], 2719431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mAreaView.getWidth(), mAreaView.getHeight()); 2729431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 2739431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 2749431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 2759431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // Cleans up if FaceLock service unexpectedly disconnects 2769431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna @Override 2779431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public void onServiceDisconnected(ComponentName className) { 2789431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna synchronized(mServiceRunningLock) { 2799431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mService = null; 2809431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mServiceRunning = false; 2819431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 2829431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mBoundToService = false; 2839431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna Log.w(TAG, "Unexpected disconnect from FaceLock service"); 2849431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 2859431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna }; 2869431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 2879431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // Tells the FaceLock service to start displaying its UI and perform recognition 2889431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public void start(IBinder windowToken, int x, int y, int w, int h) { 2899431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna if (installedAndSelected()) { 2909431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna synchronized (mServiceRunningLock) { 2919431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna if (!mServiceRunning) { 2929431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna if (DEBUG) Log.d(TAG, "Starting FaceLock"); 2939431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna try { 2949431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mService.startUi(windowToken, x, y, w, h); 2959431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } catch (RemoteException e) { 2969431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna Log.e(TAG, "Caught exception starting FaceLock: " + e.toString()); 2979431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna return; 2989431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 2999431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mServiceRunning = true; 3009431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } else { 3019431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna if (DEBUG) Log.w(TAG, "start() attempted while running"); 3029431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 3039431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 3049431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 3059431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 3069431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 3079431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // Tells the FaceLock service to stop displaying its UI and stop recognition 3089431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public void stop() { 3099431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna if (installedAndSelected()) { 3109431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // Note that attempting to stop FaceLock when it's not running is not an issue. 3119431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // FaceLock can return, which stops it and then we try to stop it when the 3129431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // screen is turned off. That's why we check. 3139431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna synchronized (mServiceRunningLock) { 3149431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna if (mServiceRunning) { 3159431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna try { 3169431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna if (DEBUG) Log.d(TAG, "Stopping FaceLock"); 3179431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mService.stopUi(); 3189431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } catch (RemoteException e) { 3199431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna Log.e(TAG, "Caught exception stopping FaceLock: " + e.toString()); 3209431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 3219431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mServiceRunning = false; 3229431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 3239431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 3249431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 3259431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 3269431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 3279431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // Implements the FaceLock service callback interface defined in AIDL 3289431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna private final IFaceLockCallback mFaceLockCallback = new IFaceLockCallback.Stub() { 3299431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // Stops the FaceLock UI and indicates that the phone should be unlocked 3309431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna @Override 3319431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public void unlock() { 3329431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna if (DEBUG) Log.d(TAG, "FaceLock unlock()"); 3339431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna showArea(); // Keep fallback covered 3349431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna stopAndUnbind(); 3359431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 3369431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mKeyguardScreenCallback.keyguardDone(true); 3379431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mKeyguardScreenCallback.reportSuccessfulUnlockAttempt(); 3389431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 3399431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 3409431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // Stops the FaceLock UI and exposes the backup method without unlocking 3419431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // This means the user has cancelled out 3429431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna @Override 3439431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public void cancel() { 3449431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna if (DEBUG) Log.d(TAG, "FaceLock cancel()"); 3459431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna hideArea(); // Expose fallback 3469431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna stopAndUnbind(); 3479431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mKeyguardScreenCallback.pokeWakelock(BACKUP_LOCK_TIMEOUT); 3489431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 3499431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 3509431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // Stops the FaceLock UI and exposes the backup method without unlocking 3519431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // This means FaceLock failed to recognize them 3529431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna @Override 3539431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public void reportFailedAttempt() { 3549431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna if (DEBUG) Log.d(TAG, "FaceLock reportFailedAttempt()"); 3559431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mUpdateMonitor.reportFailedFaceUnlockAttempt(); 3569431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna hideArea(); // Expose fallback 3579431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna stopAndUnbind(); 3589431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mKeyguardScreenCallback.pokeWakelock(BACKUP_LOCK_TIMEOUT); 3599431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 3609431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 3619431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // Removes the black area that covers the backup unlock method 3629431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna @Override 3639431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public void exposeFallback() { 3649431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna if (DEBUG) Log.d(TAG, "FaceLock exposeFallback()"); 3659431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna hideArea(); // Expose fallback 3669431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 3679431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna 3689431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna // Allows the Face Unlock service to poke the wake lock to keep the lockscreen alive 3699431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna @Override 3709431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna public void pokeWakelock() { 3719431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna if (DEBUG) Log.d(TAG, "FaceLock pokeWakelock()"); 3729431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna mKeyguardScreenCallback.pokeWakelock(); 3739431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna } 3749431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna }; 3759431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna} 376