KeyguardHostView.java revision e51cf7aeb6157017801a802b4c1d74cbf51b7a01
1dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller/*
2dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller * Copyright (C) 2012 The Android Open Source Project
3dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller *
4dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller * Licensed under the Apache License, Version 2.0 (the "License");
5dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller * you may not use this file except in compliance with the License.
6dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller * You may obtain a copy of the License at
7dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller *
8dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller *      http://www.apache.org/licenses/LICENSE-2.0
9dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller *
10dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller * Unless required by applicable law or agreed to in writing, software
11dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller * distributed under the License is distributed on an "AS IS" BASIS,
12dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller * See the License for the specific language governing permissions and
14dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller * limitations under the License.
15dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller */
16dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
175ecd81154fa039961f65bb4e36d18ac555b0d1d6Jim Millerpackage com.android.keyguard;
185ecd81154fa039961f65bb4e36d18ac555b0d1d6Jim Miller
195ecd81154fa039961f65bb4e36d18ac555b0d1d6Jim Millerimport com.android.internal.widget.LockPatternUtils;
205ecd81154fa039961f65bb4e36d18ac555b0d1d6Jim Millerimport com.android.keyguard.KeyguardSecurityModel.SecurityMode;
215950bf3a47661caa081f00dbde7c6d3b448edddaJim Millerimport com.android.keyguard.KeyguardUpdateMonitor.DisplayClientState;
22dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
23258341c377b6aa9f1bd29a9b507a97967e432dfeJim Millerimport android.app.Activity;
2495b005c196de2f99513da28fe9108b2dec200140Jim Millerimport android.app.ActivityManager;
25dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.app.ActivityOptions;
26258341c377b6aa9f1bd29a9b507a97967e432dfeJim Millerimport android.app.AlertDialog;
274eeb4f664ac6b5901a8e874dcf70c0382295f792Jim Millerimport android.app.SearchManager;
28258341c377b6aa9f1bd29a9b507a97967e432dfeJim Millerimport android.app.admin.DevicePolicyManager;
29dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.appwidget.AppWidgetHost;
30dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.appwidget.AppWidgetHostView;
31dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.appwidget.AppWidgetManager;
32dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.appwidget.AppWidgetProviderInfo;
33fc753c0cf676000b1c2d3cb2728af85a9b49f795Michael Jurkaimport android.content.ComponentName;
34dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.content.Context;
35dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.content.Intent;
36dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.content.IntentSender;
37a75a883fe9ea1790803148f0a561473073e3f264Jim Millerimport android.content.pm.PackageManager.NameNotFoundException;
3866b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohenimport android.content.pm.UserInfo;
3995b005c196de2f99513da28fe9108b2dec200140Jim Millerimport android.content.res.Resources;
40dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.graphics.Canvas;
415737534abab477cf32b4dd0aa7a72f70ede0502cJim Millerimport android.graphics.Rect;
428f09fd2e3123c7713d50886dc3745d330a1879c5Jim Millerimport android.media.RemoteControlClient;
43f229e4d3eb8f910c181f96416c6798f6f305a395Jim Millerimport android.os.Looper;
44223ce5c7326f6d13a17ccf2624605bb62864a27aJim Millerimport android.os.Parcel;
45223ce5c7326f6d13a17ccf2624605bb62864a27aJim Millerimport android.os.Parcelable;
46dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlockimport android.os.SystemClock;
474eeb4f664ac6b5901a8e874dcf70c0382295f792Jim Millerimport android.os.UserHandle;
4866b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohenimport android.os.UserManager;
49fff5614caecb0d2944b1bc206aaab0d3acb17670Michael Jurkaimport android.provider.Settings;
50dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.util.AttributeSet;
51dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.util.Log;
52258341c377b6aa9f1bd29a9b507a97967e432dfeJim Millerimport android.util.Slog;
53dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.view.KeyEvent;
5466b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohenimport android.view.LayoutInflater;
555737534abab477cf32b4dd0aa7a72f70ede0502cJim Millerimport android.view.MotionEvent;
56dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.view.View;
57258341c377b6aa9f1bd29a9b507a97967e432dfeJim Millerimport android.view.WindowManager;
58dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.view.animation.AnimationUtils;
59dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.widget.RemoteViews.OnClickHandler;
60dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
6195b005c196de2f99513da28fe9108b2dec200140Jim Millerimport java.io.File;
6266b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohenimport java.util.List;
63dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
64dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerpublic class KeyguardHostView extends KeyguardViewBase {
6551117262c8fadb6d227d137e83ad66996b013141Jim Miller    private static final String TAG = "KeyguardHostView";
664894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller    // Transport control states.
678f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller    static final int TRANSPORT_GONE = 0;
688f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller    static final int TRANSPORT_INVISIBLE = 1;
698f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller    static final int TRANSPORT_VISIBLE = 2;
708f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller
718f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller    private int mTransportState = TRANSPORT_GONE;
72ff2aa0bc8919c247bfc8e81d3f168e5064f52ffbJim Miller
73dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    // Use this to debug all of keyguard
74a71984f3da47c6e6e3164c170735362a3222d3adJim Miller    public static boolean DEBUG = KeyguardViewMediator.DEBUG;
758f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller    public static boolean DEBUGXPORT = true; // debug music transport control
76dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
77192d6d4ee271c0782a3bf5d8c64e42eb22d1a6faMichael Jurka    // Found in KeyguardAppWidgetPickActivity.java
78dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    static final int APPWIDGET_HOST_ID = 0x4B455947;
79dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
80eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka    private final int MAX_WIDGETS = 5;
81eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka
82dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    private AppWidgetHost mAppWidgetHost;
8367a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka    private AppWidgetManager mAppWidgetManager;
84f2dfc351dec58ad3c16f8496208b4e6e9c667efeJim Miller    private KeyguardWidgetPager mAppWidgetContainer;
856fb841fa219eaae3e87f2fdc05e105d7a1813c42Adam Cohen    private KeyguardSecurityViewFlipper mSecurityViewContainer;
860a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen    private KeyguardSelectorView mKeyguardSelectorView;
874e81bd4bcf60a934d4cd589dab6e2bddb88d7356Jim Miller    private KeyguardTransportControlView mTransportControl;
88dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    private boolean mIsVerifyUnlockOnly;
89258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    private boolean mEnableFallback; // TODO: This should get the value from KeyguardPatternView
9063f9b81795559443e0376985f8aaaa97a359ef94Jim Miller    private SecurityMode mCurrentSecuritySelection = SecurityMode.Invalid;
9176017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka    private int mAppWidgetToShow;
92dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
93efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen    private boolean mCheckAppWidgetConsistencyOnBootCompleted = false;
94545043e59e906525af646b1ecad1797258797590Michael Jurka    private boolean mCleanupAppWidgetsOnBootCompleted = false;
95efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen
9634c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock    protected OnDismissAction mDismissAction;
97dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
98dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    protected int mFailedAttempts;
99dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    private LockPatternUtils mLockPatternUtils;
100dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
101dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    private KeyguardSecurityModel mSecurityModel;
102d6523da1ad7bae805a3dbea8d7b398d86cd3c181Jim Miller    private KeyguardViewStateManager mViewStateManager;
103dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
1045737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller    private Rect mTempRect = new Rect();
105ff2aa0bc8919c247bfc8e81d3f168e5064f52ffbJim Miller
10651117262c8fadb6d227d137e83ad66996b013141Jim Miller    private int mDisabledFeatures;
10751117262c8fadb6d227d137e83ad66996b013141Jim Miller
10851117262c8fadb6d227d137e83ad66996b013141Jim Miller    private boolean mCameraDisabled;
10951117262c8fadb6d227d137e83ad66996b013141Jim Miller
11051117262c8fadb6d227d137e83ad66996b013141Jim Miller    private boolean mSafeModeEnabled;
11151117262c8fadb6d227d137e83ad66996b013141Jim Miller
112fff5614caecb0d2944b1bc206aaab0d3acb17670Michael Jurka    private boolean mUserSetupCompleted;
113f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren
114a75a883fe9ea1790803148f0a561473073e3f264Jim Miller    // User for whom this host view was created.  Final because we should never change the
115a75a883fe9ea1790803148f0a561473073e3f264Jim Miller    // id without reconstructing an instance of KeyguardHostView. See note below...
116a75a883fe9ea1790803148f0a561473073e3f264Jim Miller    private final int mUserId;
117fff5614caecb0d2944b1bc206aaab0d3acb17670Michael Jurka
118f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren    private KeyguardMultiUserSelectorView mKeyguardMultiUserSelectorView;
119f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren
1208f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller    protected int mClientGeneration;
1215737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller
122e51cf7aeb6157017801a802b4c1d74cbf51b7a01Jim Miller    protected boolean mShowSecurityWhenReturn;
123e51cf7aeb6157017801a802b4c1d74cbf51b7a01Jim Miller
12424b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen    /*package*/ interface UserSwitcherCallback {
12524b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen        void hideSecurityView(int duration);
12624b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen        void showSecurityView();
1270a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen        void showUnlockHint();
12819a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        void userActivity();
12924b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen    }
13024b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen
13114adfe425e67c9ec12b0841a62c5c03ce00838eaJohn Spurlock    /*package*/ interface OnDismissAction {
13214adfe425e67c9ec12b0841a62c5c03ce00838eaJohn Spurlock        /* returns true if the dismiss should be deferred */
13314adfe425e67c9ec12b0841a62c5c03ce00838eaJohn Spurlock        boolean onDismiss();
13414adfe425e67c9ec12b0841a62c5c03ce00838eaJohn Spurlock    }
13514adfe425e67c9ec12b0841a62c5c03ce00838eaJohn Spurlock
136dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    public KeyguardHostView(Context context) {
137dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        this(context, null);
138dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
139dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
140dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    public KeyguardHostView(Context context, AttributeSet attrs) {
141dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        super(context, attrs);
1424894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller
1434894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller        if (DEBUG) Log.e(TAG, "KeyguardHostView()");
1444894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller
145000464ac012471d301c6e48a8228291519915e17Jim Miller        mLockPatternUtils = new LockPatternUtils(context);
146a75a883fe9ea1790803148f0a561473073e3f264Jim Miller
147a75a883fe9ea1790803148f0a561473073e3f264Jim Miller        // Note: This depends on KeyguardHostView getting reconstructed every time the
148a75a883fe9ea1790803148f0a561473073e3f264Jim Miller        // user switches, since mUserId will be used for the entire session.
149a75a883fe9ea1790803148f0a561473073e3f264Jim Miller        // Once created, keyguard should *never* re-use this instance with another user.
150a75a883fe9ea1790803148f0a561473073e3f264Jim Miller        // In other words, mUserId should never change - hence it's marked final.
151c566b43d02596cba437e9a2723e9f989297cca72Amith Yamasani        mUserId = mLockPatternUtils.getCurrentUser();
152a75a883fe9ea1790803148f0a561473073e3f264Jim Miller
153105beddcb98efc24f37259881d9b4c267aa0d198Jim Miller        DevicePolicyManager dpm =
154105beddcb98efc24f37259881d9b4c267aa0d198Jim Miller                (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
155105beddcb98efc24f37259881d9b4c267aa0d198Jim Miller        if (dpm != null) {
156105beddcb98efc24f37259881d9b4c267aa0d198Jim Miller            mDisabledFeatures = getDisabledFeatures(dpm);
157105beddcb98efc24f37259881d9b4c267aa0d198Jim Miller            mCameraDisabled = dpm.getCameraDisabled(null);
158105beddcb98efc24f37259881d9b4c267aa0d198Jim Miller        }
159105beddcb98efc24f37259881d9b4c267aa0d198Jim Miller
160105beddcb98efc24f37259881d9b4c267aa0d198Jim Miller        mSafeModeEnabled = LockPatternUtils.isSafeModeEnabled();
161105beddcb98efc24f37259881d9b4c267aa0d198Jim Miller
162105beddcb98efc24f37259881d9b4c267aa0d198Jim Miller        // These need to be created with the user context...
163a75a883fe9ea1790803148f0a561473073e3f264Jim Miller        Context userContext = null;
164a75a883fe9ea1790803148f0a561473073e3f264Jim Miller        try {
165a75a883fe9ea1790803148f0a561473073e3f264Jim Miller            final String packageName = "system";
166a75a883fe9ea1790803148f0a561473073e3f264Jim Miller            userContext = mContext.createPackageContextAsUser(packageName, 0,
167a75a883fe9ea1790803148f0a561473073e3f264Jim Miller                    new UserHandle(mUserId));
168a75a883fe9ea1790803148f0a561473073e3f264Jim Miller
169a75a883fe9ea1790803148f0a561473073e3f264Jim Miller        } catch (NameNotFoundException e) {
170a75a883fe9ea1790803148f0a561473073e3f264Jim Miller            e.printStackTrace();
171a75a883fe9ea1790803148f0a561473073e3f264Jim Miller            // This should never happen, but it's better to have no widgets than to crash.
172a75a883fe9ea1790803148f0a561473073e3f264Jim Miller            userContext = context;
173a75a883fe9ea1790803148f0a561473073e3f264Jim Miller        }
174a75a883fe9ea1790803148f0a561473073e3f264Jim Miller
175a75a883fe9ea1790803148f0a561473073e3f264Jim Miller        mAppWidgetHost = new AppWidgetHost(userContext, APPWIDGET_HOST_ID, mOnClickHandler,
176a75a883fe9ea1790803148f0a561473073e3f264Jim Miller                Looper.myLooper());
177a75a883fe9ea1790803148f0a561473073e3f264Jim Miller
178a75a883fe9ea1790803148f0a561473073e3f264Jim Miller        cleanupAppWidgetIds();
179a75a883fe9ea1790803148f0a561473073e3f264Jim Miller
180105beddcb98efc24f37259881d9b4c267aa0d198Jim Miller        mAppWidgetManager = AppWidgetManager.getInstance(userContext);
181fc2dbb2f3a148ee90727c4319adf56c04002f3faMichael Jurka
182fc2dbb2f3a148ee90727c4319adf56c04002f3faMichael Jurka        mSecurityModel = new KeyguardSecurityModel(context);
183fc2dbb2f3a148ee90727c4319adf56c04002f3faMichael Jurka
184fc2dbb2f3a148ee90727c4319adf56c04002f3faMichael Jurka        mViewStateManager = new KeyguardViewStateManager(this);
185fc2dbb2f3a148ee90727c4319adf56c04002f3faMichael Jurka
186fff5614caecb0d2944b1bc206aaab0d3acb17670Michael Jurka        mUserSetupCompleted = Settings.Secure.getIntForUser(mContext.getContentResolver(),
187fff5614caecb0d2944b1bc206aaab0d3acb17670Michael Jurka                Settings.Secure.USER_SETUP_COMPLETE, 0, UserHandle.USER_CURRENT) != 0;
18851117262c8fadb6d227d137e83ad66996b013141Jim Miller
1898f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        // Ensure we have the current state *before* we call showAppropriateWidgetPage()
1908f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        getInitialTransportState();
1918f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller
19251117262c8fadb6d227d137e83ad66996b013141Jim Miller        if (mSafeModeEnabled) {
19351117262c8fadb6d227d137e83ad66996b013141Jim Miller            Log.v(TAG, "Keyguard widgets disabled by safe mode");
19451117262c8fadb6d227d137e83ad66996b013141Jim Miller        }
19551117262c8fadb6d227d137e83ad66996b013141Jim Miller        if ((mDisabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_WIDGETS_ALL) != 0) {
19651117262c8fadb6d227d137e83ad66996b013141Jim Miller            Log.v(TAG, "Keyguard widgets disabled by DPM");
19751117262c8fadb6d227d137e83ad66996b013141Jim Miller        }
19851117262c8fadb6d227d137e83ad66996b013141Jim Miller        if ((mDisabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) != 0) {
19951117262c8fadb6d227d137e83ad66996b013141Jim Miller            Log.v(TAG, "Keyguard secure camera disabled by DPM");
20051117262c8fadb6d227d137e83ad66996b013141Jim Miller        }
201dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
202dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
2038f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller    private void getInitialTransportState() {
2048f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        DisplayClientState dcs = KeyguardUpdateMonitor.getInstance(mContext)
2058f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller                .getCachedDisplayClientState();
2068f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        mTransportState = (dcs.clearing ? TRANSPORT_GONE :
2078f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            (isMusicPlaying(dcs.playbackState) ? TRANSPORT_VISIBLE : TRANSPORT_INVISIBLE));
2084894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller
2094894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller        if (DEBUG) Log.v(TAG, "Initial transport state: "
210dfb57cdcfc6a1fd48395c13af98ecc2722fd5254Jim Miller                + mTransportState + ", pbstate=" + dcs.playbackState);
2118f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller    }
2128f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller
21375b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka    private void cleanupAppWidgetIds() {
214545043e59e906525af646b1ecad1797258797590Michael Jurka        // Since this method may delete a widget (which we can't do until boot completed) we
215545043e59e906525af646b1ecad1797258797590Michael Jurka        // may have to defer it until after boot complete.
216545043e59e906525af646b1ecad1797258797590Michael Jurka        if (!KeyguardUpdateMonitor.getInstance(mContext).hasBootCompleted()) {
217545043e59e906525af646b1ecad1797258797590Michael Jurka            mCleanupAppWidgetsOnBootCompleted = true;
218545043e59e906525af646b1ecad1797258797590Michael Jurka            return;
219545043e59e906525af646b1ecad1797258797590Michael Jurka        }
220fc2dbb2f3a148ee90727c4319adf56c04002f3faMichael Jurka        if (!mSafeModeEnabled && !widgetsDisabledByDpm()) {
221fc2dbb2f3a148ee90727c4319adf56c04002f3faMichael Jurka            // Clean up appWidgetIds that are bound to lockscreen, but not actually used
222fc2dbb2f3a148ee90727c4319adf56c04002f3faMichael Jurka            // This is only to clean up after another bug: we used to not call
223fc2dbb2f3a148ee90727c4319adf56c04002f3faMichael Jurka            // deleteAppWidgetId when a user manually deleted a widget in keyguard. This code
224fc2dbb2f3a148ee90727c4319adf56c04002f3faMichael Jurka            // shouldn't have to run more than once per user. AppWidgetProviders rely on callbacks
225fc2dbb2f3a148ee90727c4319adf56c04002f3faMichael Jurka            // that are triggered by deleteAppWidgetId, which is why we're doing this
226fc2dbb2f3a148ee90727c4319adf56c04002f3faMichael Jurka            int[] appWidgetIdsInKeyguardSettings = mLockPatternUtils.getAppWidgets();
227fc2dbb2f3a148ee90727c4319adf56c04002f3faMichael Jurka            int[] appWidgetIdsBoundToHost = mAppWidgetHost.getAppWidgetIds();
228fc2dbb2f3a148ee90727c4319adf56c04002f3faMichael Jurka            for (int i = 0; i < appWidgetIdsBoundToHost.length; i++) {
229fc2dbb2f3a148ee90727c4319adf56c04002f3faMichael Jurka                int appWidgetId = appWidgetIdsBoundToHost[i];
230fc2dbb2f3a148ee90727c4319adf56c04002f3faMichael Jurka                if (!contains(appWidgetIdsInKeyguardSettings, appWidgetId)) {
231fc2dbb2f3a148ee90727c4319adf56c04002f3faMichael Jurka                    Log.d(TAG, "Found a appWidgetId that's not being used by keyguard, deleting id "
232fc2dbb2f3a148ee90727c4319adf56c04002f3faMichael Jurka                            + appWidgetId);
233fc2dbb2f3a148ee90727c4319adf56c04002f3faMichael Jurka                    mAppWidgetHost.deleteAppWidgetId(appWidgetId);
234fc2dbb2f3a148ee90727c4319adf56c04002f3faMichael Jurka                }
23575b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka            }
23675b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka        }
23775b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka    }
23875b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka
23975b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka    private static boolean contains(int[] array, int target) {
24075b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka        for (int value : array) {
24175b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka            if (value == target) {
24275b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka                return true;
24375b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka            }
24475b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka        }
24575b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka        return false;
24675b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka    }
24775b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka
248efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen    private KeyguardUpdateMonitorCallback mUpdateMonitorCallbacks =
249efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen            new KeyguardUpdateMonitorCallback() {
250efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen        @Override
251efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen        public void onBootCompleted() {
252efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen            if (mCheckAppWidgetConsistencyOnBootCompleted) {
253efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen                checkAppWidgetConsistency();
254efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen                mSwitchPageRunnable.run();
255efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen                mCheckAppWidgetConsistencyOnBootCompleted = false;
256efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen            }
257545043e59e906525af646b1ecad1797258797590Michael Jurka            if (mCleanupAppWidgetsOnBootCompleted) {
258545043e59e906525af646b1ecad1797258797590Michael Jurka                cleanupAppWidgetIds();
259545043e59e906525af646b1ecad1797258797590Michael Jurka                mCleanupAppWidgetsOnBootCompleted = false;
260545043e59e906525af646b1ecad1797258797590Michael Jurka            }
261efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen        }
262f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren        @Override
263f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren        public void onUserSwitchComplete(int userId) {
264f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren            if (mKeyguardMultiUserSelectorView != null) {
265f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren                mKeyguardMultiUserSelectorView.finalizeActiveUserView(true);
266f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren            }
267f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren        }
2688f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        @Override
2698f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        void onMusicClientIdChanged(
2708f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller                int clientGeneration, boolean clearing, android.app.PendingIntent intent) {
2718f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            // Set transport state to invisible until we know music is playing (below)
2728f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            if (DEBUGXPORT && (mClientGeneration != clientGeneration || clearing)) {
2738f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller                Log.v(TAG, (clearing ? "hide" : "show") + " transport, gen:" + clientGeneration);
2748f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            }
2758f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            mClientGeneration = clientGeneration;
276dfb57cdcfc6a1fd48395c13af98ecc2722fd5254Jim Miller            final int newState = (clearing ? TRANSPORT_GONE
277dfb57cdcfc6a1fd48395c13af98ecc2722fd5254Jim Miller                    : (mTransportState == TRANSPORT_VISIBLE ?
278dfb57cdcfc6a1fd48395c13af98ecc2722fd5254Jim Miller                    TRANSPORT_VISIBLE : TRANSPORT_INVISIBLE));
279dfb57cdcfc6a1fd48395c13af98ecc2722fd5254Jim Miller            if (newState != mTransportState) {
280dfb57cdcfc6a1fd48395c13af98ecc2722fd5254Jim Miller                mTransportState = newState;
281dfb57cdcfc6a1fd48395c13af98ecc2722fd5254Jim Miller                if (DEBUGXPORT) Log.v(TAG, "update widget: transport state changed");
282dfb57cdcfc6a1fd48395c13af98ecc2722fd5254Jim Miller                KeyguardHostView.this.post(mSwitchPageRunnable);
283dfb57cdcfc6a1fd48395c13af98ecc2722fd5254Jim Miller            }
2848f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        }
2858f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        @Override
2868f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        public void onMusicPlaybackStateChanged(int playbackState, long eventTime) {
2878f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            if (DEBUGXPORT) Log.v(TAG, "music state changed: " + playbackState);
2888f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            if (mTransportState != TRANSPORT_GONE) {
289dfb57cdcfc6a1fd48395c13af98ecc2722fd5254Jim Miller                final int newState = (isMusicPlaying(playbackState) ?
2908f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller                        TRANSPORT_VISIBLE : TRANSPORT_INVISIBLE);
291dfb57cdcfc6a1fd48395c13af98ecc2722fd5254Jim Miller                if (newState != mTransportState) {
292dfb57cdcfc6a1fd48395c13af98ecc2722fd5254Jim Miller                    mTransportState = newState;
293dfb57cdcfc6a1fd48395c13af98ecc2722fd5254Jim Miller                    if (DEBUGXPORT) Log.v(TAG, "update widget: play state changed");
294dfb57cdcfc6a1fd48395c13af98ecc2722fd5254Jim Miller                    KeyguardHostView.this.post(mSwitchPageRunnable);
295dfb57cdcfc6a1fd48395c13af98ecc2722fd5254Jim Miller                }
2968f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            }
2978f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        }
298efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen    };
299efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen
3008f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller    private static final boolean isMusicPlaying(int playbackState) {
3018f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        // This should agree with the list in AudioService.isPlaystateActive()
3028f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        switch (playbackState) {
3038f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            case RemoteControlClient.PLAYSTATE_PLAYING:
3048f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            case RemoteControlClient.PLAYSTATE_BUFFERING:
3058f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            case RemoteControlClient.PLAYSTATE_FAST_FORWARDING:
3068f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            case RemoteControlClient.PLAYSTATE_REWINDING:
3078f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            case RemoteControlClient.PLAYSTATE_SKIPPING_BACKWARDS:
3088f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            case RemoteControlClient.PLAYSTATE_SKIPPING_FORWARDS:
3098f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller                return true;
3108f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            default:
3118f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller                return false;
3128f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        }
3138f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller    }
3148f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller
3152cacda5fc92a28a44a37e25b96093a9cc1346080Jim Miller    private SlidingChallengeLayout mSlidingChallengeLayout;
3162cacda5fc92a28a44a37e25b96093a9cc1346080Jim Miller
317dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    @Override
318d2b82f70fede8c2ec4de34d8e6462ed4ece13c56Jim Miller    public boolean onTouchEvent(MotionEvent ev) {
319d2b82f70fede8c2ec4de34d8e6462ed4ece13c56Jim Miller        boolean result = super.onTouchEvent(ev);
3205737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller        mTempRect.set(0, 0, 0, 0);
3215737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller        offsetRectIntoDescendantCoords(mSecurityViewContainer, mTempRect);
3225737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller        ev.offsetLocation(mTempRect.left, mTempRect.top);
3235737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller        result = mSecurityViewContainer.dispatchTouchEvent(ev) || result;
3245737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller        ev.offsetLocation(-mTempRect.left, -mTempRect.top);
3255737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller        return result;
3265737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller    }
3275737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller
3285737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller    @Override
329dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    protected void dispatchDraw(Canvas canvas) {
330dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        super.dispatchDraw(canvas);
3317def1db03943251fe8cb57ec514722026425479eCraig Mautner        if (mViewMediatorCallback != null) {
3327def1db03943251fe8cb57ec514722026425479eCraig Mautner            mViewMediatorCallback.keyguardDoneDrawing();
3337def1db03943251fe8cb57ec514722026425479eCraig Mautner        }
334dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
335dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
336ff2aa0bc8919c247bfc8e81d3f168e5064f52ffbJim Miller    private int getWidgetPosition(int id) {
337982d21b9dc73eebd4b68a63579cf8be78c788c32Jim Miller        final KeyguardWidgetPager appWidgetContainer = mAppWidgetContainer;
338982d21b9dc73eebd4b68a63579cf8be78c788c32Jim Miller        final int children = appWidgetContainer.getChildCount();
339ff2aa0bc8919c247bfc8e81d3f168e5064f52ffbJim Miller        for (int i = 0; i < children; i++) {
340982d21b9dc73eebd4b68a63579cf8be78c788c32Jim Miller            final View content = appWidgetContainer.getWidgetPageAt(i).getContent();
341982d21b9dc73eebd4b68a63579cf8be78c788c32Jim Miller            if (content != null && content.getId() == id) {
342ff2aa0bc8919c247bfc8e81d3f168e5064f52ffbJim Miller                return i;
343982d21b9dc73eebd4b68a63579cf8be78c788c32Jim Miller            } else if (content == null) {
344982d21b9dc73eebd4b68a63579cf8be78c788c32Jim Miller                // Attempt to track down bug #8886916
345982d21b9dc73eebd4b68a63579cf8be78c788c32Jim Miller                Log.w(TAG, "*** Null content at " + "i=" + i + ",id=" + id + ",N=" + children);
346ff2aa0bc8919c247bfc8e81d3f168e5064f52ffbJim Miller            }
347ff2aa0bc8919c247bfc8e81d3f168e5064f52ffbJim Miller        }
348ff2aa0bc8919c247bfc8e81d3f168e5064f52ffbJim Miller        return -1;
349ff2aa0bc8919c247bfc8e81d3f168e5064f52ffbJim Miller    }
350ff2aa0bc8919c247bfc8e81d3f168e5064f52ffbJim Miller
351dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    @Override
352dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    protected void onFinishInflate() {
353d6523da1ad7bae805a3dbea8d7b398d86cd3c181Jim Miller        // Grab instances of and make any necessary changes to the main layouts. Create
354d6523da1ad7bae805a3dbea8d7b398d86cd3c181Jim Miller        // view state manager and wire up necessary listeners / callbacks.
355f3b9ec8230298e8f707c2fc44a74fb9346ec3d12Winson Chung        View deleteDropTarget = findViewById(R.id.keyguard_widget_pager_delete_target);
356f2dfc351dec58ad3c16f8496208b4e6e9c667efeJim Miller        mAppWidgetContainer = (KeyguardWidgetPager) findViewById(R.id.app_widget_container);
357838906b165e4d3cb2c512b2db344aa50cb5d4751Jim Miller        mAppWidgetContainer.setVisibility(VISIBLE);
358838906b165e4d3cb2c512b2db344aa50cb5d4751Jim Miller        mAppWidgetContainer.setCallbacks(mWidgetCallbacks);
359f3b9ec8230298e8f707c2fc44a74fb9346ec3d12Winson Chung        mAppWidgetContainer.setDeleteDropTarget(deleteDropTarget);
360d6523da1ad7bae805a3dbea8d7b398d86cd3c181Jim Miller        mAppWidgetContainer.setMinScale(0.5f);
361d6523da1ad7bae805a3dbea8d7b398d86cd3c181Jim Miller
3622cacda5fc92a28a44a37e25b96093a9cc1346080Jim Miller        mSlidingChallengeLayout = (SlidingChallengeLayout) findViewById(R.id.sliding_layout);
3632cacda5fc92a28a44a37e25b96093a9cc1346080Jim Miller        if (mSlidingChallengeLayout != null) {
3642cacda5fc92a28a44a37e25b96093a9cc1346080Jim Miller            mSlidingChallengeLayout.setOnChallengeScrolledListener(mViewStateManager);
36519a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        }
366d6523da1ad7bae805a3dbea8d7b398d86cd3c181Jim Miller        mAppWidgetContainer.setViewStateManager(mViewStateManager);
3671254f2f42f7173ef51d0034975ab5cb7d44f8209Michael Jurka        mAppWidgetContainer.setLockPatternUtils(mLockPatternUtils);
368d6523da1ad7bae805a3dbea8d7b398d86cd3c181Jim Miller
3692cacda5fc92a28a44a37e25b96093a9cc1346080Jim Miller        ChallengeLayout challenge = mSlidingChallengeLayout != null ? mSlidingChallengeLayout :
37048275d2de99ff2556031929c48f295d3f93447b6Winson Chung            (ChallengeLayout) findViewById(R.id.multi_pane_challenge);
37148275d2de99ff2556031929c48f295d3f93447b6Winson Chung        challenge.setOnBouncerStateChangedListener(mViewStateManager);
37270c2f8736437ebb6073c3b6dab2e08e6dd9f39a6Winson Chung        mAppWidgetContainer.setBouncerAnimationDuration(challenge.getBouncerAnimationDuration());
373d6523da1ad7bae805a3dbea8d7b398d86cd3c181Jim Miller        mViewStateManager.setPagedView(mAppWidgetContainer);
37448275d2de99ff2556031929c48f295d3f93447b6Winson Chung        mViewStateManager.setChallengeLayout(challenge);
3756fb841fa219eaae3e87f2fdc05e105d7a1813c42Adam Cohen        mSecurityViewContainer = (KeyguardSecurityViewFlipper) findViewById(R.id.view_flipper);
3760a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen        mKeyguardSelectorView = (KeyguardSelectorView) findViewById(R.id.keyguard_selector_view);
3776fb841fa219eaae3e87f2fdc05e105d7a1813c42Adam Cohen        mViewStateManager.setSecurityViewContainer(mSecurityViewContainer);
378ff2aa0bc8919c247bfc8e81d3f168e5064f52ffbJim Miller
37903eca859067ac0d4e419305de8ab0fdc03b4210fJohn Spurlock        setBackButtonEnabled(false);
38068c2489457631f733f542e14058c6d1274c203deJim Miller
38167a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        addDefaultWidgets();
38251117262c8fadb6d227d137e83ad66996b013141Jim Miller
38367a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        addWidgetsFromSettings();
384fff5614caecb0d2944b1bc206aaab0d3acb17670Michael Jurka        if (!shouldEnableAddWidget()) {
3854752e7d1a9ff83d946890b0020de091f4346a7aeWinson Chung            mAppWidgetContainer.setAddWidgetEnabled(false);
386eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka        }
38751117262c8fadb6d227d137e83ad66996b013141Jim Miller        checkAppWidgetConsistency();
38867a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        mSwitchPageRunnable.run();
38945adaa70203a155beb786f22b251fe66b8d6fafdAdam Cohen        // This needs to be called after the pages are all added.
39045adaa70203a155beb786f22b251fe66b8d6fafdAdam Cohen        mViewStateManager.showUsabilityHints();
39145adaa70203a155beb786f22b251fe66b8d6fafdAdam Cohen
39267a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        showPrimarySecurityScreen(false);
3939b1db682c32d103974b0f1193b50e77e254d5589Jim Miller        updateSecurityViews();
394e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller    }
395dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
39603eca859067ac0d4e419305de8ab0fdc03b4210fJohn Spurlock    private void setBackButtonEnabled(boolean enabled) {
39703eca859067ac0d4e419305de8ab0fdc03b4210fJohn Spurlock        if (mContext instanceof Activity) return;  // always enabled in activity mode
39803eca859067ac0d4e419305de8ab0fdc03b4210fJohn Spurlock        setSystemUiVisibility(enabled ?
39903eca859067ac0d4e419305de8ab0fdc03b4210fJohn Spurlock                getSystemUiVisibility() & ~View.STATUS_BAR_DISABLE_BACK :
40003eca859067ac0d4e419305de8ab0fdc03b4210fJohn Spurlock                getSystemUiVisibility() | View.STATUS_BAR_DISABLE_BACK);
40103eca859067ac0d4e419305de8ab0fdc03b4210fJohn Spurlock    }
40203eca859067ac0d4e419305de8ab0fdc03b4210fJohn Spurlock
403fff5614caecb0d2944b1bc206aaab0d3acb17670Michael Jurka    private boolean shouldEnableAddWidget() {
404fff5614caecb0d2944b1bc206aaab0d3acb17670Michael Jurka        return numWidgets() < MAX_WIDGETS && mUserSetupCompleted;
405fff5614caecb0d2944b1bc206aaab0d3acb17670Michael Jurka    }
406fff5614caecb0d2944b1bc206aaab0d3acb17670Michael Jurka
40751117262c8fadb6d227d137e83ad66996b013141Jim Miller    private int getDisabledFeatures(DevicePolicyManager dpm) {
40851117262c8fadb6d227d137e83ad66996b013141Jim Miller        int disabledFeatures = DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_NONE;
40951117262c8fadb6d227d137e83ad66996b013141Jim Miller        if (dpm != null) {
41051117262c8fadb6d227d137e83ad66996b013141Jim Miller            final int currentUser = mLockPatternUtils.getCurrentUser();
41151117262c8fadb6d227d137e83ad66996b013141Jim Miller            disabledFeatures = dpm.getKeyguardDisabledFeatures(null, currentUser);
41251117262c8fadb6d227d137e83ad66996b013141Jim Miller        }
41351117262c8fadb6d227d137e83ad66996b013141Jim Miller        return disabledFeatures;
41451117262c8fadb6d227d137e83ad66996b013141Jim Miller    }
41551117262c8fadb6d227d137e83ad66996b013141Jim Miller
41651117262c8fadb6d227d137e83ad66996b013141Jim Miller    private boolean widgetsDisabledByDpm() {
41751117262c8fadb6d227d137e83ad66996b013141Jim Miller        return (mDisabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_WIDGETS_ALL) != 0;
41851117262c8fadb6d227d137e83ad66996b013141Jim Miller    }
41951117262c8fadb6d227d137e83ad66996b013141Jim Miller
42051117262c8fadb6d227d137e83ad66996b013141Jim Miller    private boolean cameraDisabledByDpm() {
42151117262c8fadb6d227d137e83ad66996b013141Jim Miller        return mCameraDisabled
42251117262c8fadb6d227d137e83ad66996b013141Jim Miller                || (mDisabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) != 0;
42351117262c8fadb6d227d137e83ad66996b013141Jim Miller    }
42451117262c8fadb6d227d137e83ad66996b013141Jim Miller
425e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller    private void updateSecurityViews() {
426e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        int children = mSecurityViewContainer.getChildCount();
427e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        for (int i = 0; i < children; i++) {
428e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            updateSecurityView(mSecurityViewContainer.getChildAt(i));
429e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        }
430e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller    }
431dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
432e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller    private void updateSecurityView(View view) {
433e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        if (view instanceof KeyguardSecurityView) {
434e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            KeyguardSecurityView ksv = (KeyguardSecurityView) view;
435e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            ksv.setKeyguardCallback(mCallback);
436e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            ksv.setLockPatternUtils(mLockPatternUtils);
437c0ae9e67ebe6f1298800feaed1b43e867139a904Chris Wren            if (mViewStateManager.isBouncing()) {
438c0ae9e67ebe6f1298800feaed1b43e867139a904Chris Wren                ksv.showBouncer(0);
439c0ae9e67ebe6f1298800feaed1b43e867139a904Chris Wren            } else {
440c0ae9e67ebe6f1298800feaed1b43e867139a904Chris Wren                ksv.hideBouncer(0);
441c0ae9e67ebe6f1298800feaed1b43e867139a904Chris Wren            }
442e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        } else {
443e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            Log.w(TAG, "View " + view + " is not a KeyguardSecurityView");
444dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
445dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
446dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
447dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    void setLockPatternUtils(LockPatternUtils utils) {
448dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        mSecurityModel.setLockPatternUtils(utils);
449dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        mLockPatternUtils = utils;
450e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        updateSecurityViews();
451dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
452dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
453dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    @Override
454dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    protected void onAttachedToWindow() {
455dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        super.onAttachedToWindow();
456a75a883fe9ea1790803148f0a561473073e3f264Jim Miller        mAppWidgetHost.startListening();
457efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen        KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mUpdateMonitorCallbacks);
4587221d3ae08cc2be922d26e5d491038512cb6c74dJim Miller    }
4597221d3ae08cc2be922d26e5d491038512cb6c74dJim Miller
460dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    @Override
461dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    protected void onDetachedFromWindow() {
462dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        super.onDetachedFromWindow();
463a75a883fe9ea1790803148f0a561473073e3f264Jim Miller        mAppWidgetHost.stopListening();
464efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen        KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mUpdateMonitorCallbacks);
465dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
466dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
467d6523da1ad7bae805a3dbea8d7b398d86cd3c181Jim Miller    void addWidget(AppWidgetHostView view, int pageIndex) {
468d6523da1ad7bae805a3dbea8d7b398d86cd3c181Jim Miller        mAppWidgetContainer.addWidget(view, pageIndex);
469dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
470dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
471838906b165e4d3cb2c512b2db344aa50cb5d4751Jim Miller    private KeyguardWidgetPager.Callbacks mWidgetCallbacks
472838906b165e4d3cb2c512b2db344aa50cb5d4751Jim Miller            = new KeyguardWidgetPager.Callbacks() {
473c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown        @Override
474c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown        public void userActivity() {
47508c83ef48880b98ec45dd83867a29852160a96ebAdam Cohen            KeyguardHostView.this.userActivity();
476c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown        }
477c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown
478c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown        @Override
479c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown        public void onUserActivityTimeoutChanged() {
48008c83ef48880b98ec45dd83867a29852160a96ebAdam Cohen            KeyguardHostView.this.onUserActivityTimeoutChanged();
481c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown        }
482eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka
483eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka        @Override
48440f8211e6849c4c7948d7fc19127f29f0cebbeb9Winson Chung        public void onAddView(View v) {
485fff5614caecb0d2944b1bc206aaab0d3acb17670Michael Jurka            if (!shouldEnableAddWidget()) {
4864752e7d1a9ff83d946890b0020de091f4346a7aeWinson Chung                mAppWidgetContainer.setAddWidgetEnabled(false);
48740f8211e6849c4c7948d7fc19127f29f0cebbeb9Winson Chung            }
4884752e7d1a9ff83d946890b0020de091f4346a7aeWinson Chung        }
48940f8211e6849c4c7948d7fc19127f29f0cebbeb9Winson Chung
49040f8211e6849c4c7948d7fc19127f29f0cebbeb9Winson Chung        @Override
49175b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka        public void onRemoveView(View v, boolean deletePermanently) {
49275b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka            if (deletePermanently) {
49375b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka                final int appWidgetId = ((KeyguardWidgetFrame) v).getContentAppWidgetId();
49475b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka                if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID &&
49575b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka                        appWidgetId != LockPatternUtils.ID_DEFAULT_STATUS_WIDGET) {
49675b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka                    mAppWidgetHost.deleteAppWidgetId(appWidgetId);
49775b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka                }
49875b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka            }
499eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka        }
5004752e7d1a9ff83d946890b0020de091f4346a7aeWinson Chung
5014752e7d1a9ff83d946890b0020de091f4346a7aeWinson Chung        @Override
5024752e7d1a9ff83d946890b0020de091f4346a7aeWinson Chung        public void onRemoveViewAnimationCompleted() {
503fff5614caecb0d2944b1bc206aaab0d3acb17670Michael Jurka            if (shouldEnableAddWidget()) {
5044752e7d1a9ff83d946890b0020de091f4346a7aeWinson Chung                mAppWidgetContainer.setAddWidgetEnabled(true);
5054752e7d1a9ff83d946890b0020de091f4346a7aeWinson Chung            }
5064752e7d1a9ff83d946890b0020de091f4346a7aeWinson Chung        }
507c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown    };
508c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown
509f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren    public void initializeSwitchingUserState(boolean switching) {
510f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren        if (!switching && mKeyguardMultiUserSelectorView != null) {
511f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren            mKeyguardMultiUserSelectorView.finalizeActiveUserView(false);
512f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren        }
513f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren    }
514f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren
51508c83ef48880b98ec45dd83867a29852160a96ebAdam Cohen    public void userActivity() {
51608c83ef48880b98ec45dd83867a29852160a96ebAdam Cohen        if (mViewMediatorCallback != null) {
51708c83ef48880b98ec45dd83867a29852160a96ebAdam Cohen            mViewMediatorCallback.userActivity();
51808c83ef48880b98ec45dd83867a29852160a96ebAdam Cohen        }
51908c83ef48880b98ec45dd83867a29852160a96ebAdam Cohen    }
52008c83ef48880b98ec45dd83867a29852160a96ebAdam Cohen
52108c83ef48880b98ec45dd83867a29852160a96ebAdam Cohen    public void onUserActivityTimeoutChanged() {
52208c83ef48880b98ec45dd83867a29852160a96ebAdam Cohen        if (mViewMediatorCallback != null) {
52308c83ef48880b98ec45dd83867a29852160a96ebAdam Cohen            mViewMediatorCallback.onUserActivityTimeoutChanged();
52408c83ef48880b98ec45dd83867a29852160a96ebAdam Cohen        }
52508c83ef48880b98ec45dd83867a29852160a96ebAdam Cohen    }
52608c83ef48880b98ec45dd83867a29852160a96ebAdam Cohen
527c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown    @Override
528c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown    public long getUserActivityTimeout() {
529c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown        // Currently only considering user activity timeouts needed by widgets.
530c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown        // Could also take into account longer timeouts for certain security views.
531838906b165e4d3cb2c512b2db344aa50cb5d4751Jim Miller        if (mAppWidgetContainer != null) {
532838906b165e4d3cb2c512b2db344aa50cb5d4751Jim Miller            return mAppWidgetContainer.getUserActivityTimeout();
533c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown        }
534c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown        return -1;
535c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown    }
536c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown
537dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    private KeyguardSecurityCallback mCallback = new KeyguardSecurityCallback() {
538dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
539dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        public void userActivity(long timeout) {
5407def1db03943251fe8cb57ec514722026425479eCraig Mautner            if (mViewMediatorCallback != null) {
5413dc524bc31a1578693ca958ef442dfa092b7aa7fJeff Brown                mViewMediatorCallback.userActivity(timeout);
5427def1db03943251fe8cb57ec514722026425479eCraig Mautner            }
543dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
544dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
545dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        public void dismiss(boolean authenticated) {
546dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            showNextSecurityScreenOrFinish(authenticated);
547dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
548dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
549dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        public boolean isVerifyUnlockOnly() {
550258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            return mIsVerifyUnlockOnly;
551dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
552dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
553dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        public void reportSuccessfulUnlockAttempt() {
554258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            KeyguardUpdateMonitor.getInstance(mContext).clearFailedUnlockAttempts();
5557641506e3cc493ac4e6f5037fd76516754e61c6eJim Miller            mLockPatternUtils.reportSuccessfulPasswordAttempt();
556dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
557dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
558dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        public void reportFailedUnlockAttempt() {
5597641506e3cc493ac4e6f5037fd76516754e61c6eJim Miller            if (mCurrentSecuritySelection == SecurityMode.Biometric) {
5607641506e3cc493ac4e6f5037fd76516754e61c6eJim Miller                KeyguardUpdateMonitor.getInstance(mContext).reportFailedBiometricUnlockAttempt();
5617641506e3cc493ac4e6f5037fd76516754e61c6eJim Miller            } else {
5627641506e3cc493ac4e6f5037fd76516754e61c6eJim Miller                KeyguardHostView.this.reportFailedUnlockAttempt();
5637641506e3cc493ac4e6f5037fd76516754e61c6eJim Miller            }
564dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
565dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
566dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        public int getFailedAttempts() {
567258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            return KeyguardUpdateMonitor.getInstance(mContext).getFailedUnlockAttempts();
568dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
569dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
570258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        @Override
571258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        public void showBackupSecurity() {
5720ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller            KeyguardHostView.this.showBackupSecurityScreen();
573dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
574dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
5755f75aa15d7c1c5ea1c1eecd95bf2bb0920173eb2Jim Miller        @Override
57634c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock        public void setOnDismissAction(OnDismissAction action) {
57734c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock            KeyguardHostView.this.setOnDismissAction(action);
5785f75aa15d7c1c5ea1c1eecd95bf2bb0920173eb2Jim Miller        }
5795f75aa15d7c1c5ea1c1eecd95bf2bb0920173eb2Jim Miller
580dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    };
581dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
582258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    private void showDialog(String title, String message) {
583258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        final AlertDialog dialog = new AlertDialog.Builder(mContext)
584258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            .setTitle(title)
585258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            .setMessage(message)
5865ecd81154fa039961f65bb4e36d18ac555b0d1d6Jim Miller            .setNeutralButton(R.string.ok, null)
587258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            .create();
588258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        if (!(mContext instanceof Activity)) {
589258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
590258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        }
591258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        dialog.show();
592258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    }
593258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
594258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    private void showTimeoutDialog() {
595258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        int timeoutInSeconds = (int) LockPatternUtils.FAILED_ATTEMPT_TIMEOUT_MS / 1000;
596258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        int messageId = 0;
597258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
598258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        switch (mSecurityModel.getSecurityMode()) {
599258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            case Pattern:
600258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                messageId = R.string.kg_too_many_failed_pattern_attempts_dialog_message;
601258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                break;
60269bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler            case PIN:
60369bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler                messageId = R.string.kg_too_many_failed_pin_attempts_dialog_message;
60469bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler                break;
60569bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler            case Password:
60669bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler                messageId = R.string.kg_too_many_failed_password_attempts_dialog_message;
607258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                break;
608258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        }
609258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
610258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        if (messageId != 0) {
611258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            final String message = mContext.getString(messageId,
612258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                    KeyguardUpdateMonitor.getInstance(mContext).getFailedUnlockAttempts(),
613258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                    timeoutInSeconds);
614258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            showDialog(null, message);
615258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        }
616258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    }
617258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
618258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    private void showAlmostAtWipeDialog(int attempts, int remaining) {
619258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        int timeoutInSeconds = (int) LockPatternUtils.FAILED_ATTEMPT_TIMEOUT_MS / 1000;
620258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        String message = mContext.getString(R.string.kg_failed_attempts_almost_at_wipe,
621258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                attempts, remaining);
622258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        showDialog(null, message);
623258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    }
624258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
625258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    private void showWipeDialog(int attempts) {
626258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        String message = mContext.getString(R.string.kg_failed_attempts_now_wiping, attempts);
627258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        showDialog(null, message);
628258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    }
629258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
630258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    private void showAlmostAtAccountLoginDialog() {
631258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        final int timeoutInSeconds = (int) LockPatternUtils.FAILED_ATTEMPT_TIMEOUT_MS / 1000;
632258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        final int count = LockPatternUtils.FAILED_ATTEMPTS_BEFORE_RESET
633258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                - LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT;
634258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        String message = mContext.getString(R.string.kg_failed_attempts_almost_at_login,
635258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                count, LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT, timeoutInSeconds);
636258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        showDialog(null, message);
637258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    }
638258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
639258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    private void reportFailedUnlockAttempt() {
640258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        final KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(mContext);
641258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        final int failedAttempts = monitor.getFailedUnlockAttempts() + 1; // +1 for this time
642258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
643258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        if (DEBUG) Log.d(TAG, "reportFailedPatternAttempt: #" + failedAttempts);
644258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
645258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        SecurityMode mode = mSecurityModel.getSecurityMode();
646258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        final boolean usingPattern = mode == KeyguardSecurityModel.SecurityMode.Pattern;
647258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
648258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        final int failedAttemptsBeforeWipe = mLockPatternUtils.getDevicePolicyManager()
649599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                .getMaximumFailedPasswordsForWipe(null, mLockPatternUtils.getCurrentUser());
650258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
651258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        final int failedAttemptWarning = LockPatternUtils.FAILED_ATTEMPTS_BEFORE_RESET
652258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                - LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT;
653258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
654258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        final int remainingBeforeWipe = failedAttemptsBeforeWipe > 0 ?
655258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                (failedAttemptsBeforeWipe - failedAttempts)
656258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                : Integer.MAX_VALUE; // because DPM returns 0 if no restriction
657258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
65808b2b6bfe2550b65c68ad7b4bef8283f1ff17561Jim Miller        boolean showTimeout = false;
659258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        if (remainingBeforeWipe < LockPatternUtils.FAILED_ATTEMPTS_BEFORE_WIPE_GRACE) {
660258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            // If we reach this code, it means the user has installed a DevicePolicyManager
661258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            // that requests device wipe after N attempts.  Once we get below the grace
662258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            // period, we'll post this dialog every time as a clear warning until the
663258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            // bombshell hits and the device is wiped.
664258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            if (remainingBeforeWipe > 0) {
665258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                showAlmostAtWipeDialog(failedAttempts, remainingBeforeWipe);
666258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            } else {
667258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                // Too many attempts. The device will be wiped shortly.
668258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                Slog.i(TAG, "Too many unlock attempts; device will be wiped!");
669258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                showWipeDialog(failedAttempts);
670258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            }
671258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        } else {
67208b2b6bfe2550b65c68ad7b4bef8283f1ff17561Jim Miller            showTimeout =
673258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                (failedAttempts % LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT) == 0;
674258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            if (usingPattern && mEnableFallback) {
675258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                if (failedAttempts == failedAttemptWarning) {
676258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                    showAlmostAtAccountLoginDialog();
677258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                    showTimeout = false; // don't show both dialogs
678258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                } else if (failedAttempts >= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_RESET) {
679258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                    mLockPatternUtils.setPermanentlyLocked(true);
680e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller                    showSecurityScreen(SecurityMode.Account);
681258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                    // don't show timeout dialog because we show account unlock screen next
682258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                    showTimeout = false;
683258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                }
684258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            }
685258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        }
686258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        monitor.reportFailedUnlockAttempt();
687258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        mLockPatternUtils.reportFailedPasswordAttempt();
68808b2b6bfe2550b65c68ad7b4bef8283f1ff17561Jim Miller        if (showTimeout) {
68908b2b6bfe2550b65c68ad7b4bef8283f1ff17561Jim Miller            showTimeoutDialog();
69008b2b6bfe2550b65c68ad7b4bef8283f1ff17561Jim Miller        }
691258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    }
692258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
693258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    /**
6940ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller     * Shows the primary security screen for the user. This will be either the multi-selector
6950ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller     * or the user's security method.
6960ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller     * @param turningOff true if the device is being turned off
6970ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller     */
6980ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller    void showPrimarySecurityScreen(boolean turningOff) {
6990ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller        SecurityMode securityMode = mSecurityModel.getSecurityMode();
7000ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller        if (DEBUG) Log.v(TAG, "showPrimarySecurityScreen(turningOff=" + turningOff + ")");
701078f5919a9584cc3f1c7eb3a78862bfa40396de9Brian Colonna        if (!turningOff &&
702078f5919a9584cc3f1c7eb3a78862bfa40396de9Brian Colonna                KeyguardUpdateMonitor.getInstance(mContext).isAlternateUnlockEnabled()) {
7030ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller            // If we're not turning off, then allow biometric alternate.
7040ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller            // We'll reload it when the device comes back on.
7050ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller            securityMode = mSecurityModel.getAlternateFor(securityMode);
7060ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller        }
7070ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller        showSecurityScreen(securityMode);
7080ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller    }
70968c2489457631f733f542e14058c6d1274c203deJim Miller
7100ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller    /**
711258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller     * Shows the backup security screen for the current security mode.  This could be used for
712258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller     * password recovery screens but is currently only used for pattern unlock to show the
713258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller     * account unlock screen and biometric unlock to show the user's normal unlock.
714258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller     */
7150ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller    private void showBackupSecurityScreen() {
71661413b5ed215accd7b4f3eaf80edeab2f330aa49Danielle Millett        if (DEBUG) Log.d(TAG, "showBackupSecurity()");
71763f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        SecurityMode backup = mSecurityModel.getBackupSecurityMode(mCurrentSecuritySelection);
71863f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        showSecurityScreen(backup);
719258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    }
720258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
7210a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen    public boolean showNextSecurityScreenIfPresent() {
7220a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen        SecurityMode securityMode = mSecurityModel.getSecurityMode();
7230a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen        // Allow an alternate, such as biometric unlock
7240a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen        securityMode = mSecurityModel.getAlternateFor(securityMode);
7250a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen        if (SecurityMode.None == securityMode) {
7260a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen            return false;
7270a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen        } else {
7280a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen            showSecurityScreen(securityMode); // switch to the alternate security view
7290a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen            return true;
7300a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen        }
7310a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen    }
7320a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen
733258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    private void showNextSecurityScreenOrFinish(boolean authenticated) {
73461413b5ed215accd7b4f3eaf80edeab2f330aa49Danielle Millett        if (DEBUG) Log.d(TAG, "showNextSecurityScreenOrFinish(" + authenticated + ")");
735dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        boolean finish = false;
736e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        if (SecurityMode.None == mCurrentSecuritySelection) {
737258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            SecurityMode securityMode = mSecurityModel.getSecurityMode();
738258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            // Allow an alternate, such as biometric unlock
739000464ac012471d301c6e48a8228291519915e17Jim Miller            securityMode = mSecurityModel.getAlternateFor(securityMode);
740e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            if (SecurityMode.None == securityMode) {
741dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                finish = true; // no security required
742dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            } else {
743e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller                showSecurityScreen(securityMode); // switch to the alternate security view
744dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            }
745dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        } else if (authenticated) {
746e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            switch (mCurrentSecuritySelection) {
747e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller                case Pattern:
748e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller                case Password:
74969bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler                case PIN:
750e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller                case Account:
751e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller                case Biometric:
7524b09dd31fb1cefcaee87e7a206f22ba31527e250Jim Miller                    finish = true;
7534b09dd31fb1cefcaee87e7a206f22ba31527e250Jim Miller                    break;
7544b09dd31fb1cefcaee87e7a206f22ba31527e250Jim Miller
755e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller                case SimPin:
756e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller                case SimPuk:
7574b09dd31fb1cefcaee87e7a206f22ba31527e250Jim Miller                    // Shortcut for SIM PIN/PUK to go to directly to user's security screen or home
7584b09dd31fb1cefcaee87e7a206f22ba31527e250Jim Miller                    SecurityMode securityMode = mSecurityModel.getSecurityMode();
7594b09dd31fb1cefcaee87e7a206f22ba31527e250Jim Miller                    if (securityMode != SecurityMode.None) {
760e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller                        showSecurityScreen(securityMode);
7614b09dd31fb1cefcaee87e7a206f22ba31527e250Jim Miller                    } else {
7624b09dd31fb1cefcaee87e7a206f22ba31527e250Jim Miller                        finish = true;
7634b09dd31fb1cefcaee87e7a206f22ba31527e250Jim Miller                    }
7644b09dd31fb1cefcaee87e7a206f22ba31527e250Jim Miller                    break;
7654b09dd31fb1cefcaee87e7a206f22ba31527e250Jim Miller
7664b09dd31fb1cefcaee87e7a206f22ba31527e250Jim Miller                default:
7670ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller                    Log.v(TAG, "Bad security screen " + mCurrentSecuritySelection + ", fail safe");
7680ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller                    showPrimarySecurityScreen(false);
7694b09dd31fb1cefcaee87e7a206f22ba31527e250Jim Miller                    break;
770dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            }
771dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        } else {
7720ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller            showPrimarySecurityScreen(false);
773dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
774dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        if (finish) {
7750ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller            // If the alternate unlock was suppressed, it can now be safely
7760ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller            // enabled because the user has left keyguard.
7770ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller            KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(true);
77868c2489457631f733f542e14058c6d1274c203deJim Miller
779dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            // If there's a pending runnable because the user interacted with a widget
780dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            // and we're leaving keyguard, then run it.
78134c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock            boolean deferKeyguardDone = false;
78234c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock            if (mDismissAction != null) {
78334c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock                deferKeyguardDone = mDismissAction.onDismiss();
78434c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock                mDismissAction = null;
785dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            }
7867def1db03943251fe8cb57ec514722026425479eCraig Mautner            if (mViewMediatorCallback != null) {
78734c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock                if (deferKeyguardDone) {
78834c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock                    mViewMediatorCallback.keyguardDonePending();
78934c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock                } else {
79034c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock                    mViewMediatorCallback.keyguardDone(true);
79134c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock                }
7927def1db03943251fe8cb57ec514722026425479eCraig Mautner            }
793b5f3b707a7010e8d867da9342ea87cf0a1679692Jim Miller        } else {
794b5f3b707a7010e8d867da9342ea87cf0a1679692Jim Miller            mViewStateManager.showBouncer(true);
795dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
796dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
797dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
798dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    private OnClickHandler mOnClickHandler = new OnClickHandler() {
799dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        @Override
800dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        public boolean onClickHandler(final View view,
801dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                final android.app.PendingIntent pendingIntent,
802dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                final Intent fillInIntent) {
803dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            if (pendingIntent.isActivity()) {
80434c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock                setOnDismissAction(new OnDismissAction() {
80534c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock                    public boolean onDismiss() {
806dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                        try {
807dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                              // TODO: Unregister this handler if PendingIntent.FLAG_ONE_SHOT?
808dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                              Context context = view.getContext();
809dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                              ActivityOptions opts = ActivityOptions.makeScaleUpAnimation(view,
810dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                                      0, 0,
811dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                                      view.getMeasuredWidth(), view.getMeasuredHeight());
812dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                              context.startIntentSender(
813dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                                      pendingIntent.getIntentSender(), fillInIntent,
814dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                                      Intent.FLAG_ACTIVITY_NEW_TASK,
815dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                                      Intent.FLAG_ACTIVITY_NEW_TASK, 0, opts.toBundle());
81634c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock                        } catch (IntentSender.SendIntentException e) {
81734c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock                            android.util.Log.e(TAG, "Cannot send pending intent: ", e);
81834c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock                        } catch (Exception e) {
81934c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock                            android.util.Log.e(TAG, "Cannot send pending intent due to " +
82034c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock                                    "unknown exception: ", e);
82134c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock                        }
82234c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock                        return false;
823dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                    }
8245f75aa15d7c1c5ea1c1eecd95bf2bb0920173eb2Jim Miller                });
825dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
82608898375fba7cc776857ebf0846c7183563a300fJim Miller                if (mViewStateManager.isChallengeShowing()) {
82708898375fba7cc776857ebf0846c7183563a300fJim Miller                    mViewStateManager.showBouncer(true);
82808898375fba7cc776857ebf0846c7183563a300fJim Miller                } else {
82908898375fba7cc776857ebf0846c7183563a300fJim Miller                    mCallback.dismiss(false);
83008898375fba7cc776857ebf0846c7183563a300fJim Miller                }
831dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                return true;
832dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            } else {
833dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                return super.onClickHandler(view, pendingIntent, fillInIntent);
834dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            }
835dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        };
836dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    };
837dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
83863f9b81795559443e0376985f8aaaa97a359ef94Jim Miller    // Used to ignore callbacks from methods that are no longer current (e.g. face unlock).
83963f9b81795559443e0376985f8aaaa97a359ef94Jim Miller    // This avoids unwanted asynchronous events from messing with the state.
84063f9b81795559443e0376985f8aaaa97a359ef94Jim Miller    private KeyguardSecurityCallback mNullCallback = new KeyguardSecurityCallback() {
84163f9b81795559443e0376985f8aaaa97a359ef94Jim Miller
84263f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        @Override
84363f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        public void userActivity(long timeout) {
84463f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        }
84563f9b81795559443e0376985f8aaaa97a359ef94Jim Miller
84663f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        @Override
84763f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        public void showBackupSecurity() {
84863f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        }
84963f9b81795559443e0376985f8aaaa97a359ef94Jim Miller
85063f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        @Override
85134c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock        public void setOnDismissAction(OnDismissAction action) {
85263f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        }
85363f9b81795559443e0376985f8aaaa97a359ef94Jim Miller
85463f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        @Override
85563f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        public void reportSuccessfulUnlockAttempt() {
85663f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        }
85763f9b81795559443e0376985f8aaaa97a359ef94Jim Miller
85863f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        @Override
85963f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        public void reportFailedUnlockAttempt() {
86063f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        }
86163f9b81795559443e0376985f8aaaa97a359ef94Jim Miller
86263f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        @Override
86363f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        public boolean isVerifyUnlockOnly() {
86463f9b81795559443e0376985f8aaaa97a359ef94Jim Miller            return false;
86563f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        }
86663f9b81795559443e0376985f8aaaa97a359ef94Jim Miller
86763f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        @Override
86863f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        public int getFailedAttempts() {
86963f9b81795559443e0376985f8aaaa97a359ef94Jim Miller            return 0;
87063f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        }
87163f9b81795559443e0376985f8aaaa97a359ef94Jim Miller
87263f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        @Override
87363f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        public void dismiss(boolean securityVerified) {
87463f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        }
87563f9b81795559443e0376985f8aaaa97a359ef94Jim Miller    };
87663f9b81795559443e0376985f8aaaa97a359ef94Jim Miller
8775f75aa15d7c1c5ea1c1eecd95bf2bb0920173eb2Jim Miller    /**
87834c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock     * Sets an action to perform when keyguard is dismissed.
87934c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock     * @param action
8805f75aa15d7c1c5ea1c1eecd95bf2bb0920173eb2Jim Miller     */
88134c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock    protected void setOnDismissAction(OnDismissAction action) {
88234c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock        mDismissAction = action;
8835f75aa15d7c1c5ea1c1eecd95bf2bb0920173eb2Jim Miller    }
8845f75aa15d7c1c5ea1c1eecd95bf2bb0920173eb2Jim Miller
885e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller    private KeyguardSecurityView getSecurityView(SecurityMode securityMode) {
886e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        final int securityViewIdForMode = getSecurityViewIdForMode(securityMode);
887e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        KeyguardSecurityView view = null;
888e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        final int children = mSecurityViewContainer.getChildCount();
889dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        for (int child = 0; child < children; child++) {
890e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            if (mSecurityViewContainer.getChildAt(child).getId() == securityViewIdForMode) {
891e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller                view = ((KeyguardSecurityView)mSecurityViewContainer.getChildAt(child));
892e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller                break;
893dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            }
894dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
89563f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        int layoutId = getLayoutIdFor(securityMode);
89663f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        if (view == null && layoutId != 0) {
897e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            final LayoutInflater inflater = LayoutInflater.from(mContext);
898bdffd5c3a18e67443ebbd16d4f0349d0728285b1Jim Miller            if (DEBUG) Log.v(TAG, "inflating id = " + layoutId);
8999799714f6c69efe50e21a6073b879140e5e792b7Adam Powell            View v = inflater.inflate(layoutId, mSecurityViewContainer, false);
900e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            mSecurityViewContainer.addView(v);
901e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            updateSecurityView(v);
9020b728244dc87b4a453f2191c2cb37a86e91aee0aJim Miller            view = (KeyguardSecurityView)v;
9030ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller        }
9040ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller
9050ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller        if (view instanceof KeyguardSelectorView) {
9060ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller            KeyguardSelectorView selectorView = (KeyguardSelectorView) view;
9070ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller            View carrierText = selectorView.findViewById(R.id.keyguard_selector_fade_container);
9080ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller            selectorView.setCarrierArea(carrierText);
9090ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller        }
91068c2489457631f733f542e14058c6d1274c203deJim Miller
911e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        return view;
912dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
913dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
914258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    /**
915258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller     * Switches to the given security view unless it's already being shown, in which case
916258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller     * this is a no-op.
917258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller     *
918e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller     * @param securityMode
919258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller     */
920e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller    private void showSecurityScreen(SecurityMode securityMode) {
92168c2489457631f733f542e14058c6d1274c203deJim Miller        if (DEBUG) Log.d(TAG, "showSecurityScreen(" + securityMode + ")");
92268c2489457631f733f542e14058c6d1274c203deJim Miller
923e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        if (securityMode == mCurrentSecuritySelection) return;
924dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
925e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        KeyguardSecurityView oldView = getSecurityView(mCurrentSecuritySelection);
926e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        KeyguardSecurityView newView = getSecurityView(securityMode);
927dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
928a71984f3da47c6e6e3164c170735362a3222d3adJim Miller        // Enter full screen mode if we're in SIM or Account screen
9295ecd81154fa039961f65bb4e36d18ac555b0d1d6Jim Miller        boolean fullScreenEnabled = getResources().getBoolean(R.bool.kg_sim_puk_account_full_screen);
930a71984f3da47c6e6e3164c170735362a3222d3adJim Miller        boolean isSimOrAccount = securityMode == SecurityMode.SimPin
931a71984f3da47c6e6e3164c170735362a3222d3adJim Miller                || securityMode == SecurityMode.SimPuk
932a71984f3da47c6e6e3164c170735362a3222d3adJim Miller                || securityMode == SecurityMode.Account;
933a71984f3da47c6e6e3164c170735362a3222d3adJim Miller        mAppWidgetContainer.setVisibility(
934a71984f3da47c6e6e3164c170735362a3222d3adJim Miller                isSimOrAccount && fullScreenEnabled ? View.GONE : View.VISIBLE);
935a71984f3da47c6e6e3164c170735362a3222d3adJim Miller
9362cacda5fc92a28a44a37e25b96093a9cc1346080Jim Miller        if (mSlidingChallengeLayout != null) {
9372cacda5fc92a28a44a37e25b96093a9cc1346080Jim Miller            mSlidingChallengeLayout.setChallengeInteractive(!fullScreenEnabled);
9382cacda5fc92a28a44a37e25b96093a9cc1346080Jim Miller        }
9392cacda5fc92a28a44a37e25b96093a9cc1346080Jim Miller
940dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        // Emulate Activity life cycle
94163f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        if (oldView != null) {
94263f9b81795559443e0376985f8aaaa97a359ef94Jim Miller            oldView.onPause();
94363f9b81795559443e0376985f8aaaa97a359ef94Jim Miller            oldView.setKeyguardCallback(mNullCallback); // ignore requests from old view
94463f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        }
945a042ac90640c0c3fd3c5349083b86bbfd6319b64Chris Wren        newView.onResume(KeyguardSecurityView.VIEW_REVEALED);
94663f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        newView.setKeyguardCallback(mCallback);
947dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
948cd03a26f4f5663b40d4679de102519ccc163fa10Craig Mautner        final boolean needsInput = newView.needsInput();
9497def1db03943251fe8cb57ec514722026425479eCraig Mautner        if (mViewMediatorCallback != null) {
950cd03a26f4f5663b40d4679de102519ccc163fa10Craig Mautner            mViewMediatorCallback.setNeedsInput(needsInput);
9517def1db03943251fe8cb57ec514722026425479eCraig Mautner        }
952dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
953dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        // Find and show this child.
954e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        final int childCount = mSecurityViewContainer.getChildCount();
9554b09dd31fb1cefcaee87e7a206f22ba31527e250Jim Miller
95622ae05d50c7011b389a5dba7a2f717e407328bf8Jim Miller        mSecurityViewContainer.setInAnimation(
95722ae05d50c7011b389a5dba7a2f717e407328bf8Jim Miller                AnimationUtils.loadAnimation(mContext, R.anim.keyguard_security_fade_in));
95822ae05d50c7011b389a5dba7a2f717e407328bf8Jim Miller        mSecurityViewContainer.setOutAnimation(
95922ae05d50c7011b389a5dba7a2f717e407328bf8Jim Miller                AnimationUtils.loadAnimation(mContext, R.anim.keyguard_security_fade_out));
960e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        final int securityViewIdForMode = getSecurityViewIdForMode(securityMode);
961dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        for (int i = 0; i < childCount; i++) {
962e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            if (mSecurityViewContainer.getChildAt(i).getId() == securityViewIdForMode) {
963e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller                mSecurityViewContainer.setDisplayedChild(i);
964dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                break;
965dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            }
966dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
967258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
968e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        if (securityMode == SecurityMode.None) {
969e23ab8b1acea211762f1d0c4202f73a9f7700bb5Jim Miller            // Discard current runnable if we're switching back to the selector view
97034c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock            setOnDismissAction(null);
97168c2489457631f733f542e14058c6d1274c203deJim Miller        }
97203eca859067ac0d4e419305de8ab0fdc03b4210fJohn Spurlock        if (securityMode == SecurityMode.Account && !mLockPatternUtils.isPermanentlyLocked()) {
97303eca859067ac0d4e419305de8ab0fdc03b4210fJohn Spurlock            // we're showing account as a backup, provide a way to get back to primary
97403eca859067ac0d4e419305de8ab0fdc03b4210fJohn Spurlock            setBackButtonEnabled(true);
97503eca859067ac0d4e419305de8ab0fdc03b4210fJohn Spurlock        }
976e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        mCurrentSecuritySelection = securityMode;
977dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
978dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
979dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    @Override
980dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    public void onScreenTurnedOn() {
981358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock        if (DEBUG) Log.d(TAG, "screen on, instance " + Integer.toHexString(hashCode()));
9820ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller        showPrimarySecurityScreen(false);
983a042ac90640c0c3fd3c5349083b86bbfd6319b64Chris Wren        getSecurityView(mCurrentSecuritySelection).onResume(KeyguardSecurityView.SCREEN_ON);
984d03a5558350cb6adff68aaf97ad4ee946bcd91a1Jim Miller
985d03a5558350cb6adff68aaf97ad4ee946bcd91a1Jim Miller        // This is a an attempt to fix bug 7137389 where the device comes back on but the entire
986d03a5558350cb6adff68aaf97ad4ee946bcd91a1Jim Miller        // layout is blank but forcing a layout causes it to reappear (e.g. with with
987d03a5558350cb6adff68aaf97ad4ee946bcd91a1Jim Miller        // hierarchyviewer).
988d03a5558350cb6adff68aaf97ad4ee946bcd91a1Jim Miller        requestLayout();
9896fb841fa219eaae3e87f2fdc05e105d7a1813c42Adam Cohen
9906fb841fa219eaae3e87f2fdc05e105d7a1813c42Adam Cohen        if (mViewStateManager != null) {
9916fb841fa219eaae3e87f2fdc05e105d7a1813c42Adam Cohen            mViewStateManager.showUsabilityHints();
9926fb841fa219eaae3e87f2fdc05e105d7a1813c42Adam Cohen        }
993147f9568afe645d9bfb91f3037f5336d8a2482ccJim Miller        requestFocus();
994dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
995dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
996dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    @Override
997dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    public void onScreenTurnedOff() {
998dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock        if (DEBUG) Log.d(TAG, String.format("screen off, instance %s at %s",
999dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock                Integer.toHexString(hashCode()), SystemClock.uptimeMillis()));
1000078f5919a9584cc3f1c7eb3a78862bfa40396de9Brian Colonna        // Once the screen turns off, we no longer consider this to be first boot and we want the
1001078f5919a9584cc3f1c7eb3a78862bfa40396de9Brian Colonna        // biometric unlock to start next time keyguard is shown.
1002078f5919a9584cc3f1c7eb3a78862bfa40396de9Brian Colonna        KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(true);
10031413889565bc1b9d5d5fb73302460a4f25f4a8c0Michael Jurka        // We use mAppWidgetToShow to show a particular widget after you add it-- once the screen
10041413889565bc1b9d5d5fb73302460a4f25f4a8c0Michael Jurka        // turns off we reset that behavior
10051413889565bc1b9d5d5fb73302460a4f25f4a8c0Michael Jurka        clearAppWidgetToShow();
100667a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        checkAppWidgetConsistency();
10070ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller        showPrimarySecurityScreen(true);
1008e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        getSecurityView(mCurrentSecuritySelection).onPause();
1009dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock        CameraWidgetFrame cameraPage = findCameraPage();
1010dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock        if (cameraPage != null) {
1011dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock            cameraPage.onScreenTurnedOff();
1012dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock        }
1013147f9568afe645d9bfb91f3037f5336d8a2482ccJim Miller        clearFocus();
1014dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
1015dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
10161413889565bc1b9d5d5fb73302460a4f25f4a8c0Michael Jurka    public void clearAppWidgetToShow() {
10171413889565bc1b9d5d5fb73302460a4f25f4a8c0Michael Jurka        mAppWidgetToShow = AppWidgetManager.INVALID_APPWIDGET_ID;
10181413889565bc1b9d5d5fb73302460a4f25f4a8c0Michael Jurka    }
10191413889565bc1b9d5d5fb73302460a4f25f4a8c0Michael Jurka
1020dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    @Override
1021dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    public void show() {
1022086977094d96ab9352432e0941a05b09cefc92acJim Miller        if (DEBUG) Log.d(TAG, "show()");
1023086977094d96ab9352432e0941a05b09cefc92acJim Miller        showPrimarySecurityScreen(false);
1024dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
1025dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
1026dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    @Override
1027dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    public void verifyUnlock() {
1028dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        SecurityMode securityMode = mSecurityModel.getSecurityMode();
1029dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        if (securityMode == KeyguardSecurityModel.SecurityMode.None) {
10307def1db03943251fe8cb57ec514722026425479eCraig Mautner            if (mViewMediatorCallback != null) {
10317def1db03943251fe8cb57ec514722026425479eCraig Mautner                mViewMediatorCallback.keyguardDone(true);
10327def1db03943251fe8cb57ec514722026425479eCraig Mautner            }
1033dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        } else if (securityMode != KeyguardSecurityModel.SecurityMode.Pattern
103469bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler                && securityMode != KeyguardSecurityModel.SecurityMode.PIN
1035dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                && securityMode != KeyguardSecurityModel.SecurityMode.Password) {
1036dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            // can only verify unlock when in pattern/password mode
10377def1db03943251fe8cb57ec514722026425479eCraig Mautner            if (mViewMediatorCallback != null) {
10387def1db03943251fe8cb57ec514722026425479eCraig Mautner                mViewMediatorCallback.keyguardDone(false);
10397def1db03943251fe8cb57ec514722026425479eCraig Mautner            }
1040dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        } else {
1041dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            // otherwise, go to the unlock screen, see if they can verify it
1042dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            mIsVerifyUnlockOnly = true;
1043e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            showSecurityScreen(securityMode);
1044dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
1045dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
1046dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
1047dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    private int getSecurityViewIdForMode(SecurityMode securityMode) {
1048dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        switch (securityMode) {
1049e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            case None: return R.id.keyguard_selector_view;
1050e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            case Pattern: return R.id.keyguard_pattern_view;
105169bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler            case PIN: return R.id.keyguard_pin_view;
1052e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            case Password: return R.id.keyguard_password_view;
1053e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            case Biometric: return R.id.keyguard_face_unlock_view;
1054e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            case Account: return R.id.keyguard_account_view;
1055e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            case SimPin: return R.id.keyguard_sim_pin_view;
1056e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            case SimPuk: return R.id.keyguard_sim_puk_view;
1057dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
1058dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        return 0;
1059dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
1060dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
1061e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller    private int getLayoutIdFor(SecurityMode securityMode) {
1062e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        switch (securityMode) {
1063e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            case None: return R.layout.keyguard_selector_view;
1064e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            case Pattern: return R.layout.keyguard_pattern_view;
106569bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler            case PIN: return R.layout.keyguard_pin_view;
1066e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            case Password: return R.layout.keyguard_password_view;
1067e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            case Biometric: return R.layout.keyguard_face_unlock_view;
1068e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            case Account: return R.layout.keyguard_account_view;
1069e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            case SimPin: return R.layout.keyguard_sim_pin_view;
1070e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            case SimPuk: return R.layout.keyguard_sim_puk_view;
1071e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            default:
107263f9b81795559443e0376985f8aaaa97a359ef94Jim Miller                return 0;
1073e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        }
1074e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller    }
1075e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller
107651117262c8fadb6d227d137e83ad66996b013141Jim Miller    private boolean addWidget(int appId, int pageIndex, boolean updateDbIfFailed) {
107767a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appId);
107899a3cae55bd1a4ea6d82aa7fa2a67170e7cd5b3eJim Miller        if (appWidgetInfo != null) {
1079a75a883fe9ea1790803148f0a561473073e3f264Jim Miller            AppWidgetHostView view = mAppWidgetHost.createView(mContext, appId, appWidgetInfo);
1080d6523da1ad7bae805a3dbea8d7b398d86cd3c181Jim Miller            addWidget(view, pageIndex);
108167a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka            return true;
108299a3cae55bd1a4ea6d82aa7fa2a67170e7cd5b3eJim Miller        } else {
108351117262c8fadb6d227d137e83ad66996b013141Jim Miller            if (updateDbIfFailed) {
1084a75a883fe9ea1790803148f0a561473073e3f264Jim Miller                Log.w(TAG, "*** AppWidgetInfo for app widget id " + appId + "  was null for user"
1085a75a883fe9ea1790803148f0a561473073e3f264Jim Miller                        + mUserId + ", deleting");
108651117262c8fadb6d227d137e83ad66996b013141Jim Miller                mAppWidgetHost.deleteAppWidgetId(appId);
108751117262c8fadb6d227d137e83ad66996b013141Jim Miller                mLockPatternUtils.removeAppWidget(appId);
108851117262c8fadb6d227d137e83ad66996b013141Jim Miller            }
108967a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka            return false;
109099a3cae55bd1a4ea6d82aa7fa2a67170e7cd5b3eJim Miller        }
1091dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
1092dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
1093dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock    private final CameraWidgetFrame.Callbacks mCameraWidgetCallbacks =
1094dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock        new CameraWidgetFrame.Callbacks() {
1095dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock            @Override
1096dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock            public void onLaunchingCamera() {
109757f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock                setSliderHandleAlpha(0);
1098dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock            }
1099dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock
1100dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock            @Override
110157f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock            public void onCameraLaunchedSuccessfully() {
11026cf53bb3a94ec5a6eebc96a315dac32d042f1945Winson Chung                if (mAppWidgetContainer.isCameraPage(mAppWidgetContainer.getCurrentPage())) {
11034b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock                    mAppWidgetContainer.scrollLeft();
11044b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock                }
110557f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock                setSliderHandleAlpha(1);
1106aaf9b11e6232f159aa6d9863097b09bb435deae3Jim Miller                mShowSecurityWhenReturn = true;
1107dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock            }
1108dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock
110957f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock            @Override
111057f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock            public void onCameraLaunchedUnsuccessfully() {
111157f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock                setSliderHandleAlpha(1);
111257f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock            }
111357f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock
111457f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock            private void setSliderHandleAlpha(float alpha) {
111557f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock                SlidingChallengeLayout slider =
111657f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock                        (SlidingChallengeLayout) findViewById(R.id.sliding_layout);
111757f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock                if (slider != null) {
111857f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock                    slider.setHandleAlpha(alpha);
111957f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock                }
1120dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock            }
1121dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock        };
1122dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock
1123dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock    private final KeyguardActivityLauncher mActivityLauncher = new KeyguardActivityLauncher() {
1124dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock        @Override
1125dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock        Context getContext() {
1126dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock            return mContext;
1127dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock        }
1128dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock
1129dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock        @Override
1130dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock        KeyguardSecurityCallback getCallback() {
1131dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock            return mCallback;
1132dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock        }
1133dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock
1134dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock        @Override
1135dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock        LockPatternUtils getLockPatternUtils() {
1136dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock            return mLockPatternUtils;
1137bdca3c0a21ba15e8bb6d7ef0ca1b7e8024f98f19Jim Miller        }
1138bdca3c0a21ba15e8bb6d7ef0ca1b7e8024f98f19Jim Miller    };
1139dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock
1140eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka    private int numWidgets() {
1141eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka        final int childCount = mAppWidgetContainer.getChildCount();
1142eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka        int widgetCount = 0;
1143eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka        for (int i = 0; i < childCount; i++) {
1144eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka            if (mAppWidgetContainer.isWidgetPage(i)) {
1145eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka                widgetCount++;
1146eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka            }
1147eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka        }
1148eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka        return widgetCount;
1149eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka    }
1150eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka
11514e81bd4bcf60a934d4cd589dab6e2bddb88d7356Jim Miller    private void addDefaultWidgets() {
115251117262c8fadb6d227d137e83ad66996b013141Jim Miller        if (!mSafeModeEnabled && !widgetsDisabledByDpm()) {
11538f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            LayoutInflater inflater = LayoutInflater.from(mContext);
115451117262c8fadb6d227d137e83ad66996b013141Jim Miller            View addWidget = inflater.inflate(R.layout.keyguard_add_widget, this, false);
1155eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka            mAppWidgetContainer.addWidget(addWidget, 0);
115651117262c8fadb6d227d137e83ad66996b013141Jim Miller            View addWidgetButton = addWidget.findViewById(R.id.keyguard_add_widget_view);
115751117262c8fadb6d227d137e83ad66996b013141Jim Miller            addWidgetButton.setOnClickListener(new OnClickListener() {
115851117262c8fadb6d227d137e83ad66996b013141Jim Miller                @Override
115951117262c8fadb6d227d137e83ad66996b013141Jim Miller                public void onClick(View v) {
1160192d6d4ee271c0782a3bf5d8c64e42eb22d1a6faMichael Jurka                    // Pass in an invalid widget id... the picker will allocate an ID for us
1161192d6d4ee271c0782a3bf5d8c64e42eb22d1a6faMichael Jurka                    mActivityLauncher.launchWidgetPicker(AppWidgetManager.INVALID_APPWIDGET_ID);
116251117262c8fadb6d227d137e83ad66996b013141Jim Miller                }
116351117262c8fadb6d227d137e83ad66996b013141Jim Miller            });
116451117262c8fadb6d227d137e83ad66996b013141Jim Miller        }
116551117262c8fadb6d227d137e83ad66996b013141Jim Miller
116651117262c8fadb6d227d137e83ad66996b013141Jim Miller        // We currently disable cameras in safe mode because we support loading 3rd party
116751117262c8fadb6d227d137e83ad66996b013141Jim Miller        // cameras we can't trust.  TODO: plumb safe mode into camera creation code and only
116851117262c8fadb6d227d137e83ad66996b013141Jim Miller        // inflate system-provided camera?
1169371f3408d6d9c3c3781d6e35e591f61026b42240John Spurlock        if (!mSafeModeEnabled && !cameraDisabledByDpm() && mUserSetupCompleted
117051117262c8fadb6d227d137e83ad66996b013141Jim Miller                && mContext.getResources().getBoolean(R.bool.kg_enable_camera_default_widget)) {
1171dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock            View cameraWidget =
1172dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock                    CameraWidgetFrame.create(mContext, mCameraWidgetCallbacks, mActivityLauncher);
1173dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock            if (cameraWidget != null) {
1174dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock                mAppWidgetContainer.addWidget(cameraWidget);
1175dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock            }
117686b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock        }
1177838906b165e4d3cb2c512b2db344aa50cb5d4751Jim Miller
117819a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        enableUserSelectorIfNecessary();
11797221d3ae08cc2be922d26e5d491038512cb6c74dJim Miller    }
11807221d3ae08cc2be922d26e5d491038512cb6c74dJim Miller
11818f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller    /**
11828f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller     * Create KeyguardTransportControlView on demand.
11838f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller     * @return
11848f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller     */
11854894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller    private KeyguardTransportControlView getOrCreateTransportControl() {
11868f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        if (mTransportControl == null) {
11878f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            LayoutInflater inflater = LayoutInflater.from(mContext);
11888f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            mTransportControl = (KeyguardTransportControlView)
11898f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller                    inflater.inflate(R.layout.keyguard_transport_control_view, this, false);
11904e81bd4bcf60a934d4cd589dab6e2bddb88d7356Jim Miller        }
11918f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        return mTransportControl;
11924e81bd4bcf60a934d4cd589dab6e2bddb88d7356Jim Miller    }
11934e81bd4bcf60a934d4cd589dab6e2bddb88d7356Jim Miller
119451117262c8fadb6d227d137e83ad66996b013141Jim Miller    private int getInsertPageIndex() {
119567a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        View addWidget = mAppWidgetContainer.findViewById(R.id.keyguard_add_widget);
119651117262c8fadb6d227d137e83ad66996b013141Jim Miller        int insertionIndex = mAppWidgetContainer.indexOfChild(addWidget);
119751117262c8fadb6d227d137e83ad66996b013141Jim Miller        if (insertionIndex < 0) {
119851117262c8fadb6d227d137e83ad66996b013141Jim Miller            insertionIndex = 0; // no add widget page found
119951117262c8fadb6d227d137e83ad66996b013141Jim Miller        } else {
120051117262c8fadb6d227d137e83ad66996b013141Jim Miller            insertionIndex++; // place after add widget
120167a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        }
120251117262c8fadb6d227d137e83ad66996b013141Jim Miller        return insertionIndex;
120367a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka    }
120467a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka
120567a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka    private void addDefaultStatusWidget(int index) {
120667a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        LayoutInflater inflater = LayoutInflater.from(mContext);
120767a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        View statusWidget = inflater.inflate(R.layout.keyguard_status_view, null, true);
120867a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        mAppWidgetContainer.addWidget(statusWidget, index);
120967a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka    }
121067a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka
12111254f2f42f7173ef51d0034975ab5cb7d44f8209Michael Jurka    private void addWidgetsFromSettings() {
121251117262c8fadb6d227d137e83ad66996b013141Jim Miller        if (mSafeModeEnabled || widgetsDisabledByDpm()) {
121351117262c8fadb6d227d137e83ad66996b013141Jim Miller            return;
1214b8ec470617590fa2025db869e8e80dcce8eaec23Jim Miller        }
1215f229e4d3eb8f910c181f96416c6798f6f305a395Jim Miller
121651117262c8fadb6d227d137e83ad66996b013141Jim Miller        int insertionIndex = getInsertPageIndex();
121720c41d5382b70fa5a24e9ef68f19ce0aedea5234Michael Jurka
121820c41d5382b70fa5a24e9ef68f19ce0aedea5234Michael Jurka        // Add user-selected widget
1219aa2859ae61098509495b7938e32a6d59d37561beMichael Jurka        final int[] widgets = mLockPatternUtils.getAppWidgets();
122067a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka
1221aa2859ae61098509495b7938e32a6d59d37561beMichael Jurka        if (widgets == null) {
1222aa2859ae61098509495b7938e32a6d59d37561beMichael Jurka            Log.d(TAG, "Problem reading widgets");
1223aa2859ae61098509495b7938e32a6d59d37561beMichael Jurka        } else {
1224aa2859ae61098509495b7938e32a6d59d37561beMichael Jurka            for (int i = widgets.length -1; i >= 0; i--) {
12251254f2f42f7173ef51d0034975ab5cb7d44f8209Michael Jurka                if (widgets[i] == LockPatternUtils.ID_DEFAULT_STATUS_WIDGET) {
122651117262c8fadb6d227d137e83ad66996b013141Jim Miller                    addDefaultStatusWidget(insertionIndex);
12271254f2f42f7173ef51d0034975ab5cb7d44f8209Michael Jurka                } else {
1228aa2859ae61098509495b7938e32a6d59d37561beMichael Jurka                    // We add the widgets from left to right, starting after the first page after
1229aa2859ae61098509495b7938e32a6d59d37561beMichael Jurka                    // the add page. We count down, since the order will be persisted from right
1230aa2859ae61098509495b7938e32a6d59d37561beMichael Jurka                    // to left, starting after camera.
123151117262c8fadb6d227d137e83ad66996b013141Jim Miller                    addWidget(widgets[i], insertionIndex, true);
1232aa2859ae61098509495b7938e32a6d59d37561beMichael Jurka                }
1233dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            }
1234dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
123551117262c8fadb6d227d137e83ad66996b013141Jim Miller    }
123651117262c8fadb6d227d137e83ad66996b013141Jim Miller
123751117262c8fadb6d227d137e83ad66996b013141Jim Miller    private int allocateIdForDefaultAppWidget() {
123851117262c8fadb6d227d137e83ad66996b013141Jim Miller        int appWidgetId;
123951117262c8fadb6d227d137e83ad66996b013141Jim Miller        Resources res = getContext().getResources();
124051117262c8fadb6d227d137e83ad66996b013141Jim Miller        ComponentName defaultAppWidget = new ComponentName(
124151117262c8fadb6d227d137e83ad66996b013141Jim Miller                res.getString(R.string.widget_default_package_name),
124251117262c8fadb6d227d137e83ad66996b013141Jim Miller                res.getString(R.string.widget_default_class_name));
124351117262c8fadb6d227d137e83ad66996b013141Jim Miller
124451117262c8fadb6d227d137e83ad66996b013141Jim Miller        // Note: we don't support configuring the widget
124551117262c8fadb6d227d137e83ad66996b013141Jim Miller        appWidgetId = mAppWidgetHost.allocateAppWidgetId();
124651117262c8fadb6d227d137e83ad66996b013141Jim Miller
124751117262c8fadb6d227d137e83ad66996b013141Jim Miller        try {
124851117262c8fadb6d227d137e83ad66996b013141Jim Miller            mAppWidgetManager.bindAppWidgetId(appWidgetId, defaultAppWidget);
124951117262c8fadb6d227d137e83ad66996b013141Jim Miller
125051117262c8fadb6d227d137e83ad66996b013141Jim Miller        } catch (IllegalArgumentException e) {
125151117262c8fadb6d227d137e83ad66996b013141Jim Miller            Log.e(TAG, "Error when trying to bind default AppWidget: " + e);
125251117262c8fadb6d227d137e83ad66996b013141Jim Miller            mAppWidgetHost.deleteAppWidgetId(appWidgetId);
125351117262c8fadb6d227d137e83ad66996b013141Jim Miller            appWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
125451117262c8fadb6d227d137e83ad66996b013141Jim Miller        }
125551117262c8fadb6d227d137e83ad66996b013141Jim Miller        return appWidgetId;
125667a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka    }
125767a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka    public void checkAppWidgetConsistency() {
1258efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen        // Since this method may bind a widget (which we can't do until boot completed) we
1259efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen        // may have to defer it until after boot complete.
12604eb36cfdcabb51f67a887d867de9559966606d86Adam Cohen        if (!KeyguardUpdateMonitor.getInstance(mContext).hasBootCompleted()) {
1261efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen            mCheckAppWidgetConsistencyOnBootCompleted = true;
1262efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen            return;
1263efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen        }
126467a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        final int childCount = mAppWidgetContainer.getChildCount();
126567a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        boolean widgetPageExists = false;
126667a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        for (int i = 0; i < childCount; i++) {
126751117262c8fadb6d227d137e83ad66996b013141Jim Miller            if (mAppWidgetContainer.isWidgetPage(i)) {
126867a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka                widgetPageExists = true;
126967a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka                break;
127067a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka            }
127167a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        }
127267a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        if (!widgetPageExists) {
127351117262c8fadb6d227d137e83ad66996b013141Jim Miller            final int insertPageIndex = getInsertPageIndex();
127451117262c8fadb6d227d137e83ad66996b013141Jim Miller
127551117262c8fadb6d227d137e83ad66996b013141Jim Miller            final boolean userAddedWidgetsEnabled = !widgetsDisabledByDpm();
127651117262c8fadb6d227d137e83ad66996b013141Jim Miller            boolean addedDefaultAppWidget = false;
127751117262c8fadb6d227d137e83ad66996b013141Jim Miller
127851117262c8fadb6d227d137e83ad66996b013141Jim Miller            if (!mSafeModeEnabled) {
127951117262c8fadb6d227d137e83ad66996b013141Jim Miller                if (userAddedWidgetsEnabled) {
128051117262c8fadb6d227d137e83ad66996b013141Jim Miller                    int appWidgetId = allocateIdForDefaultAppWidget();
128151117262c8fadb6d227d137e83ad66996b013141Jim Miller                    if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
128251117262c8fadb6d227d137e83ad66996b013141Jim Miller                        addedDefaultAppWidget = addWidget(appWidgetId, insertPageIndex, true);
128351117262c8fadb6d227d137e83ad66996b013141Jim Miller                    }
128451117262c8fadb6d227d137e83ad66996b013141Jim Miller                } else {
128551117262c8fadb6d227d137e83ad66996b013141Jim Miller                    // note: even if widgetsDisabledByDpm() returns true, we still bind/create
128651117262c8fadb6d227d137e83ad66996b013141Jim Miller                    // the default appwidget if possible
128751117262c8fadb6d227d137e83ad66996b013141Jim Miller                    int appWidgetId = mLockPatternUtils.getFallbackAppWidgetId();
128851117262c8fadb6d227d137e83ad66996b013141Jim Miller                    if (appWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
128951117262c8fadb6d227d137e83ad66996b013141Jim Miller                        appWidgetId = allocateIdForDefaultAppWidget();
129051117262c8fadb6d227d137e83ad66996b013141Jim Miller                        if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
129151117262c8fadb6d227d137e83ad66996b013141Jim Miller                            mLockPatternUtils.writeFallbackAppWidgetId(appWidgetId);
129251117262c8fadb6d227d137e83ad66996b013141Jim Miller                        }
129351117262c8fadb6d227d137e83ad66996b013141Jim Miller                    }
129451117262c8fadb6d227d137e83ad66996b013141Jim Miller                    if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
129551117262c8fadb6d227d137e83ad66996b013141Jim Miller                        addedDefaultAppWidget = addWidget(appWidgetId, insertPageIndex, false);
129651117262c8fadb6d227d137e83ad66996b013141Jim Miller                        if (!addedDefaultAppWidget) {
129751117262c8fadb6d227d137e83ad66996b013141Jim Miller                            mAppWidgetHost.deleteAppWidgetId(appWidgetId);
129851117262c8fadb6d227d137e83ad66996b013141Jim Miller                            mLockPatternUtils.writeFallbackAppWidgetId(
129951117262c8fadb6d227d137e83ad66996b013141Jim Miller                                    AppWidgetManager.INVALID_APPWIDGET_ID);
130051117262c8fadb6d227d137e83ad66996b013141Jim Miller                        }
130151117262c8fadb6d227d137e83ad66996b013141Jim Miller                    }
130251117262c8fadb6d227d137e83ad66996b013141Jim Miller                }
130367a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka            }
130451117262c8fadb6d227d137e83ad66996b013141Jim Miller
130567a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka            // Use the built-in status/clock view if we can't inflate the default widget
130651117262c8fadb6d227d137e83ad66996b013141Jim Miller            if (!addedDefaultAppWidget) {
130751117262c8fadb6d227d137e83ad66996b013141Jim Miller                addDefaultStatusWidget(insertPageIndex);
130851117262c8fadb6d227d137e83ad66996b013141Jim Miller            }
130951117262c8fadb6d227d137e83ad66996b013141Jim Miller
131051117262c8fadb6d227d137e83ad66996b013141Jim Miller            // trigger DB updates only if user-added widgets are enabled
131151117262c8fadb6d227d137e83ad66996b013141Jim Miller            if (!mSafeModeEnabled && userAddedWidgetsEnabled) {
131251117262c8fadb6d227d137e83ad66996b013141Jim Miller                mAppWidgetContainer.onAddView(
131351117262c8fadb6d227d137e83ad66996b013141Jim Miller                        mAppWidgetContainer.getChildAt(insertPageIndex), insertPageIndex);
131467a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka            }
131567a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        }
13160207c0992cb05d0acc60540748c8ae6985917abbAdam Cohen    }
13170207c0992cb05d0acc60540748c8ae6985917abbAdam Cohen
1318223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller    Runnable mSwitchPageRunnable = new Runnable() {
1319223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        @Override
1320223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        public void run() {
1321223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller           showAppropriateWidgetPage();
1322223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        }
1323223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller    };
1324223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller
1325223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller    static class SavedState extends BaseSavedState {
1326223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        int transportState;
13271413889565bc1b9d5d5fb73302460a4f25f4a8c0Michael Jurka        int appWidgetToShow = AppWidgetManager.INVALID_APPWIDGET_ID;
1328223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller
1329223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        SavedState(Parcelable superState) {
1330223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller            super(superState);
1331223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        }
1332223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller
1333223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        private SavedState(Parcel in) {
1334223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller            super(in);
1335223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller            this.transportState = in.readInt();
13361413889565bc1b9d5d5fb73302460a4f25f4a8c0Michael Jurka            this.appWidgetToShow = in.readInt();
1337223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        }
1338223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller
1339223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        @Override
1340223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        public void writeToParcel(Parcel out, int flags) {
1341223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller            super.writeToParcel(out, flags);
1342223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller            out.writeInt(this.transportState);
13431413889565bc1b9d5d5fb73302460a4f25f4a8c0Michael Jurka            out.writeInt(this.appWidgetToShow);
1344223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        }
1345223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller
1346223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        public static final Parcelable.Creator<SavedState> CREATOR
1347223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller                = new Parcelable.Creator<SavedState>() {
1348223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller            public SavedState createFromParcel(Parcel in) {
1349223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller                return new SavedState(in);
1350223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller            }
1351223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller
1352223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller            public SavedState[] newArray(int size) {
1353223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller                return new SavedState[size];
1354223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller            }
1355223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        };
1356223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller    }
1357223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller
1358223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller    @Override
1359223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller    public Parcelable onSaveInstanceState() {
13604894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller        if (DEBUG) Log.d(TAG, "onSaveInstanceState, tstate=" + mTransportState);
1361223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        Parcelable superState = super.onSaveInstanceState();
1362223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        SavedState ss = new SavedState(superState);
13634894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller        // If the transport is showing, force it to show it on restore.
13644894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller        final boolean showing = mTransportControl != null
13654894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller                && mAppWidgetContainer.getWidgetPageIndex(mTransportControl) >= 0;
13664894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller        ss.transportState =  showing ? TRANSPORT_VISIBLE : mTransportState;
13671413889565bc1b9d5d5fb73302460a4f25f4a8c0Michael Jurka        ss.appWidgetToShow = mAppWidgetToShow;
1368223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        return ss;
1369223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller    }
1370223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller
1371223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller    @Override
1372223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller    public void onRestoreInstanceState(Parcelable state) {
1373223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        if (!(state instanceof SavedState)) {
1374223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller            super.onRestoreInstanceState(state);
1375223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller            return;
1376223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        }
1377223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        SavedState ss = (SavedState) state;
1378223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        super.onRestoreInstanceState(ss.getSuperState());
13798f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        mTransportState = (ss.transportState);
13801413889565bc1b9d5d5fb73302460a4f25f4a8c0Michael Jurka        mAppWidgetToShow = ss.appWidgetToShow;
13814894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller        if (DEBUG) Log.d(TAG, "onRestoreInstanceState, transport=" + mTransportState);
13820db59a856f9b4a6ae53854a88fea3a3675d572fdWinson Chung        post(mSwitchPageRunnable);
1383223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller    }
1384223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller
13855f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock    @Override
13865f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock    public void onWindowFocusChanged(boolean hasWindowFocus) {
13875f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock        super.onWindowFocusChanged(hasWindowFocus);
13885f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock        if (DEBUG) Log.d(TAG, "Window is " + (hasWindowFocus ? "focused" : "unfocused"));
138976017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka        if (hasWindowFocus && mShowSecurityWhenReturn) {
1390aaf9b11e6232f159aa6d9863097b09bb435deae3Jim Miller            SlidingChallengeLayout slider =
1391aaf9b11e6232f159aa6d9863097b09bb435deae3Jim Miller                (SlidingChallengeLayout) findViewById(R.id.sliding_layout);
1392aaf9b11e6232f159aa6d9863097b09bb435deae3Jim Miller            if (slider != null) {
1393aaf9b11e6232f159aa6d9863097b09bb435deae3Jim Miller                slider.setHandleAlpha(1);
1394aaf9b11e6232f159aa6d9863097b09bb435deae3Jim Miller                slider.showChallenge(true);
1395aaf9b11e6232f159aa6d9863097b09bb435deae3Jim Miller            }
1396aaf9b11e6232f159aa6d9863097b09bb435deae3Jim Miller            mShowSecurityWhenReturn = false;
13975f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock        }
13985f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock    }
13995f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock
14000207c0992cb05d0acc60540748c8ae6985917abbAdam Cohen    private void showAppropriateWidgetPage() {
14018f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        int state = mTransportState;
14028f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        ensureTransportPresentOrRemoved(state);
14038f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        int pageToShow = getAppropriateWidgetPage(state);
1404223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        mAppWidgetContainer.setCurrentPage(pageToShow);
1405dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
1406dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
14074894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller    /**
14084894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     * Examines the current state and adds the transport to the widget pager when the state changes.
14094894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     *
14104894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     * Showing the initial transport and keeping it around is a bit tricky because the signals
14114894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     * coming from music players aren't always clear. Here's how the states are handled:
14124894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     *
14134894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     * {@link TRANSPORT_GONE} means we have no reason to show the transport - remove it if present.
14144894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     *
14154894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     * {@link TRANSPORT_INVISIBLE} means we have potential to show the transport because a music
14164894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     * player is registered but not currently playing music (or we don't know the state yet). The
14174894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     * code adds it conditionally on play state.
14184894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     *
14194894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     * {@link #TRANSPORT_VISIBLE} means a music player is active and transport should be showing.
14204894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     *
14214894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     * Once the transport is showing, we always show it until keyguard is dismissed. This state is
14224894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     * maintained by onSave/RestoreInstanceState(). This state is cleared in
14234894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     * {@link KeyguardViewManager#hide} when keyguard is dismissed, which causes the transport to be
14244894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     * gone when keyguard is restarted until we get an update with the current state.
14254894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     *
14264894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     * @param state
14274894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     */
14288f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller    private void ensureTransportPresentOrRemoved(int state) {
14294894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller        final boolean showing = getWidgetPosition(R.id.keyguard_transport_control) != -1;
14304894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller        final boolean visible = state == TRANSPORT_VISIBLE;
14314894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller        final boolean shouldBeVisible = state == TRANSPORT_INVISIBLE && isMusicPlaying(state);
14324894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller        if (!showing && (visible || shouldBeVisible)) {
14334894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller            if (DEBUGXPORT) Log.v(TAG, "add transport");
14344894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller            // insert to left of camera if it exists, otherwise after right-most widget
14354894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller            int lastWidget = mAppWidgetContainer.getChildCount() - 1;
14364894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller            int position = 0; // handle no widget case
14374894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller            if (lastWidget >= 0) {
14384894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller                position = mAppWidgetContainer.isCameraPage(lastWidget) ?
14394894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller                        lastWidget : lastWidget + 1;
14408f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            }
14414894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller            mAppWidgetContainer.addWidget(getOrCreateTransportControl(), position);
14424894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller        } else if (showing && state == TRANSPORT_GONE) {
14438f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            if (DEBUGXPORT) Log.v(TAG, "remove transport");
14444894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller            mAppWidgetContainer.removeWidget(getOrCreateTransportControl());
14458f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            mTransportControl = null;
14468f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        }
14478f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller    }
14488f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller
1449dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock    private CameraWidgetFrame findCameraPage() {
1450dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock        for (int i = mAppWidgetContainer.getChildCount() - 1; i >= 0; i--) {
14516cf53bb3a94ec5a6eebc96a315dac32d042f1945Winson Chung            if (mAppWidgetContainer.isCameraPage(i)) {
1452dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock                return (CameraWidgetFrame) mAppWidgetContainer.getChildAt(i);
1453dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock            }
1454dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock        }
1455dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock        return null;
1456dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock    }
1457dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock
14586cf53bb3a94ec5a6eebc96a315dac32d042f1945Winson Chung    boolean isMusicPage(int pageIndex) {
14596cf53bb3a94ec5a6eebc96a315dac32d042f1945Winson Chung        return pageIndex >= 0 && pageIndex == getWidgetPosition(R.id.keyguard_transport_control);
14606cf53bb3a94ec5a6eebc96a315dac32d042f1945Winson Chung    }
14616cf53bb3a94ec5a6eebc96a315dac32d042f1945Winson Chung
14628f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller    private int getAppropriateWidgetPage(int musicTransportState) {
1463358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock        // assumes at least one widget (besides camera + add)
146476017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka        if (mAppWidgetToShow != AppWidgetManager.INVALID_APPWIDGET_ID) {
146576017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka            final int childCount = mAppWidgetContainer.getChildCount();
146676017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka            for (int i = 0; i < childCount; i++) {
146776017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka                if (mAppWidgetContainer.getWidgetPageAt(i).getContentAppWidgetId()
146876017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka                        == mAppWidgetToShow) {
146976017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka                    return i;
147076017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka                }
147176017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka            }
147276017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka            mAppWidgetToShow = AppWidgetManager.INVALID_APPWIDGET_ID;
147376017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka        }
1474358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock        // if music playing, show transport
14758f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        if (musicTransportState == TRANSPORT_VISIBLE) {
1476358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock            if (DEBUG) Log.d(TAG, "Music playing, show transport");
14774894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller            return mAppWidgetContainer.getWidgetPageIndex(getOrCreateTransportControl());
1478358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock        }
1479358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock
14805f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock        // else show the right-most widget (except for camera)
1481358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock        int rightMost = mAppWidgetContainer.getChildCount() - 1;
14826cf53bb3a94ec5a6eebc96a315dac32d042f1945Winson Chung        if (mAppWidgetContainer.isCameraPage(rightMost)) {
1483358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock            rightMost--;
1484358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock        }
14855f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock        if (DEBUG) Log.d(TAG, "Show right-most page " + rightMost);
1486358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock        return rightMost;
1487358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock    }
1488358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock
148919a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller    private void enableUserSelectorIfNecessary() {
149026e6c2e44235428717d7152b9e6398649452f1d2Jim Miller        if (!UserManager.supportsMultipleUsers()) {
149126e6c2e44235428717d7152b9e6398649452f1d2Jim Miller            return; // device doesn't support multi-user mode
149226e6c2e44235428717d7152b9e6398649452f1d2Jim Miller        }
1493f6ab5f9e3e7562b6ebb61ac149eb3cf9b08c443fJim Miller        final UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
1494d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren        if (um == null) {
1495d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren            Throwable t = new Throwable();
1496d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren            t.fillInStackTrace();
1497d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren            Log.e(TAG, "user service is null.", t);
1498d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren            return;
1499d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren        }
150026e6c2e44235428717d7152b9e6398649452f1d2Jim Miller
15015f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock        // if there are multiple users, we need to enable to multi-user switcher
1502f6ab5f9e3e7562b6ebb61ac149eb3cf9b08c443fJim Miller        final List<UserInfo> users = um.getUsers(true);
1503d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren        if (users == null) {
1504d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren            Throwable t = new Throwable();
1505d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren            t.fillInStackTrace();
1506d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren            Log.e(TAG, "list of users is null.", t);
1507d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren            return;
1508d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren        }
150966b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen
1510f6ab5f9e3e7562b6ebb61ac149eb3cf9b08c443fJim Miller        final View multiUserView = findViewById(R.id.keyguard_user_selector);
1511f6ab5f9e3e7562b6ebb61ac149eb3cf9b08c443fJim Miller        if (multiUserView == null) {
1512f6ab5f9e3e7562b6ebb61ac149eb3cf9b08c443fJim Miller            Throwable t = new Throwable();
1513f6ab5f9e3e7562b6ebb61ac149eb3cf9b08c443fJim Miller            t.fillInStackTrace();
1514f6ab5f9e3e7562b6ebb61ac149eb3cf9b08c443fJim Miller            Log.e(TAG, "can't find user_selector in layout.", t);
1515f6ab5f9e3e7562b6ebb61ac149eb3cf9b08c443fJim Miller            return;
1516f6ab5f9e3e7562b6ebb61ac149eb3cf9b08c443fJim Miller        }
1517f6ab5f9e3e7562b6ebb61ac149eb3cf9b08c443fJim Miller
1518d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren        if (users.size() > 1) {
151991f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren            if (multiUserView instanceof KeyguardMultiUserSelectorView) {
1520f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren                mKeyguardMultiUserSelectorView = (KeyguardMultiUserSelectorView) multiUserView;
1521f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren                mKeyguardMultiUserSelectorView.setVisibility(View.VISIBLE);
1522f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren                mKeyguardMultiUserSelectorView.addUsers(users);
152391f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                UserSwitcherCallback callback = new UserSwitcherCallback() {
152491f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                    @Override
152591f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                    public void hideSecurityView(int duration) {
152691f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                        mSecurityViewContainer.animate().alpha(0).setDuration(duration);
152791f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                    }
152824b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen
152991f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                    @Override
153091f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                    public void showSecurityView() {
153191f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                        mSecurityViewContainer.setAlpha(1.0f);
153291f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                    }
15330a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen
153491f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                    @Override
153591f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                    public void showUnlockHint() {
153691f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                        if (mKeyguardSelectorView != null) {
153791f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                            mKeyguardSelectorView.showUsabilityHint();
153891f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                        }
15390ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller                    }
15400a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen
154191f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                    @Override
154291f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                    public void userActivity() {
154391f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                        if (mViewMediatorCallback != null) {
154491f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                            mViewMediatorCallback.userActivity();
154591f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                        }
154619a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                    }
154791f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                };
1548f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren                mKeyguardMultiUserSelectorView.setCallback(callback);
1549d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren            } else {
1550d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren                Throwable t = new Throwable();
1551d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren                t.fillInStackTrace();
1552d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren                if (multiUserView == null) {
1553d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren                    Log.e(TAG, "could not find the user_selector.", t);
1554d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren                } else {
1555d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren                    Log.e(TAG, "user_selector is the wrong type.", t);
1556d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren                }
155791f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren            }
155866b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen        }
155966b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen    }
156066b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen
1561dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    @Override
1562dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    public void cleanUp() {
1563128f27632343ed8ad8bba2d96f4ec69c0e369de7Adam Cohen        // Make sure we let go of all widgets and their package contexts promptly. If we don't do
1564128f27632343ed8ad8bba2d96f4ec69c0e369de7Adam Cohen        // this, and the associated application is uninstalled, it can cause a soft reboot.
1565128f27632343ed8ad8bba2d96f4ec69c0e369de7Adam Cohen        int count = mAppWidgetContainer.getChildCount();
1566128f27632343ed8ad8bba2d96f4ec69c0e369de7Adam Cohen        for (int i = 0; i < count; i++) {
1567128f27632343ed8ad8bba2d96f4ec69c0e369de7Adam Cohen            KeyguardWidgetFrame frame = mAppWidgetContainer.getWidgetPageAt(i);
1568128f27632343ed8ad8bba2d96f4ec69c0e369de7Adam Cohen            frame.removeAllViews();
1569128f27632343ed8ad8bba2d96f4ec69c0e369de7Adam Cohen        }
1570dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
1571dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
157295b005c196de2f99513da28fe9108b2dec200140Jim Miller    /**
157395b005c196de2f99513da28fe9108b2dec200140Jim Miller     * In general, we enable unlocking the insecure keyguard with the menu key. However, there are
157495b005c196de2f99513da28fe9108b2dec200140Jim Miller     * some cases where we wish to disable it, notably when the menu button placement or technology
157595b005c196de2f99513da28fe9108b2dec200140Jim Miller     * is prone to false positives.
157695b005c196de2f99513da28fe9108b2dec200140Jim Miller     *
157795b005c196de2f99513da28fe9108b2dec200140Jim Miller     * @return true if the menu key should be enabled
157895b005c196de2f99513da28fe9108b2dec200140Jim Miller     */
157995b005c196de2f99513da28fe9108b2dec200140Jim Miller    private static final String ENABLE_MENU_KEY_FILE = "/data/local/enable_menu_key";
158095b005c196de2f99513da28fe9108b2dec200140Jim Miller    private boolean shouldEnableMenuKey() {
158195b005c196de2f99513da28fe9108b2dec200140Jim Miller        final Resources res = getResources();
15825ecd81154fa039961f65bb4e36d18ac555b0d1d6Jim Miller        final boolean configDisabled = res.getBoolean(R.bool.config_disableMenuKeyInLockScreen);
158395b005c196de2f99513da28fe9108b2dec200140Jim Miller        final boolean isTestHarness = ActivityManager.isRunningInTestHarness();
158495b005c196de2f99513da28fe9108b2dec200140Jim Miller        final boolean fileOverride = (new File(ENABLE_MENU_KEY_FILE)).exists();
158595b005c196de2f99513da28fe9108b2dec200140Jim Miller        return !configDisabled || isTestHarness || fileOverride;
158695b005c196de2f99513da28fe9108b2dec200140Jim Miller    }
158795b005c196de2f99513da28fe9108b2dec200140Jim Miller
158876017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka    public void goToWidget(int appWidgetId) {
158976017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka        mAppWidgetToShow = appWidgetId;
159076017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka        mSwitchPageRunnable.run();
159176017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka    }
159276017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka
159375931e05470992d51d135d09031902fd1b3fdbc7Jim Miller    public boolean handleMenuKey() {
159475931e05470992d51d135d09031902fd1b3fdbc7Jim Miller        // The following enables the MENU key to work for testing automation
159575931e05470992d51d135d09031902fd1b3fdbc7Jim Miller        if (shouldEnableMenuKey()) {
159675931e05470992d51d135d09031902fd1b3fdbc7Jim Miller            showNextSecurityScreenOrFinish(false);
159775931e05470992d51d135d09031902fd1b3fdbc7Jim Miller            return true;
159875931e05470992d51d135d09031902fd1b3fdbc7Jim Miller        }
159975931e05470992d51d135d09031902fd1b3fdbc7Jim Miller        return false;
160075931e05470992d51d135d09031902fd1b3fdbc7Jim Miller    }
160175931e05470992d51d135d09031902fd1b3fdbc7Jim Miller
16020a34d9edf02954d83c2861a8c6836865f8fa00fbJim Miller    public boolean handleBackKey() {
160303eca859067ac0d4e419305de8ab0fdc03b4210fJohn Spurlock        if (mCurrentSecuritySelection == SecurityMode.Account) {
160403eca859067ac0d4e419305de8ab0fdc03b4210fJohn Spurlock            // go back to primary screen and re-disable back
160503eca859067ac0d4e419305de8ab0fdc03b4210fJohn Spurlock            setBackButtonEnabled(false);
160603eca859067ac0d4e419305de8ab0fdc03b4210fJohn Spurlock            showPrimarySecurityScreen(false /*turningOff*/);
160703eca859067ac0d4e419305de8ab0fdc03b4210fJohn Spurlock            return true;
160803eca859067ac0d4e419305de8ab0fdc03b4210fJohn Spurlock        }
16090a34d9edf02954d83c2861a8c6836865f8fa00fbJim Miller        if (mCurrentSecuritySelection != SecurityMode.None) {
16100a34d9edf02954d83c2861a8c6836865f8fa00fbJim Miller            mCallback.dismiss(false);
16110a34d9edf02954d83c2861a8c6836865f8fa00fbJim Miller            return true;
16120a34d9edf02954d83c2861a8c6836865f8fa00fbJim Miller        }
16130a34d9edf02954d83c2861a8c6836865f8fa00fbJim Miller        return false;
16140a34d9edf02954d83c2861a8c6836865f8fa00fbJim Miller    }
16150a34d9edf02954d83c2861a8c6836865f8fa00fbJim Miller
1616ad09bccfe4cc0a3075e97c0911a02b329023a34aCraig Mautner    /**
1617ad09bccfe4cc0a3075e97c0911a02b329023a34aCraig Mautner     *  Dismisses the keyguard by going to the next screen or making it gone.
1618ad09bccfe4cc0a3075e97c0911a02b329023a34aCraig Mautner     */
1619ad09bccfe4cc0a3075e97c0911a02b329023a34aCraig Mautner    public void dismiss() {
1620ad09bccfe4cc0a3075e97c0911a02b329023a34aCraig Mautner        showNextSecurityScreenOrFinish(false);
1621ad09bccfe4cc0a3075e97c0911a02b329023a34aCraig Mautner    }
16224eeb4f664ac6b5901a8e874dcf70c0382295f792Jim Miller
16234eeb4f664ac6b5901a8e874dcf70c0382295f792Jim Miller    public void showAssistant() {
16244eeb4f664ac6b5901a8e874dcf70c0382295f792Jim Miller        final Intent intent = ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
1625f9c5e0fe837a3090820da502ecaabc5accc00aceDianne Hackborn          .getAssistIntent(mContext, true, UserHandle.USER_CURRENT);
16264eeb4f664ac6b5901a8e874dcf70c0382295f792Jim Miller
16274eeb4f664ac6b5901a8e874dcf70c0382295f792Jim Miller        if (intent == null) return;
16284eeb4f664ac6b5901a8e874dcf70c0382295f792Jim Miller
16294eeb4f664ac6b5901a8e874dcf70c0382295f792Jim Miller        final ActivityOptions opts = ActivityOptions.makeCustomAnimation(mContext,
16304eeb4f664ac6b5901a8e874dcf70c0382295f792Jim Miller                R.anim.keyguard_action_assist_enter, R.anim.keyguard_action_assist_exit,
16314eeb4f664ac6b5901a8e874dcf70c0382295f792Jim Miller                getHandler(), null);
16324eeb4f664ac6b5901a8e874dcf70c0382295f792Jim Miller
16334eeb4f664ac6b5901a8e874dcf70c0382295f792Jim Miller        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
16344eeb4f664ac6b5901a8e874dcf70c0382295f792Jim Miller
16356ed3fcafdbdeda9a10a62bbd0e5997017e8e2635Daniel Sandler        mActivityLauncher.launchActivityWithAnimation(
16366ed3fcafdbdeda9a10a62bbd0e5997017e8e2635Daniel Sandler                intent, false, opts.toBundle(), null, null);
16374eeb4f664ac6b5901a8e874dcf70c0382295f792Jim Miller    }
1638dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller}
1639