KeyguardHostView.java revision f45bb403884f30ecb383698ef1bcb1c7dc1964b8
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        }
220f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller        if (!mSafeModeEnabled && !widgetsDisabled()) {
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
416f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller    private boolean widgetsDisabled() {
417f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller        boolean disabledByDpm =
418f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller                (mDisabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_WIDGETS_ALL) != 0;
419f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller        boolean disabledByUser = !mLockPatternUtils.getWidgetsEnabled();
420f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller        return disabledByDpm || disabledByUser;
42151117262c8fadb6d227d137e83ad66996b013141Jim Miller    }
42251117262c8fadb6d227d137e83ad66996b013141Jim Miller
42351117262c8fadb6d227d137e83ad66996b013141Jim Miller    private boolean cameraDisabledByDpm() {
42451117262c8fadb6d227d137e83ad66996b013141Jim Miller        return mCameraDisabled
42551117262c8fadb6d227d137e83ad66996b013141Jim Miller                || (mDisabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) != 0;
42651117262c8fadb6d227d137e83ad66996b013141Jim Miller    }
42751117262c8fadb6d227d137e83ad66996b013141Jim Miller
428e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller    private void updateSecurityViews() {
429e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        int children = mSecurityViewContainer.getChildCount();
430e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        for (int i = 0; i < children; i++) {
431e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            updateSecurityView(mSecurityViewContainer.getChildAt(i));
432e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        }
433e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller    }
434dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
435e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller    private void updateSecurityView(View view) {
436e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        if (view instanceof KeyguardSecurityView) {
437e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            KeyguardSecurityView ksv = (KeyguardSecurityView) view;
438e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            ksv.setKeyguardCallback(mCallback);
439e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            ksv.setLockPatternUtils(mLockPatternUtils);
440c0ae9e67ebe6f1298800feaed1b43e867139a904Chris Wren            if (mViewStateManager.isBouncing()) {
441c0ae9e67ebe6f1298800feaed1b43e867139a904Chris Wren                ksv.showBouncer(0);
442c0ae9e67ebe6f1298800feaed1b43e867139a904Chris Wren            } else {
443c0ae9e67ebe6f1298800feaed1b43e867139a904Chris Wren                ksv.hideBouncer(0);
444c0ae9e67ebe6f1298800feaed1b43e867139a904Chris Wren            }
445e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        } else {
446e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            Log.w(TAG, "View " + view + " is not a KeyguardSecurityView");
447dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
448dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
449dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
450dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    void setLockPatternUtils(LockPatternUtils utils) {
451dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        mSecurityModel.setLockPatternUtils(utils);
452dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        mLockPatternUtils = utils;
453e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        updateSecurityViews();
454dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
455dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
456dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    @Override
457dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    protected void onAttachedToWindow() {
458dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        super.onAttachedToWindow();
459a75a883fe9ea1790803148f0a561473073e3f264Jim Miller        mAppWidgetHost.startListening();
460efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen        KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mUpdateMonitorCallbacks);
4617221d3ae08cc2be922d26e5d491038512cb6c74dJim Miller    }
4627221d3ae08cc2be922d26e5d491038512cb6c74dJim Miller
463dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    @Override
464dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    protected void onDetachedFromWindow() {
465dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        super.onDetachedFromWindow();
466a75a883fe9ea1790803148f0a561473073e3f264Jim Miller        mAppWidgetHost.stopListening();
467efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen        KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mUpdateMonitorCallbacks);
468dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
469dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
470d6523da1ad7bae805a3dbea8d7b398d86cd3c181Jim Miller    void addWidget(AppWidgetHostView view, int pageIndex) {
471d6523da1ad7bae805a3dbea8d7b398d86cd3c181Jim Miller        mAppWidgetContainer.addWidget(view, pageIndex);
472dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
473dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
474838906b165e4d3cb2c512b2db344aa50cb5d4751Jim Miller    private KeyguardWidgetPager.Callbacks mWidgetCallbacks
475838906b165e4d3cb2c512b2db344aa50cb5d4751Jim Miller            = new KeyguardWidgetPager.Callbacks() {
476c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown        @Override
477c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown        public void userActivity() {
47808c83ef48880b98ec45dd83867a29852160a96ebAdam Cohen            KeyguardHostView.this.userActivity();
479c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown        }
480c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown
481c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown        @Override
482c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown        public void onUserActivityTimeoutChanged() {
48308c83ef48880b98ec45dd83867a29852160a96ebAdam Cohen            KeyguardHostView.this.onUserActivityTimeoutChanged();
484c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown        }
485eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka
486eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka        @Override
48740f8211e6849c4c7948d7fc19127f29f0cebbeb9Winson Chung        public void onAddView(View v) {
488fff5614caecb0d2944b1bc206aaab0d3acb17670Michael Jurka            if (!shouldEnableAddWidget()) {
4894752e7d1a9ff83d946890b0020de091f4346a7aeWinson Chung                mAppWidgetContainer.setAddWidgetEnabled(false);
49040f8211e6849c4c7948d7fc19127f29f0cebbeb9Winson Chung            }
4914752e7d1a9ff83d946890b0020de091f4346a7aeWinson Chung        }
49240f8211e6849c4c7948d7fc19127f29f0cebbeb9Winson Chung
49340f8211e6849c4c7948d7fc19127f29f0cebbeb9Winson Chung        @Override
49475b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka        public void onRemoveView(View v, boolean deletePermanently) {
49575b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka            if (deletePermanently) {
49675b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka                final int appWidgetId = ((KeyguardWidgetFrame) v).getContentAppWidgetId();
49775b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka                if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID &&
49875b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka                        appWidgetId != LockPatternUtils.ID_DEFAULT_STATUS_WIDGET) {
49975b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka                    mAppWidgetHost.deleteAppWidgetId(appWidgetId);
50075b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka                }
50175b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka            }
502eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka        }
5034752e7d1a9ff83d946890b0020de091f4346a7aeWinson Chung
5044752e7d1a9ff83d946890b0020de091f4346a7aeWinson Chung        @Override
5054752e7d1a9ff83d946890b0020de091f4346a7aeWinson Chung        public void onRemoveViewAnimationCompleted() {
506fff5614caecb0d2944b1bc206aaab0d3acb17670Michael Jurka            if (shouldEnableAddWidget()) {
5074752e7d1a9ff83d946890b0020de091f4346a7aeWinson Chung                mAppWidgetContainer.setAddWidgetEnabled(true);
5084752e7d1a9ff83d946890b0020de091f4346a7aeWinson Chung            }
5094752e7d1a9ff83d946890b0020de091f4346a7aeWinson Chung        }
510c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown    };
511c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown
512f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren    public void initializeSwitchingUserState(boolean switching) {
513f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren        if (!switching && mKeyguardMultiUserSelectorView != null) {
514f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren            mKeyguardMultiUserSelectorView.finalizeActiveUserView(false);
515f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren        }
516f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren    }
517f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren
51808c83ef48880b98ec45dd83867a29852160a96ebAdam Cohen    public void userActivity() {
51908c83ef48880b98ec45dd83867a29852160a96ebAdam Cohen        if (mViewMediatorCallback != null) {
52008c83ef48880b98ec45dd83867a29852160a96ebAdam Cohen            mViewMediatorCallback.userActivity();
52108c83ef48880b98ec45dd83867a29852160a96ebAdam Cohen        }
52208c83ef48880b98ec45dd83867a29852160a96ebAdam Cohen    }
52308c83ef48880b98ec45dd83867a29852160a96ebAdam Cohen
52408c83ef48880b98ec45dd83867a29852160a96ebAdam Cohen    public void onUserActivityTimeoutChanged() {
52508c83ef48880b98ec45dd83867a29852160a96ebAdam Cohen        if (mViewMediatorCallback != null) {
52608c83ef48880b98ec45dd83867a29852160a96ebAdam Cohen            mViewMediatorCallback.onUserActivityTimeoutChanged();
52708c83ef48880b98ec45dd83867a29852160a96ebAdam Cohen        }
52808c83ef48880b98ec45dd83867a29852160a96ebAdam Cohen    }
52908c83ef48880b98ec45dd83867a29852160a96ebAdam Cohen
530c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown    @Override
531c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown    public long getUserActivityTimeout() {
532c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown        // Currently only considering user activity timeouts needed by widgets.
533c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown        // Could also take into account longer timeouts for certain security views.
534838906b165e4d3cb2c512b2db344aa50cb5d4751Jim Miller        if (mAppWidgetContainer != null) {
535838906b165e4d3cb2c512b2db344aa50cb5d4751Jim Miller            return mAppWidgetContainer.getUserActivityTimeout();
536c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown        }
537c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown        return -1;
538c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown    }
539c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown
540dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    private KeyguardSecurityCallback mCallback = new KeyguardSecurityCallback() {
541dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
542dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        public void userActivity(long timeout) {
5437def1db03943251fe8cb57ec514722026425479eCraig Mautner            if (mViewMediatorCallback != null) {
5443dc524bc31a1578693ca958ef442dfa092b7aa7fJeff Brown                mViewMediatorCallback.userActivity(timeout);
5457def1db03943251fe8cb57ec514722026425479eCraig Mautner            }
546dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
547dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
548dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        public void dismiss(boolean authenticated) {
549dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            showNextSecurityScreenOrFinish(authenticated);
550dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
551dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
552dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        public boolean isVerifyUnlockOnly() {
553258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            return mIsVerifyUnlockOnly;
554dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
555dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
556dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        public void reportSuccessfulUnlockAttempt() {
557258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            KeyguardUpdateMonitor.getInstance(mContext).clearFailedUnlockAttempts();
5587641506e3cc493ac4e6f5037fd76516754e61c6eJim Miller            mLockPatternUtils.reportSuccessfulPasswordAttempt();
559dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
560dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
561dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        public void reportFailedUnlockAttempt() {
5627641506e3cc493ac4e6f5037fd76516754e61c6eJim Miller            if (mCurrentSecuritySelection == SecurityMode.Biometric) {
5637641506e3cc493ac4e6f5037fd76516754e61c6eJim Miller                KeyguardUpdateMonitor.getInstance(mContext).reportFailedBiometricUnlockAttempt();
5647641506e3cc493ac4e6f5037fd76516754e61c6eJim Miller            } else {
5657641506e3cc493ac4e6f5037fd76516754e61c6eJim Miller                KeyguardHostView.this.reportFailedUnlockAttempt();
5667641506e3cc493ac4e6f5037fd76516754e61c6eJim Miller            }
567dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
568dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
569dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        public int getFailedAttempts() {
570258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            return KeyguardUpdateMonitor.getInstance(mContext).getFailedUnlockAttempts();
571dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
572dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
573258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        @Override
574258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        public void showBackupSecurity() {
5750ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller            KeyguardHostView.this.showBackupSecurityScreen();
576dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
577dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
5785f75aa15d7c1c5ea1c1eecd95bf2bb0920173eb2Jim Miller        @Override
57934c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock        public void setOnDismissAction(OnDismissAction action) {
58034c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock            KeyguardHostView.this.setOnDismissAction(action);
5815f75aa15d7c1c5ea1c1eecd95bf2bb0920173eb2Jim Miller        }
5825f75aa15d7c1c5ea1c1eecd95bf2bb0920173eb2Jim Miller
583dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    };
584dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
585258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    private void showDialog(String title, String message) {
586258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        final AlertDialog dialog = new AlertDialog.Builder(mContext)
587258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            .setTitle(title)
588258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            .setMessage(message)
5895ecd81154fa039961f65bb4e36d18ac555b0d1d6Jim Miller            .setNeutralButton(R.string.ok, null)
590258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            .create();
591258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        if (!(mContext instanceof Activity)) {
592258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
593258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        }
594258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        dialog.show();
595258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    }
596258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
597258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    private void showTimeoutDialog() {
598258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        int timeoutInSeconds = (int) LockPatternUtils.FAILED_ATTEMPT_TIMEOUT_MS / 1000;
599258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        int messageId = 0;
600258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
601258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        switch (mSecurityModel.getSecurityMode()) {
602258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            case Pattern:
603258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                messageId = R.string.kg_too_many_failed_pattern_attempts_dialog_message;
604258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                break;
60569bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler            case PIN:
60669bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler                messageId = R.string.kg_too_many_failed_pin_attempts_dialog_message;
60769bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler                break;
60869bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler            case Password:
60969bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler                messageId = R.string.kg_too_many_failed_password_attempts_dialog_message;
610258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                break;
611258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        }
612258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
613258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        if (messageId != 0) {
614258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            final String message = mContext.getString(messageId,
615258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                    KeyguardUpdateMonitor.getInstance(mContext).getFailedUnlockAttempts(),
616258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                    timeoutInSeconds);
617258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            showDialog(null, message);
618258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        }
619258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    }
620258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
621258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    private void showAlmostAtWipeDialog(int attempts, int remaining) {
622258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        int timeoutInSeconds = (int) LockPatternUtils.FAILED_ATTEMPT_TIMEOUT_MS / 1000;
623258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        String message = mContext.getString(R.string.kg_failed_attempts_almost_at_wipe,
624258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                attempts, remaining);
625258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        showDialog(null, message);
626258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    }
627258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
628258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    private void showWipeDialog(int attempts) {
629258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        String message = mContext.getString(R.string.kg_failed_attempts_now_wiping, attempts);
630258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        showDialog(null, message);
631258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    }
632258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
633258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    private void showAlmostAtAccountLoginDialog() {
634258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        final int timeoutInSeconds = (int) LockPatternUtils.FAILED_ATTEMPT_TIMEOUT_MS / 1000;
635258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        final int count = LockPatternUtils.FAILED_ATTEMPTS_BEFORE_RESET
636258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                - LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT;
637258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        String message = mContext.getString(R.string.kg_failed_attempts_almost_at_login,
638258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                count, LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT, timeoutInSeconds);
639258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        showDialog(null, message);
640258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    }
641258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
642258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    private void reportFailedUnlockAttempt() {
643258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        final KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(mContext);
644258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        final int failedAttempts = monitor.getFailedUnlockAttempts() + 1; // +1 for this time
645258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
646258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        if (DEBUG) Log.d(TAG, "reportFailedPatternAttempt: #" + failedAttempts);
647258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
648258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        SecurityMode mode = mSecurityModel.getSecurityMode();
649258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        final boolean usingPattern = mode == KeyguardSecurityModel.SecurityMode.Pattern;
650258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
651258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        final int failedAttemptsBeforeWipe = mLockPatternUtils.getDevicePolicyManager()
652599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                .getMaximumFailedPasswordsForWipe(null, mLockPatternUtils.getCurrentUser());
653258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
654258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        final int failedAttemptWarning = LockPatternUtils.FAILED_ATTEMPTS_BEFORE_RESET
655258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                - LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT;
656258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
657258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        final int remainingBeforeWipe = failedAttemptsBeforeWipe > 0 ?
658258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                (failedAttemptsBeforeWipe - failedAttempts)
659258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                : Integer.MAX_VALUE; // because DPM returns 0 if no restriction
660258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
66108b2b6bfe2550b65c68ad7b4bef8283f1ff17561Jim Miller        boolean showTimeout = false;
662258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        if (remainingBeforeWipe < LockPatternUtils.FAILED_ATTEMPTS_BEFORE_WIPE_GRACE) {
663258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            // If we reach this code, it means the user has installed a DevicePolicyManager
664258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            // that requests device wipe after N attempts.  Once we get below the grace
665258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            // period, we'll post this dialog every time as a clear warning until the
666258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            // bombshell hits and the device is wiped.
667258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            if (remainingBeforeWipe > 0) {
668258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                showAlmostAtWipeDialog(failedAttempts, remainingBeforeWipe);
669258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            } else {
670258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                // Too many attempts. The device will be wiped shortly.
671258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                Slog.i(TAG, "Too many unlock attempts; device will be wiped!");
672258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                showWipeDialog(failedAttempts);
673258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            }
674258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        } else {
67508b2b6bfe2550b65c68ad7b4bef8283f1ff17561Jim Miller            showTimeout =
676258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                (failedAttempts % LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT) == 0;
677258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            if (usingPattern && mEnableFallback) {
678258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                if (failedAttempts == failedAttemptWarning) {
679258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                    showAlmostAtAccountLoginDialog();
680258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                    showTimeout = false; // don't show both dialogs
681258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                } else if (failedAttempts >= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_RESET) {
682258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                    mLockPatternUtils.setPermanentlyLocked(true);
683e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller                    showSecurityScreen(SecurityMode.Account);
684258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                    // don't show timeout dialog because we show account unlock screen next
685258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                    showTimeout = false;
686258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                }
687258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            }
688258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        }
689258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        monitor.reportFailedUnlockAttempt();
690258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        mLockPatternUtils.reportFailedPasswordAttempt();
69108b2b6bfe2550b65c68ad7b4bef8283f1ff17561Jim Miller        if (showTimeout) {
69208b2b6bfe2550b65c68ad7b4bef8283f1ff17561Jim Miller            showTimeoutDialog();
69308b2b6bfe2550b65c68ad7b4bef8283f1ff17561Jim Miller        }
694258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    }
695258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
696258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    /**
6970ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller     * Shows the primary security screen for the user. This will be either the multi-selector
6980ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller     * or the user's security method.
6990ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller     * @param turningOff true if the device is being turned off
7000ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller     */
7010ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller    void showPrimarySecurityScreen(boolean turningOff) {
7020ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller        SecurityMode securityMode = mSecurityModel.getSecurityMode();
7030ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller        if (DEBUG) Log.v(TAG, "showPrimarySecurityScreen(turningOff=" + turningOff + ")");
704078f5919a9584cc3f1c7eb3a78862bfa40396de9Brian Colonna        if (!turningOff &&
705078f5919a9584cc3f1c7eb3a78862bfa40396de9Brian Colonna                KeyguardUpdateMonitor.getInstance(mContext).isAlternateUnlockEnabled()) {
7060ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller            // If we're not turning off, then allow biometric alternate.
7070ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller            // We'll reload it when the device comes back on.
7080ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller            securityMode = mSecurityModel.getAlternateFor(securityMode);
7090ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller        }
7100ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller        showSecurityScreen(securityMode);
7110ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller    }
71268c2489457631f733f542e14058c6d1274c203deJim Miller
7130ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller    /**
714258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller     * Shows the backup security screen for the current security mode.  This could be used for
715258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller     * password recovery screens but is currently only used for pattern unlock to show the
716258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller     * account unlock screen and biometric unlock to show the user's normal unlock.
717258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller     */
7180ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller    private void showBackupSecurityScreen() {
71961413b5ed215accd7b4f3eaf80edeab2f330aa49Danielle Millett        if (DEBUG) Log.d(TAG, "showBackupSecurity()");
72063f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        SecurityMode backup = mSecurityModel.getBackupSecurityMode(mCurrentSecuritySelection);
72163f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        showSecurityScreen(backup);
722258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    }
723258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
7240a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen    public boolean showNextSecurityScreenIfPresent() {
7250a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen        SecurityMode securityMode = mSecurityModel.getSecurityMode();
7260a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen        // Allow an alternate, such as biometric unlock
7270a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen        securityMode = mSecurityModel.getAlternateFor(securityMode);
7280a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen        if (SecurityMode.None == securityMode) {
7290a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen            return false;
7300a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen        } else {
7310a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen            showSecurityScreen(securityMode); // switch to the alternate security view
7320a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen            return true;
7330a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen        }
7340a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen    }
7350a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen
736258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    private void showNextSecurityScreenOrFinish(boolean authenticated) {
73761413b5ed215accd7b4f3eaf80edeab2f330aa49Danielle Millett        if (DEBUG) Log.d(TAG, "showNextSecurityScreenOrFinish(" + authenticated + ")");
738dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        boolean finish = false;
739e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        if (SecurityMode.None == mCurrentSecuritySelection) {
740258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            SecurityMode securityMode = mSecurityModel.getSecurityMode();
741258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            // Allow an alternate, such as biometric unlock
742000464ac012471d301c6e48a8228291519915e17Jim Miller            securityMode = mSecurityModel.getAlternateFor(securityMode);
743e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            if (SecurityMode.None == securityMode) {
744dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                finish = true; // no security required
745dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            } else {
746e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller                showSecurityScreen(securityMode); // switch to the alternate security view
747dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            }
748dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        } else if (authenticated) {
749e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            switch (mCurrentSecuritySelection) {
750e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller                case Pattern:
751e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller                case Password:
75269bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler                case PIN:
753e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller                case Account:
754e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller                case Biometric:
7554b09dd31fb1cefcaee87e7a206f22ba31527e250Jim Miller                    finish = true;
7564b09dd31fb1cefcaee87e7a206f22ba31527e250Jim Miller                    break;
7574b09dd31fb1cefcaee87e7a206f22ba31527e250Jim Miller
758e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller                case SimPin:
759e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller                case SimPuk:
7604b09dd31fb1cefcaee87e7a206f22ba31527e250Jim Miller                    // Shortcut for SIM PIN/PUK to go to directly to user's security screen or home
7614b09dd31fb1cefcaee87e7a206f22ba31527e250Jim Miller                    SecurityMode securityMode = mSecurityModel.getSecurityMode();
7624b09dd31fb1cefcaee87e7a206f22ba31527e250Jim Miller                    if (securityMode != SecurityMode.None) {
763e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller                        showSecurityScreen(securityMode);
7644b09dd31fb1cefcaee87e7a206f22ba31527e250Jim Miller                    } else {
7654b09dd31fb1cefcaee87e7a206f22ba31527e250Jim Miller                        finish = true;
7664b09dd31fb1cefcaee87e7a206f22ba31527e250Jim Miller                    }
7674b09dd31fb1cefcaee87e7a206f22ba31527e250Jim Miller                    break;
7684b09dd31fb1cefcaee87e7a206f22ba31527e250Jim Miller
7694b09dd31fb1cefcaee87e7a206f22ba31527e250Jim Miller                default:
7700ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller                    Log.v(TAG, "Bad security screen " + mCurrentSecuritySelection + ", fail safe");
7710ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller                    showPrimarySecurityScreen(false);
7724b09dd31fb1cefcaee87e7a206f22ba31527e250Jim Miller                    break;
773dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            }
774dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        } else {
7750ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller            showPrimarySecurityScreen(false);
776dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
777dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        if (finish) {
7780ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller            // If the alternate unlock was suppressed, it can now be safely
7790ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller            // enabled because the user has left keyguard.
7800ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller            KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(true);
78168c2489457631f733f542e14058c6d1274c203deJim Miller
782dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            // If there's a pending runnable because the user interacted with a widget
783dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            // and we're leaving keyguard, then run it.
78434c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock            boolean deferKeyguardDone = false;
78534c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock            if (mDismissAction != null) {
78634c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock                deferKeyguardDone = mDismissAction.onDismiss();
78734c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock                mDismissAction = null;
788dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            }
7897def1db03943251fe8cb57ec514722026425479eCraig Mautner            if (mViewMediatorCallback != null) {
79034c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock                if (deferKeyguardDone) {
79134c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock                    mViewMediatorCallback.keyguardDonePending();
79234c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock                } else {
79334c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock                    mViewMediatorCallback.keyguardDone(true);
79434c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock                }
7957def1db03943251fe8cb57ec514722026425479eCraig Mautner            }
796b5f3b707a7010e8d867da9342ea87cf0a1679692Jim Miller        } else {
797b5f3b707a7010e8d867da9342ea87cf0a1679692Jim Miller            mViewStateManager.showBouncer(true);
798dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
799dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
800dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
801dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    private OnClickHandler mOnClickHandler = new OnClickHandler() {
802dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        @Override
803dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        public boolean onClickHandler(final View view,
804dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                final android.app.PendingIntent pendingIntent,
805dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                final Intent fillInIntent) {
806dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            if (pendingIntent.isActivity()) {
80734c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock                setOnDismissAction(new OnDismissAction() {
80834c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock                    public boolean onDismiss() {
809dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                        try {
810dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                              // TODO: Unregister this handler if PendingIntent.FLAG_ONE_SHOT?
811dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                              Context context = view.getContext();
812dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                              ActivityOptions opts = ActivityOptions.makeScaleUpAnimation(view,
813dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                                      0, 0,
814dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                                      view.getMeasuredWidth(), view.getMeasuredHeight());
815dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                              context.startIntentSender(
816dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                                      pendingIntent.getIntentSender(), fillInIntent,
817dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                                      Intent.FLAG_ACTIVITY_NEW_TASK,
818dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                                      Intent.FLAG_ACTIVITY_NEW_TASK, 0, opts.toBundle());
81934c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock                        } catch (IntentSender.SendIntentException e) {
82034c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock                            android.util.Log.e(TAG, "Cannot send pending intent: ", e);
82134c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock                        } catch (Exception e) {
82234c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock                            android.util.Log.e(TAG, "Cannot send pending intent due to " +
82334c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock                                    "unknown exception: ", e);
82434c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock                        }
82534c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock                        return false;
826dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                    }
8275f75aa15d7c1c5ea1c1eecd95bf2bb0920173eb2Jim Miller                });
828dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
82908898375fba7cc776857ebf0846c7183563a300fJim Miller                if (mViewStateManager.isChallengeShowing()) {
83008898375fba7cc776857ebf0846c7183563a300fJim Miller                    mViewStateManager.showBouncer(true);
83108898375fba7cc776857ebf0846c7183563a300fJim Miller                } else {
83208898375fba7cc776857ebf0846c7183563a300fJim Miller                    mCallback.dismiss(false);
83308898375fba7cc776857ebf0846c7183563a300fJim Miller                }
834dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                return true;
835dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            } else {
836dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                return super.onClickHandler(view, pendingIntent, fillInIntent);
837dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            }
838dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        };
839dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    };
840dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
84163f9b81795559443e0376985f8aaaa97a359ef94Jim Miller    // Used to ignore callbacks from methods that are no longer current (e.g. face unlock).
84263f9b81795559443e0376985f8aaaa97a359ef94Jim Miller    // This avoids unwanted asynchronous events from messing with the state.
84363f9b81795559443e0376985f8aaaa97a359ef94Jim Miller    private KeyguardSecurityCallback mNullCallback = new KeyguardSecurityCallback() {
84463f9b81795559443e0376985f8aaaa97a359ef94Jim Miller
84563f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        @Override
84663f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        public void userActivity(long timeout) {
84763f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        }
84863f9b81795559443e0376985f8aaaa97a359ef94Jim Miller
84963f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        @Override
85063f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        public void showBackupSecurity() {
85163f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        }
85263f9b81795559443e0376985f8aaaa97a359ef94Jim Miller
85363f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        @Override
85434c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock        public void setOnDismissAction(OnDismissAction action) {
85563f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        }
85663f9b81795559443e0376985f8aaaa97a359ef94Jim Miller
85763f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        @Override
85863f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        public void reportSuccessfulUnlockAttempt() {
85963f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        }
86063f9b81795559443e0376985f8aaaa97a359ef94Jim Miller
86163f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        @Override
86263f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        public void reportFailedUnlockAttempt() {
86363f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        }
86463f9b81795559443e0376985f8aaaa97a359ef94Jim Miller
86563f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        @Override
86663f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        public boolean isVerifyUnlockOnly() {
86763f9b81795559443e0376985f8aaaa97a359ef94Jim Miller            return false;
86863f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        }
86963f9b81795559443e0376985f8aaaa97a359ef94Jim Miller
87063f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        @Override
87163f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        public int getFailedAttempts() {
87263f9b81795559443e0376985f8aaaa97a359ef94Jim Miller            return 0;
87363f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        }
87463f9b81795559443e0376985f8aaaa97a359ef94Jim Miller
87563f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        @Override
87663f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        public void dismiss(boolean securityVerified) {
87763f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        }
87863f9b81795559443e0376985f8aaaa97a359ef94Jim Miller    };
87963f9b81795559443e0376985f8aaaa97a359ef94Jim Miller
8805f75aa15d7c1c5ea1c1eecd95bf2bb0920173eb2Jim Miller    /**
88134c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock     * Sets an action to perform when keyguard is dismissed.
88234c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock     * @param action
8835f75aa15d7c1c5ea1c1eecd95bf2bb0920173eb2Jim Miller     */
88434c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock    protected void setOnDismissAction(OnDismissAction action) {
88534c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock        mDismissAction = action;
8865f75aa15d7c1c5ea1c1eecd95bf2bb0920173eb2Jim Miller    }
8875f75aa15d7c1c5ea1c1eecd95bf2bb0920173eb2Jim Miller
888e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller    private KeyguardSecurityView getSecurityView(SecurityMode securityMode) {
889e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        final int securityViewIdForMode = getSecurityViewIdForMode(securityMode);
890e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        KeyguardSecurityView view = null;
891e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        final int children = mSecurityViewContainer.getChildCount();
892dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        for (int child = 0; child < children; child++) {
893e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            if (mSecurityViewContainer.getChildAt(child).getId() == securityViewIdForMode) {
894e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller                view = ((KeyguardSecurityView)mSecurityViewContainer.getChildAt(child));
895e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller                break;
896dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            }
897dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
89863f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        int layoutId = getLayoutIdFor(securityMode);
89963f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        if (view == null && layoutId != 0) {
900e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            final LayoutInflater inflater = LayoutInflater.from(mContext);
901bdffd5c3a18e67443ebbd16d4f0349d0728285b1Jim Miller            if (DEBUG) Log.v(TAG, "inflating id = " + layoutId);
9029799714f6c69efe50e21a6073b879140e5e792b7Adam Powell            View v = inflater.inflate(layoutId, mSecurityViewContainer, false);
903e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            mSecurityViewContainer.addView(v);
904e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            updateSecurityView(v);
9050b728244dc87b4a453f2191c2cb37a86e91aee0aJim Miller            view = (KeyguardSecurityView)v;
9060ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller        }
9070ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller
9080ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller        if (view instanceof KeyguardSelectorView) {
9090ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller            KeyguardSelectorView selectorView = (KeyguardSelectorView) view;
9100ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller            View carrierText = selectorView.findViewById(R.id.keyguard_selector_fade_container);
9110ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller            selectorView.setCarrierArea(carrierText);
9120ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller        }
91368c2489457631f733f542e14058c6d1274c203deJim Miller
914e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        return view;
915dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
916dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
917258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    /**
918258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller     * Switches to the given security view unless it's already being shown, in which case
919258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller     * this is a no-op.
920258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller     *
921e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller     * @param securityMode
922258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller     */
923e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller    private void showSecurityScreen(SecurityMode securityMode) {
92468c2489457631f733f542e14058c6d1274c203deJim Miller        if (DEBUG) Log.d(TAG, "showSecurityScreen(" + securityMode + ")");
92568c2489457631f733f542e14058c6d1274c203deJim Miller
926e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        if (securityMode == mCurrentSecuritySelection) return;
927dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
928e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        KeyguardSecurityView oldView = getSecurityView(mCurrentSecuritySelection);
929e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        KeyguardSecurityView newView = getSecurityView(securityMode);
930dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
931a71984f3da47c6e6e3164c170735362a3222d3adJim Miller        // Enter full screen mode if we're in SIM or Account screen
9325ecd81154fa039961f65bb4e36d18ac555b0d1d6Jim Miller        boolean fullScreenEnabled = getResources().getBoolean(R.bool.kg_sim_puk_account_full_screen);
933a71984f3da47c6e6e3164c170735362a3222d3adJim Miller        boolean isSimOrAccount = securityMode == SecurityMode.SimPin
934a71984f3da47c6e6e3164c170735362a3222d3adJim Miller                || securityMode == SecurityMode.SimPuk
935a71984f3da47c6e6e3164c170735362a3222d3adJim Miller                || securityMode == SecurityMode.Account;
936a71984f3da47c6e6e3164c170735362a3222d3adJim Miller        mAppWidgetContainer.setVisibility(
937a71984f3da47c6e6e3164c170735362a3222d3adJim Miller                isSimOrAccount && fullScreenEnabled ? View.GONE : View.VISIBLE);
938a71984f3da47c6e6e3164c170735362a3222d3adJim Miller
9392cacda5fc92a28a44a37e25b96093a9cc1346080Jim Miller        if (mSlidingChallengeLayout != null) {
9402cacda5fc92a28a44a37e25b96093a9cc1346080Jim Miller            mSlidingChallengeLayout.setChallengeInteractive(!fullScreenEnabled);
9412cacda5fc92a28a44a37e25b96093a9cc1346080Jim Miller        }
9422cacda5fc92a28a44a37e25b96093a9cc1346080Jim Miller
943dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        // Emulate Activity life cycle
94463f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        if (oldView != null) {
94563f9b81795559443e0376985f8aaaa97a359ef94Jim Miller            oldView.onPause();
94663f9b81795559443e0376985f8aaaa97a359ef94Jim Miller            oldView.setKeyguardCallback(mNullCallback); // ignore requests from old view
94763f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        }
948a042ac90640c0c3fd3c5349083b86bbfd6319b64Chris Wren        newView.onResume(KeyguardSecurityView.VIEW_REVEALED);
94963f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        newView.setKeyguardCallback(mCallback);
950dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
951cd03a26f4f5663b40d4679de102519ccc163fa10Craig Mautner        final boolean needsInput = newView.needsInput();
9527def1db03943251fe8cb57ec514722026425479eCraig Mautner        if (mViewMediatorCallback != null) {
953cd03a26f4f5663b40d4679de102519ccc163fa10Craig Mautner            mViewMediatorCallback.setNeedsInput(needsInput);
9547def1db03943251fe8cb57ec514722026425479eCraig Mautner        }
955dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
956dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        // Find and show this child.
957e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        final int childCount = mSecurityViewContainer.getChildCount();
9584b09dd31fb1cefcaee87e7a206f22ba31527e250Jim Miller
95922ae05d50c7011b389a5dba7a2f717e407328bf8Jim Miller        mSecurityViewContainer.setInAnimation(
96022ae05d50c7011b389a5dba7a2f717e407328bf8Jim Miller                AnimationUtils.loadAnimation(mContext, R.anim.keyguard_security_fade_in));
96122ae05d50c7011b389a5dba7a2f717e407328bf8Jim Miller        mSecurityViewContainer.setOutAnimation(
96222ae05d50c7011b389a5dba7a2f717e407328bf8Jim Miller                AnimationUtils.loadAnimation(mContext, R.anim.keyguard_security_fade_out));
963e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        final int securityViewIdForMode = getSecurityViewIdForMode(securityMode);
964dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        for (int i = 0; i < childCount; i++) {
965e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            if (mSecurityViewContainer.getChildAt(i).getId() == securityViewIdForMode) {
966e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller                mSecurityViewContainer.setDisplayedChild(i);
967dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                break;
968dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            }
969dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
970258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
971e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        if (securityMode == SecurityMode.None) {
972e23ab8b1acea211762f1d0c4202f73a9f7700bb5Jim Miller            // Discard current runnable if we're switching back to the selector view
97334c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock            setOnDismissAction(null);
97468c2489457631f733f542e14058c6d1274c203deJim Miller        }
97503eca859067ac0d4e419305de8ab0fdc03b4210fJohn Spurlock        if (securityMode == SecurityMode.Account && !mLockPatternUtils.isPermanentlyLocked()) {
97603eca859067ac0d4e419305de8ab0fdc03b4210fJohn Spurlock            // we're showing account as a backup, provide a way to get back to primary
97703eca859067ac0d4e419305de8ab0fdc03b4210fJohn Spurlock            setBackButtonEnabled(true);
97803eca859067ac0d4e419305de8ab0fdc03b4210fJohn Spurlock        }
979e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        mCurrentSecuritySelection = securityMode;
980dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
981dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
982dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    @Override
983dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    public void onScreenTurnedOn() {
984358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock        if (DEBUG) Log.d(TAG, "screen on, instance " + Integer.toHexString(hashCode()));
9850ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller        showPrimarySecurityScreen(false);
986a042ac90640c0c3fd3c5349083b86bbfd6319b64Chris Wren        getSecurityView(mCurrentSecuritySelection).onResume(KeyguardSecurityView.SCREEN_ON);
987d03a5558350cb6adff68aaf97ad4ee946bcd91a1Jim Miller
988d03a5558350cb6adff68aaf97ad4ee946bcd91a1Jim Miller        // This is a an attempt to fix bug 7137389 where the device comes back on but the entire
989d03a5558350cb6adff68aaf97ad4ee946bcd91a1Jim Miller        // layout is blank but forcing a layout causes it to reappear (e.g. with with
990d03a5558350cb6adff68aaf97ad4ee946bcd91a1Jim Miller        // hierarchyviewer).
991d03a5558350cb6adff68aaf97ad4ee946bcd91a1Jim Miller        requestLayout();
9926fb841fa219eaae3e87f2fdc05e105d7a1813c42Adam Cohen
9936fb841fa219eaae3e87f2fdc05e105d7a1813c42Adam Cohen        if (mViewStateManager != null) {
9946fb841fa219eaae3e87f2fdc05e105d7a1813c42Adam Cohen            mViewStateManager.showUsabilityHints();
9956fb841fa219eaae3e87f2fdc05e105d7a1813c42Adam Cohen        }
996147f9568afe645d9bfb91f3037f5336d8a2482ccJim Miller        requestFocus();
997dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
998dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
999dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    @Override
1000dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    public void onScreenTurnedOff() {
1001dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock        if (DEBUG) Log.d(TAG, String.format("screen off, instance %s at %s",
1002dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock                Integer.toHexString(hashCode()), SystemClock.uptimeMillis()));
1003078f5919a9584cc3f1c7eb3a78862bfa40396de9Brian Colonna        // Once the screen turns off, we no longer consider this to be first boot and we want the
1004078f5919a9584cc3f1c7eb3a78862bfa40396de9Brian Colonna        // biometric unlock to start next time keyguard is shown.
1005078f5919a9584cc3f1c7eb3a78862bfa40396de9Brian Colonna        KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(true);
10061413889565bc1b9d5d5fb73302460a4f25f4a8c0Michael Jurka        // We use mAppWidgetToShow to show a particular widget after you add it-- once the screen
10071413889565bc1b9d5d5fb73302460a4f25f4a8c0Michael Jurka        // turns off we reset that behavior
10081413889565bc1b9d5d5fb73302460a4f25f4a8c0Michael Jurka        clearAppWidgetToShow();
100967a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        checkAppWidgetConsistency();
10100ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller        showPrimarySecurityScreen(true);
1011e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        getSecurityView(mCurrentSecuritySelection).onPause();
1012dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock        CameraWidgetFrame cameraPage = findCameraPage();
1013dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock        if (cameraPage != null) {
1014dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock            cameraPage.onScreenTurnedOff();
1015dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock        }
1016147f9568afe645d9bfb91f3037f5336d8a2482ccJim Miller        clearFocus();
1017dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
1018dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
10191413889565bc1b9d5d5fb73302460a4f25f4a8c0Michael Jurka    public void clearAppWidgetToShow() {
10201413889565bc1b9d5d5fb73302460a4f25f4a8c0Michael Jurka        mAppWidgetToShow = AppWidgetManager.INVALID_APPWIDGET_ID;
10211413889565bc1b9d5d5fb73302460a4f25f4a8c0Michael Jurka    }
10221413889565bc1b9d5d5fb73302460a4f25f4a8c0Michael Jurka
1023dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    @Override
1024dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    public void show() {
1025086977094d96ab9352432e0941a05b09cefc92acJim Miller        if (DEBUG) Log.d(TAG, "show()");
1026086977094d96ab9352432e0941a05b09cefc92acJim Miller        showPrimarySecurityScreen(false);
1027dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
1028dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
1029dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    @Override
1030dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    public void verifyUnlock() {
1031dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        SecurityMode securityMode = mSecurityModel.getSecurityMode();
1032dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        if (securityMode == KeyguardSecurityModel.SecurityMode.None) {
10337def1db03943251fe8cb57ec514722026425479eCraig Mautner            if (mViewMediatorCallback != null) {
10347def1db03943251fe8cb57ec514722026425479eCraig Mautner                mViewMediatorCallback.keyguardDone(true);
10357def1db03943251fe8cb57ec514722026425479eCraig Mautner            }
1036dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        } else if (securityMode != KeyguardSecurityModel.SecurityMode.Pattern
103769bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler                && securityMode != KeyguardSecurityModel.SecurityMode.PIN
1038dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                && securityMode != KeyguardSecurityModel.SecurityMode.Password) {
1039dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            // can only verify unlock when in pattern/password mode
10407def1db03943251fe8cb57ec514722026425479eCraig Mautner            if (mViewMediatorCallback != null) {
10417def1db03943251fe8cb57ec514722026425479eCraig Mautner                mViewMediatorCallback.keyguardDone(false);
10427def1db03943251fe8cb57ec514722026425479eCraig Mautner            }
1043dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        } else {
1044dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            // otherwise, go to the unlock screen, see if they can verify it
1045dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            mIsVerifyUnlockOnly = true;
1046e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            showSecurityScreen(securityMode);
1047dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
1048dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
1049dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
1050dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    private int getSecurityViewIdForMode(SecurityMode securityMode) {
1051dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        switch (securityMode) {
1052e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            case None: return R.id.keyguard_selector_view;
1053e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            case Pattern: return R.id.keyguard_pattern_view;
105469bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler            case PIN: return R.id.keyguard_pin_view;
1055e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            case Password: return R.id.keyguard_password_view;
1056e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            case Biometric: return R.id.keyguard_face_unlock_view;
1057e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            case Account: return R.id.keyguard_account_view;
1058e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            case SimPin: return R.id.keyguard_sim_pin_view;
1059e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            case SimPuk: return R.id.keyguard_sim_puk_view;
1060dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
1061dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        return 0;
1062dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
1063dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
1064e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller    private int getLayoutIdFor(SecurityMode securityMode) {
1065e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        switch (securityMode) {
1066e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            case None: return R.layout.keyguard_selector_view;
1067e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            case Pattern: return R.layout.keyguard_pattern_view;
106869bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler            case PIN: return R.layout.keyguard_pin_view;
1069e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            case Password: return R.layout.keyguard_password_view;
1070e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            case Biometric: return R.layout.keyguard_face_unlock_view;
1071e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            case Account: return R.layout.keyguard_account_view;
1072e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            case SimPin: return R.layout.keyguard_sim_pin_view;
1073e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            case SimPuk: return R.layout.keyguard_sim_puk_view;
1074e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            default:
107563f9b81795559443e0376985f8aaaa97a359ef94Jim Miller                return 0;
1076e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        }
1077e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller    }
1078e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller
107951117262c8fadb6d227d137e83ad66996b013141Jim Miller    private boolean addWidget(int appId, int pageIndex, boolean updateDbIfFailed) {
108067a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appId);
108199a3cae55bd1a4ea6d82aa7fa2a67170e7cd5b3eJim Miller        if (appWidgetInfo != null) {
1082a75a883fe9ea1790803148f0a561473073e3f264Jim Miller            AppWidgetHostView view = mAppWidgetHost.createView(mContext, appId, appWidgetInfo);
1083d6523da1ad7bae805a3dbea8d7b398d86cd3c181Jim Miller            addWidget(view, pageIndex);
108467a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka            return true;
108599a3cae55bd1a4ea6d82aa7fa2a67170e7cd5b3eJim Miller        } else {
108651117262c8fadb6d227d137e83ad66996b013141Jim Miller            if (updateDbIfFailed) {
1087a75a883fe9ea1790803148f0a561473073e3f264Jim Miller                Log.w(TAG, "*** AppWidgetInfo for app widget id " + appId + "  was null for user"
1088a75a883fe9ea1790803148f0a561473073e3f264Jim Miller                        + mUserId + ", deleting");
108951117262c8fadb6d227d137e83ad66996b013141Jim Miller                mAppWidgetHost.deleteAppWidgetId(appId);
109051117262c8fadb6d227d137e83ad66996b013141Jim Miller                mLockPatternUtils.removeAppWidget(appId);
109151117262c8fadb6d227d137e83ad66996b013141Jim Miller            }
109267a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka            return false;
109399a3cae55bd1a4ea6d82aa7fa2a67170e7cd5b3eJim Miller        }
1094dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
1095dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
1096dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock    private final CameraWidgetFrame.Callbacks mCameraWidgetCallbacks =
1097dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock        new CameraWidgetFrame.Callbacks() {
1098dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock            @Override
1099dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock            public void onLaunchingCamera() {
110057f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock                setSliderHandleAlpha(0);
1101dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock            }
1102dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock
1103dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock            @Override
110457f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock            public void onCameraLaunchedSuccessfully() {
11056cf53bb3a94ec5a6eebc96a315dac32d042f1945Winson Chung                if (mAppWidgetContainer.isCameraPage(mAppWidgetContainer.getCurrentPage())) {
11064b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock                    mAppWidgetContainer.scrollLeft();
11074b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock                }
110857f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock                setSliderHandleAlpha(1);
1109aaf9b11e6232f159aa6d9863097b09bb435deae3Jim Miller                mShowSecurityWhenReturn = true;
1110dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock            }
1111dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock
111257f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock            @Override
111357f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock            public void onCameraLaunchedUnsuccessfully() {
111457f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock                setSliderHandleAlpha(1);
111557f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock            }
111657f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock
111757f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock            private void setSliderHandleAlpha(float alpha) {
111857f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock                SlidingChallengeLayout slider =
111957f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock                        (SlidingChallengeLayout) findViewById(R.id.sliding_layout);
112057f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock                if (slider != null) {
112157f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock                    slider.setHandleAlpha(alpha);
112257f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock                }
1123dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock            }
1124dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock        };
1125dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock
1126dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock    private final KeyguardActivityLauncher mActivityLauncher = new KeyguardActivityLauncher() {
1127dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock        @Override
1128dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock        Context getContext() {
1129dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock            return mContext;
1130dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock        }
1131dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock
1132dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock        @Override
1133dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock        KeyguardSecurityCallback getCallback() {
1134dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock            return mCallback;
1135dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock        }
1136dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock
1137dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock        @Override
1138dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock        LockPatternUtils getLockPatternUtils() {
1139dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock            return mLockPatternUtils;
1140bdca3c0a21ba15e8bb6d7ef0ca1b7e8024f98f19Jim Miller        }
1141bdca3c0a21ba15e8bb6d7ef0ca1b7e8024f98f19Jim Miller    };
1142dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock
1143eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka    private int numWidgets() {
1144eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka        final int childCount = mAppWidgetContainer.getChildCount();
1145eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka        int widgetCount = 0;
1146eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka        for (int i = 0; i < childCount; i++) {
1147eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka            if (mAppWidgetContainer.isWidgetPage(i)) {
1148eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka                widgetCount++;
1149eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka            }
1150eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka        }
1151eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka        return widgetCount;
1152eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka    }
1153eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka
11544e81bd4bcf60a934d4cd589dab6e2bddb88d7356Jim Miller    private void addDefaultWidgets() {
1155f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller        if (!mSafeModeEnabled && !widgetsDisabled()) {
11568f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            LayoutInflater inflater = LayoutInflater.from(mContext);
115751117262c8fadb6d227d137e83ad66996b013141Jim Miller            View addWidget = inflater.inflate(R.layout.keyguard_add_widget, this, false);
1158eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka            mAppWidgetContainer.addWidget(addWidget, 0);
115951117262c8fadb6d227d137e83ad66996b013141Jim Miller            View addWidgetButton = addWidget.findViewById(R.id.keyguard_add_widget_view);
116051117262c8fadb6d227d137e83ad66996b013141Jim Miller            addWidgetButton.setOnClickListener(new OnClickListener() {
116151117262c8fadb6d227d137e83ad66996b013141Jim Miller                @Override
116251117262c8fadb6d227d137e83ad66996b013141Jim Miller                public void onClick(View v) {
1163192d6d4ee271c0782a3bf5d8c64e42eb22d1a6faMichael Jurka                    // Pass in an invalid widget id... the picker will allocate an ID for us
1164192d6d4ee271c0782a3bf5d8c64e42eb22d1a6faMichael Jurka                    mActivityLauncher.launchWidgetPicker(AppWidgetManager.INVALID_APPWIDGET_ID);
116551117262c8fadb6d227d137e83ad66996b013141Jim Miller                }
116651117262c8fadb6d227d137e83ad66996b013141Jim Miller            });
116751117262c8fadb6d227d137e83ad66996b013141Jim Miller        }
116851117262c8fadb6d227d137e83ad66996b013141Jim Miller
116951117262c8fadb6d227d137e83ad66996b013141Jim Miller        // We currently disable cameras in safe mode because we support loading 3rd party
117051117262c8fadb6d227d137e83ad66996b013141Jim Miller        // cameras we can't trust.  TODO: plumb safe mode into camera creation code and only
117151117262c8fadb6d227d137e83ad66996b013141Jim Miller        // inflate system-provided camera?
1172371f3408d6d9c3c3781d6e35e591f61026b42240John Spurlock        if (!mSafeModeEnabled && !cameraDisabledByDpm() && mUserSetupCompleted
117351117262c8fadb6d227d137e83ad66996b013141Jim Miller                && mContext.getResources().getBoolean(R.bool.kg_enable_camera_default_widget)) {
1174dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock            View cameraWidget =
1175dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock                    CameraWidgetFrame.create(mContext, mCameraWidgetCallbacks, mActivityLauncher);
1176dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock            if (cameraWidget != null) {
1177dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock                mAppWidgetContainer.addWidget(cameraWidget);
1178dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock            }
117986b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock        }
1180838906b165e4d3cb2c512b2db344aa50cb5d4751Jim Miller
118119a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        enableUserSelectorIfNecessary();
11827221d3ae08cc2be922d26e5d491038512cb6c74dJim Miller    }
11837221d3ae08cc2be922d26e5d491038512cb6c74dJim Miller
11848f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller    /**
11858f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller     * Create KeyguardTransportControlView on demand.
11868f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller     * @return
11878f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller     */
11884894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller    private KeyguardTransportControlView getOrCreateTransportControl() {
11898f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        if (mTransportControl == null) {
11908f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            LayoutInflater inflater = LayoutInflater.from(mContext);
11918f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            mTransportControl = (KeyguardTransportControlView)
11928f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller                    inflater.inflate(R.layout.keyguard_transport_control_view, this, false);
11934e81bd4bcf60a934d4cd589dab6e2bddb88d7356Jim Miller        }
11948f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        return mTransportControl;
11954e81bd4bcf60a934d4cd589dab6e2bddb88d7356Jim Miller    }
11964e81bd4bcf60a934d4cd589dab6e2bddb88d7356Jim Miller
119751117262c8fadb6d227d137e83ad66996b013141Jim Miller    private int getInsertPageIndex() {
119867a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        View addWidget = mAppWidgetContainer.findViewById(R.id.keyguard_add_widget);
119951117262c8fadb6d227d137e83ad66996b013141Jim Miller        int insertionIndex = mAppWidgetContainer.indexOfChild(addWidget);
120051117262c8fadb6d227d137e83ad66996b013141Jim Miller        if (insertionIndex < 0) {
120151117262c8fadb6d227d137e83ad66996b013141Jim Miller            insertionIndex = 0; // no add widget page found
120251117262c8fadb6d227d137e83ad66996b013141Jim Miller        } else {
120351117262c8fadb6d227d137e83ad66996b013141Jim Miller            insertionIndex++; // place after add widget
120467a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        }
120551117262c8fadb6d227d137e83ad66996b013141Jim Miller        return insertionIndex;
120667a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka    }
120767a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka
120867a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka    private void addDefaultStatusWidget(int index) {
120967a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        LayoutInflater inflater = LayoutInflater.from(mContext);
121067a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        View statusWidget = inflater.inflate(R.layout.keyguard_status_view, null, true);
121167a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        mAppWidgetContainer.addWidget(statusWidget, index);
121267a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka    }
121367a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka
12141254f2f42f7173ef51d0034975ab5cb7d44f8209Michael Jurka    private void addWidgetsFromSettings() {
1215f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller        if (mSafeModeEnabled || widgetsDisabled()) {
121651117262c8fadb6d227d137e83ad66996b013141Jim Miller            return;
1217b8ec470617590fa2025db869e8e80dcce8eaec23Jim Miller        }
1218f229e4d3eb8f910c181f96416c6798f6f305a395Jim Miller
121951117262c8fadb6d227d137e83ad66996b013141Jim Miller        int insertionIndex = getInsertPageIndex();
122020c41d5382b70fa5a24e9ef68f19ce0aedea5234Michael Jurka
122120c41d5382b70fa5a24e9ef68f19ce0aedea5234Michael Jurka        // Add user-selected widget
1222aa2859ae61098509495b7938e32a6d59d37561beMichael Jurka        final int[] widgets = mLockPatternUtils.getAppWidgets();
122367a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka
1224aa2859ae61098509495b7938e32a6d59d37561beMichael Jurka        if (widgets == null) {
1225aa2859ae61098509495b7938e32a6d59d37561beMichael Jurka            Log.d(TAG, "Problem reading widgets");
1226aa2859ae61098509495b7938e32a6d59d37561beMichael Jurka        } else {
1227aa2859ae61098509495b7938e32a6d59d37561beMichael Jurka            for (int i = widgets.length -1; i >= 0; i--) {
12281254f2f42f7173ef51d0034975ab5cb7d44f8209Michael Jurka                if (widgets[i] == LockPatternUtils.ID_DEFAULT_STATUS_WIDGET) {
122951117262c8fadb6d227d137e83ad66996b013141Jim Miller                    addDefaultStatusWidget(insertionIndex);
12301254f2f42f7173ef51d0034975ab5cb7d44f8209Michael Jurka                } else {
1231aa2859ae61098509495b7938e32a6d59d37561beMichael Jurka                    // We add the widgets from left to right, starting after the first page after
1232aa2859ae61098509495b7938e32a6d59d37561beMichael Jurka                    // the add page. We count down, since the order will be persisted from right
1233aa2859ae61098509495b7938e32a6d59d37561beMichael Jurka                    // to left, starting after camera.
123451117262c8fadb6d227d137e83ad66996b013141Jim Miller                    addWidget(widgets[i], insertionIndex, true);
1235aa2859ae61098509495b7938e32a6d59d37561beMichael Jurka                }
1236dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            }
1237dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
123851117262c8fadb6d227d137e83ad66996b013141Jim Miller    }
123951117262c8fadb6d227d137e83ad66996b013141Jim Miller
124051117262c8fadb6d227d137e83ad66996b013141Jim Miller    private int allocateIdForDefaultAppWidget() {
124151117262c8fadb6d227d137e83ad66996b013141Jim Miller        int appWidgetId;
124251117262c8fadb6d227d137e83ad66996b013141Jim Miller        Resources res = getContext().getResources();
124351117262c8fadb6d227d137e83ad66996b013141Jim Miller        ComponentName defaultAppWidget = new ComponentName(
124451117262c8fadb6d227d137e83ad66996b013141Jim Miller                res.getString(R.string.widget_default_package_name),
124551117262c8fadb6d227d137e83ad66996b013141Jim Miller                res.getString(R.string.widget_default_class_name));
124651117262c8fadb6d227d137e83ad66996b013141Jim Miller
124751117262c8fadb6d227d137e83ad66996b013141Jim Miller        // Note: we don't support configuring the widget
124851117262c8fadb6d227d137e83ad66996b013141Jim Miller        appWidgetId = mAppWidgetHost.allocateAppWidgetId();
124951117262c8fadb6d227d137e83ad66996b013141Jim Miller
125051117262c8fadb6d227d137e83ad66996b013141Jim Miller        try {
125151117262c8fadb6d227d137e83ad66996b013141Jim Miller            mAppWidgetManager.bindAppWidgetId(appWidgetId, defaultAppWidget);
125251117262c8fadb6d227d137e83ad66996b013141Jim Miller        } catch (IllegalArgumentException e) {
125351117262c8fadb6d227d137e83ad66996b013141Jim Miller            Log.e(TAG, "Error when trying to bind default AppWidget: " + e);
125451117262c8fadb6d227d137e83ad66996b013141Jim Miller            mAppWidgetHost.deleteAppWidgetId(appWidgetId);
125551117262c8fadb6d227d137e83ad66996b013141Jim Miller            appWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
125651117262c8fadb6d227d137e83ad66996b013141Jim Miller        }
125751117262c8fadb6d227d137e83ad66996b013141Jim Miller        return appWidgetId;
125867a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka    }
1259f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller
126067a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka    public void checkAppWidgetConsistency() {
1261efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen        // Since this method may bind a widget (which we can't do until boot completed) we
1262efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen        // may have to defer it until after boot complete.
12634eb36cfdcabb51f67a887d867de9559966606d86Adam Cohen        if (!KeyguardUpdateMonitor.getInstance(mContext).hasBootCompleted()) {
1264efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen            mCheckAppWidgetConsistencyOnBootCompleted = true;
1265efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen            return;
1266efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen        }
126767a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        final int childCount = mAppWidgetContainer.getChildCount();
126867a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        boolean widgetPageExists = false;
126967a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        for (int i = 0; i < childCount; i++) {
127051117262c8fadb6d227d137e83ad66996b013141Jim Miller            if (mAppWidgetContainer.isWidgetPage(i)) {
127167a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka                widgetPageExists = true;
127267a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka                break;
127367a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka            }
127467a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        }
127567a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        if (!widgetPageExists) {
127651117262c8fadb6d227d137e83ad66996b013141Jim Miller            final int insertPageIndex = getInsertPageIndex();
127751117262c8fadb6d227d137e83ad66996b013141Jim Miller
1278f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller            final boolean userAddedWidgetsEnabled = !widgetsDisabled();
1279f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller
128051117262c8fadb6d227d137e83ad66996b013141Jim Miller            boolean addedDefaultAppWidget = false;
128151117262c8fadb6d227d137e83ad66996b013141Jim Miller
128251117262c8fadb6d227d137e83ad66996b013141Jim Miller            if (!mSafeModeEnabled) {
128351117262c8fadb6d227d137e83ad66996b013141Jim Miller                if (userAddedWidgetsEnabled) {
128451117262c8fadb6d227d137e83ad66996b013141Jim Miller                    int appWidgetId = allocateIdForDefaultAppWidget();
128551117262c8fadb6d227d137e83ad66996b013141Jim Miller                    if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
128651117262c8fadb6d227d137e83ad66996b013141Jim Miller                        addedDefaultAppWidget = addWidget(appWidgetId, insertPageIndex, true);
128751117262c8fadb6d227d137e83ad66996b013141Jim Miller                    }
128851117262c8fadb6d227d137e83ad66996b013141Jim Miller                } else {
128951117262c8fadb6d227d137e83ad66996b013141Jim Miller                    // note: even if widgetsDisabledByDpm() returns true, we still bind/create
129051117262c8fadb6d227d137e83ad66996b013141Jim Miller                    // the default appwidget if possible
129151117262c8fadb6d227d137e83ad66996b013141Jim Miller                    int appWidgetId = mLockPatternUtils.getFallbackAppWidgetId();
129251117262c8fadb6d227d137e83ad66996b013141Jim Miller                    if (appWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
129351117262c8fadb6d227d137e83ad66996b013141Jim Miller                        appWidgetId = allocateIdForDefaultAppWidget();
129451117262c8fadb6d227d137e83ad66996b013141Jim Miller                        if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
129551117262c8fadb6d227d137e83ad66996b013141Jim Miller                            mLockPatternUtils.writeFallbackAppWidgetId(appWidgetId);
129651117262c8fadb6d227d137e83ad66996b013141Jim Miller                        }
129751117262c8fadb6d227d137e83ad66996b013141Jim Miller                    }
129851117262c8fadb6d227d137e83ad66996b013141Jim Miller                    if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
129951117262c8fadb6d227d137e83ad66996b013141Jim Miller                        addedDefaultAppWidget = addWidget(appWidgetId, insertPageIndex, false);
130051117262c8fadb6d227d137e83ad66996b013141Jim Miller                        if (!addedDefaultAppWidget) {
130151117262c8fadb6d227d137e83ad66996b013141Jim Miller                            mAppWidgetHost.deleteAppWidgetId(appWidgetId);
130251117262c8fadb6d227d137e83ad66996b013141Jim Miller                            mLockPatternUtils.writeFallbackAppWidgetId(
130351117262c8fadb6d227d137e83ad66996b013141Jim Miller                                    AppWidgetManager.INVALID_APPWIDGET_ID);
130451117262c8fadb6d227d137e83ad66996b013141Jim Miller                        }
130551117262c8fadb6d227d137e83ad66996b013141Jim Miller                    }
130651117262c8fadb6d227d137e83ad66996b013141Jim Miller                }
130767a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka            }
130851117262c8fadb6d227d137e83ad66996b013141Jim Miller
130967a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka            // Use the built-in status/clock view if we can't inflate the default widget
131051117262c8fadb6d227d137e83ad66996b013141Jim Miller            if (!addedDefaultAppWidget) {
131151117262c8fadb6d227d137e83ad66996b013141Jim Miller                addDefaultStatusWidget(insertPageIndex);
131251117262c8fadb6d227d137e83ad66996b013141Jim Miller            }
131351117262c8fadb6d227d137e83ad66996b013141Jim Miller
131451117262c8fadb6d227d137e83ad66996b013141Jim Miller            // trigger DB updates only if user-added widgets are enabled
131551117262c8fadb6d227d137e83ad66996b013141Jim Miller            if (!mSafeModeEnabled && userAddedWidgetsEnabled) {
131651117262c8fadb6d227d137e83ad66996b013141Jim Miller                mAppWidgetContainer.onAddView(
131751117262c8fadb6d227d137e83ad66996b013141Jim Miller                        mAppWidgetContainer.getChildAt(insertPageIndex), insertPageIndex);
131867a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka            }
131967a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        }
13200207c0992cb05d0acc60540748c8ae6985917abbAdam Cohen    }
13210207c0992cb05d0acc60540748c8ae6985917abbAdam Cohen
1322223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller    Runnable mSwitchPageRunnable = new Runnable() {
1323223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        @Override
1324223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        public void run() {
1325223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller           showAppropriateWidgetPage();
1326223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        }
1327223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller    };
1328223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller
1329223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller    static class SavedState extends BaseSavedState {
1330223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        int transportState;
13311413889565bc1b9d5d5fb73302460a4f25f4a8c0Michael Jurka        int appWidgetToShow = AppWidgetManager.INVALID_APPWIDGET_ID;
1332223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller
1333223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        SavedState(Parcelable superState) {
1334223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller            super(superState);
1335223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        }
1336223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller
1337223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        private SavedState(Parcel in) {
1338223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller            super(in);
1339223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller            this.transportState = in.readInt();
13401413889565bc1b9d5d5fb73302460a4f25f4a8c0Michael Jurka            this.appWidgetToShow = in.readInt();
1341223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        }
1342223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller
1343223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        @Override
1344223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        public void writeToParcel(Parcel out, int flags) {
1345223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller            super.writeToParcel(out, flags);
1346223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller            out.writeInt(this.transportState);
13471413889565bc1b9d5d5fb73302460a4f25f4a8c0Michael Jurka            out.writeInt(this.appWidgetToShow);
1348223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        }
1349223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller
1350223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        public static final Parcelable.Creator<SavedState> CREATOR
1351223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller                = new Parcelable.Creator<SavedState>() {
1352223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller            public SavedState createFromParcel(Parcel in) {
1353223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller                return new SavedState(in);
1354223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller            }
1355223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller
1356223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller            public SavedState[] newArray(int size) {
1357223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller                return new SavedState[size];
1358223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller            }
1359223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        };
1360223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller    }
1361223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller
1362223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller    @Override
1363223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller    public Parcelable onSaveInstanceState() {
13644894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller        if (DEBUG) Log.d(TAG, "onSaveInstanceState, tstate=" + mTransportState);
1365223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        Parcelable superState = super.onSaveInstanceState();
1366223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        SavedState ss = new SavedState(superState);
13674894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller        // If the transport is showing, force it to show it on restore.
13684894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller        final boolean showing = mTransportControl != null
13694894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller                && mAppWidgetContainer.getWidgetPageIndex(mTransportControl) >= 0;
13704894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller        ss.transportState =  showing ? TRANSPORT_VISIBLE : mTransportState;
13711413889565bc1b9d5d5fb73302460a4f25f4a8c0Michael Jurka        ss.appWidgetToShow = mAppWidgetToShow;
1372223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        return ss;
1373223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller    }
1374223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller
1375223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller    @Override
1376223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller    public void onRestoreInstanceState(Parcelable state) {
1377223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        if (!(state instanceof SavedState)) {
1378223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller            super.onRestoreInstanceState(state);
1379223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller            return;
1380223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        }
1381223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        SavedState ss = (SavedState) state;
1382223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        super.onRestoreInstanceState(ss.getSuperState());
13838f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        mTransportState = (ss.transportState);
13841413889565bc1b9d5d5fb73302460a4f25f4a8c0Michael Jurka        mAppWidgetToShow = ss.appWidgetToShow;
13854894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller        if (DEBUG) Log.d(TAG, "onRestoreInstanceState, transport=" + mTransportState);
13860db59a856f9b4a6ae53854a88fea3a3675d572fdWinson Chung        post(mSwitchPageRunnable);
1387223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller    }
1388223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller
13895f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock    @Override
13905f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock    public void onWindowFocusChanged(boolean hasWindowFocus) {
13915f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock        super.onWindowFocusChanged(hasWindowFocus);
13925f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock        if (DEBUG) Log.d(TAG, "Window is " + (hasWindowFocus ? "focused" : "unfocused"));
139376017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka        if (hasWindowFocus && mShowSecurityWhenReturn) {
1394aaf9b11e6232f159aa6d9863097b09bb435deae3Jim Miller            SlidingChallengeLayout slider =
1395aaf9b11e6232f159aa6d9863097b09bb435deae3Jim Miller                (SlidingChallengeLayout) findViewById(R.id.sliding_layout);
1396aaf9b11e6232f159aa6d9863097b09bb435deae3Jim Miller            if (slider != null) {
1397aaf9b11e6232f159aa6d9863097b09bb435deae3Jim Miller                slider.setHandleAlpha(1);
1398aaf9b11e6232f159aa6d9863097b09bb435deae3Jim Miller                slider.showChallenge(true);
1399aaf9b11e6232f159aa6d9863097b09bb435deae3Jim Miller            }
1400aaf9b11e6232f159aa6d9863097b09bb435deae3Jim Miller            mShowSecurityWhenReturn = false;
14015f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock        }
14025f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock    }
14035f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock
14040207c0992cb05d0acc60540748c8ae6985917abbAdam Cohen    private void showAppropriateWidgetPage() {
14058f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        int state = mTransportState;
14068f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        ensureTransportPresentOrRemoved(state);
14078f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        int pageToShow = getAppropriateWidgetPage(state);
1408223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        mAppWidgetContainer.setCurrentPage(pageToShow);
1409dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
1410dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
14114894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller    /**
14124894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     * Examines the current state and adds the transport to the widget pager when the state changes.
14134894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     *
14144894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     * Showing the initial transport and keeping it around is a bit tricky because the signals
14154894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     * coming from music players aren't always clear. Here's how the states are handled:
14164894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     *
14174894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     * {@link TRANSPORT_GONE} means we have no reason to show the transport - remove it if present.
14184894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     *
14194894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     * {@link TRANSPORT_INVISIBLE} means we have potential to show the transport because a music
14204894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     * player is registered but not currently playing music (or we don't know the state yet). The
14214894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     * code adds it conditionally on play state.
14224894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     *
14234894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     * {@link #TRANSPORT_VISIBLE} means a music player is active and transport should be showing.
14244894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     *
14254894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     * Once the transport is showing, we always show it until keyguard is dismissed. This state is
14264894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     * maintained by onSave/RestoreInstanceState(). This state is cleared in
14274894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     * {@link KeyguardViewManager#hide} when keyguard is dismissed, which causes the transport to be
14284894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     * gone when keyguard is restarted until we get an update with the current state.
14294894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     *
14304894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     * @param state
14314894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     */
14328f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller    private void ensureTransportPresentOrRemoved(int state) {
14334894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller        final boolean showing = getWidgetPosition(R.id.keyguard_transport_control) != -1;
14344894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller        final boolean visible = state == TRANSPORT_VISIBLE;
14354894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller        final boolean shouldBeVisible = state == TRANSPORT_INVISIBLE && isMusicPlaying(state);
14364894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller        if (!showing && (visible || shouldBeVisible)) {
14374894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller            if (DEBUGXPORT) Log.v(TAG, "add transport");
14384894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller            // insert to left of camera if it exists, otherwise after right-most widget
14394894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller            int lastWidget = mAppWidgetContainer.getChildCount() - 1;
14404894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller            int position = 0; // handle no widget case
14414894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller            if (lastWidget >= 0) {
14424894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller                position = mAppWidgetContainer.isCameraPage(lastWidget) ?
14434894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller                        lastWidget : lastWidget + 1;
14448f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            }
14454894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller            mAppWidgetContainer.addWidget(getOrCreateTransportControl(), position);
14464894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller        } else if (showing && state == TRANSPORT_GONE) {
14478f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            if (DEBUGXPORT) Log.v(TAG, "remove transport");
14484894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller            mAppWidgetContainer.removeWidget(getOrCreateTransportControl());
14498f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            mTransportControl = null;
14508f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        }
14518f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller    }
14528f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller
1453dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock    private CameraWidgetFrame findCameraPage() {
1454dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock        for (int i = mAppWidgetContainer.getChildCount() - 1; i >= 0; i--) {
14556cf53bb3a94ec5a6eebc96a315dac32d042f1945Winson Chung            if (mAppWidgetContainer.isCameraPage(i)) {
1456dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock                return (CameraWidgetFrame) mAppWidgetContainer.getChildAt(i);
1457dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock            }
1458dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock        }
1459dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock        return null;
1460dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock    }
1461dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock
14626cf53bb3a94ec5a6eebc96a315dac32d042f1945Winson Chung    boolean isMusicPage(int pageIndex) {
14636cf53bb3a94ec5a6eebc96a315dac32d042f1945Winson Chung        return pageIndex >= 0 && pageIndex == getWidgetPosition(R.id.keyguard_transport_control);
14646cf53bb3a94ec5a6eebc96a315dac32d042f1945Winson Chung    }
14656cf53bb3a94ec5a6eebc96a315dac32d042f1945Winson Chung
14668f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller    private int getAppropriateWidgetPage(int musicTransportState) {
1467358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock        // assumes at least one widget (besides camera + add)
146876017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka        if (mAppWidgetToShow != AppWidgetManager.INVALID_APPWIDGET_ID) {
146976017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka            final int childCount = mAppWidgetContainer.getChildCount();
147076017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka            for (int i = 0; i < childCount; i++) {
147176017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka                if (mAppWidgetContainer.getWidgetPageAt(i).getContentAppWidgetId()
147276017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka                        == mAppWidgetToShow) {
147376017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka                    return i;
147476017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka                }
147576017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka            }
147676017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka            mAppWidgetToShow = AppWidgetManager.INVALID_APPWIDGET_ID;
147776017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka        }
1478358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock        // if music playing, show transport
14798f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        if (musicTransportState == TRANSPORT_VISIBLE) {
1480358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock            if (DEBUG) Log.d(TAG, "Music playing, show transport");
14814894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller            return mAppWidgetContainer.getWidgetPageIndex(getOrCreateTransportControl());
1482358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock        }
1483358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock
14845f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock        // else show the right-most widget (except for camera)
1485358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock        int rightMost = mAppWidgetContainer.getChildCount() - 1;
14866cf53bb3a94ec5a6eebc96a315dac32d042f1945Winson Chung        if (mAppWidgetContainer.isCameraPage(rightMost)) {
1487358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock            rightMost--;
1488358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock        }
14895f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock        if (DEBUG) Log.d(TAG, "Show right-most page " + rightMost);
1490358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock        return rightMost;
1491358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock    }
1492358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock
149319a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller    private void enableUserSelectorIfNecessary() {
149426e6c2e44235428717d7152b9e6398649452f1d2Jim Miller        if (!UserManager.supportsMultipleUsers()) {
149526e6c2e44235428717d7152b9e6398649452f1d2Jim Miller            return; // device doesn't support multi-user mode
149626e6c2e44235428717d7152b9e6398649452f1d2Jim Miller        }
1497f6ab5f9e3e7562b6ebb61ac149eb3cf9b08c443fJim Miller        final UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
1498d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren        if (um == null) {
1499d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren            Throwable t = new Throwable();
1500d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren            t.fillInStackTrace();
1501d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren            Log.e(TAG, "user service is null.", t);
1502d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren            return;
1503d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren        }
150426e6c2e44235428717d7152b9e6398649452f1d2Jim Miller
15055f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock        // if there are multiple users, we need to enable to multi-user switcher
1506f6ab5f9e3e7562b6ebb61ac149eb3cf9b08c443fJim Miller        final List<UserInfo> users = um.getUsers(true);
1507d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren        if (users == null) {
1508d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren            Throwable t = new Throwable();
1509d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren            t.fillInStackTrace();
1510d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren            Log.e(TAG, "list of users is null.", t);
1511d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren            return;
1512d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren        }
151366b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen
1514f6ab5f9e3e7562b6ebb61ac149eb3cf9b08c443fJim Miller        final View multiUserView = findViewById(R.id.keyguard_user_selector);
1515f6ab5f9e3e7562b6ebb61ac149eb3cf9b08c443fJim Miller        if (multiUserView == null) {
1516f6ab5f9e3e7562b6ebb61ac149eb3cf9b08c443fJim Miller            Throwable t = new Throwable();
1517f6ab5f9e3e7562b6ebb61ac149eb3cf9b08c443fJim Miller            t.fillInStackTrace();
1518f6ab5f9e3e7562b6ebb61ac149eb3cf9b08c443fJim Miller            Log.e(TAG, "can't find user_selector in layout.", t);
1519f6ab5f9e3e7562b6ebb61ac149eb3cf9b08c443fJim Miller            return;
1520f6ab5f9e3e7562b6ebb61ac149eb3cf9b08c443fJim Miller        }
1521f6ab5f9e3e7562b6ebb61ac149eb3cf9b08c443fJim Miller
1522d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren        if (users.size() > 1) {
152391f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren            if (multiUserView instanceof KeyguardMultiUserSelectorView) {
1524f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren                mKeyguardMultiUserSelectorView = (KeyguardMultiUserSelectorView) multiUserView;
1525f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren                mKeyguardMultiUserSelectorView.setVisibility(View.VISIBLE);
1526f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren                mKeyguardMultiUserSelectorView.addUsers(users);
152791f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                UserSwitcherCallback callback = new UserSwitcherCallback() {
152891f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                    @Override
152991f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                    public void hideSecurityView(int duration) {
153091f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                        mSecurityViewContainer.animate().alpha(0).setDuration(duration);
153191f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                    }
153224b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen
153391f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                    @Override
153491f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                    public void showSecurityView() {
153591f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                        mSecurityViewContainer.setAlpha(1.0f);
153691f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                    }
15370a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen
153891f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                    @Override
153991f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                    public void showUnlockHint() {
154091f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                        if (mKeyguardSelectorView != null) {
154191f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                            mKeyguardSelectorView.showUsabilityHint();
154291f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                        }
15430ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller                    }
15440a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen
154591f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                    @Override
154691f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                    public void userActivity() {
154791f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                        if (mViewMediatorCallback != null) {
154891f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                            mViewMediatorCallback.userActivity();
154991f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                        }
155019a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                    }
155191f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                };
1552f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren                mKeyguardMultiUserSelectorView.setCallback(callback);
1553d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren            } else {
1554d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren                Throwable t = new Throwable();
1555d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren                t.fillInStackTrace();
1556d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren                if (multiUserView == null) {
1557d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren                    Log.e(TAG, "could not find the user_selector.", t);
1558d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren                } else {
1559d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren                    Log.e(TAG, "user_selector is the wrong type.", t);
1560d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren                }
156191f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren            }
156266b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen        }
156366b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen    }
156466b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen
1565dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    @Override
1566dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    public void cleanUp() {
1567128f27632343ed8ad8bba2d96f4ec69c0e369de7Adam Cohen        // Make sure we let go of all widgets and their package contexts promptly. If we don't do
1568128f27632343ed8ad8bba2d96f4ec69c0e369de7Adam Cohen        // this, and the associated application is uninstalled, it can cause a soft reboot.
1569128f27632343ed8ad8bba2d96f4ec69c0e369de7Adam Cohen        int count = mAppWidgetContainer.getChildCount();
1570128f27632343ed8ad8bba2d96f4ec69c0e369de7Adam Cohen        for (int i = 0; i < count; i++) {
1571128f27632343ed8ad8bba2d96f4ec69c0e369de7Adam Cohen            KeyguardWidgetFrame frame = mAppWidgetContainer.getWidgetPageAt(i);
1572128f27632343ed8ad8bba2d96f4ec69c0e369de7Adam Cohen            frame.removeAllViews();
1573128f27632343ed8ad8bba2d96f4ec69c0e369de7Adam Cohen        }
1574dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
1575dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
157695b005c196de2f99513da28fe9108b2dec200140Jim Miller    /**
157795b005c196de2f99513da28fe9108b2dec200140Jim Miller     * In general, we enable unlocking the insecure keyguard with the menu key. However, there are
157895b005c196de2f99513da28fe9108b2dec200140Jim Miller     * some cases where we wish to disable it, notably when the menu button placement or technology
157995b005c196de2f99513da28fe9108b2dec200140Jim Miller     * is prone to false positives.
158095b005c196de2f99513da28fe9108b2dec200140Jim Miller     *
158195b005c196de2f99513da28fe9108b2dec200140Jim Miller     * @return true if the menu key should be enabled
158295b005c196de2f99513da28fe9108b2dec200140Jim Miller     */
158395b005c196de2f99513da28fe9108b2dec200140Jim Miller    private static final String ENABLE_MENU_KEY_FILE = "/data/local/enable_menu_key";
158495b005c196de2f99513da28fe9108b2dec200140Jim Miller    private boolean shouldEnableMenuKey() {
158595b005c196de2f99513da28fe9108b2dec200140Jim Miller        final Resources res = getResources();
15865ecd81154fa039961f65bb4e36d18ac555b0d1d6Jim Miller        final boolean configDisabled = res.getBoolean(R.bool.config_disableMenuKeyInLockScreen);
158795b005c196de2f99513da28fe9108b2dec200140Jim Miller        final boolean isTestHarness = ActivityManager.isRunningInTestHarness();
158895b005c196de2f99513da28fe9108b2dec200140Jim Miller        final boolean fileOverride = (new File(ENABLE_MENU_KEY_FILE)).exists();
158995b005c196de2f99513da28fe9108b2dec200140Jim Miller        return !configDisabled || isTestHarness || fileOverride;
159095b005c196de2f99513da28fe9108b2dec200140Jim Miller    }
159195b005c196de2f99513da28fe9108b2dec200140Jim Miller
159276017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka    public void goToWidget(int appWidgetId) {
159376017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka        mAppWidgetToShow = appWidgetId;
159476017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka        mSwitchPageRunnable.run();
159576017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka    }
159676017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka
159775931e05470992d51d135d09031902fd1b3fdbc7Jim Miller    public boolean handleMenuKey() {
159875931e05470992d51d135d09031902fd1b3fdbc7Jim Miller        // The following enables the MENU key to work for testing automation
159975931e05470992d51d135d09031902fd1b3fdbc7Jim Miller        if (shouldEnableMenuKey()) {
160075931e05470992d51d135d09031902fd1b3fdbc7Jim Miller            showNextSecurityScreenOrFinish(false);
160175931e05470992d51d135d09031902fd1b3fdbc7Jim Miller            return true;
160275931e05470992d51d135d09031902fd1b3fdbc7Jim Miller        }
160375931e05470992d51d135d09031902fd1b3fdbc7Jim Miller        return false;
160475931e05470992d51d135d09031902fd1b3fdbc7Jim Miller    }
160575931e05470992d51d135d09031902fd1b3fdbc7Jim Miller
16060a34d9edf02954d83c2861a8c6836865f8fa00fbJim Miller    public boolean handleBackKey() {
160703eca859067ac0d4e419305de8ab0fdc03b4210fJohn Spurlock        if (mCurrentSecuritySelection == SecurityMode.Account) {
160803eca859067ac0d4e419305de8ab0fdc03b4210fJohn Spurlock            // go back to primary screen and re-disable back
160903eca859067ac0d4e419305de8ab0fdc03b4210fJohn Spurlock            setBackButtonEnabled(false);
161003eca859067ac0d4e419305de8ab0fdc03b4210fJohn Spurlock            showPrimarySecurityScreen(false /*turningOff*/);
161103eca859067ac0d4e419305de8ab0fdc03b4210fJohn Spurlock            return true;
161203eca859067ac0d4e419305de8ab0fdc03b4210fJohn Spurlock        }
16130a34d9edf02954d83c2861a8c6836865f8fa00fbJim Miller        if (mCurrentSecuritySelection != SecurityMode.None) {
16140a34d9edf02954d83c2861a8c6836865f8fa00fbJim Miller            mCallback.dismiss(false);
16150a34d9edf02954d83c2861a8c6836865f8fa00fbJim Miller            return true;
16160a34d9edf02954d83c2861a8c6836865f8fa00fbJim Miller        }
16170a34d9edf02954d83c2861a8c6836865f8fa00fbJim Miller        return false;
16180a34d9edf02954d83c2861a8c6836865f8fa00fbJim Miller    }
16190a34d9edf02954d83c2861a8c6836865f8fa00fbJim Miller
1620ad09bccfe4cc0a3075e97c0911a02b329023a34aCraig Mautner    /**
1621ad09bccfe4cc0a3075e97c0911a02b329023a34aCraig Mautner     *  Dismisses the keyguard by going to the next screen or making it gone.
1622ad09bccfe4cc0a3075e97c0911a02b329023a34aCraig Mautner     */
1623ad09bccfe4cc0a3075e97c0911a02b329023a34aCraig Mautner    public void dismiss() {
1624ad09bccfe4cc0a3075e97c0911a02b329023a34aCraig Mautner        showNextSecurityScreenOrFinish(false);
1625ad09bccfe4cc0a3075e97c0911a02b329023a34aCraig Mautner    }
16264eeb4f664ac6b5901a8e874dcf70c0382295f792Jim Miller
16274eeb4f664ac6b5901a8e874dcf70c0382295f792Jim Miller    public void showAssistant() {
16284eeb4f664ac6b5901a8e874dcf70c0382295f792Jim Miller        final Intent intent = ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
1629f9c5e0fe837a3090820da502ecaabc5accc00aceDianne Hackborn          .getAssistIntent(mContext, true, UserHandle.USER_CURRENT);
16304eeb4f664ac6b5901a8e874dcf70c0382295f792Jim Miller
16314eeb4f664ac6b5901a8e874dcf70c0382295f792Jim Miller        if (intent == null) return;
16324eeb4f664ac6b5901a8e874dcf70c0382295f792Jim Miller
16334eeb4f664ac6b5901a8e874dcf70c0382295f792Jim Miller        final ActivityOptions opts = ActivityOptions.makeCustomAnimation(mContext,
16344eeb4f664ac6b5901a8e874dcf70c0382295f792Jim Miller                R.anim.keyguard_action_assist_enter, R.anim.keyguard_action_assist_exit,
16354eeb4f664ac6b5901a8e874dcf70c0382295f792Jim Miller                getHandler(), null);
16364eeb4f664ac6b5901a8e874dcf70c0382295f792Jim Miller
16374eeb4f664ac6b5901a8e874dcf70c0382295f792Jim Miller        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
16384eeb4f664ac6b5901a8e874dcf70c0382295f792Jim Miller
16396ed3fcafdbdeda9a10a62bbd0e5997017e8e2635Daniel Sandler        mActivityLauncher.launchActivityWithAnimation(
16406ed3fcafdbdeda9a10a62bbd0e5997017e8e2635Daniel Sandler                intent, false, opts.toBundle(), null, null);
16414eeb4f664ac6b5901a8e874dcf70c0382295f792Jim Miller    }
1642dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller}
1643