KeyguardFaceUnlockView.java revision 25a272a9f6323f6a3513bb522d45e839449878ce
1/* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16package com.android.internal.policy.impl.keyguard; 17 18import android.content.Context; 19import android.graphics.drawable.Drawable; 20import android.os.PowerManager; 21import android.telephony.TelephonyManager; 22import android.util.AttributeSet; 23import android.util.Log; 24import android.view.View; 25import android.widget.ImageButton; 26import android.widget.LinearLayout; 27 28import com.android.internal.R; 29 30import com.android.internal.widget.LockPatternUtils; 31 32public class KeyguardFaceUnlockView extends LinearLayout implements KeyguardSecurityView { 33 34 private static final String TAG = "FULKeyguardFaceUnlockView"; 35 private static final boolean DEBUG = false; 36 private KeyguardSecurityCallback mKeyguardSecurityCallback; 37 private LockPatternUtils mLockPatternUtils; 38 private BiometricSensorUnlock mBiometricUnlock; 39 private View mFaceUnlockAreaView; 40 private ImageButton mCancelButton; 41 private SecurityMessageDisplay mSecurityMessageDisplay; 42 private View mEcaView; 43 private Drawable mBouncerFrame; 44 45 private boolean mIsShowing = false; 46 private final Object mIsShowingLock = new Object(); 47 48 public KeyguardFaceUnlockView(Context context) { 49 this(context, null); 50 } 51 52 public KeyguardFaceUnlockView(Context context, AttributeSet attrs) { 53 super(context, attrs); 54 } 55 56 @Override 57 protected void onFinishInflate() { 58 super.onFinishInflate(); 59 60 initializeBiometricUnlockView(); 61 62 mSecurityMessageDisplay = new KeyguardMessageArea.Helper(this); 63 mEcaView = findViewById(R.id.keyguard_selector_fade_container); 64 View bouncerFrameView = findViewById(R.id.keyguard_bouncer_frame); 65 if (bouncerFrameView != null) { 66 mBouncerFrame = bouncerFrameView.getBackground(); 67 } 68 } 69 70 @Override 71 public void setKeyguardCallback(KeyguardSecurityCallback callback) { 72 mKeyguardSecurityCallback = callback; 73 // TODO: formalize this in the interface or factor it out 74 ((FaceUnlock)mBiometricUnlock).setKeyguardCallback(callback); 75 } 76 77 @Override 78 public void setLockPatternUtils(LockPatternUtils utils) { 79 mLockPatternUtils = utils; 80 } 81 82 @Override 83 public void reset() { 84 85 } 86 87 @Override 88 public void onDetachedFromWindow() { 89 if (DEBUG) Log.d(TAG, "onDetachedFromWindow()"); 90 if (mBiometricUnlock != null) { 91 mBiometricUnlock.stop(); 92 } 93 KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mUpdateCallback); 94 } 95 96 @Override 97 public void onPause() { 98 if (DEBUG) Log.d(TAG, "onPause()"); 99 if (mBiometricUnlock != null) { 100 mBiometricUnlock.stop(); 101 } 102 KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mUpdateCallback); 103 } 104 105 @Override 106 public void onResume(int reason) { 107 if (DEBUG) Log.d(TAG, "onResume()"); 108 mIsShowing = KeyguardUpdateMonitor.getInstance(mContext).isKeyguardVisible(); 109 maybeStartBiometricUnlock(); 110 KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mUpdateCallback); 111 } 112 113 @Override 114 public boolean needsInput() { 115 return false; 116 } 117 118 @Override 119 public KeyguardSecurityCallback getCallback() { 120 return mKeyguardSecurityCallback; 121 } 122 123 @Override 124 protected void onLayout(boolean changed, int l, int t, int r, int b) { 125 super.onLayout(changed, l, t, r, b); 126 mBiometricUnlock.initializeView(mFaceUnlockAreaView); 127 } 128 129 private void initializeBiometricUnlockView() { 130 if (DEBUG) Log.d(TAG, "initializeBiometricUnlockView()"); 131 mFaceUnlockAreaView = findViewById(R.id.face_unlock_area_view); 132 if (mFaceUnlockAreaView != null) { 133 mBiometricUnlock = new FaceUnlock(mContext); 134 135 mCancelButton = (ImageButton) findViewById(R.id.face_unlock_cancel_button); 136 mCancelButton.setOnClickListener(new OnClickListener() { 137 @Override 138 public void onClick(View v) { 139 mBiometricUnlock.stopAndShowBackup(); 140 } 141 }); 142 } else { 143 Log.w(TAG, "Couldn't find biometric unlock view"); 144 } 145 } 146 147 /** 148 * Starts the biometric unlock if it should be started based on a number of factors. If it 149 * should not be started, it either goes to the back up, or remains showing to prepare for 150 * it being started later. 151 */ 152 private void maybeStartBiometricUnlock() { 153 if (DEBUG) Log.d(TAG, "maybeStartBiometricUnlock()"); 154 if (mBiometricUnlock != null) { 155 KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(mContext); 156 final boolean backupIsTimedOut = ( 157 monitor.getFailedUnlockAttempts() >= 158 LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT); 159 PowerManager powerManager = (PowerManager) mContext.getSystemService( 160 Context.POWER_SERVICE); 161 162 boolean isShowing; 163 synchronized(mIsShowingLock) { 164 isShowing = mIsShowing; 165 } 166 167 // Don't start it if the screen is off or if it's not showing, but keep this view up 168 // because we want it here and ready for when the screen turns on or when it does start 169 // showing. 170 if (!powerManager.isScreenOn() || !isShowing) { 171 mBiometricUnlock.stop(); // It shouldn't be running but calling this can't hurt. 172 return; 173 } 174 175 // TODO: Some of these conditions are handled in KeyguardSecurityModel and may not be 176 // necessary here. 177 if (monitor.getPhoneState() == TelephonyManager.CALL_STATE_IDLE 178 && !monitor.getMaxBiometricUnlockAttemptsReached() 179 && !backupIsTimedOut) { 180 mBiometricUnlock.start(); 181 } else { 182 mBiometricUnlock.stopAndShowBackup(); 183 } 184 } 185 } 186 187 KeyguardUpdateMonitorCallback mUpdateCallback = new KeyguardUpdateMonitorCallback() { 188 // We need to stop the biometric unlock when a phone call comes in 189 @Override 190 public void onPhoneStateChanged(int phoneState) { 191 if (DEBUG) Log.d(TAG, "onPhoneStateChanged(" + phoneState + ")"); 192 if (phoneState == TelephonyManager.CALL_STATE_RINGING) { 193 if (mBiometricUnlock != null) { 194 mBiometricUnlock.stopAndShowBackup(); 195 } 196 } 197 } 198 199 @Override 200 public void onUserSwitching(int userId) { 201 if (DEBUG) Log.d(TAG, "onUserSwitched(" + userId + ")"); 202 if (mBiometricUnlock != null) { 203 mBiometricUnlock.stop(); 204 } 205 // No longer required; static value set by KeyguardViewMediator 206 // mLockPatternUtils.setCurrentUser(userId); 207 } 208 209 @Override 210 public void onKeyguardVisibilityChanged(boolean showing) { 211 if (DEBUG) Log.d(TAG, "onKeyguardVisibilityChanged(" + showing + ")"); 212 boolean wasShowing = false; 213 synchronized(mIsShowingLock) { 214 wasShowing = mIsShowing; 215 mIsShowing = showing; 216 } 217 PowerManager powerManager = (PowerManager) mContext.getSystemService( 218 Context.POWER_SERVICE); 219 if (mBiometricUnlock != null) { 220 if (!showing && wasShowing) { 221 mBiometricUnlock.stop(); 222 } else if (showing && powerManager.isScreenOn() && !wasShowing) { 223 maybeStartBiometricUnlock(); 224 } 225 } 226 } 227 }; 228 229 @Override 230 public void showUsabilityHint() { 231 } 232 233 @Override 234 public void showBouncer(int duration) { 235 KeyguardSecurityViewHelper. 236 showBouncer(mSecurityMessageDisplay, mEcaView, mBouncerFrame, duration); 237 } 238 239 @Override 240 public void hideBouncer(int duration) { 241 KeyguardSecurityViewHelper. 242 hideBouncer(mSecurityMessageDisplay, mEcaView, mBouncerFrame, duration); 243 } 244 245} 246