LockPatternKeyguardView.java revision dce0bb62ce4e1afbdacd2b4a8ee2e02a1563e852
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;
204ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Millerimport com.android.internal.policy.impl.LockPatternKeyguardView.UnlockMode;
216edf2637e96139735df83907c221cce16d4d7eaaJim Millerimport com.android.internal.policy.IFaceLockCallback;
226edf2637e96139735df83907c221cce16d4d7eaaJim Millerimport com.android.internal.policy.IFaceLockInterface;
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;
376edf2637e96139735df83907c221cce16d4d7eaaJim Millerimport android.content.ComponentName;
381f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.content.Context;
391f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.content.Intent;
403a1837e9947505edc41d3f422bf0e0d268e349c3Jim Millerimport android.content.res.Configuration;
414ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Millerimport android.content.res.Resources;
426edf2637e96139735df83907c221cce16d4d7eaaJim Millerimport android.content.ServiceConnection;
4324cfa450fa46a333ea9fa7de20a8755e592e1bedIlia Tulchinskyimport android.graphics.Bitmap;
4424cfa450fa46a333ea9fa7de20a8755e592e1bedIlia Tulchinskyimport android.graphics.Canvas;
4524cfa450fa46a333ea9fa7de20a8755e592e1bedIlia Tulchinskyimport android.graphics.ColorFilter;
4624cfa450fa46a333ea9fa7de20a8755e592e1bedIlia Tulchinskyimport android.graphics.PixelFormat;
4724cfa450fa46a333ea9fa7de20a8755e592e1bedIlia Tulchinskyimport android.graphics.drawable.Drawable;
48cf59a0b72d3fa6bfe21b3c4cab317ef06496961eDirk Balfanzimport android.os.Bundle;
494d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonnaimport android.os.Handler;
504d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonnaimport android.os.Message;
516edf2637e96139735df83907c221cce16d4d7eaaJim Millerimport android.os.IBinder;
526edf2637e96139735df83907c221cce16d4d7eaaJim Millerimport android.os.RemoteException;
535475906f53e2d79807548932dfabbf9945143740Jim Millerimport android.os.SystemClock;
541f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.os.SystemProperties;
55c23024d32779b170dde32a50fbdd945ce521b874Jim Millerimport android.telephony.TelephonyManager;
561f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.text.TextUtils;
571f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.util.Log;
584f36995777a4136e8e63ea51cef2ff61df48790dJim Millerimport android.util.Slog;
591f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.view.KeyEvent;
602e1db30d18a0ff6640bb0ad61f922ec1fdcf5a3cSvetoslav Ganovimport android.view.MotionEvent;
611f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.view.View;
621f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.view.WindowManager;
632e1db30d18a0ff6640bb0ad61f922ec1fdcf5a3cSvetoslav Ganovimport android.view.accessibility.AccessibilityManager;
641f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
6563b90f28858b9d259a1d4a145f51bdd36ada8730Dianne Hackbornimport java.io.IOException;
6663b90f28858b9d259a1d4a145f51bdd36ada8730Dianne Hackborn
676edf2637e96139735df83907c221cce16d4d7eaaJim Miller
681f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project/**
691f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * The host view for all of the screens of the pattern unlock screen.  There are
701f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * two {@link Mode}s of operation, lock and unlock.  This will show the appropriate
7124cfa450fa46a333ea9fa7de20a8755e592e1bedIlia Tulchinsky * screen, and listen for callbacks via
7224cfa450fa46a333ea9fa7de20a8755e592e1bedIlia Tulchinsky * {@link com.android.internal.policy.impl.KeyguardScreenCallback}
731f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * from the current screen.
741f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project *
7524cfa450fa46a333ea9fa7de20a8755e592e1bedIlia Tulchinsky * This view, in turn, communicates back to
7624cfa450fa46a333ea9fa7de20a8755e592e1bedIlia Tulchinsky * {@link com.android.internal.policy.impl.KeyguardViewManager}
771f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * via its {@link com.android.internal.policy.impl.KeyguardViewCallback}, as appropriate.
781f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project */
79dce0bb62ce4e1afbdacd2b4a8ee2e02a1563e852Steven Rosspublic class LockPatternKeyguardView extends KeyguardViewBase implements Handler.Callback,
80dce0bb62ce4e1afbdacd2b4a8ee2e02a1563e852Steven Ross        KeyguardUpdateMonitor.InfoCallback {
811f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
821c18828d20807342d37000746b18a3c1696f3b2eJim Miller    private static final int TRANSPORT_USERACTIVITY_TIMEOUT = 10000;
831c18828d20807342d37000746b18a3c1696f3b2eJim Miller
8475787398fa5db9add16f3d3bc298198ed2c6671fDianne Hackborn    static final boolean DEBUG_CONFIGURATION = false;
85cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana
86c23024d32779b170dde32a50fbdd945ce521b874Jim Miller    // time after launching EmergencyDialer before the screen goes blank.
87c23024d32779b170dde32a50fbdd945ce521b874Jim Miller    private static final int EMERGENCY_CALL_TIMEOUT = 10000;
88c23024d32779b170dde32a50fbdd945ce521b874Jim Miller
891f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    // intent action for launching emergency dialer activity.
901f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    static final String ACTION_EMERGENCY_DIAL = "com.android.phone.EmergencyDialer.DIAL";
911f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
921f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private static final boolean DEBUG = false;
931f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private static final String TAG = "LockPatternKeyguardView";
941f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
951f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private final KeyguardUpdateMonitor mUpdateMonitor;
961f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private final KeyguardWindowController mWindowController;
9724cfa450fa46a333ea9fa7de20a8755e592e1bedIlia Tulchinsky
981f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private View mLockScreen;
991f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private View mUnlockScreen;
1001f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1011f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private boolean mScreenOn = false;
10224cfa450fa46a333ea9fa7de20a8755e592e1bedIlia Tulchinsky    private boolean mEnableFallback = false; // assume no fallback UI until we know better
1031f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1044ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller    private boolean mShowLockBeforeUnlock = false;
1054ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller
1066edf2637e96139735df83907c221cce16d4d7eaaJim Miller    // The following were added to support FaceLock
1076edf2637e96139735df83907c221cce16d4d7eaaJim Miller    private IFaceLockInterface mFaceLockService;
1086edf2637e96139735df83907c221cce16d4d7eaaJim Miller    private boolean mBoundToFaceLockService = false;
1096edf2637e96139735df83907c221cce16d4d7eaaJim Miller    private View mFaceLockAreaView;
1106edf2637e96139735df83907c221cce16d4d7eaaJim Miller
1114d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna    private boolean mFaceLockServiceRunning = false;
1124d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna    private final Object mFaceLockServiceRunningLock = new Object();
1134d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna
1144d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna    private Handler mHandler;
1154d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna    private final int MSG_SHOW_FACELOCK_AREA_VIEW = 0;
1164d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna    private final int MSG_HIDE_FACELOCK_AREA_VIEW = 1;
1174d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna
118eef1ae1d91d55341c25d01547ac9b952be5aa658Brian Colonna    // Long enough to stay black while dialer comes up
119eef1ae1d91d55341c25d01547ac9b952be5aa658Brian Colonna    // Short enough to not be black if the user goes back immediately
120eef1ae1d91d55341c25d01547ac9b952be5aa658Brian Colonna    private final int FACELOCK_VIEW_AREA_EMERGENCY_HIDE_TIMEOUT = 1000;
121eef1ae1d91d55341c25d01547ac9b952be5aa658Brian Colonna
1221f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
1231f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * The current {@link KeyguardScreen} will use this to communicate back to us.
1241f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
1251f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    KeyguardScreenCallback mKeyguardScreenCallback;
1261f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1271f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1281f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private boolean mRequiresSim;
1291f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1301f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1311f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
1321f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * Either a lock screen (an informational keyguard screen), or an unlock
1331f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * screen (a means for unlocking the device) is shown at any given time.
1341f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
1351f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    enum Mode {
1361f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        LockScreen,
1371f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        UnlockScreen
1381f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
1391f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1401f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
1411f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * The different types screens available for {@link Mode#UnlockScreen}.
1421f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * @see com.android.internal.policy.impl.LockPatternKeyguardView#getUnlockMode()
1431f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
1441f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    enum UnlockMode {
1451f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1461f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        /**
1471f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * Unlock by drawing a pattern.
1481f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         */
1491f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        Pattern,
1501f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1511f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        /**
1521f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * Unlock by entering a sim pin.
1531f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         */
1541f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        SimPin,
1551f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1561f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        /**
1570f7b3f8ba5c2f0b8f96e072bd866c9fb374ebdebJohn Wang         * Unlock by entering a sim puk.
1580f7b3f8ba5c2f0b8f96e072bd866c9fb374ebdebJohn Wang         */
1590f7b3f8ba5c2f0b8f96e072bd866c9fb374ebdebJohn Wang        SimPuk,
1600f7b3f8ba5c2f0b8f96e072bd866c9fb374ebdebJohn Wang
1610f7b3f8ba5c2f0b8f96e072bd866c9fb374ebdebJohn Wang        /**
1621f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * Unlock by entering an account's login and password.
1631f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         */
1645e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller        Account,
1655e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller
1665e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller        /**
1675e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller         * Unlock by entering a password or PIN
1685e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller         */
1690d9f798e9f76b13b07ac3dee3ff90b5530f53145Jim Miller        Password,
1700d9f798e9f76b13b07ac3dee3ff90b5530f53145Jim Miller
1710d9f798e9f76b13b07ac3dee3ff90b5530f53145Jim Miller        /**
1720d9f798e9f76b13b07ac3dee3ff90b5530f53145Jim Miller         * Unknown (uninitialized) value
1730d9f798e9f76b13b07ac3dee3ff90b5530f53145Jim Miller         */
1740d9f798e9f76b13b07ac3dee3ff90b5530f53145Jim Miller        Unknown
1751f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
1761f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1771f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
1781f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * The current mode.
1791f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
1801f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private Mode mMode = Mode.LockScreen;
1811f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1821f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
18384999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaen     * Keeps track of what mode the current unlock screen is (cached from most recent computation in
18484999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaen     * {@link #getUnlockMode}).
1851f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
1864ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller    private UnlockMode mUnlockScreenMode = UnlockMode.Unknown;
1871f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
18884999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaen    private boolean mForgotPattern;
18984999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaen
1901f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
1911f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * If true, it means we are in the process of verifying that the user
1921f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * can get past the lock screen per {@link #verifyUnlock()}
1931f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
1941f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private boolean mIsVerifyUnlockOnly = false;
1951f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1961f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1971f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
1981f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * Used to lookup the state of the lock pattern
1991f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
2001f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private final LockPatternUtils mLockPatternUtils;
2011f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2021f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
2035475906f53e2d79807548932dfabbf9945143740Jim Miller     * The current configuration.
2045475906f53e2d79807548932dfabbf9945143740Jim Miller     */
2055475906f53e2d79807548932dfabbf9945143740Jim Miller    private Configuration mConfiguration;
2065475906f53e2d79807548932dfabbf9945143740Jim Miller
2071e0c7ae184984051e8f42c71f89435fc1d40be35Kenneth Andersson    private Runnable mRecreateRunnable = new Runnable() {
2081e0c7ae184984051e8f42c71f89435fc1d40be35Kenneth Andersson        public void run() {
20962c3efd204acdf1f7bf3bde584e2a0dfd9ca046eJim Miller            updateScreen(mMode, true);
2101e0c7ae184984051e8f42c71f89435fc1d40be35Kenneth Andersson        }
2111e0c7ae184984051e8f42c71f89435fc1d40be35Kenneth Andersson    };
2121e0c7ae184984051e8f42c71f89435fc1d40be35Kenneth Andersson
2131c18828d20807342d37000746b18a3c1696f3b2eJim Miller    private LockScreenWidgetCallback mWidgetCallback = new LockScreenWidgetCallback() {
2141c18828d20807342d37000746b18a3c1696f3b2eJim Miller        public void userActivity(View self) {
2151c18828d20807342d37000746b18a3c1696f3b2eJim Miller            mKeyguardScreenCallback.pokeWakelock(TRANSPORT_USERACTIVITY_TIMEOUT);
2161c18828d20807342d37000746b18a3c1696f3b2eJim Miller        }
2171c18828d20807342d37000746b18a3c1696f3b2eJim Miller
2181c18828d20807342d37000746b18a3c1696f3b2eJim Miller        public void requestShow(View view) {
2191c18828d20807342d37000746b18a3c1696f3b2eJim Miller            if (DEBUG) Log.v(TAG, "View " + view + " requested show transports");
2201c18828d20807342d37000746b18a3c1696f3b2eJim Miller            view.setVisibility(View.VISIBLE);
221054340d0a3f242efeaf898cca38625bdcb3b4b5aJeff Sharkey
222054340d0a3f242efeaf898cca38625bdcb3b4b5aJeff Sharkey            // TODO: examine all widgets to derive clock status
223054340d0a3f242efeaf898cca38625bdcb3b4b5aJeff Sharkey            mUpdateMonitor.reportClockVisible(false);
2241c18828d20807342d37000746b18a3c1696f3b2eJim Miller        }
2251c18828d20807342d37000746b18a3c1696f3b2eJim Miller
2261c18828d20807342d37000746b18a3c1696f3b2eJim Miller        public void requestHide(View view) {
2271c18828d20807342d37000746b18a3c1696f3b2eJim Miller            if (DEBUG) Log.v(TAG, "View " + view + " requested hide transports");
2281c18828d20807342d37000746b18a3c1696f3b2eJim Miller            view.setVisibility(View.GONE);
229054340d0a3f242efeaf898cca38625bdcb3b4b5aJeff Sharkey
230054340d0a3f242efeaf898cca38625bdcb3b4b5aJeff Sharkey            // TODO: examine all widgets to derive clock status
231054340d0a3f242efeaf898cca38625bdcb3b4b5aJeff Sharkey            mUpdateMonitor.reportClockVisible(true);
2321c18828d20807342d37000746b18a3c1696f3b2eJim Miller        }
2331c18828d20807342d37000746b18a3c1696f3b2eJim Miller    };
2341c18828d20807342d37000746b18a3c1696f3b2eJim Miller
23585b10b0dd0e568699f349ba500ddc8d3e6c1c12dJim Miller    private TransportControlView mTransportControlView;
23685b10b0dd0e568699f349ba500ddc8d3e6c1c12dJim Miller
2375475906f53e2d79807548932dfabbf9945143740Jim Miller    /**
2381f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * @return Whether we are stuck on the lock screen because the sim is
2391f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     *   missing.
2401f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
2411f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private boolean stuckOnLockScreenBecauseSimMissing() {
2421f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        return mRequiresSim
2431f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                && (!mUpdateMonitor.isDeviceProvisioned())
244b0b24b3df50988d23f571b83d829fecc986ec497John Wang                && (mUpdateMonitor.getSimState() == IccCard.State.ABSENT ||
245b0b24b3df50988d23f571b83d829fecc986ec497John Wang                    mUpdateMonitor.getSimState() == IccCard.State.PERM_DISABLED);
2461f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
2471f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2481f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
2491f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * @param context Used to inflate, and create views.
2501f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * @param updateMonitor Knows the state of the world, and passed along to each
2511f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     *   screen so they can use the knowledge, and also register for callbacks
2521f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     *   on dynamic information.
2531f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * @param lockPatternUtils Used to look up state of lock pattern.
2541f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
2551f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    public LockPatternKeyguardView(
2561f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            Context context,
2571f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            KeyguardUpdateMonitor updateMonitor,
2581f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            LockPatternUtils lockPatternUtils,
2591f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            KeyguardWindowController controller) {
2601f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        super(context);
2614e8f62fbcb4c1edf0e6ef379ad231fa74b12a248Fred Quintana
2624d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna        mHandler = new Handler(this);
2635475906f53e2d79807548932dfabbf9945143740Jim Miller        mConfiguration = context.getResources().getConfiguration();
26463b90f28858b9d259a1d4a145f51bdd36ada8730Dianne Hackborn        mEnableFallback = false;
2654ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller        mRequiresSim = TextUtils.isEmpty(SystemProperties.get("keyguard.no_require_sim"));
2661f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mUpdateMonitor = updateMonitor;
2671f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mLockPatternUtils = lockPatternUtils;
2681f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mWindowController = controller;
2691f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
270dce0bb62ce4e1afbdacd2b4a8ee2e02a1563e852Steven Ross        mUpdateMonitor.registerInfoCallback(this);
271dce0bb62ce4e1afbdacd2b4a8ee2e02a1563e852Steven Ross
2721f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mKeyguardScreenCallback = new KeyguardScreenCallback() {
2731f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2741f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            public void goToLockScreen() {
27584999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaen                mForgotPattern = false;
2761f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                if (mIsVerifyUnlockOnly) {
2771f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    // navigating away from unlock screen during verify mode means
2781f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    // we are done and the user failed to authenticate.
2791f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    mIsVerifyUnlockOnly = false;
2801f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    getCallback().keyguardDone(false);
2811f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                } else {
2824ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller                    updateScreen(Mode.LockScreen, false);
2831f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                }
2841f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
2851f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2861f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            public void goToUnlockScreen() {
28776c65a66884ae1b7ab06c908632dd2a66182422cWink Saville                final IccCard.State simState = mUpdateMonitor.getSimState();
2881f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                if (stuckOnLockScreenBecauseSimMissing()
2890f7b3f8ba5c2f0b8f96e072bd866c9fb374ebdebJohn Wang                         || (simState == IccCard.State.PUK_REQUIRED
2900f7b3f8ba5c2f0b8f96e072bd866c9fb374ebdebJohn Wang                             && !mLockPatternUtils.isPukUnlockScreenEnable())){
2910f7b3f8ba5c2f0b8f96e072bd866c9fb374ebdebJohn Wang                    // stuck on lock screen when sim missing or
2920f7b3f8ba5c2f0b8f96e072bd866c9fb374ebdebJohn Wang                    // puk'd but puk unlock screen is disabled
2931f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    return;
2941f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                }
2951f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                if (!isSecure()) {
2961f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    getCallback().keyguardDone(true);
2971f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                } else {
2984ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller                    updateScreen(Mode.UnlockScreen, false);
2991f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                }
3001f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
3011f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
30284999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaen            public void forgotPattern(boolean isForgotten) {
30384999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaen                if (mEnableFallback) {
30484999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaen                    mForgotPattern = isForgotten;
3054ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller                    updateScreen(Mode.UnlockScreen, false);
30684999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaen                }
30784999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaen            }
30884999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaen
3091f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            public boolean isSecure() {
3101f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                return LockPatternKeyguardView.this.isSecure();
3111f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
3121f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3131f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            public boolean isVerifyUnlockOnly() {
3141f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                return mIsVerifyUnlockOnly;
3151f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
3161f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3175475906f53e2d79807548932dfabbf9945143740Jim Miller            public void recreateMe(Configuration config) {
3181e0c7ae184984051e8f42c71f89435fc1d40be35Kenneth Andersson                removeCallbacks(mRecreateRunnable);
3191e0c7ae184984051e8f42c71f89435fc1d40be35Kenneth Andersson                post(mRecreateRunnable);
3201f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
3211f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3221f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            public void takeEmergencyCallAction() {
323eef1ae1d91d55341c25d01547ac9b952be5aa658Brian Colonna                // FaceLock must be stopped if it is running when emergency call is pressed
324eef1ae1d91d55341c25d01547ac9b952be5aa658Brian Colonna                stopAndUnbindFromFaceLock();
325eef1ae1d91d55341c25d01547ac9b952be5aa658Brian Colonna
326eef1ae1d91d55341c25d01547ac9b952be5aa658Brian Colonna                // Delay hiding FaceLock area so unlock doesn't display while dialer is coming up
327eef1ae1d91d55341c25d01547ac9b952be5aa658Brian Colonna                mHandler.sendEmptyMessageDelayed(MSG_HIDE_FACELOCK_AREA_VIEW,
328eef1ae1d91d55341c25d01547ac9b952be5aa658Brian Colonna                        FACELOCK_VIEW_AREA_EMERGENCY_HIDE_TIMEOUT);
329eef1ae1d91d55341c25d01547ac9b952be5aa658Brian Colonna
330c23024d32779b170dde32a50fbdd945ce521b874Jim Miller                pokeWakelock(EMERGENCY_CALL_TIMEOUT);
331c23024d32779b170dde32a50fbdd945ce521b874Jim Miller                if (TelephonyManager.getDefault().getCallState()
332c23024d32779b170dde32a50fbdd945ce521b874Jim Miller                        == TelephonyManager.CALL_STATE_OFFHOOK) {
333c23024d32779b170dde32a50fbdd945ce521b874Jim Miller                    mLockPatternUtils.resumeCall();
334c23024d32779b170dde32a50fbdd945ce521b874Jim Miller                } else {
335c23024d32779b170dde32a50fbdd945ce521b874Jim Miller                    Intent intent = new Intent(ACTION_EMERGENCY_DIAL);
336c23024d32779b170dde32a50fbdd945ce521b874Jim Miller                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
337c23024d32779b170dde32a50fbdd945ce521b874Jim Miller                            | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
338c23024d32779b170dde32a50fbdd945ce521b874Jim Miller                    getContext().startActivity(intent);
339c23024d32779b170dde32a50fbdd945ce521b874Jim Miller                }
3401f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
3411f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3421f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            public void pokeWakelock() {
3431f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                getCallback().pokeWakelock();
3441f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
3451f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3461f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            public void pokeWakelock(int millis) {
3471f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                getCallback().pokeWakelock(millis);
3481f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
3491f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3501f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            public void keyguardDone(boolean authenticated) {
3511f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                getCallback().keyguardDone(authenticated);
3521f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
3531f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3541f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            public void keyguardDoneDrawing() {
3551f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                // irrelevant to keyguard screen, they shouldn't be calling this
3561f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
3571f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3580340b4299282bcbddd29b26751186431cc4af17bJim Miller            public void reportFailedUnlockAttempt() {
3591f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                mUpdateMonitor.reportFailedAttempt();
3601f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                final int failedAttempts = mUpdateMonitor.getFailedAttempts();
3614f36995777a4136e8e63ea51cef2ff61df48790dJim Miller                if (DEBUG) Log.d(TAG, "reportFailedPatternAttempt: #" + failedAttempts +
36216541e4f88bf645408de098d1368cb49dd09e4c3Daniel Sandler                    " (enableFallback=" + mEnableFallback + ")");
3634f36995777a4136e8e63ea51cef2ff61df48790dJim Miller
3644f36995777a4136e8e63ea51cef2ff61df48790dJim Miller                final boolean usingPattern = mLockPatternUtils.getKeyguardStoredPasswordQuality()
365f7c5d0e46ced3ec3edb6f656acd82900b9ac988cJim Miller                        == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
3664f36995777a4136e8e63ea51cef2ff61df48790dJim Miller
3674f36995777a4136e8e63ea51cef2ff61df48790dJim Miller                final int failedAttemptsBeforeWipe = mLockPatternUtils.getDevicePolicyManager()
3684f36995777a4136e8e63ea51cef2ff61df48790dJim Miller                        .getMaximumFailedPasswordsForWipe(null);
3694f36995777a4136e8e63ea51cef2ff61df48790dJim Miller
3704f36995777a4136e8e63ea51cef2ff61df48790dJim Miller                final int failedAttemptWarning = LockPatternUtils.FAILED_ATTEMPTS_BEFORE_RESET
3714f36995777a4136e8e63ea51cef2ff61df48790dJim Miller                        - LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT;
3724f36995777a4136e8e63ea51cef2ff61df48790dJim Miller
3734f36995777a4136e8e63ea51cef2ff61df48790dJim Miller                final int remainingBeforeWipe = failedAttemptsBeforeWipe > 0 ?
3744f36995777a4136e8e63ea51cef2ff61df48790dJim Miller                        (failedAttemptsBeforeWipe - failedAttempts)
3754f36995777a4136e8e63ea51cef2ff61df48790dJim Miller                        : Integer.MAX_VALUE; // because DPM returns 0 if no restriction
3764f36995777a4136e8e63ea51cef2ff61df48790dJim Miller
3774f36995777a4136e8e63ea51cef2ff61df48790dJim Miller                if (remainingBeforeWipe < LockPatternUtils.FAILED_ATTEMPTS_BEFORE_WIPE_GRACE) {
3784f36995777a4136e8e63ea51cef2ff61df48790dJim Miller                    // If we reach this code, it means the user has installed a DevicePolicyManager
3794f36995777a4136e8e63ea51cef2ff61df48790dJim Miller                    // that requests device wipe after N attempts.  Once we get below the grace
3804f36995777a4136e8e63ea51cef2ff61df48790dJim Miller                    // period, we'll post this dialog every time as a clear warning until the
3814f36995777a4136e8e63ea51cef2ff61df48790dJim Miller                    // bombshell hits and the device is wiped.
3824f36995777a4136e8e63ea51cef2ff61df48790dJim Miller                    if (remainingBeforeWipe > 0) {
3834f36995777a4136e8e63ea51cef2ff61df48790dJim Miller                        showAlmostAtWipeDialog(failedAttempts, remainingBeforeWipe);
3844f36995777a4136e8e63ea51cef2ff61df48790dJim Miller                    } else {
3854f36995777a4136e8e63ea51cef2ff61df48790dJim Miller                        // Too many attempts. The device will be wiped shortly.
3864f36995777a4136e8e63ea51cef2ff61df48790dJim Miller                        Slog.i(TAG, "Too many unlock attempts; device will be wiped!");
3874f36995777a4136e8e63ea51cef2ff61df48790dJim Miller                        showWipeDialog(failedAttempts);
3884f36995777a4136e8e63ea51cef2ff61df48790dJim Miller                    }
3894f36995777a4136e8e63ea51cef2ff61df48790dJim Miller                } else if (usingPattern && mEnableFallback) {
3904f36995777a4136e8e63ea51cef2ff61df48790dJim Miller                    if (failedAttempts == failedAttemptWarning) {
3914f36995777a4136e8e63ea51cef2ff61df48790dJim Miller                        showAlmostAtAccountLoginDialog();
3924f36995777a4136e8e63ea51cef2ff61df48790dJim Miller                    } else if (failedAttempts >= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_RESET) {
3934f36995777a4136e8e63ea51cef2ff61df48790dJim Miller                        mLockPatternUtils.setPermanentlyLocked(true);
3944ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller                        updateScreen(mMode, false);
3954f36995777a4136e8e63ea51cef2ff61df48790dJim Miller                    }
3964f36995777a4136e8e63ea51cef2ff61df48790dJim Miller                } else {
3974f36995777a4136e8e63ea51cef2ff61df48790dJim Miller                    final boolean showTimeout =
3984f36995777a4136e8e63ea51cef2ff61df48790dJim Miller                        (failedAttempts % LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT) == 0;
3994f36995777a4136e8e63ea51cef2ff61df48790dJim Miller                    if (showTimeout) {
4004f36995777a4136e8e63ea51cef2ff61df48790dJim Miller                        showTimeoutDialog();
4014f36995777a4136e8e63ea51cef2ff61df48790dJim Miller                    }
4021f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                }
4030340b4299282bcbddd29b26751186431cc4af17bJim Miller                mLockPatternUtils.reportFailedPasswordAttempt();
4041f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
40524cfa450fa46a333ea9fa7de20a8755e592e1bedIlia Tulchinsky
4061f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            public boolean doesFallbackUnlockScreenExist() {
40724cfa450fa46a333ea9fa7de20a8755e592e1bedIlia Tulchinsky                return mEnableFallback;
4081f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
4096fe0f0e46d7863bd75f6bd23b2fa805df84b5a4dJim Miller
4106fe0f0e46d7863bd75f6bd23b2fa805df84b5a4dJim Miller            public void reportSuccessfulUnlockAttempt() {
4116fe0f0e46d7863bd75f6bd23b2fa805df84b5a4dJim Miller                mLockPatternUtils.reportSuccessfulPasswordAttempt();
4126fe0f0e46d7863bd75f6bd23b2fa805df84b5a4dJim Miller            }
4131f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        };
4141f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4151f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        /**
4161f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * We'll get key events the current screen doesn't use. see
4171f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * {@link KeyguardViewBase#onKeyDown(int, android.view.KeyEvent)}
4181f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         */
4191f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        setFocusableInTouchMode(true);
4201f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        setDescendantFocusability(FOCUS_AFTER_DESCENDANTS);
4211f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4224ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller        updateScreen(getInitialMode(), false);
42318c59475445751e9ed24cacd7cfdbf86a94412fdJim Miller        maybeEnableFallback(context);
42418c59475445751e9ed24cacd7cfdbf86a94412fdJim Miller    }
42518c59475445751e9ed24cacd7cfdbf86a94412fdJim Miller
426cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana    private class AccountAnalyzer implements AccountManagerCallback<Bundle> {
427cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana        private final AccountManager mAccountManager;
428cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana        private final Account[] mAccounts;
429cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana        private int mAccountIndex;
430cf59a0b72d3fa6bfe21b3c4cab317ef06496961eDirk Balfanz
431cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana        private AccountAnalyzer(AccountManager accountManager) {
432cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana            mAccountManager = accountManager;
433cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana            mAccounts = accountManager.getAccountsByType("com.google");
434cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana        }
435cf59a0b72d3fa6bfe21b3c4cab317ef06496961eDirk Balfanz
436cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana        private void next() {
437cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana            // if we are ready to enable the fallback or if we depleted the list of accounts
438cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana            // then finish and get out
439cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana            if (mEnableFallback || mAccountIndex >= mAccounts.length) {
440cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana                if (mUnlockScreen == null) {
44162c3efd204acdf1f7bf3bde584e2a0dfd9ca046eJim Miller                    if (DEBUG) Log.w(TAG, "no unlock screen when trying to enable fallback");
442cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana                } else if (mUnlockScreen instanceof PatternUnlockScreen) {
443cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana                    ((PatternUnlockScreen)mUnlockScreen).setEnableFallback(mEnableFallback);
444cf59a0b72d3fa6bfe21b3c4cab317ef06496961eDirk Balfanz                }
445cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana                return;
446cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana            }
447cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana
448cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana            // lookup the confirmCredentials intent for the current account
449cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana            mAccountManager.confirmCredentials(mAccounts[mAccountIndex], null, null, this, null);
450cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana        }
451cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana
452cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana        public void start() {
453cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana            mEnableFallback = false;
454cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana            mAccountIndex = 0;
455cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana            next();
456cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana        }
457cf59a0b72d3fa6bfe21b3c4cab317ef06496961eDirk Balfanz
458cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana        public void run(AccountManagerFuture<Bundle> future) {
459cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana            try {
460cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana                Bundle result = future.getResult();
461cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana                if (result.getParcelable(AccountManager.KEY_INTENT) != null) {
462cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana                    mEnableFallback = true;
463cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana                }
464cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana            } catch (OperationCanceledException e) {
465cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana                // just skip the account if we are unable to query it
466cf59a0b72d3fa6bfe21b3c4cab317ef06496961eDirk Balfanz            } catch (IOException e) {
467cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana                // just skip the account if we are unable to query it
468cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana            } catch (AuthenticatorException e) {
469cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana                // just skip the account if we are unable to query it
470cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana            } finally {
471cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana                mAccountIndex++;
472cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana                next();
473cf59a0b72d3fa6bfe21b3c4cab317ef06496961eDirk Balfanz            }
474cf59a0b72d3fa6bfe21b3c4cab317ef06496961eDirk Balfanz        }
475cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana    }
476cf59a0b72d3fa6bfe21b3c4cab317ef06496961eDirk Balfanz
477cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana    private void maybeEnableFallback(Context context) {
478cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana        // Ask the account manager if we have an account that can be used as a
479cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana        // fallback in case the user forgets his pattern.
480cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana        AccountAnalyzer accountAnalyzer = new AccountAnalyzer(AccountManager.get(context));
481cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana        accountAnalyzer.start();
4821f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
4831f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4841f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4853a1837e9947505edc41d3f422bf0e0d268e349c3Jim Miller    // TODO:
4863a1837e9947505edc41d3f422bf0e0d268e349c3Jim Miller    // This overloaded method was added to workaround a race condition in the framework between
4873a1837e9947505edc41d3f422bf0e0d268e349c3Jim Miller    // notification for orientation changed, layout() and switching resources.  This code attempts
4883a1837e9947505edc41d3f422bf0e0d268e349c3Jim Miller    // to avoid drawing the incorrect layout while things are in transition.  The method can just
4893a1837e9947505edc41d3f422bf0e0d268e349c3Jim Miller    // be removed once the race condition is fixed. See bugs 2262578 and 2292713.
4903a1837e9947505edc41d3f422bf0e0d268e349c3Jim Miller    @Override
4913a1837e9947505edc41d3f422bf0e0d268e349c3Jim Miller    protected void dispatchDraw(Canvas canvas) {
4925475906f53e2d79807548932dfabbf9945143740Jim Miller        if (DEBUG) Log.v(TAG, "*** dispatchDraw() time: " + SystemClock.elapsedRealtime());
4933a1837e9947505edc41d3f422bf0e0d268e349c3Jim Miller        super.dispatchDraw(canvas);
4943a1837e9947505edc41d3f422bf0e0d268e349c3Jim Miller    }
4953a1837e9947505edc41d3f422bf0e0d268e349c3Jim Miller
4961f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    @Override
4971f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    public void reset() {
4981f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mIsVerifyUnlockOnly = false;
49984999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaen        mForgotPattern = false;
50062c3efd204acdf1f7bf3bde584e2a0dfd9ca046eJim Miller        post(mRecreateRunnable);
5011f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
5021f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
5031f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    @Override
5041f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    public void onScreenTurnedOff() {
5051f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mScreenOn = false;
50684999d69e0a70f5e510577b09ea1e788142252a8Karl Rosaen        mForgotPattern = false;
5071f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        if (mMode == Mode.LockScreen) {
5084ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller            ((KeyguardScreen) mLockScreen).onPause();
5091f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        } else {
5101f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            ((KeyguardScreen) mUnlockScreen).onPause();
5111f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
512267cb2b284626f910cf64352bfc494d0f8d3dc42Brian Colonna
513267cb2b284626f910cf64352bfc494d0f8d3dc42Brian Colonna        // When screen is turned off, need to unbind from FaceLock service if using FaceLock
514267cb2b284626f910cf64352bfc494d0f8d3dc42Brian Colonna        stopAndUnbindFromFaceLock();
5151f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
5161f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
5171f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    @Override
5181f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    public void onScreenTurnedOn() {
5191f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mScreenOn = true;
5204284e9d19a3f917b85e5eac4d6e304fc9b866139Brian Colonna        show();
521267cb2b284626f910cf64352bfc494d0f8d3dc42Brian Colonna
522267cb2b284626f910cf64352bfc494d0f8d3dc42Brian Colonna        // When screen is turned on, need to bind to FaceLock service if we are using FaceLock
523267cb2b284626f910cf64352bfc494d0f8d3dc42Brian Colonna        // But only if not dealing with a call
52485b10b0dd0e568699f349ba500ddc8d3e6c1c12dJim Miller        final boolean transportInvisible = mTransportControlView == null ? true :
52585b10b0dd0e568699f349ba500ddc8d3e6c1c12dJim Miller                mTransportControlView.getVisibility() != View.VISIBLE;
52685b10b0dd0e568699f349ba500ddc8d3e6c1c12dJim Miller        if (mUpdateMonitor.getPhoneState() == TelephonyManager.CALL_STATE_IDLE
52785b10b0dd0e568699f349ba500ddc8d3e6c1c12dJim Miller                && transportInvisible) {
528267cb2b284626f910cf64352bfc494d0f8d3dc42Brian Colonna            bindToFaceLock();
529267cb2b284626f910cf64352bfc494d0f8d3dc42Brian Colonna        } else {
530267cb2b284626f910cf64352bfc494d0f8d3dc42Brian Colonna            mHandler.sendEmptyMessage(MSG_HIDE_FACELOCK_AREA_VIEW);
531267cb2b284626f910cf64352bfc494d0f8d3dc42Brian Colonna        }
5321f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
5331f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
5344284e9d19a3f917b85e5eac4d6e304fc9b866139Brian Colonna    @Override
5354284e9d19a3f917b85e5eac4d6e304fc9b866139Brian Colonna    public void show() {
5364284e9d19a3f917b85e5eac4d6e304fc9b866139Brian Colonna        if (mMode == Mode.LockScreen) {
5374284e9d19a3f917b85e5eac4d6e304fc9b866139Brian Colonna            ((KeyguardScreen) mLockScreen).onResume();
5384284e9d19a3f917b85e5eac4d6e304fc9b866139Brian Colonna        } else {
5394284e9d19a3f917b85e5eac4d6e304fc9b866139Brian Colonna            ((KeyguardScreen) mUnlockScreen).onResume();
5404284e9d19a3f917b85e5eac4d6e304fc9b866139Brian Colonna        }
541cfdd6242eb0c26373b9c57d2ad1ddc126708189eBrian Colonna
54258396984ef49080d5550919130fc0d869ccf840bDanielle Millett        if (mLockPatternUtils.usingBiometricWeak() &&
54358396984ef49080d5550919130fc0d869ccf840bDanielle Millett                mLockPatternUtils.isBiometricWeakInstalled()) {
544cfdd6242eb0c26373b9c57d2ad1ddc126708189eBrian Colonna            mHandler.sendEmptyMessage(MSG_SHOW_FACELOCK_AREA_VIEW);
545cfdd6242eb0c26373b9c57d2ad1ddc126708189eBrian Colonna        } else {
546cfdd6242eb0c26373b9c57d2ad1ddc126708189eBrian Colonna            mHandler.sendEmptyMessage(MSG_HIDE_FACELOCK_AREA_VIEW);
547cfdd6242eb0c26373b9c57d2ad1ddc126708189eBrian Colonna        }
5484284e9d19a3f917b85e5eac4d6e304fc9b866139Brian Colonna    }
5494284e9d19a3f917b85e5eac4d6e304fc9b866139Brian Colonna
5500d9f798e9f76b13b07ac3dee3ff90b5530f53145Jim Miller    private void recreateLockScreen() {
5514ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller        if (mLockScreen != null) {
55262c3efd204acdf1f7bf3bde584e2a0dfd9ca046eJim Miller            ((KeyguardScreen) mLockScreen).onPause();
5534ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller            ((KeyguardScreen) mLockScreen).cleanUp();
5544ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller            removeView(mLockScreen);
5551f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
5561f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
5571f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mLockScreen = createLockScreen();
5581f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mLockScreen.setVisibility(View.INVISIBLE);
5591f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        addView(mLockScreen);
5600d9f798e9f76b13b07ac3dee3ff90b5530f53145Jim Miller    }
5611f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
5624ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller    private void recreateUnlockScreen(UnlockMode unlockMode) {
5634ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller        if (mUnlockScreen != null) {
56462c3efd204acdf1f7bf3bde584e2a0dfd9ca046eJim Miller            ((KeyguardScreen) mUnlockScreen).onPause();
5654ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller            ((KeyguardScreen) mUnlockScreen).cleanUp();
5664ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller            removeView(mUnlockScreen);
5671f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
5681f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
5691f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mUnlockScreen = createUnlockScreenFor(unlockMode);
5701f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mUnlockScreen.setVisibility(View.INVISIBLE);
5711f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        addView(mUnlockScreen);
5720d9f798e9f76b13b07ac3dee3ff90b5530f53145Jim Miller    }
5731f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
5741f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    @Override
5751e0c7ae184984051e8f42c71f89435fc1d40be35Kenneth Andersson    protected void onDetachedFromWindow() {
5761e0c7ae184984051e8f42c71f89435fc1d40be35Kenneth Andersson        removeCallbacks(mRecreateRunnable);
577267cb2b284626f910cf64352bfc494d0f8d3dc42Brian Colonna
578267cb2b284626f910cf64352bfc494d0f8d3dc42Brian Colonna        // When view is hidden, need to unbind from FaceLock service if we are using FaceLock
579267cb2b284626f910cf64352bfc494d0f8d3dc42Brian Colonna        // e.g., when device becomes unlocked
580267cb2b284626f910cf64352bfc494d0f8d3dc42Brian Colonna        stopAndUnbindFromFaceLock();
581267cb2b284626f910cf64352bfc494d0f8d3dc42Brian Colonna
5821e0c7ae184984051e8f42c71f89435fc1d40be35Kenneth Andersson        super.onDetachedFromWindow();
5831e0c7ae184984051e8f42c71f89435fc1d40be35Kenneth Andersson    }
5841e0c7ae184984051e8f42c71f89435fc1d40be35Kenneth Andersson
5851c18828d20807342d37000746b18a3c1696f3b2eJim Miller    protected void onConfigurationChanged(Configuration newConfig) {
5861c18828d20807342d37000746b18a3c1696f3b2eJim Miller        Resources resources = getResources();
5871c18828d20807342d37000746b18a3c1696f3b2eJim Miller        mShowLockBeforeUnlock = resources.getBoolean(R.bool.config_enableLockBeforeUnlockScreen);
5881c18828d20807342d37000746b18a3c1696f3b2eJim Miller        mConfiguration = newConfig;
5891c18828d20807342d37000746b18a3c1696f3b2eJim Miller        if (DEBUG_CONFIGURATION) Log.v(TAG, "**** re-creating lock screen since config changed");
59051e9d5c635b8882c1947122f1aa7e820d3a5f287Adam Cohen        removeCallbacks(mRecreateRunnable);
59151e9d5c635b8882c1947122f1aa7e820d3a5f287Adam Cohen        post(mRecreateRunnable);
5921c18828d20807342d37000746b18a3c1696f3b2eJim Miller    }
5931c18828d20807342d37000746b18a3c1696f3b2eJim Miller
594dce0bb62ce4e1afbdacd2b4a8ee2e02a1563e852Steven Ross    //Ignore these events; they are implemented only because they come from the same interface
595dce0bb62ce4e1afbdacd2b4a8ee2e02a1563e852Steven Ross    @Override
596dce0bb62ce4e1afbdacd2b4a8ee2e02a1563e852Steven Ross    public void onRefreshBatteryInfo(boolean showBatteryInfo, boolean pluggedIn, int batteryLevel)
597dce0bb62ce4e1afbdacd2b4a8ee2e02a1563e852Steven Ross    {}
598dce0bb62ce4e1afbdacd2b4a8ee2e02a1563e852Steven Ross    @Override
599dce0bb62ce4e1afbdacd2b4a8ee2e02a1563e852Steven Ross    public void onTimeChanged() {}
600dce0bb62ce4e1afbdacd2b4a8ee2e02a1563e852Steven Ross    @Override
601dce0bb62ce4e1afbdacd2b4a8ee2e02a1563e852Steven Ross    public void onRefreshCarrierInfo(CharSequence plmn, CharSequence spn) {}
602dce0bb62ce4e1afbdacd2b4a8ee2e02a1563e852Steven Ross    @Override
603dce0bb62ce4e1afbdacd2b4a8ee2e02a1563e852Steven Ross    public void onRingerModeChanged(int state) {}
604dce0bb62ce4e1afbdacd2b4a8ee2e02a1563e852Steven Ross    @Override
605dce0bb62ce4e1afbdacd2b4a8ee2e02a1563e852Steven Ross    public void onClockVisibilityChanged() {}
606dce0bb62ce4e1afbdacd2b4a8ee2e02a1563e852Steven Ross
607dce0bb62ce4e1afbdacd2b4a8ee2e02a1563e852Steven Ross    //We need to stop faceunlock when a phonecall comes in
608dce0bb62ce4e1afbdacd2b4a8ee2e02a1563e852Steven Ross    @Override
609dce0bb62ce4e1afbdacd2b4a8ee2e02a1563e852Steven Ross    public void onPhoneStateChanged(int phoneState) {
610dce0bb62ce4e1afbdacd2b4a8ee2e02a1563e852Steven Ross        if(phoneState == TelephonyManager.CALL_STATE_RINGING) stopAndUnbindFromFaceLock();
611dce0bb62ce4e1afbdacd2b4a8ee2e02a1563e852Steven Ross    }
612dce0bb62ce4e1afbdacd2b4a8ee2e02a1563e852Steven Ross
6131e0c7ae184984051e8f42c71f89435fc1d40be35Kenneth Andersson    @Override
6142e1db30d18a0ff6640bb0ad61f922ec1fdcf5a3cSvetoslav Ganov    protected boolean dispatchHoverEvent(MotionEvent event) {
6152e1db30d18a0ff6640bb0ad61f922ec1fdcf5a3cSvetoslav Ganov        // Do not let the screen to get locked while the user is disabled and touch
6162e1db30d18a0ff6640bb0ad61f922ec1fdcf5a3cSvetoslav Ganov        // exploring. A blind user will need significantly more time to find and
6172e1db30d18a0ff6640bb0ad61f922ec1fdcf5a3cSvetoslav Ganov        // interact with the lock screen views.
6182e1db30d18a0ff6640bb0ad61f922ec1fdcf5a3cSvetoslav Ganov        AccessibilityManager accessibilityManager = AccessibilityManager.getInstance(mContext);
6192e1db30d18a0ff6640bb0ad61f922ec1fdcf5a3cSvetoslav Ganov        if (accessibilityManager.isEnabled() && accessibilityManager.isTouchExplorationEnabled()) {
6202e1db30d18a0ff6640bb0ad61f922ec1fdcf5a3cSvetoslav Ganov            getCallback().pokeWakelock();
6212e1db30d18a0ff6640bb0ad61f922ec1fdcf5a3cSvetoslav Ganov        }
6222e1db30d18a0ff6640bb0ad61f922ec1fdcf5a3cSvetoslav Ganov        return super.dispatchHoverEvent(event);
6232e1db30d18a0ff6640bb0ad61f922ec1fdcf5a3cSvetoslav Ganov    }
6242e1db30d18a0ff6640bb0ad61f922ec1fdcf5a3cSvetoslav Ganov
6252e1db30d18a0ff6640bb0ad61f922ec1fdcf5a3cSvetoslav Ganov    @Override
6261f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    public void wakeWhenReadyTq(int keyCode) {
6271f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        if (DEBUG) Log.d(TAG, "onWakeKey");
6281f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        if (keyCode == KeyEvent.KEYCODE_MENU && isSecure() && (mMode == Mode.LockScreen)
62976c65a66884ae1b7ab06c908632dd2a66182422cWink Saville                && (mUpdateMonitor.getSimState() != IccCard.State.PUK_REQUIRED)) {
6301f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            if (DEBUG) Log.d(TAG, "switching screens to unlock screen because wake key was MENU");
6314ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller            updateScreen(Mode.UnlockScreen, false);
6321f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            getCallback().pokeWakelock();
6331f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        } else {
6341f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            if (DEBUG) Log.d(TAG, "poking wake lock immediately");
6351f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            getCallback().pokeWakelock();
6361f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
6371f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
6381f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
6391f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    @Override
6401f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    public void verifyUnlock() {
6411f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        if (!isSecure()) {
6421f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            // non-secure keyguard screens are successfull by default
6431f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            getCallback().keyguardDone(true);
6444ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller        } else if (mUnlockScreenMode != UnlockMode.Pattern
6454ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller                && mUnlockScreenMode != UnlockMode.Password) {
6464ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller            // can only verify unlock when in pattern/password mode
6471f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            getCallback().keyguardDone(false);
6481f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        } else {
6491f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            // otherwise, go to the unlock screen, see if they can verify it
6501f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mIsVerifyUnlockOnly = true;
6514ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller            updateScreen(Mode.UnlockScreen, false);
6521f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
6531f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
6541f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
6551f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    @Override
6561f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    public void cleanUp() {
6574ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller        if (mLockScreen != null) {
6584ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller            ((KeyguardScreen) mLockScreen).onPause();
6594ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller            ((KeyguardScreen) mLockScreen).cleanUp();
6604ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller            this.removeView(mLockScreen);
6614ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller            mLockScreen = null;
6624ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller        }
6634ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller        if (mUnlockScreen != null) {
6644ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller            ((KeyguardScreen) mUnlockScreen).onPause();
6654ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller            ((KeyguardScreen) mUnlockScreen).cleanUp();
6664ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller            this.removeView(mUnlockScreen);
6674ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller            mUnlockScreen = null;
6684ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller        }
6691f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
6701f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
6711f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private boolean isSecure() {
6721f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        UnlockMode unlockMode = getUnlockMode();
6735e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller        boolean secure = false;
6745e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller        switch (unlockMode) {
6755e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller            case Pattern:
6765e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller                secure = mLockPatternUtils.isLockPatternEnabled();
6775e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller                break;
6785e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller            case SimPin:
6790f7b3f8ba5c2f0b8f96e072bd866c9fb374ebdebJohn Wang                secure = mUpdateMonitor.getSimState() == IccCard.State.PIN_REQUIRED;
6800f7b3f8ba5c2f0b8f96e072bd866c9fb374ebdebJohn Wang                break;
6810f7b3f8ba5c2f0b8f96e072bd866c9fb374ebdebJohn Wang            case SimPuk:
6820f7b3f8ba5c2f0b8f96e072bd866c9fb374ebdebJohn Wang                secure = mUpdateMonitor.getSimState() == IccCard.State.PUK_REQUIRED;
6835e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller                break;
6845e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller            case Account:
6855e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller                secure = true;
6865e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller                break;
6875e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller            case Password:
6885e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller                secure = mLockPatternUtils.isLockPasswordEnabled();
6895e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller                break;
6905e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller            default:
6915e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller                throw new IllegalStateException("unknown unlock mode " + unlockMode);
6921f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
6935e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller        return secure;
6941f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
6951f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
6964ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller    private void updateScreen(Mode mode, boolean force) {
6971f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
69875787398fa5db9add16f3d3bc298198ed2c6671fDianne Hackborn        if (DEBUG_CONFIGURATION) Log.v(TAG, "**** UPDATE SCREEN: mode=" + mode
69962c3efd204acdf1f7bf3bde584e2a0dfd9ca046eJim Miller                + " last mode=" + mMode + ", force = " + force, new RuntimeException());
700cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana
7011f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mMode = mode;
7021f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
7034ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller        // Re-create the lock screen if necessary
7044ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller        if (mode == Mode.LockScreen || mShowLockBeforeUnlock) {
7054ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller            if (force || mLockScreen == null) {
7064ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller                recreateLockScreen();
7074ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller            }
7084ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller        }
7094ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller
7100d9f798e9f76b13b07ac3dee3ff90b5530f53145Jim Miller        // Re-create the unlock screen if necessary. This is primarily required to properly handle
7110d9f798e9f76b13b07ac3dee3ff90b5530f53145Jim Miller        // SIM state changes. This typically happens when this method is called by reset()
7124ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller        if (mode == Mode.UnlockScreen) {
7134ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller            final UnlockMode unlockMode = getUnlockMode();
7144ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller            if (force || mUnlockScreen == null || unlockMode != mUnlockScreenMode) {
7154ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller                recreateUnlockScreen(unlockMode);
7164ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller            }
7170d9f798e9f76b13b07ac3dee3ff90b5530f53145Jim Miller        }
7180d9f798e9f76b13b07ac3dee3ff90b5530f53145Jim Miller
7194ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller        // visibleScreen should never be null
7201f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        final View goneScreen = (mode == Mode.LockScreen) ? mUnlockScreen : mLockScreen;
72142b432d84cd3bf860a03a10e9191738e05f2eaddJim Miller        final View visibleScreen = (mode == Mode.LockScreen) ? mLockScreen : mUnlockScreen;
7221f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
7231f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        // do this before changing visibility so focus isn't requested before the input
7241f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        // flag is set
7251f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mWindowController.setNeedsInput(((KeyguardScreen)visibleScreen).needsInput());
72624cfa450fa46a333ea9fa7de20a8755e592e1bedIlia Tulchinsky
72775787398fa5db9add16f3d3bc298198ed2c6671fDianne Hackborn        if (DEBUG_CONFIGURATION) {
72875787398fa5db9add16f3d3bc298198ed2c6671fDianne Hackborn            Log.v(TAG, "Gone=" + goneScreen);
72975787398fa5db9add16f3d3bc298198ed2c6671fDianne Hackborn            Log.v(TAG, "Visible=" + visibleScreen);
73075787398fa5db9add16f3d3bc298198ed2c6671fDianne Hackborn        }
731cd8aed8c503ee37fa36b7d14744c9d0271faf12dFred Quintana
7321f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        if (mScreenOn) {
7334ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller            if (goneScreen != null && goneScreen.getVisibility() == View.VISIBLE) {
7341f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                ((KeyguardScreen) goneScreen).onPause();
7351f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
7361f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            if (visibleScreen.getVisibility() != View.VISIBLE) {
7371f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                ((KeyguardScreen) visibleScreen).onResume();
7381f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
7391f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
7401f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
7414ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller        if (goneScreen != null) {
7424ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller            goneScreen.setVisibility(View.GONE);
7434ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller        }
7441f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        visibleScreen.setVisibility(View.VISIBLE);
74575787398fa5db9add16f3d3bc298198ed2c6671fDianne Hackborn        requestLayout();
7461f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
7471f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        if (!visibleScreen.requestFocus()) {
7481f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            throw new IllegalStateException("keyguard screen must be able to take "
7491f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    + "focus when shown " + visibleScreen.getClass().getCanonicalName());
7501f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
7511f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
7521f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
7531f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    View createLockScreen() {
7541c18828d20807342d37000746b18a3c1696f3b2eJim Miller        View lockView = new LockScreen(
7551f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                mContext,
7565475906f53e2d79807548932dfabbf9945143740Jim Miller                mConfiguration,
7571f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                mLockPatternUtils,
7581f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                mUpdateMonitor,
7591f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                mKeyguardScreenCallback);
7601c18828d20807342d37000746b18a3c1696f3b2eJim Miller        initializeTransportControlView(lockView);
7611c18828d20807342d37000746b18a3c1696f3b2eJim Miller        return lockView;
7621f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
7631f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
7641f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    View createUnlockScreenFor(UnlockMode unlockMode) {
7650d9f798e9f76b13b07ac3dee3ff90b5530f53145Jim Miller        View unlockView = null;
7660f7b3f8ba5c2f0b8f96e072bd866c9fb374ebdebJohn Wang
7670f7b3f8ba5c2f0b8f96e072bd866c9fb374ebdebJohn Wang        if (DEBUG) Log.d(TAG,
7680f7b3f8ba5c2f0b8f96e072bd866c9fb374ebdebJohn Wang                "createUnlockScreenFor(" + unlockMode + "): mEnableFallback=" + mEnableFallback);
7690f7b3f8ba5c2f0b8f96e072bd866c9fb374ebdebJohn Wang
7701f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        if (unlockMode == UnlockMode.Pattern) {
77142b432d84cd3bf860a03a10e9191738e05f2eaddJim Miller            PatternUnlockScreen view = new PatternUnlockScreen(
7721f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    mContext,
7735475906f53e2d79807548932dfabbf9945143740Jim Miller                    mConfiguration,
7741f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    mLockPatternUtils,
7751f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    mUpdateMonitor,
7761f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    mKeyguardScreenCallback,
77763b90f28858b9d259a1d4a145f51bdd36ada8730Dianne Hackborn                    mUpdateMonitor.getFailedAttempts());
77863b90f28858b9d259a1d4a145f51bdd36ada8730Dianne Hackborn            view.setEnableFallback(mEnableFallback);
7790d9f798e9f76b13b07ac3dee3ff90b5530f53145Jim Miller            unlockView = view;
7800f7b3f8ba5c2f0b8f96e072bd866c9fb374ebdebJohn Wang        } else if (unlockMode == UnlockMode.SimPuk) {
7810f7b3f8ba5c2f0b8f96e072bd866c9fb374ebdebJohn Wang            unlockView = new SimPukUnlockScreen(
7820f7b3f8ba5c2f0b8f96e072bd866c9fb374ebdebJohn Wang                    mContext,
7830f7b3f8ba5c2f0b8f96e072bd866c9fb374ebdebJohn Wang                    mConfiguration,
7840f7b3f8ba5c2f0b8f96e072bd866c9fb374ebdebJohn Wang                    mUpdateMonitor,
7850f7b3f8ba5c2f0b8f96e072bd866c9fb374ebdebJohn Wang                    mKeyguardScreenCallback,
7860f7b3f8ba5c2f0b8f96e072bd866c9fb374ebdebJohn Wang                    mLockPatternUtils);
7871f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        } else if (unlockMode == UnlockMode.SimPin) {
7880d9f798e9f76b13b07ac3dee3ff90b5530f53145Jim Miller            unlockView = new SimUnlockScreen(
7891f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    mContext,
7905475906f53e2d79807548932dfabbf9945143740Jim Miller                    mConfiguration,
7911f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    mUpdateMonitor,
792c23024d32779b170dde32a50fbdd945ce521b874Jim Miller                    mKeyguardScreenCallback,
793c23024d32779b170dde32a50fbdd945ce521b874Jim Miller                    mLockPatternUtils);
7941f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        } else if (unlockMode == UnlockMode.Account) {
7951f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            try {
7960d9f798e9f76b13b07ac3dee3ff90b5530f53145Jim Miller                unlockView = new AccountUnlockScreen(
7971f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                        mContext,
7985475906f53e2d79807548932dfabbf9945143740Jim Miller                        mConfiguration,
799ecaced9a788910b3517bdab08b382c9d45e34dfeJim Miller                        mUpdateMonitor,
8001f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                        mKeyguardScreenCallback,
8011f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                        mLockPatternUtils);
8021f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            } catch (IllegalStateException e) {
8031f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                Log.i(TAG, "Couldn't instantiate AccountUnlockScreen"
8041f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                      + " (IAccountsService isn't available)");
8051f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                // TODO: Need a more general way to provide a
8061f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                // platform-specific fallback UI here.
8071f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                // For now, if we can't display the account login
8081f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                // unlock UI, just bring back the regular "Pattern" unlock mode.
8091f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
8101f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                // (We do this by simply returning a regular UnlockScreen
8111f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                // here.  This means that the user will still see the
8121f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                // regular pattern unlock UI, regardless of the value of
8131f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                // mUnlockScreenMode or whether or not we're in the
8141f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                // "permanently locked" state.)
8154ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller                return createUnlockScreenFor(UnlockMode.Pattern);
8161f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
8175e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller        } else if (unlockMode == UnlockMode.Password) {
8180d9f798e9f76b13b07ac3dee3ff90b5530f53145Jim Miller            unlockView = new PasswordUnlockScreen(
8195e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller                    mContext,
8205475906f53e2d79807548932dfabbf9945143740Jim Miller                    mConfiguration,
8215e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller                    mLockPatternUtils,
8225e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller                    mUpdateMonitor,
8235e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller                    mKeyguardScreenCallback);
8241f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        } else {
8251f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            throw new IllegalArgumentException("unknown unlock mode " + unlockMode);
8261f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
8271c18828d20807342d37000746b18a3c1696f3b2eJim Miller        initializeTransportControlView(unlockView);
8284d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna        initializeFaceLockAreaView(unlockView); // Only shows view if FaceLock is enabled
8294d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna
8304ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller        mUnlockScreenMode = unlockMode;
8310d9f798e9f76b13b07ac3dee3ff90b5530f53145Jim Miller        return unlockView;
8320d9f798e9f76b13b07ac3dee3ff90b5530f53145Jim Miller    }
8330d9f798e9f76b13b07ac3dee3ff90b5530f53145Jim Miller
8341c18828d20807342d37000746b18a3c1696f3b2eJim Miller    private void initializeTransportControlView(View view) {
83585b10b0dd0e568699f349ba500ddc8d3e6c1c12dJim Miller        mTransportControlView = (TransportControlView) view.findViewById(R.id.transport);
83685b10b0dd0e568699f349ba500ddc8d3e6c1c12dJim Miller        if (mTransportControlView == null) {
8371c18828d20807342d37000746b18a3c1696f3b2eJim Miller            if (DEBUG) Log.w(TAG, "Couldn't find transport control widget");
8381c18828d20807342d37000746b18a3c1696f3b2eJim Miller        } else {
839054340d0a3f242efeaf898cca38625bdcb3b4b5aJeff Sharkey            mUpdateMonitor.reportClockVisible(true);
84085b10b0dd0e568699f349ba500ddc8d3e6c1c12dJim Miller            mTransportControlView.setVisibility(View.GONE); // hide until it requests being shown.
84185b10b0dd0e568699f349ba500ddc8d3e6c1c12dJim Miller            mTransportControlView.setCallback(mWidgetCallback);
8421c18828d20807342d37000746b18a3c1696f3b2eJim Miller        }
8431c18828d20807342d37000746b18a3c1696f3b2eJim Miller    }
8441c18828d20807342d37000746b18a3c1696f3b2eJim Miller
8451f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
8461f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * Given the current state of things, what should be the initial mode of
8471f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * the lock screen (lock or unlock).
8481f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
8491f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private Mode getInitialMode() {
85076c65a66884ae1b7ab06c908632dd2a66182422cWink Saville        final IccCard.State simState = mUpdateMonitor.getSimState();
8510f7b3f8ba5c2f0b8f96e072bd866c9fb374ebdebJohn Wang        if (stuckOnLockScreenBecauseSimMissing() ||
8520f7b3f8ba5c2f0b8f96e072bd866c9fb374ebdebJohn Wang                (simState == IccCard.State.PUK_REQUIRED &&
8530f7b3f8ba5c2f0b8f96e072bd866c9fb374ebdebJohn Wang                        !mLockPatternUtils.isPukUnlockScreenEnable())) {
8541f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return Mode.LockScreen;
8551f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        } else {
8564ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller            if (!isSecure() || mShowLockBeforeUnlock) {
857466d77617ace8380ab8c52ede20790755d8ff092Jim Miller                return Mode.LockScreen;
8584ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller            } else {
8594ae8cb9e73b3b516434c9dc26fcc9697daff851dJim Miller                return Mode.UnlockScreen;
860466d77617ace8380ab8c52ede20790755d8ff092Jim Miller            }
8611f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
8621f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
8631f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
8641f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
8651f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * Given the current state of things, what should the unlock screen be?
8661f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
8671f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private UnlockMode getUnlockMode() {
86876c65a66884ae1b7ab06c908632dd2a66182422cWink Saville        final IccCard.State simState = mUpdateMonitor.getSimState();
8695e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller        UnlockMode currentMode;
8700f7b3f8ba5c2f0b8f96e072bd866c9fb374ebdebJohn Wang        if (simState == IccCard.State.PIN_REQUIRED) {
8715e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller            currentMode = UnlockMode.SimPin;
8720f7b3f8ba5c2f0b8f96e072bd866c9fb374ebdebJohn Wang        } else if (simState == IccCard.State.PUK_REQUIRED) {
8730f7b3f8ba5c2f0b8f96e072bd866c9fb374ebdebJohn Wang            currentMode = UnlockMode.SimPuk;
8741f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        } else {
875f7c5d0e46ced3ec3edb6f656acd82900b9ac988cJim Miller            final int mode = mLockPatternUtils.getKeyguardStoredPasswordQuality();
8765e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller            switch (mode) {
877f7c5d0e46ced3ec3edb6f656acd82900b9ac988cJim Miller                case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
878f7c5d0e46ced3ec3edb6f656acd82900b9ac988cJim Miller                case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
879f7c5d0e46ced3ec3edb6f656acd82900b9ac988cJim Miller                case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
880a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
8815e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller                    currentMode = UnlockMode.Password;
8825e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller                    break;
883f7c5d0e46ced3ec3edb6f656acd82900b9ac988cJim Miller                case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
884f7c5d0e46ced3ec3edb6f656acd82900b9ac988cJim Miller                case DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED:
8855e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller                    // "forgot pattern" button is only available in the pattern mode...
8860340b4299282bcbddd29b26751186431cc4af17bJim Miller                    if (mForgotPattern || mLockPatternUtils.isPermanentlyLocked()) {
8875e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller                        currentMode = UnlockMode.Account;
8885e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller                    } else {
8895e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller                        currentMode = UnlockMode.Pattern;
8905e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller                    }
8915e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller                    break;
8925e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller                default:
8935e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller                   throw new IllegalStateException("Unknown unlock mode:" + mode);
8945e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller            }
8951f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
8965e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller        return currentMode;
8971f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
8981f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
8994f36995777a4136e8e63ea51cef2ff61df48790dJim Miller    private void showDialog(String title, String message) {
9004f36995777a4136e8e63ea51cef2ff61df48790dJim Miller        final AlertDialog dialog = new AlertDialog.Builder(mContext)
9014f36995777a4136e8e63ea51cef2ff61df48790dJim Miller            .setTitle(title)
9024f36995777a4136e8e63ea51cef2ff61df48790dJim Miller            .setMessage(message)
9034f36995777a4136e8e63ea51cef2ff61df48790dJim Miller            .setNeutralButton(R.string.ok, null)
9044f36995777a4136e8e63ea51cef2ff61df48790dJim Miller            .create();
9054f36995777a4136e8e63ea51cef2ff61df48790dJim Miller        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
9064f36995777a4136e8e63ea51cef2ff61df48790dJim Miller        dialog.show();
9074f36995777a4136e8e63ea51cef2ff61df48790dJim Miller    }
9084f36995777a4136e8e63ea51cef2ff61df48790dJim Miller
9091f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private void showTimeoutDialog() {
9101f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        int timeoutInSeconds = (int) LockPatternUtils.FAILED_ATTEMPT_TIMEOUT_MS / 1000;
9118171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung        int messageId = R.string.lockscreen_too_many_failed_attempts_dialog_message;
9124f36995777a4136e8e63ea51cef2ff61df48790dJim Miller        if (getUnlockMode() == UnlockMode.Password) {
913c15dcf7ea1421305a54f256777212373c28c53c0Konstantin Lopyrev            if(mLockPatternUtils.getKeyguardStoredPasswordQuality() ==
914c15dcf7ea1421305a54f256777212373c28c53c0Konstantin Lopyrev                DevicePolicyManager.PASSWORD_QUALITY_NUMERIC) {
915c15dcf7ea1421305a54f256777212373c28c53c0Konstantin Lopyrev                messageId = R.string.lockscreen_too_many_failed_pin_attempts_dialog_message;
916c15dcf7ea1421305a54f256777212373c28c53c0Konstantin Lopyrev            } else {
917c15dcf7ea1421305a54f256777212373c28c53c0Konstantin Lopyrev                messageId = R.string.lockscreen_too_many_failed_password_attempts_dialog_message;
918c15dcf7ea1421305a54f256777212373c28c53c0Konstantin Lopyrev            }
919c15dcf7ea1421305a54f256777212373c28c53c0Konstantin Lopyrev        }
9204f36995777a4136e8e63ea51cef2ff61df48790dJim Miller        String message = mContext.getString(messageId, mUpdateMonitor.getFailedAttempts(),
9211f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                timeoutInSeconds);
92267403e096e6f59b7cd18a90d0d3f5c3d17c31407Mathias Agopian
9234f36995777a4136e8e63ea51cef2ff61df48790dJim Miller        showDialog(null, message);
9241f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
9251f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
9261f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private void showAlmostAtAccountLoginDialog() {
9274f36995777a4136e8e63ea51cef2ff61df48790dJim Miller        final int timeoutInSeconds = (int) LockPatternUtils.FAILED_ATTEMPT_TIMEOUT_MS / 1000;
9284f36995777a4136e8e63ea51cef2ff61df48790dJim Miller        final int count = LockPatternUtils.FAILED_ATTEMPTS_BEFORE_RESET
9294f36995777a4136e8e63ea51cef2ff61df48790dJim Miller                - LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT;
9304f36995777a4136e8e63ea51cef2ff61df48790dJim Miller        String message = mContext.getString(R.string.lockscreen_failed_attempts_almost_glogin,
9314f36995777a4136e8e63ea51cef2ff61df48790dJim Miller                count, LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT, timeoutInSeconds);
9324f36995777a4136e8e63ea51cef2ff61df48790dJim Miller        showDialog(null, message);
9334f36995777a4136e8e63ea51cef2ff61df48790dJim Miller    }
9344f36995777a4136e8e63ea51cef2ff61df48790dJim Miller
9354f36995777a4136e8e63ea51cef2ff61df48790dJim Miller    private void showAlmostAtWipeDialog(int attempts, int remaining) {
9361f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        int timeoutInSeconds = (int) LockPatternUtils.FAILED_ATTEMPT_TIMEOUT_MS / 1000;
9371f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        String message = mContext.getString(
9384f36995777a4136e8e63ea51cef2ff61df48790dJim Miller                R.string.lockscreen_failed_attempts_almost_at_wipe, attempts, remaining);
9394f36995777a4136e8e63ea51cef2ff61df48790dJim Miller        showDialog(null, message);
9404f36995777a4136e8e63ea51cef2ff61df48790dJim Miller    }
9414f36995777a4136e8e63ea51cef2ff61df48790dJim Miller
9424f36995777a4136e8e63ea51cef2ff61df48790dJim Miller    private void showWipeDialog(int attempts) {
9434f36995777a4136e8e63ea51cef2ff61df48790dJim Miller        String message = mContext.getString(
9444f36995777a4136e8e63ea51cef2ff61df48790dJim Miller                R.string.lockscreen_failed_attempts_now_wiping, attempts);
9454f36995777a4136e8e63ea51cef2ff61df48790dJim Miller        showDialog(null, message);
9461f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
9471f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
9481f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
949c4d9d21009db7b977a2201f6760d78786be3028dDianne Hackborn     * Used to put wallpaper on the background of the lock screen.  Centers it
950c4d9d21009db7b977a2201f6760d78786be3028dDianne Hackborn     * Horizontally and pins the bottom (assuming that the lock screen is aligned
951c4d9d21009db7b977a2201f6760d78786be3028dDianne Hackborn     * with the bottom, so the wallpaper should extend above the top into the
952c4d9d21009db7b977a2201f6760d78786be3028dDianne Hackborn     * status bar).
9531f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
9541f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    static private class FastBitmapDrawable extends Drawable {
9551f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        private Bitmap mBitmap;
9569593e0a0073d77ab65cc97156da4d0e890e4cf27Romain Guy        private int mOpacity;
9571f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
9581f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        private FastBitmapDrawable(Bitmap bitmap) {
9591f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mBitmap = bitmap;
9609593e0a0073d77ab65cc97156da4d0e890e4cf27Romain Guy            mOpacity = mBitmap.hasAlpha() ? PixelFormat.TRANSLUCENT : PixelFormat.OPAQUE;
9611f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
9621f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
9631f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        @Override
9641f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public void draw(Canvas canvas) {
9651f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            canvas.drawBitmap(
9661f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    mBitmap,
9671f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    (getBounds().width() - mBitmap.getWidth()) / 2,
968c4d9d21009db7b977a2201f6760d78786be3028dDianne Hackborn                    (getBounds().height() - mBitmap.getHeight()),
9691f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    null);
9701f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
9711f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
9721f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        @Override
9731f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public int getOpacity() {
9749593e0a0073d77ab65cc97156da4d0e890e4cf27Romain Guy            return mOpacity;
9751f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
9761f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
9771f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        @Override
9781f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public void setAlpha(int alpha) {
9791f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
9801f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
9811f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        @Override
9821f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public void setColorFilter(ColorFilter cf) {
9831f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
9841f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
9851f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        @Override
9861f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public int getIntrinsicWidth() {
9871f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return mBitmap.getWidth();
9881f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
9891f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
9901f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        @Override
9911f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public int getIntrinsicHeight() {
9921f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return mBitmap.getHeight();
9931f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
9941f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
9951f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        @Override
9961f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public int getMinimumWidth() {
9971f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return mBitmap.getWidth();
9981f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
9991f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
10001f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        @Override
10011f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public int getMinimumHeight() {
10021f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return mBitmap.getHeight();
10031f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
10041f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
100576c65a66884ae1b7ab06c908632dd2a66182422cWink Saville
10066edf2637e96139735df83907c221cce16d4d7eaaJim Miller    // Everything below pertains to FaceLock - might want to separate this out
10076edf2637e96139735df83907c221cce16d4d7eaaJim Miller
10084d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna    // Only pattern and pin unlock screens actually have a view for the FaceLock area, so it's not
1009267cb2b284626f910cf64352bfc494d0f8d3dc42Brian Colonna    // uncommon for it to not exist.  But if it does exist, we need to make sure it's shown (hiding
1010267cb2b284626f910cf64352bfc494d0f8d3dc42Brian Colonna    // the fallback) if FaceLock is enabled, and make sure it's hidden (showing the unlock) if
1011267cb2b284626f910cf64352bfc494d0f8d3dc42Brian Colonna    // FaceLock is disabled
10124d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna    private void initializeFaceLockAreaView(View view) {
10134d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna        mFaceLockAreaView = view.findViewById(R.id.faceLockAreaView);
10144d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna        if (mFaceLockAreaView == null) {
10154d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna            if (DEBUG) Log.d(TAG, "Layout does not have faceLockAreaView");
10164d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna        }
10174d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna    }
10184d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna
10194d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna    // Handles covering or exposing FaceLock area on the client side when FaceLock starts or stops
10204d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna    // This needs to be done in a handler because the call could be coming from a callback from the
10214d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna    // FaceLock service that is in a thread that can't modify the UI
10224d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna    @Override
10234d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna    public boolean handleMessage(Message msg) {
10244d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna        switch (msg.what) {
10254d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna        case MSG_SHOW_FACELOCK_AREA_VIEW:
1026b9a4b3c18aa0094bbbbc2858c765fb4aeafdee67Justin Ho            if (mFaceLockAreaView != null) {
1027b9a4b3c18aa0094bbbbc2858c765fb4aeafdee67Justin Ho                mFaceLockAreaView.setVisibility(View.VISIBLE);
1028b9a4b3c18aa0094bbbbc2858c765fb4aeafdee67Justin Ho            }
10294d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna            break;
10304d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna        case MSG_HIDE_FACELOCK_AREA_VIEW:
1031b9a4b3c18aa0094bbbbc2858c765fb4aeafdee67Justin Ho            if (mFaceLockAreaView != null) {
1032b9a4b3c18aa0094bbbbc2858c765fb4aeafdee67Justin Ho                mFaceLockAreaView.setVisibility(View.GONE);
1033b9a4b3c18aa0094bbbbc2858c765fb4aeafdee67Justin Ho            }
10344d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna            break;
10354d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna        default:
10364d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna            Log.w(TAG, "Unhandled message");
10374d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna            return false;
10384d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna        }
10394d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna        return true;
10404d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna    }
10414d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna
10426edf2637e96139735df83907c221cce16d4d7eaaJim Miller    // Binds to FaceLock service, but does not tell it to start
10436edf2637e96139735df83907c221cce16d4d7eaaJim Miller    public void bindToFaceLock() {
104458396984ef49080d5550919130fc0d869ccf840bDanielle Millett        if (mLockPatternUtils.usingBiometricWeak() &&
104558396984ef49080d5550919130fc0d869ccf840bDanielle Millett                mLockPatternUtils.isBiometricWeakInstalled()) {
10466edf2637e96139735df83907c221cce16d4d7eaaJim Miller            if (!mBoundToFaceLockService) {
10476edf2637e96139735df83907c221cce16d4d7eaaJim Miller                if (DEBUG) Log.d(TAG, "before bind to FaceLock service");
10486edf2637e96139735df83907c221cce16d4d7eaaJim Miller                mContext.bindService(new Intent(IFaceLockInterface.class.getName()),
10496edf2637e96139735df83907c221cce16d4d7eaaJim Miller                        mFaceLockConnection,
10506edf2637e96139735df83907c221cce16d4d7eaaJim Miller                        Context.BIND_AUTO_CREATE);
10516edf2637e96139735df83907c221cce16d4d7eaaJim Miller                if (DEBUG) Log.d(TAG, "after bind to FaceLock service");
10526edf2637e96139735df83907c221cce16d4d7eaaJim Miller                mBoundToFaceLockService = true;
10536edf2637e96139735df83907c221cce16d4d7eaaJim Miller            } else {
1054267cb2b284626f910cf64352bfc494d0f8d3dc42Brian Colonna                Log.w(TAG, "Attempt to bind to FaceLock when already bound");
10556edf2637e96139735df83907c221cce16d4d7eaaJim Miller            }
10566edf2637e96139735df83907c221cce16d4d7eaaJim Miller        }
10576edf2637e96139735df83907c221cce16d4d7eaaJim Miller    }
10586edf2637e96139735df83907c221cce16d4d7eaaJim Miller
10596edf2637e96139735df83907c221cce16d4d7eaaJim Miller    // Tells FaceLock to stop and then unbinds from the FaceLock service
10606edf2637e96139735df83907c221cce16d4d7eaaJim Miller    public void stopAndUnbindFromFaceLock() {
106158396984ef49080d5550919130fc0d869ccf840bDanielle Millett        if (mLockPatternUtils.usingBiometricWeak() &&
106258396984ef49080d5550919130fc0d869ccf840bDanielle Millett                mLockPatternUtils.isBiometricWeakInstalled()) {
10636edf2637e96139735df83907c221cce16d4d7eaaJim Miller            stopFaceLock();
10646edf2637e96139735df83907c221cce16d4d7eaaJim Miller
10656edf2637e96139735df83907c221cce16d4d7eaaJim Miller            if (mBoundToFaceLockService) {
10666edf2637e96139735df83907c221cce16d4d7eaaJim Miller                if (DEBUG) Log.d(TAG, "before unbind from FaceLock service");
10676edf2637e96139735df83907c221cce16d4d7eaaJim Miller                mContext.unbindService(mFaceLockConnection);
10686edf2637e96139735df83907c221cce16d4d7eaaJim Miller                if (DEBUG) Log.d(TAG, "after unbind from FaceLock service");
10696edf2637e96139735df83907c221cce16d4d7eaaJim Miller                mBoundToFaceLockService = false;
10706edf2637e96139735df83907c221cce16d4d7eaaJim Miller            } else {
10716edf2637e96139735df83907c221cce16d4d7eaaJim Miller                // This could probably happen after the session when someone activates FaceLock
10726edf2637e96139735df83907c221cce16d4d7eaaJim Miller                // because it wasn't active when the phone was turned on
1073267cb2b284626f910cf64352bfc494d0f8d3dc42Brian Colonna                Log.w(TAG, "Attempt to unbind from FaceLock when not bound");
10746edf2637e96139735df83907c221cce16d4d7eaaJim Miller            }
10756edf2637e96139735df83907c221cce16d4d7eaaJim Miller        }
10766edf2637e96139735df83907c221cce16d4d7eaaJim Miller    }
10776edf2637e96139735df83907c221cce16d4d7eaaJim Miller
10786edf2637e96139735df83907c221cce16d4d7eaaJim Miller    private ServiceConnection mFaceLockConnection = new ServiceConnection() {
10796edf2637e96139735df83907c221cce16d4d7eaaJim Miller        // Completes connection, registers callback and starts FaceLock when service is bound
10806edf2637e96139735df83907c221cce16d4d7eaaJim Miller        @Override
10816edf2637e96139735df83907c221cce16d4d7eaaJim Miller        public void onServiceConnected(ComponentName className, IBinder iservice) {
10826edf2637e96139735df83907c221cce16d4d7eaaJim Miller            mFaceLockService = IFaceLockInterface.Stub.asInterface(iservice);
10836edf2637e96139735df83907c221cce16d4d7eaaJim Miller            if (DEBUG) Log.d(TAG, "Connected to FaceLock service");
10846edf2637e96139735df83907c221cce16d4d7eaaJim Miller            try {
10856edf2637e96139735df83907c221cce16d4d7eaaJim Miller                mFaceLockService.registerCallback(mFaceLockCallback);
10866edf2637e96139735df83907c221cce16d4d7eaaJim Miller            } catch (RemoteException e) {
10876edf2637e96139735df83907c221cce16d4d7eaaJim Miller                throw new RuntimeException("Remote exception");
10886edf2637e96139735df83907c221cce16d4d7eaaJim Miller            }
10896edf2637e96139735df83907c221cce16d4d7eaaJim Miller
10906edf2637e96139735df83907c221cce16d4d7eaaJim Miller            if (mFaceLockAreaView != null) {
10914d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna                startFaceLock(mFaceLockAreaView.getWindowToken(),
10924d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna                        mFaceLockAreaView.getLeft(), mFaceLockAreaView.getTop(),
10934d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna                        mFaceLockAreaView.getWidth(), mFaceLockAreaView.getHeight());
10946edf2637e96139735df83907c221cce16d4d7eaaJim Miller            }
10956edf2637e96139735df83907c221cce16d4d7eaaJim Miller        }
10966edf2637e96139735df83907c221cce16d4d7eaaJim Miller
10976edf2637e96139735df83907c221cce16d4d7eaaJim Miller        // Cleans up if FaceLock service unexpectedly disconnects
10986edf2637e96139735df83907c221cce16d4d7eaaJim Miller        @Override
10996edf2637e96139735df83907c221cce16d4d7eaaJim Miller        public void onServiceDisconnected(ComponentName className) {
11004d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna            synchronized(mFaceLockServiceRunningLock) {
11014d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna                mFaceLockService = null;
11024d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna                mFaceLockServiceRunning = false;
11034d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna            }
1104267cb2b284626f910cf64352bfc494d0f8d3dc42Brian Colonna            Log.w(TAG, "Unexpected disconnect from FaceLock service");
11056edf2637e96139735df83907c221cce16d4d7eaaJim Miller        }
11066edf2637e96139735df83907c221cce16d4d7eaaJim Miller    };
11076edf2637e96139735df83907c221cce16d4d7eaaJim Miller
11086edf2637e96139735df83907c221cce16d4d7eaaJim Miller    // Tells the FaceLock service to start displaying its UI and perform recognition
11096edf2637e96139735df83907c221cce16d4d7eaaJim Miller    public void startFaceLock(IBinder windowToken, int x, int y, int h, int w)
11106edf2637e96139735df83907c221cce16d4d7eaaJim Miller    {
111158396984ef49080d5550919130fc0d869ccf840bDanielle Millett        if (mLockPatternUtils.usingBiometricWeak() &&
111258396984ef49080d5550919130fc0d869ccf840bDanielle Millett                mLockPatternUtils.isBiometricWeakInstalled()) {
11134d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna            synchronized (mFaceLockServiceRunningLock) {
11144d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna                if (!mFaceLockServiceRunning) {
11154d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna                    if (DEBUG) Log.d(TAG, "Starting FaceLock");
11164d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna                    try {
11174d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna                        mFaceLockService.startUi(windowToken, x, y, h, w);
11184d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna                    } catch (RemoteException e) {
11194d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna                        throw new RuntimeException("Remote exception");
11204d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna                    }
11214d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna                    mFaceLockServiceRunning = true;
11224d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna                } else {
11234d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna                    if (DEBUG) Log.w(TAG, "startFaceLock() attempted while running");
11246edf2637e96139735df83907c221cce16d4d7eaaJim Miller                }
11256edf2637e96139735df83907c221cce16d4d7eaaJim Miller            }
11266edf2637e96139735df83907c221cce16d4d7eaaJim Miller        }
11276edf2637e96139735df83907c221cce16d4d7eaaJim Miller    }
11286edf2637e96139735df83907c221cce16d4d7eaaJim Miller
11296edf2637e96139735df83907c221cce16d4d7eaaJim Miller    // Tells the FaceLock service to stop displaying its UI and stop recognition
11306edf2637e96139735df83907c221cce16d4d7eaaJim Miller    public void stopFaceLock()
11316edf2637e96139735df83907c221cce16d4d7eaaJim Miller    {
113258396984ef49080d5550919130fc0d869ccf840bDanielle Millett        if (mLockPatternUtils.usingBiometricWeak() &&
113358396984ef49080d5550919130fc0d869ccf840bDanielle Millett                mLockPatternUtils.isBiometricWeakInstalled()) {
11346edf2637e96139735df83907c221cce16d4d7eaaJim Miller            // Note that attempting to stop FaceLock when it's not running is not an issue.
11356edf2637e96139735df83907c221cce16d4d7eaaJim Miller            // FaceLock can return, which stops it and then we try to stop it when the
11366edf2637e96139735df83907c221cce16d4d7eaaJim Miller            // screen is turned off.  That's why we check.
11374d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna            synchronized (mFaceLockServiceRunningLock) {
11384d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna                if (mFaceLockServiceRunning) {
11394d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna                    try {
11404d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna                        if (DEBUG) Log.d(TAG, "Stopping FaceLock");
11414d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna                        mFaceLockService.stopUi();
11424d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna                    } catch (RemoteException e) {
11434d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna                        throw new RuntimeException("Remote exception");
11444d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna                    }
11454d7cee1e4b9ed17da8fc041be80369eb525901f1Brian Colonna                    mFaceLockServiceRunning = false;
11466edf2637e96139735df83907c221cce16d4d7eaaJim Miller                }
11476edf2637e96139735df83907c221cce16d4d7eaaJim Miller            }
11486edf2637e96139735df83907c221cce16d4d7eaaJim Miller        }
11496edf2637e96139735df83907c221cce16d4d7eaaJim Miller    }
11506edf2637e96139735df83907c221cce16d4d7eaaJim Miller
11516edf2637e96139735df83907c221cce16d4d7eaaJim Miller    // Implements the FaceLock service callback interface defined in AIDL
11526edf2637e96139735df83907c221cce16d4d7eaaJim Miller    private final IFaceLockCallback mFaceLockCallback = new IFaceLockCallback.Stub() {
11536edf2637e96139735df83907c221cce16d4d7eaaJim Miller
11546edf2637e96139735df83907c221cce16d4d7eaaJim Miller        // Stops the FaceLock UI and indicates that the phone should be unlocked
11556edf2637e96139735df83907c221cce16d4d7eaaJim Miller        @Override
11566edf2637e96139735df83907c221cce16d4d7eaaJim Miller        public void unlock() {
1157267cb2b284626f910cf64352bfc494d0f8d3dc42Brian Colonna            if (DEBUG) Log.d(TAG, "FaceLock unlock()");
1158267cb2b284626f910cf64352bfc494d0f8d3dc42Brian Colonna            mHandler.sendEmptyMessage(MSG_SHOW_FACELOCK_AREA_VIEW); // Keep fallback covered
11596edf2637e96139735df83907c221cce16d4d7eaaJim Miller            stopFaceLock();
1160267cb2b284626f910cf64352bfc494d0f8d3dc42Brian Colonna
11616edf2637e96139735df83907c221cce16d4d7eaaJim Miller            mKeyguardScreenCallback.keyguardDone(true);
11626edf2637e96139735df83907c221cce16d4d7eaaJim Miller            mKeyguardScreenCallback.reportSuccessfulUnlockAttempt();
11636edf2637e96139735df83907c221cce16d4d7eaaJim Miller        }
11646edf2637e96139735df83907c221cce16d4d7eaaJim Miller
11656edf2637e96139735df83907c221cce16d4d7eaaJim Miller        // Stops the FaceLock UI and exposes the backup method without unlocking
1166267cb2b284626f910cf64352bfc494d0f8d3dc42Brian Colonna        // This means either the user has cancelled out or FaceLock failed to recognize them
11676edf2637e96139735df83907c221cce16d4d7eaaJim Miller        @Override
11686edf2637e96139735df83907c221cce16d4d7eaaJim Miller        public void cancel() {
1169267cb2b284626f910cf64352bfc494d0f8d3dc42Brian Colonna            if (DEBUG) Log.d(TAG, "FaceLock cancel()");
1170267cb2b284626f910cf64352bfc494d0f8d3dc42Brian Colonna            mHandler.sendEmptyMessage(MSG_HIDE_FACELOCK_AREA_VIEW); // Expose fallback
11716edf2637e96139735df83907c221cce16d4d7eaaJim Miller            stopFaceLock();
11726edf2637e96139735df83907c221cce16d4d7eaaJim Miller        }
11736edf2637e96139735df83907c221cce16d4d7eaaJim Miller    };
11746edf2637e96139735df83907c221cce16d4d7eaaJim Miller}
1175