11f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project/*
21f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
31f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project *
41f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
51f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * you may not use this file except in compliance with the License.
61f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * You may obtain a copy of the License at
71f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project *
81f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
91f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project *
101f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
111f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
121f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * See the License for the specific language governing permissions and
141f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * limitations under the License.
151f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project */
161f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
171f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectpackage com.android.internal.policy.impl;
181f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1924cfa450fa46a333ea9fa7de20a8755e592e1bedIlia Tulchinskyimport com.android.internal.R;
20b030476d193a423f6c1baf3053f66fc768c925e0Jim Millerimport com.android.internal.policy.impl.KeyguardUpdateMonitor.InfoCallback;
21b030476d193a423f6c1baf3053f66fc768c925e0Jim Millerimport com.android.internal.policy.impl.KeyguardUpdateMonitor.InfoCallbackImpl;
224ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Millerimport com.android.internal.policy.impl.LockPatternKeyguardView.UnlockMode;
2324cfa450fa46a333ea9fa7de20a8755e592e1bedIlia Tulchinskyimport com.android.internal.telephony.IccCard;
2424cfa450fa46a333ea9fa7de20a8755e592e1bedIlia Tulchinskyimport com.android.internal.widget.LockPatternUtils;
251c18828d20807342d37000746b18a3c1696f3b2eJim Millerimport com.android.internal.widget.LockScreenWidgetCallback;
26054340d0a3f242efeaf898cca38625bdcb3b4b5aJeff Sharkeyimport com.android.internal.widget.LockScreenWidgetInterface;
271c18828d20807342d37000746b18a3c1696f3b2eJim Millerimport com.android.internal.widget.TransportControlView;
2824cfa450fa46a333ea9fa7de20a8755e592e1bedIlia Tulchinsky
2963b90f28858b9d259a1d4a145f51bdd36ada8730Dianne Hackbornimport android.accounts.Account;
304e8f62fbcb4c1edf0e6ef379ad231fa74b12a248Fred Quintanaimport android.accounts.AccountManager;
3163b90f28858b9d259a1d4a145f51bdd36ada8730Dianne Hackbornimport android.accounts.AccountManagerCallback;
3263b90f28858b9d259a1d4a145f51bdd36ada8730Dianne Hackbornimport android.accounts.AccountManagerFuture;
3363b90f28858b9d259a1d4a145f51bdd36ada8730Dianne Hackbornimport android.accounts.AuthenticatorException;
3463b90f28858b9d259a1d4a145f51bdd36ada8730Dianne Hackbornimport android.accounts.OperationCanceledException;
351f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.app.AlertDialog;
36f7c5d0e46ced3ec3edb6f656acd82900b9ac988cJim Millerimport android.app.admin.DevicePolicyManager;
371f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.content.Context;
381f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.content.Intent;
393a1837e9947505edc41d3f422bf0e0d268e349c3Jim Millerimport android.content.res.Configuration;
404ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Millerimport android.content.res.Resources;
4124cfa450fa46a333ea9fa7de20a8755e592e1bedIlia Tulchinskyimport android.graphics.Bitmap;
4224cfa450fa46a333ea9fa7de20a8755e592e1bedIlia Tulchinskyimport android.graphics.Canvas;
4302c4c8a700ab2c5dc10566550ba0cab121eff0ceJim Millerimport android.graphics.Color;
4424cfa450fa46a333ea9fa7de20a8755e592e1bedIlia Tulchinskyimport android.graphics.ColorFilter;
4524cfa450fa46a333ea9fa7de20a8755e592e1bedIlia Tulchinskyimport android.graphics.PixelFormat;
4602c4c8a700ab2c5dc10566550ba0cab121eff0ceJim Millerimport android.graphics.drawable.ColorDrawable;
4724cfa450fa46a333ea9fa7de20a8755e592e1bedIlia Tulchinskyimport android.graphics.drawable.Drawable;
48cf59a0b72d3fa6bfe21b3c4cab317ef06496961eDirk Balfanzimport android.os.Bundle;
494e6d35829ebf98ea37f77ea434550d51950c1119Jim Millerimport android.os.Parcelable;
50ebc6fb46c28c972d745c3d34b9fdfaf46fb20c1dSteven Rossimport android.os.PowerManager;
515475906f53e2d79807548932dfabbf9945143740Jim Millerimport android.os.SystemClock;
521f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.os.SystemProperties;
53c23024d32779b170dde32a50fbdd945ce521b874Jim Millerimport android.telephony.TelephonyManager;
541f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.text.TextUtils;
551f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.util.Log;
564f36995777a4136e8e63ea51cef2ff61df48790dJim Millerimport android.util.Slog;
571f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.view.KeyEvent;
582e1db30d18a0ff6640bb0ad61f922ec1fdcf5a3cSvetoslav Ganovimport android.view.MotionEvent;
591f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.view.View;
601f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.view.WindowManager;
612e1db30d18a0ff6640bb0ad61f922ec1fdcf5a3cSvetoslav Ganovimport android.view.accessibility.AccessibilityManager;
621f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
6363b90f28858b9d259a1d4a145f51bdd36ada8730Dianne Hackbornimport java.io.IOException;
6463b90f28858b9d259a1d4a145f51bdd36ada8730Dianne Hackborn
656edf2637e96139735df83907c221cce16d4d7eaaJim Miller
661f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project/**
671f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * The host view for all of the screens of the pattern unlock screen.  There are
681f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * two {@link Mode}s of operation, lock and unlock.  This will show the appropriate
6924cfa450fa46a333ea9fa7de20a8755e592e1bedIlia Tulchinsky * screen, and listen for callbacks via
7024cfa450fa46a333ea9fa7de20a8755e592e1bedIlia Tulchinsky * {@link com.android.internal.policy.impl.KeyguardScreenCallback}
711f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * from the current screen.
721f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project *
7324cfa450fa46a333ea9fa7de20a8755e592e1bedIlia Tulchinsky * This view, in turn, communicates back to
7424cfa450fa46a333ea9fa7de20a8755e592e1bedIlia Tulchinsky * {@link com.android.internal.policy.impl.KeyguardViewManager}
751f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * via its {@link com.android.internal.policy.impl.KeyguardViewCallback}, as appropriate.
761f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project */
779431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonnapublic class LockPatternKeyguardView extends KeyguardViewBase {
781f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
791c18828d20807342d37000746b18a3c1696f3b2eJim Miller    private static final int TRANSPORT_USERACTIVITY_TIMEOUT = 10000;
801c18828d20807342d37000746b18a3c1696f3b2eJim Miller
8175787398fa5db9add16f3d3bc298198ed2c6671fDianne Hackborn    static final boolean DEBUG_CONFIGURATION = false;
82cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana
83c23024d32779b170dde32a50fbdd945ce521b874Jim Miller    // time after launching EmergencyDialer before the screen goes blank.
84c23024d32779b170dde32a50fbdd945ce521b874Jim Miller    private static final int EMERGENCY_CALL_TIMEOUT = 10000;
85c23024d32779b170dde32a50fbdd945ce521b874Jim Miller
861f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    // intent action for launching emergency dialer activity.
871f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    static final String ACTION_EMERGENCY_DIAL = "com.android.phone.EmergencyDialer.DIAL";
881f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
891f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private static final boolean DEBUG = false;
901f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private static final String TAG = "LockPatternKeyguardView";
911f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
921f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private final KeyguardUpdateMonitor mUpdateMonitor;
931f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private final KeyguardWindowController mWindowController;
9424cfa450fa46a333ea9fa7de20a8755e592e1bedIlia Tulchinsky
951f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private View mLockScreen;
961f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private View mUnlockScreen;
971f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
98ebc6fb46c28c972d745c3d34b9fdfaf46fb20c1dSteven Ross    private boolean mScreenOn;
99ebc6fb46c28c972d745c3d34b9fdfaf46fb20c1dSteven Ross    private boolean mWindowFocused = false;
10024cfa450fa46a333ea9fa7de20a8755e592e1bedIlia Tulchinsky    private boolean mEnableFallback = false; // assume no fallback UI until we know better
1011f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1024ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller    private boolean mShowLockBeforeUnlock = false;
1034ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller
1043223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna    // Interface to a biometric sensor that can optionally be used to unlock the device
1053223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna    private BiometricSensorUnlock mBiometricUnlock;
1063223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna    private final Object mBiometricUnlockStartupLock = new Object();
1073223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna    // Long enough to stay visible while dialer comes up
1083223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna    // Short enough to not be visible if the user goes back immediately
1093223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna    private final int BIOMETRIC_AREA_EMERGENCY_DIALER_TIMEOUT = 1000;
1104d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna
1111f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private boolean mRequiresSim;
1123223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna    // True if the biometric unlock should not be displayed.  For example, if there is an overlay on
1133223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna    // lockscreen or the user is plugging in / unplugging the device.
114c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna    private boolean mSuppressBiometricUnlock;
1150a981cf522ba816065494473651105f4aa981654Steven Ross    //True if a dialog is currently displaying on top of this window
1160a981cf522ba816065494473651105f4aa981654Steven Ross    //Unlike other overlays, this does not close with a power button cycle
1170a981cf522ba816065494473651105f4aa981654Steven Ross    private boolean mHasDialog = false;
118c753a1865ca049fb20fc5cea036c06ea77647ff1Steven Ross    //True if this device is currently plugged in
119c753a1865ca049fb20fc5cea036c06ea77647ff1Steven Ross    private boolean mPluggedIn;
12078c629807c8fe914801ed17f7e16dc1f820e67cdSteven Ross    // True the first time lockscreen is showing after boot
12178c629807c8fe914801ed17f7e16dc1f820e67cdSteven Ross    private static boolean sIsFirstAppearanceAfterBoot = true;
1221f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
123b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller    // The music control widget
124b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller    private TransportControlView mTransportControlView;
125b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller
126b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller    private Parcelable mSavedState;
1271f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1281f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
1291f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * Either a lock screen (an informational keyguard screen), or an unlock
1301f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * screen (a means for unlocking the device) is shown at any given time.
1311f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
1321f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    enum Mode {
1331f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        LockScreen,
1341f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        UnlockScreen
1351f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
1361f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1371f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
1381f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * The different types screens available for {@link Mode#UnlockScreen}.
1391f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * @see com.android.internal.policy.impl.LockPatternKeyguardView#getUnlockMode()
1401f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
1411f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    enum UnlockMode {
1421f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1431f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        /**
1441f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * Unlock by drawing a pattern.
1451f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         */
1461f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        Pattern,
1471f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1481f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        /**
1491f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * Unlock by entering a sim pin.
1501f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         */
1511f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        SimPin,
1521f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1531f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        /**
1540f7b3f8ba5c2f0b8f96e072bd866c9fb374ebdebJohn Wang         * Unlock by entering a sim puk.
1550f7b3f8ba5c2f0b8f96e072bd866c9fb374ebdebJohn Wang         */
1560f7b3f8ba5c2f0b8f96e072bd866c9fb374ebdebJohn Wang        SimPuk,
1570f7b3f8ba5c2f0b8f96e072bd866c9fb374ebdebJohn Wang
1580f7b3f8ba5c2f0b8f96e072bd866c9fb374ebdebJohn Wang        /**
1591f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * Unlock by entering an account's login and password.
1601f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         */
1615e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller        Account,
1625e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller
1635e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller        /**
1645e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller         * Unlock by entering a password or PIN
1655e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller         */
1660d9f798e9f76b13b07ac3dee3ff90b5530f53145Jim Miller        Password,
1670d9f798e9f76b13b07ac3dee3ff90b5530f53145Jim Miller
1680d9f798e9f76b13b07ac3dee3ff90b5530f53145Jim Miller        /**
1690d9f798e9f76b13b07ac3dee3ff90b5530f53145Jim Miller         * Unknown (uninitialized) value
1700d9f798e9f76b13b07ac3dee3ff90b5530f53145Jim Miller         */
1710d9f798e9f76b13b07ac3dee3ff90b5530f53145Jim Miller        Unknown
1721f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
1731f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1741f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
1751f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * The current mode.
1761f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
1771f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private Mode mMode = Mode.LockScreen;
1781f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1791f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
18084999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaen     * Keeps track of what mode the current unlock screen is (cached from most recent computation in
18184999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaen     * {@link #getUnlockMode}).
1821f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
1834ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller    private UnlockMode mUnlockScreenMode = UnlockMode.Unknown;
1841f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
18584999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaen    private boolean mForgotPattern;
18684999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaen
1871f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
1881f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * If true, it means we are in the process of verifying that the user
1891f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * can get past the lock screen per {@link #verifyUnlock()}
1901f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
1911f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private boolean mIsVerifyUnlockOnly = false;
1921f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1931f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
1941f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * Used to lookup the state of the lock pattern
1951f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
1961f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private final LockPatternUtils mLockPatternUtils;
1971f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1981f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
1995475906f53e2d79807548932dfabbf9945143740Jim Miller     * The current configuration.
2005475906f53e2d79807548932dfabbf9945143740Jim Miller     */
2015475906f53e2d79807548932dfabbf9945143740Jim Miller    private Configuration mConfiguration;
2025475906f53e2d79807548932dfabbf9945143740Jim Miller
2031e0c7ae184984051e8f42c71f89435fc1d40be35Kenneth Andersson    private Runnable mRecreateRunnable = new Runnable() {
2041e0c7ae184984051e8f42c71f89435fc1d40be35Kenneth Andersson        public void run() {
2052de5ee84636739dc82a4c4dda76666bf38cf281cJim Miller            Mode mode = mMode;
2062de5ee84636739dc82a4c4dda76666bf38cf281cJim Miller            // If we were previously in a locked state but now it's Unknown, it means the phone
2072de5ee84636739dc82a4c4dda76666bf38cf281cJim Miller            // was previously locked because of SIM state and has since been resolved. This
2082de5ee84636739dc82a4c4dda76666bf38cf281cJim Miller            // bit of code checks this condition and dismisses keyguard.
2092de5ee84636739dc82a4c4dda76666bf38cf281cJim Miller            boolean dismissAfterCreation = false;
2102de5ee84636739dc82a4c4dda76666bf38cf281cJim Miller            if (mode == Mode.UnlockScreen && getUnlockMode() == UnlockMode.Unknown) {
2112de5ee84636739dc82a4c4dda76666bf38cf281cJim Miller                if (DEBUG) Log.v(TAG, "Switch to Mode.LockScreen because SIM unlocked");
2122de5ee84636739dc82a4c4dda76666bf38cf281cJim Miller                mode = Mode.LockScreen;
2132de5ee84636739dc82a4c4dda76666bf38cf281cJim Miller                dismissAfterCreation = true;
2142de5ee84636739dc82a4c4dda76666bf38cf281cJim Miller            }
2152de5ee84636739dc82a4c4dda76666bf38cf281cJim Miller            updateScreen(mode, true);
2164e6d35829ebf98ea37f77ea434550d51950c1119Jim Miller            restoreWidgetState();
2172de5ee84636739dc82a4c4dda76666bf38cf281cJim Miller            if (dismissAfterCreation) {
2182de5ee84636739dc82a4c4dda76666bf38cf281cJim Miller                mKeyguardScreenCallback.keyguardDone(false);
2192de5ee84636739dc82a4c4dda76666bf38cf281cJim Miller            }
2201e0c7ae184984051e8f42c71f89435fc1d40be35Kenneth Andersson        }
2211e0c7ae184984051e8f42c71f89435fc1d40be35Kenneth Andersson    };
2221e0c7ae184984051e8f42c71f89435fc1d40be35Kenneth Andersson
2231c18828d20807342d37000746b18a3c1696f3b2eJim Miller    private LockScreenWidgetCallback mWidgetCallback = new LockScreenWidgetCallback() {
2241c18828d20807342d37000746b18a3c1696f3b2eJim Miller        public void userActivity(View self) {
2251c18828d20807342d37000746b18a3c1696f3b2eJim Miller            mKeyguardScreenCallback.pokeWakelock(TRANSPORT_USERACTIVITY_TIMEOUT);
2261c18828d20807342d37000746b18a3c1696f3b2eJim Miller        }
2271c18828d20807342d37000746b18a3c1696f3b2eJim Miller
2281c18828d20807342d37000746b18a3c1696f3b2eJim Miller        public void requestShow(View view) {
2291c18828d20807342d37000746b18a3c1696f3b2eJim Miller            if (DEBUG) Log.v(TAG, "View " + view + " requested show transports");
2301c18828d20807342d37000746b18a3c1696f3b2eJim Miller            view.setVisibility(View.VISIBLE);
231054340d0a3f242efeaf898cca38625bdcb3b4b5aJeff Sharkey
232054340d0a3f242efeaf898cca38625bdcb3b4b5aJeff Sharkey            // TODO: examine all widgets to derive clock status
233054340d0a3f242efeaf898cca38625bdcb3b4b5aJeff Sharkey            mUpdateMonitor.reportClockVisible(false);
23402c4c8a700ab2c5dc10566550ba0cab121eff0ceJim Miller
235faed16030df5221f790a4d6fd5bdfb592db977faJim Miller            // If there's not a bg protection view containing the transport, then show a black
236faed16030df5221f790a4d6fd5bdfb592db977faJim Miller            // background. Otherwise, allow the normal background to show.
237faed16030df5221f790a4d6fd5bdfb592db977faJim Miller            if (findViewById(R.id.transport_bg_protect) == null) {
238faed16030df5221f790a4d6fd5bdfb592db977faJim Miller                // TODO: We should disable the wallpaper instead
239faed16030df5221f790a4d6fd5bdfb592db977faJim Miller                setBackgroundColor(0xff000000);
240faed16030df5221f790a4d6fd5bdfb592db977faJim Miller            } else {
241faed16030df5221f790a4d6fd5bdfb592db977faJim Miller                resetBackground();
242faed16030df5221f790a4d6fd5bdfb592db977faJim Miller            }
2431c18828d20807342d37000746b18a3c1696f3b2eJim Miller        }
2441c18828d20807342d37000746b18a3c1696f3b2eJim Miller
2451c18828d20807342d37000746b18a3c1696f3b2eJim Miller        public void requestHide(View view) {
2461c18828d20807342d37000746b18a3c1696f3b2eJim Miller            if (DEBUG) Log.v(TAG, "View " + view + " requested hide transports");
2471c18828d20807342d37000746b18a3c1696f3b2eJim Miller            view.setVisibility(View.GONE);
248054340d0a3f242efeaf898cca38625bdcb3b4b5aJeff Sharkey
249054340d0a3f242efeaf898cca38625bdcb3b4b5aJeff Sharkey            // TODO: examine all widgets to derive clock status
250054340d0a3f242efeaf898cca38625bdcb3b4b5aJeff Sharkey            mUpdateMonitor.reportClockVisible(true);
2512928c9d82b4fcca67472cf77e3c508e64baff1fcJim Miller            resetBackground();
2521c18828d20807342d37000746b18a3c1696f3b2eJim Miller        }
2534e6d35829ebf98ea37f77ea434550d51950c1119Jim Miller
2544e6d35829ebf98ea37f77ea434550d51950c1119Jim Miller        public boolean isVisible(View self) {
2554e6d35829ebf98ea37f77ea434550d51950c1119Jim Miller            // TODO: this should be up to the lockscreen to determine if the view
2564e6d35829ebf98ea37f77ea434550d51950c1119Jim Miller            // is currently showing. The idea is it can be used for the widget to
2574e6d35829ebf98ea37f77ea434550d51950c1119Jim Miller            // avoid doing work if it's not visible. For now just returns the view's
2584e6d35829ebf98ea37f77ea434550d51950c1119Jim Miller            // actual visibility.
2594e6d35829ebf98ea37f77ea434550d51950c1119Jim Miller            return self.getVisibility() == View.VISIBLE;
2604e6d35829ebf98ea37f77ea434550d51950c1119Jim Miller        }
2611c18828d20807342d37000746b18a3c1696f3b2eJim Miller    };
2621c18828d20807342d37000746b18a3c1696f3b2eJim Miller
2635475906f53e2d79807548932dfabbf9945143740Jim Miller    /**
2641f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * @return Whether we are stuck on the lock screen because the sim is
2651f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     *   missing.
2661f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
2671f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private boolean stuckOnLockScreenBecauseSimMissing() {
2681f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        return mRequiresSim
2691f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                && (!mUpdateMonitor.isDeviceProvisioned())
270b0b24b3df50988d23f571b83d829fecc986ec497John Wang                && (mUpdateMonitor.getSimState() == IccCard.State.ABSENT ||
271b0b24b3df50988d23f571b83d829fecc986ec497John Wang                    mUpdateMonitor.getSimState() == IccCard.State.PERM_DISABLED);
2721f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
2731f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2741f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
275b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller     * The current {@link KeyguardScreen} will use this to communicate back to us.
2761f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
277b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller    KeyguardScreenCallback mKeyguardScreenCallback = new KeyguardScreenCallback() {
278b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller
279b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller        public void goToLockScreen() {
280b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller            mForgotPattern = false;
281b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller            if (mIsVerifyUnlockOnly) {
282b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller                // navigating away from unlock screen during verify mode means
283b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller                // we are done and the user failed to authenticate.
284b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller                mIsVerifyUnlockOnly = false;
285b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller                getCallback().keyguardDone(false);
286b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller            } else {
287b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller                updateScreen(Mode.LockScreen, false);
288b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller            }
289b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller        }
2904e8f62fbcb4c1edf0e6ef379ad231fa74b12a248Fred Quintana
291b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller        public void goToUnlockScreen() {
292b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller            final IccCard.State simState = mUpdateMonitor.getSimState();
293b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller            if (stuckOnLockScreenBecauseSimMissing()
294b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller                     || (simState == IccCard.State.PUK_REQUIRED
295b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller                         && !mLockPatternUtils.isPukUnlockScreenEnable())){
296b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller                // stuck on lock screen when sim missing or
297b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller                // puk'd but puk unlock screen is disabled
298b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller                return;
299b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller            }
300b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller            if (!isSecure()) {
301b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller                getCallback().keyguardDone(true);
302b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller            } else {
303b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller                updateScreen(Mode.UnlockScreen, false);
304b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller            }
305b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller        }
3061f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
307b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller        public void forgotPattern(boolean isForgotten) {
308b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller            if (mEnableFallback) {
309b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller                mForgotPattern = isForgotten;
310b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller                updateScreen(Mode.UnlockScreen, false);
311b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller            }
312b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller        }
313dce0bb62ce4e1afbdacd2b4a8ee2e02a1563e852Steven Ross
314b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller        public boolean isSecure() {
315b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller            return LockPatternKeyguardView.this.isSecure();
316b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller        }
3171f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
318b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller        public boolean isVerifyUnlockOnly() {
319b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller            return mIsVerifyUnlockOnly;
320b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller        }
3211f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
322b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller        public void recreateMe(Configuration config) {
3232de5ee84636739dc82a4c4dda76666bf38cf281cJim Miller            if (DEBUG) Log.v(TAG, "recreateMe()");
324b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller            removeCallbacks(mRecreateRunnable);
325b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller            post(mRecreateRunnable);
326b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller        }
3271f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
328b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller        public void takeEmergencyCallAction() {
329c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna            mSuppressBiometricUnlock = true;
33084999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaen
331c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna            if (mBiometricUnlock != null) {
332c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna                if (mBiometricUnlock.isRunning()) {
333c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna                    // Continue covering backup lock until dialer comes up or call is resumed
334c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna                    mBiometricUnlock.show(BIOMETRIC_AREA_EMERGENCY_DIALER_TIMEOUT);
335c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna                }
3361f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
337c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna                // We must ensure the biometric unlock is stopped when emergency call is pressed
338c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna                mBiometricUnlock.stop();
339c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna            }
3401f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
341b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller            pokeWakelock(EMERGENCY_CALL_TIMEOUT);
342b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller            if (TelephonyManager.getDefault().getCallState()
343b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller                    == TelephonyManager.CALL_STATE_OFFHOOK) {
344b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller                mLockPatternUtils.resumeCall();
345b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller            } else {
346b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller                Intent intent = new Intent(ACTION_EMERGENCY_DIAL);
347b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
348b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller                        | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
349b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller                getContext().startActivity(intent);
3501f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
351b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller        }
3521f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
353b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller        public void pokeWakelock() {
354b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller            getCallback().pokeWakelock();
355b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller        }
356eef1ae1d91d55341c25d01547ac9b952be5aa658Brian Colonna
357b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller        public void pokeWakelock(int millis) {
358b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller            getCallback().pokeWakelock(millis);
359b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller        }
360eef1ae1d91d55341c25d01547ac9b952be5aa658Brian Colonna
361b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller        public void keyguardDone(boolean authenticated) {
362b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller            getCallback().keyguardDone(authenticated);
363b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller            mSavedState = null; // clear state so we re-establish when locked again
364b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller        }
3656e6e5df754bb6f41a37500d5b1c45329a37ca326Brian Colonna
366b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller        public void keyguardDoneDrawing() {
367b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller            // irrelevant to keyguard screen, they shouldn't be calling this
368b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller        }
3691f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
370b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller        public void reportFailedUnlockAttempt() {
371b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller            mUpdateMonitor.reportFailedAttempt();
372b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller            final int failedAttempts = mUpdateMonitor.getFailedAttempts();
373b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller            if (DEBUG) Log.d(TAG, "reportFailedPatternAttempt: #" + failedAttempts +
374b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller                " (enableFallback=" + mEnableFallback + ")");
3751f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
376b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller            final boolean usingPattern = mLockPatternUtils.getKeyguardStoredPasswordQuality()
377b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller                    == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
3781f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
379b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller            final int failedAttemptsBeforeWipe = mLockPatternUtils.getDevicePolicyManager()
380b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller                    .getMaximumFailedPasswordsForWipe(null);
3811f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
382b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller            final int failedAttemptWarning = LockPatternUtils.FAILED_ATTEMPTS_BEFORE_RESET
383b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller                    - LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT;
3841f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
385b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller            final int remainingBeforeWipe = failedAttemptsBeforeWipe > 0 ?
386b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller                    (failedAttemptsBeforeWipe - failedAttempts)
387b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller                    : Integer.MAX_VALUE; // because DPM returns 0 if no restriction
388b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller
389b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller            if (remainingBeforeWipe < LockPatternUtils.FAILED_ATTEMPTS_BEFORE_WIPE_GRACE) {
390b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller                // If we reach this code, it means the user has installed a DevicePolicyManager
391b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller                // that requests device wipe after N attempts.  Once we get below the grace
392b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller                // period, we'll post this dialog every time as a clear warning until the
393b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller                // bombshell hits and the device is wiped.
394b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller                if (remainingBeforeWipe > 0) {
395b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller                    showAlmostAtWipeDialog(failedAttempts, remainingBeforeWipe);
3964f36995777a4136e8e63ea51cef2ff61df48790dJim Miller                } else {
397b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller                    // Too many attempts. The device will be wiped shortly.
398b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller                    Slog.i(TAG, "Too many unlock attempts; device will be wiped!");
399b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller                    showWipeDialog(failedAttempts);
400b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller                }
401b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller            } else {
402b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller                boolean showTimeout =
403b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller                    (failedAttempts % LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT) == 0;
404b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller                if (usingPattern && mEnableFallback) {
405b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller                    if (failedAttempts == failedAttemptWarning) {
406b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller                        showAlmostAtAccountLoginDialog();
407b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller                        showTimeout = false; // don't show both dialogs
408b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller                    } else if (failedAttempts >= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_RESET) {
409b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller                        mLockPatternUtils.setPermanentlyLocked(true);
410b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller                        updateScreen(mMode, false);
411b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller                        // don't show timeout dialog because we show account unlock screen next
412b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller                        showTimeout = false;
4134f36995777a4136e8e63ea51cef2ff61df48790dJim Miller                    }
4141f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                }
415b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller                if (showTimeout) {
416b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller                    showTimeoutDialog();
417b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller                }
4181f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
419b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller            mLockPatternUtils.reportFailedPasswordAttempt();
420b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller        }
42124cfa450fa46a333ea9fa7de20a8755e592e1bedIlia Tulchinsky
422b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller        public boolean doesFallbackUnlockScreenExist() {
423b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller            return mEnableFallback;
424b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller        }
4256fe0f0e46d7863bd75f6bd23b2fa805df84b5a4dJim Miller
426b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller        public void reportSuccessfulUnlockAttempt() {
427b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller            mLockPatternUtils.reportSuccessfulPasswordAttempt();
428b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller        }
429b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller    };
430b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller
431b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller    /**
432b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller     * @param context Used to inflate, and create views.
433b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller     * @param callback Keyguard callback object for pokewakelock(), etc.
434b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller     * @param updateMonitor Knows the state of the world, and passed along to each
435b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller     *   screen so they can use the knowledge, and also register for callbacks
436b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller     *   on dynamic information.
437b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller     * @param lockPatternUtils Used to look up state of lock pattern.
438b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller     */
439b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller    public LockPatternKeyguardView(
440b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller            Context context, KeyguardViewCallback callback, KeyguardUpdateMonitor updateMonitor,
441b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller            LockPatternUtils lockPatternUtils, KeyguardWindowController controller) {
442b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller        super(context, callback);
443b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller
444b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller        mConfiguration = context.getResources().getConfiguration();
445b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller        mEnableFallback = false;
446b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller        mRequiresSim = TextUtils.isEmpty(SystemProperties.get("keyguard.no_require_sim"));
447b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller        mUpdateMonitor = updateMonitor;
448b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller        mLockPatternUtils = lockPatternUtils;
449b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller        mWindowController = controller;
45078c629807c8fe914801ed17f7e16dc1f820e67cdSteven Ross        mSuppressBiometricUnlock = sIsFirstAppearanceAfterBoot;
45178c629807c8fe914801ed17f7e16dc1f820e67cdSteven Ross        sIsFirstAppearanceAfterBoot = false;
452b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller        mPluggedIn = mUpdateMonitor.isDevicePluggedIn();
453b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller        mScreenOn = ((PowerManager)context.getSystemService(Context.POWER_SERVICE)).isScreenOn();
454b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller        mUpdateMonitor.registerInfoCallback(mInfoCallback);
4551f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4561f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        /**
4571f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * We'll get key events the current screen doesn't use. see
4581f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * {@link KeyguardViewBase#onKeyDown(int, android.view.KeyEvent)}
4591f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         */
4601f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        setFocusableInTouchMode(true);
4611f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        setDescendantFocusability(FOCUS_AFTER_DESCENDANTS);
4621f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4634ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller        updateScreen(getInitialMode(), false);
46418c59475445751e9ed24cacd7cfdbf86a94412fdJim Miller        maybeEnableFallback(context);
46518c59475445751e9ed24cacd7cfdbf86a94412fdJim Miller    }
46618c59475445751e9ed24cacd7cfdbf86a94412fdJim Miller
467cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana    private class AccountAnalyzer implements AccountManagerCallback<Bundle> {
468cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana        private final AccountManager mAccountManager;
469cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana        private final Account[] mAccounts;
470cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana        private int mAccountIndex;
471cf59a0b72d3fa6bfe21b3c4cab317ef06496961eDirk Balfanz
472cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana        private AccountAnalyzer(AccountManager accountManager) {
473cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana            mAccountManager = accountManager;
474cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana            mAccounts = accountManager.getAccountsByType("com.google");
475cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana        }
476cf59a0b72d3fa6bfe21b3c4cab317ef06496961eDirk Balfanz
477cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana        private void next() {
478cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana            // if we are ready to enable the fallback or if we depleted the list of accounts
479cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana            // then finish and get out
480cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana            if (mEnableFallback || mAccountIndex >= mAccounts.length) {
481cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana                if (mUnlockScreen == null) {
48262c3efd204acdf1f7bf3bde584e2a0dfd9ca046eJim Miller                    if (DEBUG) Log.w(TAG, "no unlock screen when trying to enable fallback");
483cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana                } else if (mUnlockScreen instanceof PatternUnlockScreen) {
484cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana                    ((PatternUnlockScreen)mUnlockScreen).setEnableFallback(mEnableFallback);
485cf59a0b72d3fa6bfe21b3c4cab317ef06496961eDirk Balfanz                }
486cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana                return;
487cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana            }
488cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana
489cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana            // lookup the confirmCredentials intent for the current account
490cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana            mAccountManager.confirmCredentials(mAccounts[mAccountIndex], null, null, this, null);
491cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana        }
492cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana
493cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana        public void start() {
494cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana            mEnableFallback = false;
495cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana            mAccountIndex = 0;
496cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana            next();
497cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana        }
498cf59a0b72d3fa6bfe21b3c4cab317ef06496961eDirk Balfanz
499cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana        public void run(AccountManagerFuture<Bundle> future) {
500cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana            try {
501cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana                Bundle result = future.getResult();
502cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana                if (result.getParcelable(AccountManager.KEY_INTENT) != null) {
503cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana                    mEnableFallback = true;
504cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana                }
505cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana            } catch (OperationCanceledException e) {
506cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana                // just skip the account if we are unable to query it
507cf59a0b72d3fa6bfe21b3c4cab317ef06496961eDirk Balfanz            } catch (IOException e) {
508cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana                // just skip the account if we are unable to query it
509cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana            } catch (AuthenticatorException e) {
510cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana                // just skip the account if we are unable to query it
511cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana            } finally {
512cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana                mAccountIndex++;
513cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana                next();
514cf59a0b72d3fa6bfe21b3c4cab317ef06496961eDirk Balfanz            }
515cf59a0b72d3fa6bfe21b3c4cab317ef06496961eDirk Balfanz        }
516cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana    }
517cf59a0b72d3fa6bfe21b3c4cab317ef06496961eDirk Balfanz
518cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana    private void maybeEnableFallback(Context context) {
519cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana        // Ask the account manager if we have an account that can be used as a
520cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana        // fallback in case the user forgets his pattern.
521cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana        AccountAnalyzer accountAnalyzer = new AccountAnalyzer(AccountManager.get(context));
522cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana        accountAnalyzer.start();
5231f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
5241f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
5251f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
5263a1837e9947505edc41d3f422bf0e0d268e349c3Jim Miller    // TODO:
5273a1837e9947505edc41d3f422bf0e0d268e349c3Jim Miller    // This overloaded method was added to workaround a race condition in the framework between
5283a1837e9947505edc41d3f422bf0e0d268e349c3Jim Miller    // notification for orientation changed, layout() and switching resources.  This code attempts
5293a1837e9947505edc41d3f422bf0e0d268e349c3Jim Miller    // to avoid drawing the incorrect layout while things are in transition.  The method can just
5303a1837e9947505edc41d3f422bf0e0d268e349c3Jim Miller    // be removed once the race condition is fixed. See bugs 2262578 and 2292713.
5313a1837e9947505edc41d3f422bf0e0d268e349c3Jim Miller    @Override
5323a1837e9947505edc41d3f422bf0e0d268e349c3Jim Miller    protected void dispatchDraw(Canvas canvas) {
5335475906f53e2d79807548932dfabbf9945143740Jim Miller        if (DEBUG) Log.v(TAG, "*** dispatchDraw() time: " + SystemClock.elapsedRealtime());
5343a1837e9947505edc41d3f422bf0e0d268e349c3Jim Miller        super.dispatchDraw(canvas);
5353a1837e9947505edc41d3f422bf0e0d268e349c3Jim Miller    }
5363a1837e9947505edc41d3f422bf0e0d268e349c3Jim Miller
5371f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    @Override
5381f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    public void reset() {
5391f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mIsVerifyUnlockOnly = false;
54084999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaen        mForgotPattern = false;
5412de5ee84636739dc82a4c4dda76666bf38cf281cJim Miller        if (DEBUG) Log.v(TAG, "reset()");
54262c3efd204acdf1f7bf3bde584e2a0dfd9ca046eJim Miller        post(mRecreateRunnable);
5431f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
5441f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
5451f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    @Override
5461f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    public void onScreenTurnedOff() {
5477726289c2890d13baa3d10dc504b43e2128b4918Steven Ross        if (DEBUG) Log.d(TAG, "screen off");
5481f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mScreenOn = false;
54984999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaen        mForgotPattern = false;
5509a3caf39e4c628c6dfcac92f7e2b7e4538a73009Jim Miller
5519a3caf39e4c628c6dfcac92f7e2b7e4538a73009Jim Miller        // Emulate activity life-cycle for both lock and unlock screen.
5529a3caf39e4c628c6dfcac92f7e2b7e4538a73009Jim Miller        if (mLockScreen != null) {
5534ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller            ((KeyguardScreen) mLockScreen).onPause();
5549a3caf39e4c628c6dfcac92f7e2b7e4538a73009Jim Miller        }
5559a3caf39e4c628c6dfcac92f7e2b7e4538a73009Jim Miller        if (mUnlockScreen != null) {
5561f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            ((KeyguardScreen) mUnlockScreen).onPause();
5571f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
558267cb2b284626f910cf64352bfc494d0f8d3dc42Brian Colonna
5594e6d35829ebf98ea37f77ea434550d51950c1119Jim Miller        saveWidgetState();
5604e6d35829ebf98ea37f77ea434550d51950c1119Jim Miller
561c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna        if (mBiometricUnlock != null) {
562c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna            // The biometric unlock must stop when screen turns off.
563c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna            mBiometricUnlock.stop();
564c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna        }
5651f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
5661f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
567c3892c525d5fffc40f068e7fdc975807e987c9d4Steven Ross    @Override
568c3892c525d5fffc40f068e7fdc975807e987c9d4Steven Ross    public void onScreenTurnedOn() {
5697726289c2890d13baa3d10dc504b43e2128b4918Steven Ross        if (DEBUG) Log.d(TAG, "screen on");
5703223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna        boolean startBiometricUnlock = false;
5713223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna        // Start the biometric unlock if and only if the screen is both on and focused
5723223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna        synchronized(mBiometricUnlockStartupLock) {
573c3892c525d5fffc40f068e7fdc975807e987c9d4Steven Ross            mScreenOn = true;
5743223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna            startBiometricUnlock = mWindowFocused;
575c3892c525d5fffc40f068e7fdc975807e987c9d4Steven Ross        }
5764e6d35829ebf98ea37f77ea434550d51950c1119Jim Miller
577c3892c525d5fffc40f068e7fdc975807e987c9d4Steven Ross        show();
5784e6d35829ebf98ea37f77ea434550d51950c1119Jim Miller
5794e6d35829ebf98ea37f77ea434550d51950c1119Jim Miller        restoreWidgetState();
5804e6d35829ebf98ea37f77ea434550d51950c1119Jim Miller
581c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna        if (mBiometricUnlock != null && startBiometricUnlock) {
582ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna            maybeStartBiometricUnlock();
583c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna        }
5844e6d35829ebf98ea37f77ea434550d51950c1119Jim Miller    }
5854e6d35829ebf98ea37f77ea434550d51950c1119Jim Miller
5864e6d35829ebf98ea37f77ea434550d51950c1119Jim Miller    private void saveWidgetState() {
5874e6d35829ebf98ea37f77ea434550d51950c1119Jim Miller        if (mTransportControlView != null) {
5884e6d35829ebf98ea37f77ea434550d51950c1119Jim Miller            if (DEBUG) Log.v(TAG, "Saving widget state");
5894e6d35829ebf98ea37f77ea434550d51950c1119Jim Miller            mSavedState = mTransportControlView.onSaveInstanceState();
5904e6d35829ebf98ea37f77ea434550d51950c1119Jim Miller        }
5914e6d35829ebf98ea37f77ea434550d51950c1119Jim Miller    }
5924e6d35829ebf98ea37f77ea434550d51950c1119Jim Miller
5934e6d35829ebf98ea37f77ea434550d51950c1119Jim Miller    private void restoreWidgetState() {
5944e6d35829ebf98ea37f77ea434550d51950c1119Jim Miller        if (mTransportControlView != null) {
5954e6d35829ebf98ea37f77ea434550d51950c1119Jim Miller            if (DEBUG) Log.v(TAG, "Restoring widget state");
5964e6d35829ebf98ea37f77ea434550d51950c1119Jim Miller            if (mSavedState != null) {
5974e6d35829ebf98ea37f77ea434550d51950c1119Jim Miller                mTransportControlView.onRestoreInstanceState(mSavedState);
5984e6d35829ebf98ea37f77ea434550d51950c1119Jim Miller            }
5994e6d35829ebf98ea37f77ea434550d51950c1119Jim Miller        }
600c3892c525d5fffc40f068e7fdc975807e987c9d4Steven Ross    }
601c3892c525d5fffc40f068e7fdc975807e987c9d4Steven Ross
6023223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna    /**
6033223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna     * Stop the biometric unlock if something covers this window (such as an alarm)
6043223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna     * Start the biometric unlock if the lockscreen window just came into focus and the screen is on
605c3892c525d5fffc40f068e7fdc975807e987c9d4Steven Ross     */
6069c2df261797259728845a04d5e47ddf36251f93dSteven Ross    @Override
6079c2df261797259728845a04d5e47ddf36251f93dSteven Ross    public void onWindowFocusChanged (boolean hasWindowFocus) {
6087726289c2890d13baa3d10dc504b43e2128b4918Steven Ross        if (DEBUG) Log.d(TAG, hasWindowFocus ? "focused" : "unfocused");
609c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna
6103223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna        boolean startBiometricUnlock = false;
6113223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna        // Start the biometric unlock if and only if the screen is both on and focused
6123223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna        synchronized(mBiometricUnlockStartupLock) {
6133223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna            if (mScreenOn && !mWindowFocused) startBiometricUnlock = hasWindowFocus;
614c3892c525d5fffc40f068e7fdc975807e987c9d4Steven Ross            mWindowFocused = hasWindowFocus;
615c3892c525d5fffc40f068e7fdc975807e987c9d4Steven Ross        }
6169431366ecb4b6e4a87c0047c36548aa0bc23f2b1Brian Colonna        if (!hasWindowFocus) {
617c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna            if (mBiometricUnlock != null) {
618c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna                mSuppressBiometricUnlock = true;
619c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna                mBiometricUnlock.stop();
620c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna                mBiometricUnlock.hide();
621c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna            }
6220a981cf522ba816065494473651105f4aa981654Steven Ross        } else {
6230a981cf522ba816065494473651105f4aa981654Steven Ross            mHasDialog = false;
624c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna            if (mBiometricUnlock != null && startBiometricUnlock) {
625ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna                maybeStartBiometricUnlock();
626c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna            }
6279c2df261797259728845a04d5e47ddf36251f93dSteven Ross        }
6289c2df261797259728845a04d5e47ddf36251f93dSteven Ross    }
6299c2df261797259728845a04d5e47ddf36251f93dSteven Ross
6304284e9d19a3f917b85e5eac4d6e304fc9b866139Brian Colonna    @Override
6314284e9d19a3f917b85e5eac4d6e304fc9b866139Brian Colonna    public void show() {
6329a3caf39e4c628c6dfcac92f7e2b7e4538a73009Jim Miller        // Emulate activity life-cycle for both lock and unlock screen.
6339a3caf39e4c628c6dfcac92f7e2b7e4538a73009Jim Miller        if (mLockScreen != null) {
6344284e9d19a3f917b85e5eac4d6e304fc9b866139Brian Colonna            ((KeyguardScreen) mLockScreen).onResume();
6359a3caf39e4c628c6dfcac92f7e2b7e4538a73009Jim Miller        }
6369a3caf39e4c628c6dfcac92f7e2b7e4538a73009Jim Miller        if (mUnlockScreen != null) {
6374284e9d19a3f917b85e5eac4d6e304fc9b866139Brian Colonna            ((KeyguardScreen) mUnlockScreen).onResume();
6384284e9d19a3f917b85e5eac4d6e304fc9b866139Brian Colonna        }
639cfdd6242eb0c26373b9c57d2ad1ddc126708189eBrian Colonna
640c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna        if (mBiometricUnlock != null && mSuppressBiometricUnlock) {
6413223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna            mBiometricUnlock.hide();
642cfdd6242eb0c26373b9c57d2ad1ddc126708189eBrian Colonna        }
6434284e9d19a3f917b85e5eac4d6e304fc9b866139Brian Colonna    }
6444284e9d19a3f917b85e5eac4d6e304fc9b866139Brian Colonna
6450d9f798e9f76b13b07ac3dee3ff90b5530f53145Jim Miller    private void recreateLockScreen() {
6464ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller        if (mLockScreen != null) {
64762c3efd204acdf1f7bf3bde584e2a0dfd9ca046eJim Miller            ((KeyguardScreen) mLockScreen).onPause();
6484ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller            ((KeyguardScreen) mLockScreen).cleanUp();
6494ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller            removeView(mLockScreen);
6501f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
6511f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
6521f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mLockScreen = createLockScreen();
6531f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mLockScreen.setVisibility(View.INVISIBLE);
6541f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        addView(mLockScreen);
6550d9f798e9f76b13b07ac3dee3ff90b5530f53145Jim Miller    }
6561f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
6574ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller    private void recreateUnlockScreen(UnlockMode unlockMode) {
6584ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller        if (mUnlockScreen != null) {
65962c3efd204acdf1f7bf3bde584e2a0dfd9ca046eJim Miller            ((KeyguardScreen) mUnlockScreen).onPause();
6604ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller            ((KeyguardScreen) mUnlockScreen).cleanUp();
6614ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller            removeView(mUnlockScreen);
6621f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
6631f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
6641f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mUnlockScreen = createUnlockScreenFor(unlockMode);
6651f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mUnlockScreen.setVisibility(View.INVISIBLE);
6661f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        addView(mUnlockScreen);
6670d9f798e9f76b13b07ac3dee3ff90b5530f53145Jim Miller    }
6681f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
6691f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    @Override
6701e0c7ae184984051e8f42c71f89435fc1d40be35Kenneth Andersson    protected void onDetachedFromWindow() {
671b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller        mUpdateMonitor.removeCallback(mInfoCallback);
672b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller
6731e0c7ae184984051e8f42c71f89435fc1d40be35Kenneth Andersson        removeCallbacks(mRecreateRunnable);
674267cb2b284626f910cf64352bfc494d0f8d3dc42Brian Colonna
675c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna        if (mBiometricUnlock != null) {
676c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna            // When view is hidden, we need to stop the biometric unlock
677c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna            // e.g., when device becomes unlocked
678c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna            mBiometricUnlock.stop();
679c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna        }
680267cb2b284626f910cf64352bfc494d0f8d3dc42Brian Colonna
6811e0c7ae184984051e8f42c71f89435fc1d40be35Kenneth Andersson        super.onDetachedFromWindow();
6821e0c7ae184984051e8f42c71f89435fc1d40be35Kenneth Andersson    }
6831e0c7ae184984051e8f42c71f89435fc1d40be35Kenneth Andersson
6841c18828d20807342d37000746b18a3c1696f3b2eJim Miller    protected void onConfigurationChanged(Configuration newConfig) {
6851c18828d20807342d37000746b18a3c1696f3b2eJim Miller        Resources resources = getResources();
6861c18828d20807342d37000746b18a3c1696f3b2eJim Miller        mShowLockBeforeUnlock = resources.getBoolean(R.bool.config_enableLockBeforeUnlockScreen);
6871c18828d20807342d37000746b18a3c1696f3b2eJim Miller        mConfiguration = newConfig;
6881c18828d20807342d37000746b18a3c1696f3b2eJim Miller        if (DEBUG_CONFIGURATION) Log.v(TAG, "**** re-creating lock screen since config changed");
6894e6d35829ebf98ea37f77ea434550d51950c1119Jim Miller        saveWidgetState();
69051e9d5c635b8882c1947122f1aa7e820d3a5f287Adam Cohen        removeCallbacks(mRecreateRunnable);
6912de5ee84636739dc82a4c4dda76666bf38cf281cJim Miller        if (DEBUG) Log.v(TAG, "recreating lockscreen because config changed");
69251e9d5c635b8882c1947122f1aa7e820d3a5f287Adam Cohen        post(mRecreateRunnable);
6931c18828d20807342d37000746b18a3c1696f3b2eJim Miller    }
6941c18828d20807342d37000746b18a3c1696f3b2eJim Miller
695b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller    InfoCallbackImpl mInfoCallback = new InfoCallbackImpl() {
696305c78cce649056643641c51f12f2b6d2eb839f3Jim Miller
697b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller        @Override
698b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller        public void onRefreshBatteryInfo(boolean showBatteryInfo, boolean pluggedIn,
699b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller                int batteryLevel) {
700f6d61c64fb173aa7a1415870d5fdfe730eaa4160Brian Colonna            // When someone plugs in or unplugs the device, we hide the biometric sensor area and
701f6d61c64fb173aa7a1415870d5fdfe730eaa4160Brian Colonna            // suppress its startup for the next onScreenTurnedOn().  Since plugging/unplugging
702f6d61c64fb173aa7a1415870d5fdfe730eaa4160Brian Colonna            // causes the screen to turn on, the biometric unlock would start if it wasn't
703f6d61c64fb173aa7a1415870d5fdfe730eaa4160Brian Colonna            // suppressed.
704f6d61c64fb173aa7a1415870d5fdfe730eaa4160Brian Colonna            //
705f6d61c64fb173aa7a1415870d5fdfe730eaa4160Brian Colonna            // However, if the biometric unlock is already running, we do not want to interrupt it.
706c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna            if (mBiometricUnlock != null && mPluggedIn != pluggedIn
707c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna                    && !mBiometricUnlock.isRunning()) {
7083223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna                mBiometricUnlock.stop();
7093223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna                mBiometricUnlock.hide();
710c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna                mSuppressBiometricUnlock = true;
711b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller            }
712f6d61c64fb173aa7a1415870d5fdfe730eaa4160Brian Colonna            mPluggedIn = pluggedIn;
713b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller        }
714305c78cce649056643641c51f12f2b6d2eb839f3Jim Miller
715b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller        @Override
716b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller        public void onClockVisibilityChanged() {
717354619c1cc1b4668c81c5368b2256335cc9e8538Jim Miller            int visFlags = (getSystemUiVisibility() & ~View.STATUS_BAR_DISABLE_CLOCK)
718354619c1cc1b4668c81c5368b2256335cc9e8538Jim Miller                    | (mUpdateMonitor.isClockVisible() ? View.STATUS_BAR_DISABLE_CLOCK : 0);
719354619c1cc1b4668c81c5368b2256335cc9e8538Jim Miller            Log.v(TAG, "Set visibility on " + this + " to " + visFlags);
720354619c1cc1b4668c81c5368b2256335cc9e8538Jim Miller            setSystemUiVisibility(visFlags);
721b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller        }
722dce0bb62ce4e1afbdacd2b4a8ee2e02a1563e852Steven Ross
7233223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna        // We need to stop the biometric unlock when a phone call comes in
724b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller        @Override
725b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller        public void onPhoneStateChanged(int phoneState) {
726b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller            if (DEBUG) Log.d(TAG, "phone state: " + phoneState);
727c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna            if (mBiometricUnlock != null && phoneState == TelephonyManager.CALL_STATE_RINGING) {
728c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna                mSuppressBiometricUnlock = true;
7293223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna                mBiometricUnlock.stop();
7303223e2537d5f4e2eceeb321405dbd6da50df66b6Brian Colonna                mBiometricUnlock.hide();
731b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller            }
7329c2df261797259728845a04d5e47ddf36251f93dSteven Ross        }
73352c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani
73452c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani        @Override
73552c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani        public void onUserChanged(int userId) {
736c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna            if (mBiometricUnlock != null) {
737c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna                mBiometricUnlock.stop();
738c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna            }
73952c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani            mLockPatternUtils.setCurrentUser(userId);
74052c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani            updateScreen(getInitialMode(), true);
74152c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani        }
742b030476d193a423f6c1baf3053f66fc768c925e0Jim Miller    };
743dce0bb62ce4e1afbdacd2b4a8ee2e02a1563e852Steven Ross
7441e0c7ae184984051e8f42c71f89435fc1d40be35Kenneth Andersson    @Override
7452e1db30d18a0ff6640bb0ad61f922ec1fdcf5a3cSvetoslav Ganov    protected boolean dispatchHoverEvent(MotionEvent event) {
7462e1db30d18a0ff6640bb0ad61f922ec1fdcf5a3cSvetoslav Ganov        // Do not let the screen to get locked while the user is disabled and touch
7472e1db30d18a0ff6640bb0ad61f922ec1fdcf5a3cSvetoslav Ganov        // exploring. A blind user will need significantly more time to find and
7482e1db30d18a0ff6640bb0ad61f922ec1fdcf5a3cSvetoslav Ganov        // interact with the lock screen views.
7492e1db30d18a0ff6640bb0ad61f922ec1fdcf5a3cSvetoslav Ganov        AccessibilityManager accessibilityManager = AccessibilityManager.getInstance(mContext);
7502e1db30d18a0ff6640bb0ad61f922ec1fdcf5a3cSvetoslav Ganov        if (accessibilityManager.isEnabled() && accessibilityManager.isTouchExplorationEnabled()) {
7512e1db30d18a0ff6640bb0ad61f922ec1fdcf5a3cSvetoslav Ganov            getCallback().pokeWakelock();
7522e1db30d18a0ff6640bb0ad61f922ec1fdcf5a3cSvetoslav Ganov        }
7532e1db30d18a0ff6640bb0ad61f922ec1fdcf5a3cSvetoslav Ganov        return super.dispatchHoverEvent(event);
7542e1db30d18a0ff6640bb0ad61f922ec1fdcf5a3cSvetoslav Ganov    }
7552e1db30d18a0ff6640bb0ad61f922ec1fdcf5a3cSvetoslav Ganov
7562e1db30d18a0ff6640bb0ad61f922ec1fdcf5a3cSvetoslav Ganov    @Override
7571f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    public void wakeWhenReadyTq(int keyCode) {
7581f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        if (DEBUG) Log.d(TAG, "onWakeKey");
7591f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        if (keyCode == KeyEvent.KEYCODE_MENU && isSecure() && (mMode == Mode.LockScreen)
76076c65a66884ae1b7ab06c908632dd2a66182422cWink Saville                && (mUpdateMonitor.getSimState() != IccCard.State.PUK_REQUIRED)) {
7611f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            if (DEBUG) Log.d(TAG, "switching screens to unlock screen because wake key was MENU");
7624ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller            updateScreen(Mode.UnlockScreen, false);
7631f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            getCallback().pokeWakelock();
7641f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        } else {
7651f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            if (DEBUG) Log.d(TAG, "poking wake lock immediately");
7661f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            getCallback().pokeWakelock();
7671f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
7681f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
7691f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
7701f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    @Override
7711f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    public void verifyUnlock() {
7721f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        if (!isSecure()) {
7731f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            // non-secure keyguard screens are successfull by default
7741f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            getCallback().keyguardDone(true);
7754ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller        } else if (mUnlockScreenMode != UnlockMode.Pattern
7764ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller                && mUnlockScreenMode != UnlockMode.Password) {
7774ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller            // can only verify unlock when in pattern/password mode
7781f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            getCallback().keyguardDone(false);
7791f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        } else {
7801f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            // otherwise, go to the unlock screen, see if they can verify it
7811f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mIsVerifyUnlockOnly = true;
7824ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller            updateScreen(Mode.UnlockScreen, false);
7831f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
7841f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
7851f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
7861f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    @Override
7871f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    public void cleanUp() {
7884ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller        if (mLockScreen != null) {
7894ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller            ((KeyguardScreen) mLockScreen).onPause();
7904ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller            ((KeyguardScreen) mLockScreen).cleanUp();
7914ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller            this.removeView(mLockScreen);
7924ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller            mLockScreen = null;
7934ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller        }
7944ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller        if (mUnlockScreen != null) {
7954ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller            ((KeyguardScreen) mUnlockScreen).onPause();
7964ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller            ((KeyguardScreen) mUnlockScreen).cleanUp();
7974ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller            this.removeView(mUnlockScreen);
7984ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller            mUnlockScreen = null;
7994ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller        }
800ef0e259d59a20e6ed2334f37b2fb8067ff9cbf99Jim Miller        mUpdateMonitor.removeCallback(this);
801c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna        if (mBiometricUnlock != null) {
802c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna            mBiometricUnlock.cleanUp();
803c169366f2cc44fc395dba76c763505ac2bd61640Brian Colonna        }
8041f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
8051f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
8061f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private boolean isSecure() {
8071f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        UnlockMode unlockMode = getUnlockMode();
8085e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller        boolean secure = false;
8095e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller        switch (unlockMode) {
8105e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller            case Pattern:
8115e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller                secure = mLockPatternUtils.isLockPatternEnabled();
8125e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller                break;
8135e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller            case SimPin:
8140f7b3f8ba5c2f0b8f96e072bd866c9fb374ebdebJohn Wang                secure = mUpdateMonitor.getSimState() == IccCard.State.PIN_REQUIRED;
8150f7b3f8ba5c2f0b8f96e072bd866c9fb374ebdebJohn Wang                break;
8160f7b3f8ba5c2f0b8f96e072bd866c9fb374ebdebJohn Wang            case SimPuk:
8170f7b3f8ba5c2f0b8f96e072bd866c9fb374ebdebJohn Wang                secure = mUpdateMonitor.getSimState() == IccCard.State.PUK_REQUIRED;
8185e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller                break;
8195e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller            case Account:
8205e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller                secure = true;
8215e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller                break;
8225e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller            case Password:
8235e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller                secure = mLockPatternUtils.isLockPasswordEnabled();
8245e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller                break;
82593708af1329bb278d83c1fac6a623629cb42a3d4Jim Miller            case Unknown:
82693708af1329bb278d83c1fac6a623629cb42a3d4Jim Miller                // This means no security is set up
82793708af1329bb278d83c1fac6a623629cb42a3d4Jim Miller                break;
8285e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller            default:
8295e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller                throw new IllegalStateException("unknown unlock mode " + unlockMode);
8301f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
8315e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller        return secure;
8321f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
8331f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
8344ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller    private void updateScreen(Mode mode, boolean force) {
8351f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
83675787398fa5db9add16f3d3bc298198ed2c6671fDianne Hackborn        if (DEBUG_CONFIGURATION) Log.v(TAG, "**** UPDATE SCREEN: mode=" + mode
83762c3efd204acdf1f7bf3bde584e2a0dfd9ca046eJim Miller                + " last mode=" + mMode + ", force = " + force, new RuntimeException());
838cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana
8391f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mMode = mode;
8401f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
8414ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller        // Re-create the lock screen if necessary
8424ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller        if (mode == Mode.LockScreen || mShowLockBeforeUnlock) {
8434ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller            if (force || mLockScreen == null) {
8444ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller                recreateLockScreen();
8454ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller            }
8464ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller        }
8474ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller
84888240596fce58afe79a4d06752cd8f6c086e2600Brian Colonna        // Re-create the unlock screen if necessary.
84993708af1329bb278d83c1fac6a623629cb42a3d4Jim Miller        final UnlockMode unlockMode = getUnlockMode();
85093708af1329bb278d83c1fac6a623629cb42a3d4Jim Miller        if (mode == Mode.UnlockScreen && unlockMode != UnlockMode.Unknown) {
8514ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller            if (force || mUnlockScreen == null || unlockMode != mUnlockScreenMode) {
8524ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller                recreateUnlockScreen(unlockMode);
8534ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller            }
8540d9f798e9f76b13b07ac3dee3ff90b5530f53145Jim Miller        }
8550d9f798e9f76b13b07ac3dee3ff90b5530f53145Jim Miller
8564ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller        // visibleScreen should never be null
8571f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        final View goneScreen = (mode == Mode.LockScreen) ? mUnlockScreen : mLockScreen;
85842b432d84cd3bf860a03a10e9191738e05f2eaddJim Miller        final View visibleScreen = (mode == Mode.LockScreen) ? mLockScreen : mUnlockScreen;
8591f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
8601f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        // do this before changing visibility so focus isn't requested before the input
8611f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        // flag is set
8621f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mWindowController.setNeedsInput(((KeyguardScreen)visibleScreen).needsInput());
86324cfa450fa46a333ea9fa7de20a8755e592e1bedIlia Tulchinsky
86475787398fa5db9add16f3d3bc298198ed2c6671fDianne Hackborn        if (DEBUG_CONFIGURATION) {
86575787398fa5db9add16f3d3bc298198ed2c6671fDianne Hackborn            Log.v(TAG, "Gone=" + goneScreen);
86675787398fa5db9add16f3d3bc298198ed2c6671fDianne Hackborn            Log.v(TAG, "Visible=" + visibleScreen);
86775787398fa5db9add16f3d3bc298198ed2c6671fDianne Hackborn        }
868cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana
8691f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        if (mScreenOn) {
8704ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller            if (goneScreen != null && goneScreen.getVisibility() == View.VISIBLE) {
8711f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                ((KeyguardScreen) goneScreen).onPause();
8721f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
8731f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            if (visibleScreen.getVisibility() != View.VISIBLE) {
8741f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                ((KeyguardScreen) visibleScreen).onResume();
8751f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
8761f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
8771f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
8784ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller        if (goneScreen != null) {
8794ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller            goneScreen.setVisibility(View.GONE);
8804ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller        }
8811f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        visibleScreen.setVisibility(View.VISIBLE);
88275787398fa5db9add16f3d3bc298198ed2c6671fDianne Hackborn        requestLayout();
8831f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
8841f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        if (!visibleScreen.requestFocus()) {
8851f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            throw new IllegalStateException("keyguard screen must be able to take "
8861f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    + "focus when shown " + visibleScreen.getClass().getCanonicalName());
8871f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
8881f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
8891f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
8901f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    View createLockScreen() {
8911c18828d20807342d37000746b18a3c1696f3b2eJim Miller        View lockView = new LockScreen(
8921f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                mContext,
8935475906f53e2d79807548932dfabbf9945143740Jim Miller                mConfiguration,
8941f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                mLockPatternUtils,
8951f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                mUpdateMonitor,
8961f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                mKeyguardScreenCallback);
8971c18828d20807342d37000746b18a3c1696f3b2eJim Miller        initializeTransportControlView(lockView);
8981c18828d20807342d37000746b18a3c1696f3b2eJim Miller        return lockView;
8991f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
9001f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
9011f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    View createUnlockScreenFor(UnlockMode unlockMode) {
9020d9f798e9f76b13b07ac3dee3ff90b5530f53145Jim Miller        View unlockView = null;
9030f7b3f8ba5c2f0b8f96e072bd866c9fb374ebdebJohn Wang
9040f7b3f8ba5c2f0b8f96e072bd866c9fb374ebdebJohn Wang        if (DEBUG) Log.d(TAG,
9050f7b3f8ba5c2f0b8f96e072bd866c9fb374ebdebJohn Wang                "createUnlockScreenFor(" + unlockMode + "): mEnableFallback=" + mEnableFallback);
9060f7b3f8ba5c2f0b8f96e072bd866c9fb374ebdebJohn Wang
9071f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        if (unlockMode == UnlockMode.Pattern) {
90842b432d84cd3bf860a03a10e9191738e05f2eaddJim Miller            PatternUnlockScreen view = new PatternUnlockScreen(
9091f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    mContext,
9105475906f53e2d79807548932dfabbf9945143740Jim Miller                    mConfiguration,
9111f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    mLockPatternUtils,
9121f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    mUpdateMonitor,
9131f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    mKeyguardScreenCallback,
91463b90f28858b9d259a1d4a145f51bdd36ada8730Dianne Hackborn                    mUpdateMonitor.getFailedAttempts());
91563b90f28858b9d259a1d4a145f51bdd36ada8730Dianne Hackborn            view.setEnableFallback(mEnableFallback);
9160d9f798e9f76b13b07ac3dee3ff90b5530f53145Jim Miller            unlockView = view;
9170f7b3f8ba5c2f0b8f96e072bd866c9fb374ebdebJohn Wang        } else if (unlockMode == UnlockMode.SimPuk) {
9180f7b3f8ba5c2f0b8f96e072bd866c9fb374ebdebJohn Wang            unlockView = new SimPukUnlockScreen(
9190f7b3f8ba5c2f0b8f96e072bd866c9fb374ebdebJohn Wang                    mContext,
9200f7b3f8ba5c2f0b8f96e072bd866c9fb374ebdebJohn Wang                    mConfiguration,
9210f7b3f8ba5c2f0b8f96e072bd866c9fb374ebdebJohn Wang                    mUpdateMonitor,
9220f7b3f8ba5c2f0b8f96e072bd866c9fb374ebdebJohn Wang                    mKeyguardScreenCallback,
9230f7b3f8ba5c2f0b8f96e072bd866c9fb374ebdebJohn Wang                    mLockPatternUtils);
9241f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        } else if (unlockMode == UnlockMode.SimPin) {
9250d9f798e9f76b13b07ac3dee3ff90b5530f53145Jim Miller            unlockView = new SimUnlockScreen(
9261f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    mContext,
9275475906f53e2d79807548932dfabbf9945143740Jim Miller                    mConfiguration,
9281f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    mUpdateMonitor,
929c23024d32779b170dde32a50fbdd945ce521b874Jim Miller                    mKeyguardScreenCallback,
930c23024d32779b170dde32a50fbdd945ce521b874Jim Miller                    mLockPatternUtils);
9311f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        } else if (unlockMode == UnlockMode.Account) {
9321f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            try {
9330d9f798e9f76b13b07ac3dee3ff90b5530f53145Jim Miller                unlockView = new AccountUnlockScreen(
9341f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                        mContext,
9355475906f53e2d79807548932dfabbf9945143740Jim Miller                        mConfiguration,
936ecaced9a788910b3517bdab08b382c9d45e34dfeJim Miller                        mUpdateMonitor,
9371f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                        mKeyguardScreenCallback,
9381f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                        mLockPatternUtils);
9391f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            } catch (IllegalStateException e) {
9401f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                Log.i(TAG, "Couldn't instantiate AccountUnlockScreen"
9411f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                      + " (IAccountsService isn't available)");
9421f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                // TODO: Need a more general way to provide a
9431f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                // platform-specific fallback UI here.
9441f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                // For now, if we can't display the account login
9451f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                // unlock UI, just bring back the regular "Pattern" unlock mode.
9461f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
9471f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                // (We do this by simply returning a regular UnlockScreen
9481f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                // here.  This means that the user will still see the
9491f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                // regular pattern unlock UI, regardless of the value of
9501f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                // mUnlockScreenMode or whether or not we're in the
9511f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                // "permanently locked" state.)
9524ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller                return createUnlockScreenFor(UnlockMode.Pattern);
9531f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
9545e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller        } else if (unlockMode == UnlockMode.Password) {
9550d9f798e9f76b13b07ac3dee3ff90b5530f53145Jim Miller            unlockView = new PasswordUnlockScreen(
9565e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller                    mContext,
9575475906f53e2d79807548932dfabbf9945143740Jim Miller                    mConfiguration,
9585e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller                    mLockPatternUtils,
9595e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller                    mUpdateMonitor,
9605e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller                    mKeyguardScreenCallback);
9611f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        } else {
9621f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            throw new IllegalArgumentException("unknown unlock mode " + unlockMode);
9631f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
9641c18828d20807342d37000746b18a3c1696f3b2eJim Miller        initializeTransportControlView(unlockView);
96588240596fce58afe79a4d06752cd8f6c086e2600Brian Colonna        initializeBiometricUnlockView(unlockView);
9664d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna
9674ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller        mUnlockScreenMode = unlockMode;
9680d9f798e9f76b13b07ac3dee3ff90b5530f53145Jim Miller        return unlockView;
9690d9f798e9f76b13b07ac3dee3ff90b5530f53145Jim Miller    }
9700d9f798e9f76b13b07ac3dee3ff90b5530f53145Jim Miller
9711c18828d20807342d37000746b18a3c1696f3b2eJim Miller    private void initializeTransportControlView(View view) {
9724e6d35829ebf98ea37f77ea434550d51950c1119Jim Miller        mTransportControlView = (TransportControlView) view.findViewById(R.id.transport);
9734e6d35829ebf98ea37f77ea434550d51950c1119Jim Miller        if (mTransportControlView == null) {
9741c18828d20807342d37000746b18a3c1696f3b2eJim Miller            if (DEBUG) Log.w(TAG, "Couldn't find transport control widget");
9751c18828d20807342d37000746b18a3c1696f3b2eJim Miller        } else {
976054340d0a3f242efeaf898cca38625bdcb3b4b5aJeff Sharkey            mUpdateMonitor.reportClockVisible(true);
9774e6d35829ebf98ea37f77ea434550d51950c1119Jim Miller            mTransportControlView.setVisibility(View.GONE); // hide until it requests being shown.
9784e6d35829ebf98ea37f77ea434550d51950c1119Jim Miller            mTransportControlView.setCallback(mWidgetCallback);
9791c18828d20807342d37000746b18a3c1696f3b2eJim Miller        }
98088240596fce58afe79a4d06752cd8f6c086e2600Brian Colonna    }
98188240596fce58afe79a4d06752cd8f6c086e2600Brian Colonna
98288240596fce58afe79a4d06752cd8f6c086e2600Brian Colonna    /**
98388240596fce58afe79a4d06752cd8f6c086e2600Brian Colonna     * This returns false if there is any condition that indicates that the biometric unlock should
98488240596fce58afe79a4d06752cd8f6c086e2600Brian Colonna     * not be used before the next time the unlock screen is recreated.  In other words, if this
98588240596fce58afe79a4d06752cd8f6c086e2600Brian Colonna     * returns false there is no need to even construct the biometric unlock.
98688240596fce58afe79a4d06752cd8f6c086e2600Brian Colonna     */
98788240596fce58afe79a4d06752cd8f6c086e2600Brian Colonna    private boolean useBiometricUnlock() {
98888240596fce58afe79a4d06752cd8f6c086e2600Brian Colonna        final UnlockMode unlockMode = getUnlockMode();
98988240596fce58afe79a4d06752cd8f6c086e2600Brian Colonna        final boolean backupIsTimedOut = (mUpdateMonitor.getFailedAttempts() >=
99088240596fce58afe79a4d06752cd8f6c086e2600Brian Colonna                LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT);
99188240596fce58afe79a4d06752cd8f6c086e2600Brian Colonna        return (mLockPatternUtils.usingBiometricWeak() &&
99288240596fce58afe79a4d06752cd8f6c086e2600Brian Colonna                mLockPatternUtils.isBiometricWeakInstalled() &&
99388240596fce58afe79a4d06752cd8f6c086e2600Brian Colonna                !mUpdateMonitor.getMaxBiometricUnlockAttemptsReached() &&
99488240596fce58afe79a4d06752cd8f6c086e2600Brian Colonna                !backupIsTimedOut &&
99588240596fce58afe79a4d06752cd8f6c086e2600Brian Colonna                (unlockMode == UnlockMode.Pattern || unlockMode == UnlockMode.Password));
99688240596fce58afe79a4d06752cd8f6c086e2600Brian Colonna    }
99788240596fce58afe79a4d06752cd8f6c086e2600Brian Colonna
99888240596fce58afe79a4d06752cd8f6c086e2600Brian Colonna    private void initializeBiometricUnlockView(View view) {
99988240596fce58afe79a4d06752cd8f6c086e2600Brian Colonna        boolean restartBiometricUnlock = false;
100088240596fce58afe79a4d06752cd8f6c086e2600Brian Colonna
100188240596fce58afe79a4d06752cd8f6c086e2600Brian Colonna        if (mBiometricUnlock != null) {
100288240596fce58afe79a4d06752cd8f6c086e2600Brian Colonna            restartBiometricUnlock = mBiometricUnlock.stop();
100388240596fce58afe79a4d06752cd8f6c086e2600Brian Colonna        }
100488240596fce58afe79a4d06752cd8f6c086e2600Brian Colonna
1005cafd387d7a2d91a2c900b7744b0486818cd1aac2Danielle Millett        // Prevents biometric unlock from coming up immediately after a phone call or if there
1006cafd387d7a2d91a2c900b7744b0486818cd1aac2Danielle Millett        // is a dialog on top of lockscreen. It is only updated if the screen is off because if the
1007cafd387d7a2d91a2c900b7744b0486818cd1aac2Danielle Millett        // screen is on it's either because of an orientation change, or when it first boots.
1008cafd387d7a2d91a2c900b7744b0486818cd1aac2Danielle Millett        // In both those cases, we don't want to override the current value of
1009cafd387d7a2d91a2c900b7744b0486818cd1aac2Danielle Millett        // mSuppressBiometricUnlock and instead want to use the previous value.
1010cafd387d7a2d91a2c900b7744b0486818cd1aac2Danielle Millett        if (!mScreenOn) {
1011cafd387d7a2d91a2c900b7744b0486818cd1aac2Danielle Millett            mSuppressBiometricUnlock =
1012cafd387d7a2d91a2c900b7744b0486818cd1aac2Danielle Millett                    mUpdateMonitor.getPhoneState() != TelephonyManager.CALL_STATE_IDLE
1013cafd387d7a2d91a2c900b7744b0486818cd1aac2Danielle Millett                    || mHasDialog;
1014cafd387d7a2d91a2c900b7744b0486818cd1aac2Danielle Millett        }
1015cafd387d7a2d91a2c900b7744b0486818cd1aac2Danielle Millett
101688240596fce58afe79a4d06752cd8f6c086e2600Brian Colonna        // If the biometric unlock is not being used, we don't bother constructing it.  Then we can
101788240596fce58afe79a4d06752cd8f6c086e2600Brian Colonna        // simply check if it is null when deciding whether we should make calls to it.
101888240596fce58afe79a4d06752cd8f6c086e2600Brian Colonna        mBiometricUnlock = null;
101988240596fce58afe79a4d06752cd8f6c086e2600Brian Colonna        if (useBiometricUnlock()) {
102088240596fce58afe79a4d06752cd8f6c086e2600Brian Colonna            // TODO: make faceLockAreaView a more general biometricUnlockView
102188240596fce58afe79a4d06752cd8f6c086e2600Brian Colonna            // We will need to add our Face Unlock specific child views programmatically in
102288240596fce58afe79a4d06752cd8f6c086e2600Brian Colonna            // initializeView rather than having them in the XML files.
102388240596fce58afe79a4d06752cd8f6c086e2600Brian Colonna            View biometricUnlockView = view.findViewById(R.id.faceLockAreaView);
102488240596fce58afe79a4d06752cd8f6c086e2600Brian Colonna            if (biometricUnlockView != null) {
102588240596fce58afe79a4d06752cd8f6c086e2600Brian Colonna                mBiometricUnlock = new FaceUnlock(mContext, mUpdateMonitor, mLockPatternUtils,
102688240596fce58afe79a4d06752cd8f6c086e2600Brian Colonna                        mKeyguardScreenCallback);
102788240596fce58afe79a4d06752cd8f6c086e2600Brian Colonna                mBiometricUnlock.initializeView(biometricUnlockView);
102888240596fce58afe79a4d06752cd8f6c086e2600Brian Colonna
102988240596fce58afe79a4d06752cd8f6c086e2600Brian Colonna                // If this is being called because the screen turned off, we want to cover the
103088240596fce58afe79a4d06752cd8f6c086e2600Brian Colonna                // backup lock so it is covered when the screen turns back on.
103188240596fce58afe79a4d06752cd8f6c086e2600Brian Colonna                if (!mScreenOn) mBiometricUnlock.show(0);
103288240596fce58afe79a4d06752cd8f6c086e2600Brian Colonna            } else {
103388240596fce58afe79a4d06752cd8f6c086e2600Brian Colonna                Log.w(TAG, "Couldn't find biometric unlock view");
103488240596fce58afe79a4d06752cd8f6c086e2600Brian Colonna            }
103588240596fce58afe79a4d06752cd8f6c086e2600Brian Colonna        }
103688240596fce58afe79a4d06752cd8f6c086e2600Brian Colonna
103788240596fce58afe79a4d06752cd8f6c086e2600Brian Colonna        if (mBiometricUnlock != null && restartBiometricUnlock) {
103888240596fce58afe79a4d06752cd8f6c086e2600Brian Colonna            maybeStartBiometricUnlock();
103988240596fce58afe79a4d06752cd8f6c086e2600Brian Colonna        }
10401c18828d20807342d37000746b18a3c1696f3b2eJim Miller    }
10411c18828d20807342d37000746b18a3c1696f3b2eJim Miller
10421f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
10431f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * Given the current state of things, what should be the initial mode of
10441f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * the lock screen (lock or unlock).
10451f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
10461f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private Mode getInitialMode() {
104776c65a66884ae1b7ab06c908632dd2a66182422cWink Saville        final IccCard.State simState = mUpdateMonitor.getSimState();
10480f7b3f8ba5c2f0b8f96e072bd866c9fb374ebdebJohn Wang        if (stuckOnLockScreenBecauseSimMissing() ||
10490f7b3f8ba5c2f0b8f96e072bd866c9fb374ebdebJohn Wang                (simState == IccCard.State.PUK_REQUIRED &&
10500f7b3f8ba5c2f0b8f96e072bd866c9fb374ebdebJohn Wang                        !mLockPatternUtils.isPukUnlockScreenEnable())) {
10511f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return Mode.LockScreen;
10521f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        } else {
10534ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller            if (!isSecure() || mShowLockBeforeUnlock) {
1054466d77617ace8380ab8c52ede20790755d8ff092Jim Miller                return Mode.LockScreen;
10554ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller            } else {
10564ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller                return Mode.UnlockScreen;
1057466d77617ace8380ab8c52ede20790755d8ff092Jim Miller            }
10581f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
10591f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
10601f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
10611f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
10621f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * Given the current state of things, what should the unlock screen be?
10631f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
10641f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private UnlockMode getUnlockMode() {
106576c65a66884ae1b7ab06c908632dd2a66182422cWink Saville        final IccCard.State simState = mUpdateMonitor.getSimState();
10665e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller        UnlockMode currentMode;
10670f7b3f8ba5c2f0b8f96e072bd866c9fb374ebdebJohn Wang        if (simState == IccCard.State.PIN_REQUIRED) {
10685e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller            currentMode = UnlockMode.SimPin;
10690f7b3f8ba5c2f0b8f96e072bd866c9fb374ebdebJohn Wang        } else if (simState == IccCard.State.PUK_REQUIRED) {
10700f7b3f8ba5c2f0b8f96e072bd866c9fb374ebdebJohn Wang            currentMode = UnlockMode.SimPuk;
10711f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        } else {
1072f7c5d0e46ced3ec3edb6f656acd82900b9ac988cJim Miller            final int mode = mLockPatternUtils.getKeyguardStoredPasswordQuality();
10735e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller            switch (mode) {
1074f7c5d0e46ced3ec3edb6f656acd82900b9ac988cJim Miller                case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
1075f7c5d0e46ced3ec3edb6f656acd82900b9ac988cJim Miller                case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
1076f7c5d0e46ced3ec3edb6f656acd82900b9ac988cJim Miller                case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
1077a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
10785e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller                    currentMode = UnlockMode.Password;
10795e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller                    break;
1080f7c5d0e46ced3ec3edb6f656acd82900b9ac988cJim Miller                case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
1081f7c5d0e46ced3ec3edb6f656acd82900b9ac988cJim Miller                case DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED:
108293708af1329bb278d83c1fac6a623629cb42a3d4Jim Miller                    if (mLockPatternUtils.isLockPatternEnabled()) {
108393708af1329bb278d83c1fac6a623629cb42a3d4Jim Miller                        // "forgot pattern" button is only available in the pattern mode...
108493708af1329bb278d83c1fac6a623629cb42a3d4Jim Miller                        if (mForgotPattern || mLockPatternUtils.isPermanentlyLocked()) {
108593708af1329bb278d83c1fac6a623629cb42a3d4Jim Miller                            currentMode = UnlockMode.Account;
108693708af1329bb278d83c1fac6a623629cb42a3d4Jim Miller                        } else {
108793708af1329bb278d83c1fac6a623629cb42a3d4Jim Miller                            currentMode = UnlockMode.Pattern;
108893708af1329bb278d83c1fac6a623629cb42a3d4Jim Miller                        }
10895e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller                    } else {
109093708af1329bb278d83c1fac6a623629cb42a3d4Jim Miller                        currentMode = UnlockMode.Unknown;
10915e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller                    }
10925e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller                    break;
10935e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller                default:
10945e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller                   throw new IllegalStateException("Unknown unlock mode:" + mode);
10955e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller            }
10961f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
10975e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller        return currentMode;
10981f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
10991f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
11004f36995777a4136e8e63ea51cef2ff61df48790dJim Miller    private void showDialog(String title, String message) {
11010a981cf522ba816065494473651105f4aa981654Steven Ross        mHasDialog = true;
11024f36995777a4136e8e63ea51cef2ff61df48790dJim Miller        final AlertDialog dialog = new AlertDialog.Builder(mContext)
11034f36995777a4136e8e63ea51cef2ff61df48790dJim Miller            .setTitle(title)
11044f36995777a4136e8e63ea51cef2ff61df48790dJim Miller            .setMessage(message)
11054f36995777a4136e8e63ea51cef2ff61df48790dJim Miller            .setNeutralButton(R.string.ok, null)
11064f36995777a4136e8e63ea51cef2ff61df48790dJim Miller            .create();
11074f36995777a4136e8e63ea51cef2ff61df48790dJim Miller        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
11084f36995777a4136e8e63ea51cef2ff61df48790dJim Miller        dialog.show();
11094f36995777a4136e8e63ea51cef2ff61df48790dJim Miller    }
11104f36995777a4136e8e63ea51cef2ff61df48790dJim Miller
11111f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private void showTimeoutDialog() {
11121f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        int timeoutInSeconds = (int) LockPatternUtils.FAILED_ATTEMPT_TIMEOUT_MS / 1000;
11138171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung        int messageId = R.string.lockscreen_too_many_failed_attempts_dialog_message;
11144f36995777a4136e8e63ea51cef2ff61df48790dJim Miller        if (getUnlockMode() == UnlockMode.Password) {
1115c15dcf7ea1421305a54f256777212373c28c53c0Konstantin Lopyrev            if(mLockPatternUtils.getKeyguardStoredPasswordQuality() ==
1116c15dcf7ea1421305a54f256777212373c28c53c0Konstantin Lopyrev                DevicePolicyManager.PASSWORD_QUALITY_NUMERIC) {
1117c15dcf7ea1421305a54f256777212373c28c53c0Konstantin Lopyrev                messageId = R.string.lockscreen_too_many_failed_pin_attempts_dialog_message;
1118c15dcf7ea1421305a54f256777212373c28c53c0Konstantin Lopyrev            } else {
1119c15dcf7ea1421305a54f256777212373c28c53c0Konstantin Lopyrev                messageId = R.string.lockscreen_too_many_failed_password_attempts_dialog_message;
1120c15dcf7ea1421305a54f256777212373c28c53c0Konstantin Lopyrev            }
1121c15dcf7ea1421305a54f256777212373c28c53c0Konstantin Lopyrev        }
11224f36995777a4136e8e63ea51cef2ff61df48790dJim Miller        String message = mContext.getString(messageId, mUpdateMonitor.getFailedAttempts(),
11231f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                timeoutInSeconds);
112467403e096e6f59b7cd18a90d0d3f5c3d17c31407Mathias Agopian
11254f36995777a4136e8e63ea51cef2ff61df48790dJim Miller        showDialog(null, message);
11261f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
11271f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
11281f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private void showAlmostAtAccountLoginDialog() {
11294f36995777a4136e8e63ea51cef2ff61df48790dJim Miller        final int timeoutInSeconds = (int) LockPatternUtils.FAILED_ATTEMPT_TIMEOUT_MS / 1000;
11304f36995777a4136e8e63ea51cef2ff61df48790dJim Miller        final int count = LockPatternUtils.FAILED_ATTEMPTS_BEFORE_RESET
11314f36995777a4136e8e63ea51cef2ff61df48790dJim Miller                - LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT;
11324f36995777a4136e8e63ea51cef2ff61df48790dJim Miller        String message = mContext.getString(R.string.lockscreen_failed_attempts_almost_glogin,
11334f36995777a4136e8e63ea51cef2ff61df48790dJim Miller                count, LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT, timeoutInSeconds);
11344f36995777a4136e8e63ea51cef2ff61df48790dJim Miller        showDialog(null, message);
11354f36995777a4136e8e63ea51cef2ff61df48790dJim Miller    }
11364f36995777a4136e8e63ea51cef2ff61df48790dJim Miller
11374f36995777a4136e8e63ea51cef2ff61df48790dJim Miller    private void showAlmostAtWipeDialog(int attempts, int remaining) {
11381f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        int timeoutInSeconds = (int) LockPatternUtils.FAILED_ATTEMPT_TIMEOUT_MS / 1000;
11391f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        String message = mContext.getString(
11404f36995777a4136e8e63ea51cef2ff61df48790dJim Miller                R.string.lockscreen_failed_attempts_almost_at_wipe, attempts, remaining);
11414f36995777a4136e8e63ea51cef2ff61df48790dJim Miller        showDialog(null, message);
11424f36995777a4136e8e63ea51cef2ff61df48790dJim Miller    }
11434f36995777a4136e8e63ea51cef2ff61df48790dJim Miller
11444f36995777a4136e8e63ea51cef2ff61df48790dJim Miller    private void showWipeDialog(int attempts) {
11454f36995777a4136e8e63ea51cef2ff61df48790dJim Miller        String message = mContext.getString(
11464f36995777a4136e8e63ea51cef2ff61df48790dJim Miller                R.string.lockscreen_failed_attempts_now_wiping, attempts);
11474f36995777a4136e8e63ea51cef2ff61df48790dJim Miller        showDialog(null, message);
11481f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
11491f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
11501f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
1151c4d9d21009db7b977a2201f6760d78786be3028dDianne Hackborn     * Used to put wallpaper on the background of the lock screen.  Centers it
1152c4d9d21009db7b977a2201f6760d78786be3028dDianne Hackborn     * Horizontally and pins the bottom (assuming that the lock screen is aligned
1153c4d9d21009db7b977a2201f6760d78786be3028dDianne Hackborn     * with the bottom, so the wallpaper should extend above the top into the
1154c4d9d21009db7b977a2201f6760d78786be3028dDianne Hackborn     * status bar).
11551f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
11561f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    static private class FastBitmapDrawable extends Drawable {
11571f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        private Bitmap mBitmap;
11589593e0a0073d77ab65cc97156da4d0e890e4cf27Romain Guy        private int mOpacity;
11591f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
11601f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        private FastBitmapDrawable(Bitmap bitmap) {
11611f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mBitmap = bitmap;
11629593e0a0073d77ab65cc97156da4d0e890e4cf27Romain Guy            mOpacity = mBitmap.hasAlpha() ? PixelFormat.TRANSLUCENT : PixelFormat.OPAQUE;
11631f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
11641f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
11651f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        @Override
11661f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public void draw(Canvas canvas) {
11671f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            canvas.drawBitmap(
11681f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    mBitmap,
11691f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    (getBounds().width() - mBitmap.getWidth()) / 2,
1170c4d9d21009db7b977a2201f6760d78786be3028dDianne Hackborn                    (getBounds().height() - mBitmap.getHeight()),
11711f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    null);
11721f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
11731f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
11741f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        @Override
11751f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public int getOpacity() {
11769593e0a0073d77ab65cc97156da4d0e890e4cf27Romain Guy            return mOpacity;
11771f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
11781f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
11791f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        @Override
11801f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public void setAlpha(int alpha) {
11811f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
11821f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
11831f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        @Override
11841f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public void setColorFilter(ColorFilter cf) {
11851f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
11861f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
11871f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        @Override
11881f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public int getIntrinsicWidth() {
11891f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return mBitmap.getWidth();
11901f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
11911f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
11921f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        @Override
11931f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public int getIntrinsicHeight() {
11941f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return mBitmap.getHeight();
11951f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
11961f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
11971f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        @Override
11981f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public int getMinimumWidth() {
11991f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return mBitmap.getWidth();
12001f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
12011f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
12021f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        @Override
12031f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public int getMinimumHeight() {
12041f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return mBitmap.getHeight();
12051f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
12061f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
1207ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna
1208ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna    /**
1209ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna     * Starts the biometric unlock if it should be started based on a number of factors including
1210ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna     * the mSuppressBiometricUnlock flag.  If it should not be started, it hides the biometric
1211ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna     * unlock area.
1212ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna     */
1213ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna    private void maybeStartBiometricUnlock() {
1214ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna        if (mBiometricUnlock != null) {
1215ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna            final boolean backupIsTimedOut = (mUpdateMonitor.getFailedAttempts() >=
1216ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna                    LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT);
1217ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna            if (!mSuppressBiometricUnlock
1218ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna                    && mUpdateMonitor.getPhoneState() == TelephonyManager.CALL_STATE_IDLE
1219ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna                    && !mUpdateMonitor.getMaxBiometricUnlockAttemptsReached()
1220ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna                    && !backupIsTimedOut) {
1221ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna                mBiometricUnlock.start();
1222ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna            } else {
1223ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna                mBiometricUnlock.hide();
1224ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna            }
1225ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna        }
1226ea8441e22a4316cb6e78dd8bf461d3e658545b64Brian Colonna    }
12276edf2637e96139735df83907c221cce16d4d7eaaJim Miller}
1228