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
194d20ed3f26d1ec2c47519484bcc968098581c3d6Jim Millerimport com.android.internal.widget.LockPatternUtils;
204d20ed3f26d1ec2c47519484bcc968098581c3d6Jim Millerimport com.android.keyguard.KeyguardSecurityModel.SecurityMode;
214d20ed3f26d1ec2c47519484bcc968098581c3d6Jim Millerimport com.android.keyguard.KeyguardUpdateMonitor.DisplayClientState;
224d20ed3f26d1ec2c47519484bcc968098581c3d6Jim 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;
5366b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohenimport android.view.LayoutInflater;
545737534abab477cf32b4dd0aa7a72f70ede0502cJim Millerimport android.view.MotionEvent;
55dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.view.View;
56258341c377b6aa9f1bd29a9b507a97967e432dfeJim Millerimport android.view.WindowManager;
57dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.widget.RemoteViews.OnClickHandler;
58dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
5995b005c196de2f99513da28fe9108b2dec200140Jim Millerimport java.io.File;
607fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haaseimport java.lang.ref.WeakReference;
6166b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohenimport java.util.List;
62dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
63dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerpublic class KeyguardHostView extends KeyguardViewBase {
6451117262c8fadb6d227d137e83ad66996b013141Jim Miller    private static final String TAG = "KeyguardHostView";
65eec83dcadd1dca722d3070fe5eae7d4e0561aa2bSandeep Siddhartha
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
9334c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock    protected OnDismissAction mDismissAction;
94dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
95dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    protected int mFailedAttempts;
96dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    private LockPatternUtils mLockPatternUtils;
97dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
98dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    private KeyguardSecurityModel mSecurityModel;
99d6523da1ad7bae805a3dbea8d7b398d86cd3c181Jim Miller    private KeyguardViewStateManager mViewStateManager;
100dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
1015737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller    private Rect mTempRect = new Rect();
102ff2aa0bc8919c247bfc8e81d3f168e5064f52ffbJim Miller
10351117262c8fadb6d227d137e83ad66996b013141Jim Miller    private int mDisabledFeatures;
10451117262c8fadb6d227d137e83ad66996b013141Jim Miller
10551117262c8fadb6d227d137e83ad66996b013141Jim Miller    private boolean mCameraDisabled;
10651117262c8fadb6d227d137e83ad66996b013141Jim Miller
10751117262c8fadb6d227d137e83ad66996b013141Jim Miller    private boolean mSafeModeEnabled;
10851117262c8fadb6d227d137e83ad66996b013141Jim Miller
109fff5614caecb0d2944b1bc206aaab0d3acb17670Michael Jurka    private boolean mUserSetupCompleted;
110f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren
111a75a883fe9ea1790803148f0a561473073e3f264Jim Miller    // User for whom this host view was created.  Final because we should never change the
112a75a883fe9ea1790803148f0a561473073e3f264Jim Miller    // id without reconstructing an instance of KeyguardHostView. See note below...
113a75a883fe9ea1790803148f0a561473073e3f264Jim Miller    private final int mUserId;
114fff5614caecb0d2944b1bc206aaab0d3acb17670Michael Jurka
115f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren    private KeyguardMultiUserSelectorView mKeyguardMultiUserSelectorView;
116f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren
1178f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller    protected int mClientGeneration;
1185737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller
119e51cf7aeb6157017801a802b4c1d74cbf51b7a01Jim Miller    protected boolean mShowSecurityWhenReturn;
120e51cf7aeb6157017801a802b4c1d74cbf51b7a01Jim Miller
121256ae67b9a629178b458dfc01102c9c0b9963d03John Spurlock    private final Rect mInsets = new Rect();
122256ae67b9a629178b458dfc01102c9c0b9963d03John Spurlock
1237fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haase    private MyOnClickHandler mOnClickHandler = new MyOnClickHandler(this);
1247fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haase
1259ccf123ee0596ec9cab724f252a4932961c083afJim Miller    private Runnable mPostBootCompletedRunnable;
1269ccf123ee0596ec9cab724f252a4932961c083afJim Miller
12724b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen    /*package*/ interface UserSwitcherCallback {
12824b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen        void hideSecurityView(int duration);
12924b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen        void showSecurityView();
1300a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen        void showUnlockHint();
13119a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        void userActivity();
13224b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen    }
13324b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen
134f8895248e2ac4dbb46622f3e04c7256f03175b4fAdam Powell    interface TransportControlCallback {
135f8895248e2ac4dbb46622f3e04c7256f03175b4fAdam Powell        void userActivity();
136f8895248e2ac4dbb46622f3e04c7256f03175b4fAdam Powell    }
137f8895248e2ac4dbb46622f3e04c7256f03175b4fAdam Powell
13814adfe425e67c9ec12b0841a62c5c03ce00838eaJohn Spurlock    /*package*/ interface OnDismissAction {
13914adfe425e67c9ec12b0841a62c5c03ce00838eaJohn Spurlock        /* returns true if the dismiss should be deferred */
14014adfe425e67c9ec12b0841a62c5c03ce00838eaJohn Spurlock        boolean onDismiss();
14114adfe425e67c9ec12b0841a62c5c03ce00838eaJohn Spurlock    }
14214adfe425e67c9ec12b0841a62c5c03ce00838eaJohn Spurlock
143dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    public KeyguardHostView(Context context) {
144dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        this(context, null);
145dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
146dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
147dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    public KeyguardHostView(Context context, AttributeSet attrs) {
148dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        super(context, attrs);
1494894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller
1504894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller        if (DEBUG) Log.e(TAG, "KeyguardHostView()");
1514894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller
152000464ac012471d301c6e48a8228291519915e17Jim Miller        mLockPatternUtils = new LockPatternUtils(context);
153a75a883fe9ea1790803148f0a561473073e3f264Jim Miller
154a75a883fe9ea1790803148f0a561473073e3f264Jim Miller        // Note: This depends on KeyguardHostView getting reconstructed every time the
155a75a883fe9ea1790803148f0a561473073e3f264Jim Miller        // user switches, since mUserId will be used for the entire session.
156a75a883fe9ea1790803148f0a561473073e3f264Jim Miller        // Once created, keyguard should *never* re-use this instance with another user.
157a75a883fe9ea1790803148f0a561473073e3f264Jim Miller        // In other words, mUserId should never change - hence it's marked final.
158c566b43d02596cba437e9a2723e9f989297cca72Amith Yamasani        mUserId = mLockPatternUtils.getCurrentUser();
159a75a883fe9ea1790803148f0a561473073e3f264Jim Miller
160105beddcb98efc24f37259881d9b4c267aa0d198Jim Miller        DevicePolicyManager dpm =
161105beddcb98efc24f37259881d9b4c267aa0d198Jim Miller                (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
162105beddcb98efc24f37259881d9b4c267aa0d198Jim Miller        if (dpm != null) {
163105beddcb98efc24f37259881d9b4c267aa0d198Jim Miller            mDisabledFeatures = getDisabledFeatures(dpm);
164105beddcb98efc24f37259881d9b4c267aa0d198Jim Miller            mCameraDisabled = dpm.getCameraDisabled(null);
165105beddcb98efc24f37259881d9b4c267aa0d198Jim Miller        }
166105beddcb98efc24f37259881d9b4c267aa0d198Jim Miller
167105beddcb98efc24f37259881d9b4c267aa0d198Jim Miller        mSafeModeEnabled = LockPatternUtils.isSafeModeEnabled();
168105beddcb98efc24f37259881d9b4c267aa0d198Jim Miller
169105beddcb98efc24f37259881d9b4c267aa0d198Jim Miller        // These need to be created with the user context...
170a75a883fe9ea1790803148f0a561473073e3f264Jim Miller        Context userContext = null;
171a75a883fe9ea1790803148f0a561473073e3f264Jim Miller        try {
172a75a883fe9ea1790803148f0a561473073e3f264Jim Miller            final String packageName = "system";
173a75a883fe9ea1790803148f0a561473073e3f264Jim Miller            userContext = mContext.createPackageContextAsUser(packageName, 0,
174a75a883fe9ea1790803148f0a561473073e3f264Jim Miller                    new UserHandle(mUserId));
175a75a883fe9ea1790803148f0a561473073e3f264Jim Miller
176a75a883fe9ea1790803148f0a561473073e3f264Jim Miller        } catch (NameNotFoundException e) {
177a75a883fe9ea1790803148f0a561473073e3f264Jim Miller            e.printStackTrace();
178a75a883fe9ea1790803148f0a561473073e3f264Jim Miller            // This should never happen, but it's better to have no widgets than to crash.
179a75a883fe9ea1790803148f0a561473073e3f264Jim Miller            userContext = context;
180a75a883fe9ea1790803148f0a561473073e3f264Jim Miller        }
181a75a883fe9ea1790803148f0a561473073e3f264Jim Miller
182a75a883fe9ea1790803148f0a561473073e3f264Jim Miller        mAppWidgetHost = new AppWidgetHost(userContext, APPWIDGET_HOST_ID, mOnClickHandler,
183a75a883fe9ea1790803148f0a561473073e3f264Jim Miller                Looper.myLooper());
184a75a883fe9ea1790803148f0a561473073e3f264Jim Miller
185105beddcb98efc24f37259881d9b4c267aa0d198Jim Miller        mAppWidgetManager = AppWidgetManager.getInstance(userContext);
186fc2dbb2f3a148ee90727c4319adf56c04002f3faMichael Jurka
187fc2dbb2f3a148ee90727c4319adf56c04002f3faMichael Jurka        mSecurityModel = new KeyguardSecurityModel(context);
188fc2dbb2f3a148ee90727c4319adf56c04002f3faMichael Jurka
189fc2dbb2f3a148ee90727c4319adf56c04002f3faMichael Jurka        mViewStateManager = new KeyguardViewStateManager(this);
190fc2dbb2f3a148ee90727c4319adf56c04002f3faMichael Jurka
191fff5614caecb0d2944b1bc206aaab0d3acb17670Michael Jurka        mUserSetupCompleted = Settings.Secure.getIntForUser(mContext.getContentResolver(),
192fff5614caecb0d2944b1bc206aaab0d3acb17670Michael Jurka                Settings.Secure.USER_SETUP_COMPLETE, 0, UserHandle.USER_CURRENT) != 0;
19351117262c8fadb6d227d137e83ad66996b013141Jim Miller
1948f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        // Ensure we have the current state *before* we call showAppropriateWidgetPage()
1958f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        getInitialTransportState();
1968f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller
19751117262c8fadb6d227d137e83ad66996b013141Jim Miller        if (mSafeModeEnabled) {
19851117262c8fadb6d227d137e83ad66996b013141Jim Miller            Log.v(TAG, "Keyguard widgets disabled by safe mode");
19951117262c8fadb6d227d137e83ad66996b013141Jim Miller        }
20051117262c8fadb6d227d137e83ad66996b013141Jim Miller        if ((mDisabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_WIDGETS_ALL) != 0) {
20151117262c8fadb6d227d137e83ad66996b013141Jim Miller            Log.v(TAG, "Keyguard widgets disabled by DPM");
20251117262c8fadb6d227d137e83ad66996b013141Jim Miller        }
20351117262c8fadb6d227d137e83ad66996b013141Jim Miller        if ((mDisabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) != 0) {
20451117262c8fadb6d227d137e83ad66996b013141Jim Miller            Log.v(TAG, "Keyguard secure camera disabled by DPM");
20551117262c8fadb6d227d137e83ad66996b013141Jim Miller        }
206dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
207dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
208138f25d75665bd07d34294364c5b6f530b33503fJim Miller    public void announceCurrentSecurityMethod() {
209138f25d75665bd07d34294364c5b6f530b33503fJim Miller        View v = (View) getSecurityView(mCurrentSecuritySelection);
210138f25d75665bd07d34294364c5b6f530b33503fJim Miller        if (v != null) {
211138f25d75665bd07d34294364c5b6f530b33503fJim Miller            v.announceForAccessibility(v.getContentDescription());
212138f25d75665bd07d34294364c5b6f530b33503fJim Miller        }
213138f25d75665bd07d34294364c5b6f530b33503fJim Miller    }
214138f25d75665bd07d34294364c5b6f530b33503fJim Miller
2158f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller    private void getInitialTransportState() {
2168f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        DisplayClientState dcs = KeyguardUpdateMonitor.getInstance(mContext)
2178f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller                .getCachedDisplayClientState();
2188f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        mTransportState = (dcs.clearing ? TRANSPORT_GONE :
2198f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            (isMusicPlaying(dcs.playbackState) ? TRANSPORT_VISIBLE : TRANSPORT_INVISIBLE));
2204894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller
22181190befe66e297d93ad0c7661d02d56f8f01f24Jim Miller        if (DEBUGXPORT) Log.v(TAG, "Initial transport state: "
222dfb57cdcfc6a1fd48395c13af98ecc2722fd5254Jim Miller                + mTransportState + ", pbstate=" + dcs.playbackState);
2238f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller    }
2248f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller
22575b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka    private void cleanupAppWidgetIds() {
2269ccf123ee0596ec9cab724f252a4932961c083afJim Miller        if (mSafeModeEnabled || widgetsDisabled()) return;
2279ccf123ee0596ec9cab724f252a4932961c083afJim Miller
2289ccf123ee0596ec9cab724f252a4932961c083afJim Miller        // Clean up appWidgetIds that are bound to lockscreen, but not actually used
2299ccf123ee0596ec9cab724f252a4932961c083afJim Miller        // This is only to clean up after another bug: we used to not call
2309ccf123ee0596ec9cab724f252a4932961c083afJim Miller        // deleteAppWidgetId when a user manually deleted a widget in keyguard. This code
2319ccf123ee0596ec9cab724f252a4932961c083afJim Miller        // shouldn't have to run more than once per user. AppWidgetProviders rely on callbacks
2329ccf123ee0596ec9cab724f252a4932961c083afJim Miller        // that are triggered by deleteAppWidgetId, which is why we're doing this
2339ccf123ee0596ec9cab724f252a4932961c083afJim Miller        int[] appWidgetIdsInKeyguardSettings = mLockPatternUtils.getAppWidgets();
2349ccf123ee0596ec9cab724f252a4932961c083afJim Miller        int[] appWidgetIdsBoundToHost = mAppWidgetHost.getAppWidgetIds();
2359ccf123ee0596ec9cab724f252a4932961c083afJim Miller        for (int i = 0; i < appWidgetIdsBoundToHost.length; i++) {
2369ccf123ee0596ec9cab724f252a4932961c083afJim Miller            int appWidgetId = appWidgetIdsBoundToHost[i];
2379ccf123ee0596ec9cab724f252a4932961c083afJim Miller            if (!contains(appWidgetIdsInKeyguardSettings, appWidgetId)) {
2389ccf123ee0596ec9cab724f252a4932961c083afJim Miller                Log.d(TAG, "Found a appWidgetId that's not being used by keyguard, deleting id "
2399ccf123ee0596ec9cab724f252a4932961c083afJim Miller                        + appWidgetId);
2409ccf123ee0596ec9cab724f252a4932961c083afJim Miller                mAppWidgetHost.deleteAppWidgetId(appWidgetId);
24175b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka            }
24275b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka        }
24375b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka    }
24475b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka
24575b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka    private static boolean contains(int[] array, int target) {
24675b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka        for (int value : array) {
24775b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka            if (value == target) {
24875b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka                return true;
24975b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka            }
25075b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka        }
25175b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka        return false;
25275b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka    }
25375b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka
254efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen    private KeyguardUpdateMonitorCallback mUpdateMonitorCallbacks =
255efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen            new KeyguardUpdateMonitorCallback() {
256efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen        @Override
257efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen        public void onBootCompleted() {
2589ccf123ee0596ec9cab724f252a4932961c083afJim Miller            if (mPostBootCompletedRunnable != null) {
2599ccf123ee0596ec9cab724f252a4932961c083afJim Miller                mPostBootCompletedRunnable.run();
2609ccf123ee0596ec9cab724f252a4932961c083afJim Miller                mPostBootCompletedRunnable = null;
261545043e59e906525af646b1ecad1797258797590Michael Jurka            }
262efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen        }
263f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren        @Override
264f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren        public void onUserSwitchComplete(int userId) {
265f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren            if (mKeyguardMultiUserSelectorView != null) {
266f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren                mKeyguardMultiUserSelectorView.finalizeActiveUserView(true);
267f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren            }
268f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren        }
2698f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        @Override
2708f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        void onMusicClientIdChanged(
2718f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller                int clientGeneration, boolean clearing, android.app.PendingIntent intent) {
2728f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            // Set transport state to invisible until we know music is playing (below)
2738f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            if (DEBUGXPORT && (mClientGeneration != clientGeneration || clearing)) {
2748f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller                Log.v(TAG, (clearing ? "hide" : "show") + " transport, gen:" + clientGeneration);
2758f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            }
2768f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            mClientGeneration = clientGeneration;
277dfb57cdcfc6a1fd48395c13af98ecc2722fd5254Jim Miller            final int newState = (clearing ? TRANSPORT_GONE
278dfb57cdcfc6a1fd48395c13af98ecc2722fd5254Jim Miller                    : (mTransportState == TRANSPORT_VISIBLE ?
279dfb57cdcfc6a1fd48395c13af98ecc2722fd5254Jim Miller                    TRANSPORT_VISIBLE : TRANSPORT_INVISIBLE));
280dfb57cdcfc6a1fd48395c13af98ecc2722fd5254Jim Miller            if (newState != mTransportState) {
281dfb57cdcfc6a1fd48395c13af98ecc2722fd5254Jim Miller                mTransportState = newState;
282dfb57cdcfc6a1fd48395c13af98ecc2722fd5254Jim Miller                if (DEBUGXPORT) Log.v(TAG, "update widget: transport state changed");
2834d20ed3f26d1ec2c47519484bcc968098581c3d6Jim Miller                KeyguardHostView.this.post(mSwitchPageRunnable);
284dfb57cdcfc6a1fd48395c13af98ecc2722fd5254Jim Miller            }
2858f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        }
2868f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        @Override
2878f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        public void onMusicPlaybackStateChanged(int playbackState, long eventTime) {
2888f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            if (DEBUGXPORT) Log.v(TAG, "music state changed: " + playbackState);
2898f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            if (mTransportState != TRANSPORT_GONE) {
290dfb57cdcfc6a1fd48395c13af98ecc2722fd5254Jim Miller                final int newState = (isMusicPlaying(playbackState) ?
2918f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller                        TRANSPORT_VISIBLE : TRANSPORT_INVISIBLE);
292dfb57cdcfc6a1fd48395c13af98ecc2722fd5254Jim Miller                if (newState != mTransportState) {
293dfb57cdcfc6a1fd48395c13af98ecc2722fd5254Jim Miller                    mTransportState = newState;
294dfb57cdcfc6a1fd48395c13af98ecc2722fd5254Jim Miller                    if (DEBUGXPORT) Log.v(TAG, "update widget: play state changed");
2954d20ed3f26d1ec2c47519484bcc968098581c3d6Jim Miller                    KeyguardHostView.this.post(mSwitchPageRunnable);
296dfb57cdcfc6a1fd48395c13af98ecc2722fd5254Jim Miller                }
2978f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            }
2988f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        }
299efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen    };
300efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen
3018f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller    private static final boolean isMusicPlaying(int playbackState) {
3028f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        // This should agree with the list in AudioService.isPlaystateActive()
3038f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        switch (playbackState) {
3048f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            case RemoteControlClient.PLAYSTATE_PLAYING:
3058f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            case RemoteControlClient.PLAYSTATE_BUFFERING:
3068f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            case RemoteControlClient.PLAYSTATE_FAST_FORWARDING:
3078f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            case RemoteControlClient.PLAYSTATE_REWINDING:
3088f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            case RemoteControlClient.PLAYSTATE_SKIPPING_BACKWARDS:
3098f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            case RemoteControlClient.PLAYSTATE_SKIPPING_FORWARDS:
3108f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller                return true;
3118f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            default:
3128f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller                return false;
3138f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        }
3148f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller    }
3158f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller
3162cacda5fc92a28a44a37e25b96093a9cc1346080Jim Miller    private SlidingChallengeLayout mSlidingChallengeLayout;
317257f283b0e4cc1c1fa4e7f2472d3ee4ab3b451d0John Spurlock    private MultiPaneChallengeLayout mMultiPaneChallengeLayout;
3182cacda5fc92a28a44a37e25b96093a9cc1346080Jim Miller
319dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    @Override
320d2b82f70fede8c2ec4de34d8e6462ed4ece13c56Jim Miller    public boolean onTouchEvent(MotionEvent ev) {
321d2b82f70fede8c2ec4de34d8e6462ed4ece13c56Jim Miller        boolean result = super.onTouchEvent(ev);
3225737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller        mTempRect.set(0, 0, 0, 0);
3235737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller        offsetRectIntoDescendantCoords(mSecurityViewContainer, mTempRect);
3245737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller        ev.offsetLocation(mTempRect.left, mTempRect.top);
3255737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller        result = mSecurityViewContainer.dispatchTouchEvent(ev) || result;
3265737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller        ev.offsetLocation(-mTempRect.left, -mTempRect.top);
3275737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller        return result;
3285737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller    }
3295737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller
3305737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller    @Override
331dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    protected void dispatchDraw(Canvas canvas) {
332dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        super.dispatchDraw(canvas);
3337def1db03943251fe8cb57ec514722026425479eCraig Mautner        if (mViewMediatorCallback != null) {
3347def1db03943251fe8cb57ec514722026425479eCraig Mautner            mViewMediatorCallback.keyguardDoneDrawing();
3357def1db03943251fe8cb57ec514722026425479eCraig Mautner        }
336dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
337dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
338ff2aa0bc8919c247bfc8e81d3f168e5064f52ffbJim Miller    private int getWidgetPosition(int id) {
339982d21b9dc73eebd4b68a63579cf8be78c788c32Jim Miller        final KeyguardWidgetPager appWidgetContainer = mAppWidgetContainer;
340982d21b9dc73eebd4b68a63579cf8be78c788c32Jim Miller        final int children = appWidgetContainer.getChildCount();
341ff2aa0bc8919c247bfc8e81d3f168e5064f52ffbJim Miller        for (int i = 0; i < children; i++) {
342982d21b9dc73eebd4b68a63579cf8be78c788c32Jim Miller            final View content = appWidgetContainer.getWidgetPageAt(i).getContent();
343982d21b9dc73eebd4b68a63579cf8be78c788c32Jim Miller            if (content != null && content.getId() == id) {
344ff2aa0bc8919c247bfc8e81d3f168e5064f52ffbJim Miller                return i;
345982d21b9dc73eebd4b68a63579cf8be78c788c32Jim Miller            } else if (content == null) {
346982d21b9dc73eebd4b68a63579cf8be78c788c32Jim Miller                // Attempt to track down bug #8886916
347982d21b9dc73eebd4b68a63579cf8be78c788c32Jim Miller                Log.w(TAG, "*** Null content at " + "i=" + i + ",id=" + id + ",N=" + children);
348ff2aa0bc8919c247bfc8e81d3f168e5064f52ffbJim Miller            }
349ff2aa0bc8919c247bfc8e81d3f168e5064f52ffbJim Miller        }
350ff2aa0bc8919c247bfc8e81d3f168e5064f52ffbJim Miller        return -1;
351ff2aa0bc8919c247bfc8e81d3f168e5064f52ffbJim Miller    }
352ff2aa0bc8919c247bfc8e81d3f168e5064f52ffbJim Miller
353dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    @Override
354dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    protected void onFinishInflate() {
355d6523da1ad7bae805a3dbea8d7b398d86cd3c181Jim Miller        // Grab instances of and make any necessary changes to the main layouts. Create
356d6523da1ad7bae805a3dbea8d7b398d86cd3c181Jim Miller        // view state manager and wire up necessary listeners / callbacks.
357f3b9ec8230298e8f707c2fc44a74fb9346ec3d12Winson Chung        View deleteDropTarget = findViewById(R.id.keyguard_widget_pager_delete_target);
358f2dfc351dec58ad3c16f8496208b4e6e9c667efeJim Miller        mAppWidgetContainer = (KeyguardWidgetPager) findViewById(R.id.app_widget_container);
359838906b165e4d3cb2c512b2db344aa50cb5d4751Jim Miller        mAppWidgetContainer.setVisibility(VISIBLE);
360838906b165e4d3cb2c512b2db344aa50cb5d4751Jim Miller        mAppWidgetContainer.setCallbacks(mWidgetCallbacks);
361f3b9ec8230298e8f707c2fc44a74fb9346ec3d12Winson Chung        mAppWidgetContainer.setDeleteDropTarget(deleteDropTarget);
362d6523da1ad7bae805a3dbea8d7b398d86cd3c181Jim Miller        mAppWidgetContainer.setMinScale(0.5f);
363d6523da1ad7bae805a3dbea8d7b398d86cd3c181Jim Miller
3642cacda5fc92a28a44a37e25b96093a9cc1346080Jim Miller        mSlidingChallengeLayout = (SlidingChallengeLayout) findViewById(R.id.sliding_layout);
3652cacda5fc92a28a44a37e25b96093a9cc1346080Jim Miller        if (mSlidingChallengeLayout != null) {
3662cacda5fc92a28a44a37e25b96093a9cc1346080Jim Miller            mSlidingChallengeLayout.setOnChallengeScrolledListener(mViewStateManager);
36719a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        }
368d6523da1ad7bae805a3dbea8d7b398d86cd3c181Jim Miller        mAppWidgetContainer.setViewStateManager(mViewStateManager);
3691254f2f42f7173ef51d0034975ab5cb7d44f8209Michael Jurka        mAppWidgetContainer.setLockPatternUtils(mLockPatternUtils);
370d6523da1ad7bae805a3dbea8d7b398d86cd3c181Jim Miller
371257f283b0e4cc1c1fa4e7f2472d3ee4ab3b451d0John Spurlock        mMultiPaneChallengeLayout =
372257f283b0e4cc1c1fa4e7f2472d3ee4ab3b451d0John Spurlock                (MultiPaneChallengeLayout) findViewById(R.id.multi_pane_challenge);
3732cacda5fc92a28a44a37e25b96093a9cc1346080Jim Miller        ChallengeLayout challenge = mSlidingChallengeLayout != null ? mSlidingChallengeLayout :
374257f283b0e4cc1c1fa4e7f2472d3ee4ab3b451d0John Spurlock                mMultiPaneChallengeLayout;
37548275d2de99ff2556031929c48f295d3f93447b6Winson Chung        challenge.setOnBouncerStateChangedListener(mViewStateManager);
37670c2f8736437ebb6073c3b6dab2e08e6dd9f39a6Winson Chung        mAppWidgetContainer.setBouncerAnimationDuration(challenge.getBouncerAnimationDuration());
377d6523da1ad7bae805a3dbea8d7b398d86cd3c181Jim Miller        mViewStateManager.setPagedView(mAppWidgetContainer);
37848275d2de99ff2556031929c48f295d3f93447b6Winson Chung        mViewStateManager.setChallengeLayout(challenge);
3796fb841fa219eaae3e87f2fdc05e105d7a1813c42Adam Cohen        mSecurityViewContainer = (KeyguardSecurityViewFlipper) findViewById(R.id.view_flipper);
3800a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen        mKeyguardSelectorView = (KeyguardSelectorView) findViewById(R.id.keyguard_selector_view);
3816fb841fa219eaae3e87f2fdc05e105d7a1813c42Adam Cohen        mViewStateManager.setSecurityViewContainer(mSecurityViewContainer);
382ff2aa0bc8919c247bfc8e81d3f168e5064f52ffbJim Miller
38303eca859067ac0d4e419305de8ab0fdc03b4210fJohn Spurlock        setBackButtonEnabled(false);
38468c2489457631f733f542e14058c6d1274c203deJim Miller
3859ccf123ee0596ec9cab724f252a4932961c083afJim Miller        if (KeyguardUpdateMonitor.getInstance(mContext).hasBootCompleted()) {
3869ccf123ee0596ec9cab724f252a4932961c083afJim Miller            updateAndAddWidgets();
3879ccf123ee0596ec9cab724f252a4932961c083afJim Miller        } else {
3889ccf123ee0596ec9cab724f252a4932961c083afJim Miller            // We can't add widgets until after boot completes because AppWidgetHost may try
3899ccf123ee0596ec9cab724f252a4932961c083afJim Miller            // to contact the providers.  Do it later.
3909ccf123ee0596ec9cab724f252a4932961c083afJim Miller            mPostBootCompletedRunnable = new Runnable() {
3919ccf123ee0596ec9cab724f252a4932961c083afJim Miller                @Override
3929ccf123ee0596ec9cab724f252a4932961c083afJim Miller                public void run() {
3939ccf123ee0596ec9cab724f252a4932961c083afJim Miller                    updateAndAddWidgets();
3949ccf123ee0596ec9cab724f252a4932961c083afJim Miller                }
3959ccf123ee0596ec9cab724f252a4932961c083afJim Miller            };
3969ccf123ee0596ec9cab724f252a4932961c083afJim Miller        }
3979ccf123ee0596ec9cab724f252a4932961c083afJim Miller
3989ccf123ee0596ec9cab724f252a4932961c083afJim Miller        showPrimarySecurityScreen(false);
3999ccf123ee0596ec9cab724f252a4932961c083afJim Miller        updateSecurityViews();
4009ccf123ee0596ec9cab724f252a4932961c083afJim Miller        enableUserSelectorIfNecessary();
4019ccf123ee0596ec9cab724f252a4932961c083afJim Miller    }
40251117262c8fadb6d227d137e83ad66996b013141Jim Miller
4039ccf123ee0596ec9cab724f252a4932961c083afJim Miller    private void updateAndAddWidgets() {
4049ccf123ee0596ec9cab724f252a4932961c083afJim Miller        cleanupAppWidgetIds();
4059ccf123ee0596ec9cab724f252a4932961c083afJim Miller        addDefaultWidgets();
40667a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        addWidgetsFromSettings();
4079ccf123ee0596ec9cab724f252a4932961c083afJim Miller        maybeEnableAddButton();
40851117262c8fadb6d227d137e83ad66996b013141Jim Miller        checkAppWidgetConsistency();
4095547b55bae92e6674e528d671f7700d7f5a9b3d0Jim Miller
4105547b55bae92e6674e528d671f7700d7f5a9b3d0Jim Miller        // Don't let the user drag the challenge down if widgets are disabled.
4115547b55bae92e6674e528d671f7700d7f5a9b3d0Jim Miller        if (mSlidingChallengeLayout != null) {
4125547b55bae92e6674e528d671f7700d7f5a9b3d0Jim Miller            mSlidingChallengeLayout.setEnableChallengeDragging(!widgetsDisabled());
4135547b55bae92e6674e528d671f7700d7f5a9b3d0Jim Miller        }
4145547b55bae92e6674e528d671f7700d7f5a9b3d0Jim Miller
4159ccf123ee0596ec9cab724f252a4932961c083afJim Miller        // Select the appropriate page
41667a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        mSwitchPageRunnable.run();
4179ccf123ee0596ec9cab724f252a4932961c083afJim Miller
41845adaa70203a155beb786f22b251fe66b8d6fafdAdam Cohen        // This needs to be called after the pages are all added.
41945adaa70203a155beb786f22b251fe66b8d6fafdAdam Cohen        mViewStateManager.showUsabilityHints();
4209ccf123ee0596ec9cab724f252a4932961c083afJim Miller    }
42145adaa70203a155beb786f22b251fe66b8d6fafdAdam Cohen
4229ccf123ee0596ec9cab724f252a4932961c083afJim Miller    private void maybeEnableAddButton() {
4239ccf123ee0596ec9cab724f252a4932961c083afJim Miller        if (!shouldEnableAddWidget()) {
4249ccf123ee0596ec9cab724f252a4932961c083afJim Miller            mAppWidgetContainer.setAddWidgetEnabled(false);
4259ccf123ee0596ec9cab724f252a4932961c083afJim Miller        }
426e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller    }
427dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
42803eca859067ac0d4e419305de8ab0fdc03b4210fJohn Spurlock    private void setBackButtonEnabled(boolean enabled) {
42903eca859067ac0d4e419305de8ab0fdc03b4210fJohn Spurlock        if (mContext instanceof Activity) return;  // always enabled in activity mode
43003eca859067ac0d4e419305de8ab0fdc03b4210fJohn Spurlock        setSystemUiVisibility(enabled ?
43103eca859067ac0d4e419305de8ab0fdc03b4210fJohn Spurlock                getSystemUiVisibility() & ~View.STATUS_BAR_DISABLE_BACK :
43203eca859067ac0d4e419305de8ab0fdc03b4210fJohn Spurlock                getSystemUiVisibility() | View.STATUS_BAR_DISABLE_BACK);
43303eca859067ac0d4e419305de8ab0fdc03b4210fJohn Spurlock    }
43403eca859067ac0d4e419305de8ab0fdc03b4210fJohn Spurlock
435fff5614caecb0d2944b1bc206aaab0d3acb17670Michael Jurka    private boolean shouldEnableAddWidget() {
436fff5614caecb0d2944b1bc206aaab0d3acb17670Michael Jurka        return numWidgets() < MAX_WIDGETS && mUserSetupCompleted;
437fff5614caecb0d2944b1bc206aaab0d3acb17670Michael Jurka    }
438fff5614caecb0d2944b1bc206aaab0d3acb17670Michael Jurka
43951117262c8fadb6d227d137e83ad66996b013141Jim Miller    private int getDisabledFeatures(DevicePolicyManager dpm) {
44051117262c8fadb6d227d137e83ad66996b013141Jim Miller        int disabledFeatures = DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_NONE;
44151117262c8fadb6d227d137e83ad66996b013141Jim Miller        if (dpm != null) {
44251117262c8fadb6d227d137e83ad66996b013141Jim Miller            final int currentUser = mLockPatternUtils.getCurrentUser();
44351117262c8fadb6d227d137e83ad66996b013141Jim Miller            disabledFeatures = dpm.getKeyguardDisabledFeatures(null, currentUser);
44451117262c8fadb6d227d137e83ad66996b013141Jim Miller        }
44551117262c8fadb6d227d137e83ad66996b013141Jim Miller        return disabledFeatures;
44651117262c8fadb6d227d137e83ad66996b013141Jim Miller    }
44751117262c8fadb6d227d137e83ad66996b013141Jim Miller
448f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller    private boolean widgetsDisabled() {
449461b345886bc3c82b8e264158a7a754d59ea41ceJim Miller        boolean disabledByLowRamDevice = ActivityManager.isLowRamDeviceStatic();
450f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller        boolean disabledByDpm =
451f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller                (mDisabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_WIDGETS_ALL) != 0;
452f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller        boolean disabledByUser = !mLockPatternUtils.getWidgetsEnabled();
453461b345886bc3c82b8e264158a7a754d59ea41ceJim Miller        return disabledByLowRamDevice || disabledByDpm || disabledByUser;
45451117262c8fadb6d227d137e83ad66996b013141Jim Miller    }
45551117262c8fadb6d227d137e83ad66996b013141Jim Miller
45651117262c8fadb6d227d137e83ad66996b013141Jim Miller    private boolean cameraDisabledByDpm() {
45751117262c8fadb6d227d137e83ad66996b013141Jim Miller        return mCameraDisabled
45851117262c8fadb6d227d137e83ad66996b013141Jim Miller                || (mDisabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) != 0;
45951117262c8fadb6d227d137e83ad66996b013141Jim Miller    }
46051117262c8fadb6d227d137e83ad66996b013141Jim Miller
461e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller    private void updateSecurityViews() {
462e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        int children = mSecurityViewContainer.getChildCount();
463e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        for (int i = 0; i < children; i++) {
464e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            updateSecurityView(mSecurityViewContainer.getChildAt(i));
465e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        }
466e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller    }
467dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
468e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller    private void updateSecurityView(View view) {
469e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        if (view instanceof KeyguardSecurityView) {
470e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            KeyguardSecurityView ksv = (KeyguardSecurityView) view;
471e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            ksv.setKeyguardCallback(mCallback);
472e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            ksv.setLockPatternUtils(mLockPatternUtils);
473c0ae9e67ebe6f1298800feaed1b43e867139a904Chris Wren            if (mViewStateManager.isBouncing()) {
474c0ae9e67ebe6f1298800feaed1b43e867139a904Chris Wren                ksv.showBouncer(0);
475c0ae9e67ebe6f1298800feaed1b43e867139a904Chris Wren            } else {
476c0ae9e67ebe6f1298800feaed1b43e867139a904Chris Wren                ksv.hideBouncer(0);
477c0ae9e67ebe6f1298800feaed1b43e867139a904Chris Wren            }
478e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        } else {
479e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            Log.w(TAG, "View " + view + " is not a KeyguardSecurityView");
480dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
481dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
482dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
483dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    void setLockPatternUtils(LockPatternUtils utils) {
484dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        mSecurityModel.setLockPatternUtils(utils);
485dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        mLockPatternUtils = utils;
486e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        updateSecurityViews();
487dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
488dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
489dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    @Override
490dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    protected void onAttachedToWindow() {
491dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        super.onAttachedToWindow();
492a75a883fe9ea1790803148f0a561473073e3f264Jim Miller        mAppWidgetHost.startListening();
493efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen        KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mUpdateMonitorCallbacks);
4947221d3ae08cc2be922d26e5d491038512cb6c74dJim Miller    }
4957221d3ae08cc2be922d26e5d491038512cb6c74dJim Miller
496dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    @Override
497dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    protected void onDetachedFromWindow() {
498dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        super.onDetachedFromWindow();
499a75a883fe9ea1790803148f0a561473073e3f264Jim Miller        mAppWidgetHost.stopListening();
500efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen        KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mUpdateMonitorCallbacks);
501dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
502dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
503d6523da1ad7bae805a3dbea8d7b398d86cd3c181Jim Miller    void addWidget(AppWidgetHostView view, int pageIndex) {
504d6523da1ad7bae805a3dbea8d7b398d86cd3c181Jim Miller        mAppWidgetContainer.addWidget(view, pageIndex);
505dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
506dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
507838906b165e4d3cb2c512b2db344aa50cb5d4751Jim Miller    private KeyguardWidgetPager.Callbacks mWidgetCallbacks
508838906b165e4d3cb2c512b2db344aa50cb5d4751Jim Miller            = new KeyguardWidgetPager.Callbacks() {
509c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown        @Override
510c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown        public void userActivity() {
51108c83ef48880b98ec45dd83867a29852160a96ebAdam Cohen            KeyguardHostView.this.userActivity();
512c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown        }
513c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown
514c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown        @Override
515c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown        public void onUserActivityTimeoutChanged() {
51608c83ef48880b98ec45dd83867a29852160a96ebAdam Cohen            KeyguardHostView.this.onUserActivityTimeoutChanged();
517c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown        }
518eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka
519eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka        @Override
52040f8211e6849c4c7948d7fc19127f29f0cebbeb9Winson Chung        public void onAddView(View v) {
521fff5614caecb0d2944b1bc206aaab0d3acb17670Michael Jurka            if (!shouldEnableAddWidget()) {
5224752e7d1a9ff83d946890b0020de091f4346a7aeWinson Chung                mAppWidgetContainer.setAddWidgetEnabled(false);
52340f8211e6849c4c7948d7fc19127f29f0cebbeb9Winson Chung            }
5244752e7d1a9ff83d946890b0020de091f4346a7aeWinson Chung        }
52540f8211e6849c4c7948d7fc19127f29f0cebbeb9Winson Chung
52640f8211e6849c4c7948d7fc19127f29f0cebbeb9Winson Chung        @Override
52775b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka        public void onRemoveView(View v, boolean deletePermanently) {
52875b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka            if (deletePermanently) {
52975b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka                final int appWidgetId = ((KeyguardWidgetFrame) v).getContentAppWidgetId();
53075b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka                if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID &&
53175b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka                        appWidgetId != LockPatternUtils.ID_DEFAULT_STATUS_WIDGET) {
53275b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka                    mAppWidgetHost.deleteAppWidgetId(appWidgetId);
53375b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka                }
53475b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka            }
535eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka        }
5364752e7d1a9ff83d946890b0020de091f4346a7aeWinson Chung
5374752e7d1a9ff83d946890b0020de091f4346a7aeWinson Chung        @Override
5384752e7d1a9ff83d946890b0020de091f4346a7aeWinson Chung        public void onRemoveViewAnimationCompleted() {
539fff5614caecb0d2944b1bc206aaab0d3acb17670Michael Jurka            if (shouldEnableAddWidget()) {
5404752e7d1a9ff83d946890b0020de091f4346a7aeWinson Chung                mAppWidgetContainer.setAddWidgetEnabled(true);
5414752e7d1a9ff83d946890b0020de091f4346a7aeWinson Chung            }
5424752e7d1a9ff83d946890b0020de091f4346a7aeWinson Chung        }
543c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown    };
544c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown
545f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren    public void initializeSwitchingUserState(boolean switching) {
546f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren        if (!switching && mKeyguardMultiUserSelectorView != null) {
547f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren            mKeyguardMultiUserSelectorView.finalizeActiveUserView(false);
548f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren        }
549f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren    }
550f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren
55108c83ef48880b98ec45dd83867a29852160a96ebAdam Cohen    public void userActivity() {
55208c83ef48880b98ec45dd83867a29852160a96ebAdam Cohen        if (mViewMediatorCallback != null) {
55308c83ef48880b98ec45dd83867a29852160a96ebAdam Cohen            mViewMediatorCallback.userActivity();
55408c83ef48880b98ec45dd83867a29852160a96ebAdam Cohen        }
55508c83ef48880b98ec45dd83867a29852160a96ebAdam Cohen    }
55608c83ef48880b98ec45dd83867a29852160a96ebAdam Cohen
55708c83ef48880b98ec45dd83867a29852160a96ebAdam Cohen    public void onUserActivityTimeoutChanged() {
55808c83ef48880b98ec45dd83867a29852160a96ebAdam Cohen        if (mViewMediatorCallback != null) {
55908c83ef48880b98ec45dd83867a29852160a96ebAdam Cohen            mViewMediatorCallback.onUserActivityTimeoutChanged();
56008c83ef48880b98ec45dd83867a29852160a96ebAdam Cohen        }
56108c83ef48880b98ec45dd83867a29852160a96ebAdam Cohen    }
56208c83ef48880b98ec45dd83867a29852160a96ebAdam Cohen
563c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown    @Override
564c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown    public long getUserActivityTimeout() {
565c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown        // Currently only considering user activity timeouts needed by widgets.
566c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown        // Could also take into account longer timeouts for certain security views.
567838906b165e4d3cb2c512b2db344aa50cb5d4751Jim Miller        if (mAppWidgetContainer != null) {
568838906b165e4d3cb2c512b2db344aa50cb5d4751Jim Miller            return mAppWidgetContainer.getUserActivityTimeout();
569c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown        }
570c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown        return -1;
571c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown    }
572c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown
573dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    private KeyguardSecurityCallback mCallback = new KeyguardSecurityCallback() {
574dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
575dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        public void userActivity(long timeout) {
5767def1db03943251fe8cb57ec514722026425479eCraig Mautner            if (mViewMediatorCallback != null) {
5773dc524bc31a1578693ca958ef442dfa092b7aa7fJeff Brown                mViewMediatorCallback.userActivity(timeout);
5787def1db03943251fe8cb57ec514722026425479eCraig Mautner            }
579dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
580dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
581dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        public void dismiss(boolean authenticated) {
582dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            showNextSecurityScreenOrFinish(authenticated);
583dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
584dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
585dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        public boolean isVerifyUnlockOnly() {
586258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            return mIsVerifyUnlockOnly;
587dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
588dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
589dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        public void reportSuccessfulUnlockAttempt() {
590258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            KeyguardUpdateMonitor.getInstance(mContext).clearFailedUnlockAttempts();
5917641506e3cc493ac4e6f5037fd76516754e61c6eJim Miller            mLockPatternUtils.reportSuccessfulPasswordAttempt();
592dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
593dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
594dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        public void reportFailedUnlockAttempt() {
5957641506e3cc493ac4e6f5037fd76516754e61c6eJim Miller            if (mCurrentSecuritySelection == SecurityMode.Biometric) {
5967641506e3cc493ac4e6f5037fd76516754e61c6eJim Miller                KeyguardUpdateMonitor.getInstance(mContext).reportFailedBiometricUnlockAttempt();
5977641506e3cc493ac4e6f5037fd76516754e61c6eJim Miller            } else {
5987641506e3cc493ac4e6f5037fd76516754e61c6eJim Miller                KeyguardHostView.this.reportFailedUnlockAttempt();
5997641506e3cc493ac4e6f5037fd76516754e61c6eJim Miller            }
600dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
601dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
602dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        public int getFailedAttempts() {
603258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            return KeyguardUpdateMonitor.getInstance(mContext).getFailedUnlockAttempts();
604dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
605dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
606258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        @Override
607258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        public void showBackupSecurity() {
6080ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller            KeyguardHostView.this.showBackupSecurityScreen();
609dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
610dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
6115f75aa15d7c1c5ea1c1eecd95bf2bb0920173eb2Jim Miller        @Override
61234c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock        public void setOnDismissAction(OnDismissAction action) {
61334c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock            KeyguardHostView.this.setOnDismissAction(action);
6145f75aa15d7c1c5ea1c1eecd95bf2bb0920173eb2Jim Miller        }
6155f75aa15d7c1c5ea1c1eecd95bf2bb0920173eb2Jim Miller
616dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    };
617dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
618258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    private void showDialog(String title, String message) {
619258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        final AlertDialog dialog = new AlertDialog.Builder(mContext)
620258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            .setTitle(title)
621258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            .setMessage(message)
6225ecd81154fa039961f65bb4e36d18ac555b0d1d6Jim Miller            .setNeutralButton(R.string.ok, null)
623258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            .create();
624258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        if (!(mContext instanceof Activity)) {
625258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
626258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        }
627258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        dialog.show();
628258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    }
629258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
630258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    private void showTimeoutDialog() {
631258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        int timeoutInSeconds = (int) LockPatternUtils.FAILED_ATTEMPT_TIMEOUT_MS / 1000;
632258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        int messageId = 0;
633258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
634258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        switch (mSecurityModel.getSecurityMode()) {
635258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            case Pattern:
636258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                messageId = R.string.kg_too_many_failed_pattern_attempts_dialog_message;
637258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                break;
63869bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler            case PIN:
63969bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler                messageId = R.string.kg_too_many_failed_pin_attempts_dialog_message;
64069bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler                break;
64169bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler            case Password:
64269bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler                messageId = R.string.kg_too_many_failed_password_attempts_dialog_message;
643258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                break;
644258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        }
645258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
646258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        if (messageId != 0) {
647258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            final String message = mContext.getString(messageId,
648258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                    KeyguardUpdateMonitor.getInstance(mContext).getFailedUnlockAttempts(),
649258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                    timeoutInSeconds);
650258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            showDialog(null, message);
651258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        }
652258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    }
653258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
654258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    private void showAlmostAtWipeDialog(int attempts, int remaining) {
655258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        String message = mContext.getString(R.string.kg_failed_attempts_almost_at_wipe,
656258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                attempts, remaining);
657258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        showDialog(null, message);
658258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    }
659258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
660258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    private void showWipeDialog(int attempts) {
661258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        String message = mContext.getString(R.string.kg_failed_attempts_now_wiping, attempts);
662258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        showDialog(null, message);
663258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    }
664258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
665258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    private void showAlmostAtAccountLoginDialog() {
666258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        final int timeoutInSeconds = (int) LockPatternUtils.FAILED_ATTEMPT_TIMEOUT_MS / 1000;
667258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        final int count = LockPatternUtils.FAILED_ATTEMPTS_BEFORE_RESET
668258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                - LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT;
669258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        String message = mContext.getString(R.string.kg_failed_attempts_almost_at_login,
670258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                count, LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT, timeoutInSeconds);
671258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        showDialog(null, message);
672258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    }
673258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
674258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    private void reportFailedUnlockAttempt() {
675258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        final KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(mContext);
676258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        final int failedAttempts = monitor.getFailedUnlockAttempts() + 1; // +1 for this time
677258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
678258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        if (DEBUG) Log.d(TAG, "reportFailedPatternAttempt: #" + failedAttempts);
679258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
680258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        SecurityMode mode = mSecurityModel.getSecurityMode();
681258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        final boolean usingPattern = mode == KeyguardSecurityModel.SecurityMode.Pattern;
682258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
683258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        final int failedAttemptsBeforeWipe = mLockPatternUtils.getDevicePolicyManager()
684599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                .getMaximumFailedPasswordsForWipe(null, mLockPatternUtils.getCurrentUser());
685258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
686258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        final int failedAttemptWarning = LockPatternUtils.FAILED_ATTEMPTS_BEFORE_RESET
687258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                - LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT;
688258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
689258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        final int remainingBeforeWipe = failedAttemptsBeforeWipe > 0 ?
690258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                (failedAttemptsBeforeWipe - failedAttempts)
691258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                : Integer.MAX_VALUE; // because DPM returns 0 if no restriction
692258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
69308b2b6bfe2550b65c68ad7b4bef8283f1ff17561Jim Miller        boolean showTimeout = false;
694258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        if (remainingBeforeWipe < LockPatternUtils.FAILED_ATTEMPTS_BEFORE_WIPE_GRACE) {
695258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            // If we reach this code, it means the user has installed a DevicePolicyManager
696258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            // that requests device wipe after N attempts.  Once we get below the grace
697258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            // period, we'll post this dialog every time as a clear warning until the
698258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            // bombshell hits and the device is wiped.
699258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            if (remainingBeforeWipe > 0) {
700258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                showAlmostAtWipeDialog(failedAttempts, remainingBeforeWipe);
701258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            } else {
702258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                // Too many attempts. The device will be wiped shortly.
703258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                Slog.i(TAG, "Too many unlock attempts; device will be wiped!");
704258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                showWipeDialog(failedAttempts);
705258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            }
706258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        } else {
70708b2b6bfe2550b65c68ad7b4bef8283f1ff17561Jim Miller            showTimeout =
708258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                (failedAttempts % LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT) == 0;
709258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            if (usingPattern && mEnableFallback) {
710258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                if (failedAttempts == failedAttemptWarning) {
711258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                    showAlmostAtAccountLoginDialog();
712258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                    showTimeout = false; // don't show both dialogs
713258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                } else if (failedAttempts >= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_RESET) {
714258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                    mLockPatternUtils.setPermanentlyLocked(true);
715e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller                    showSecurityScreen(SecurityMode.Account);
716258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                    // don't show timeout dialog because we show account unlock screen next
717258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                    showTimeout = false;
718258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                }
719258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            }
720258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        }
721258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        monitor.reportFailedUnlockAttempt();
722258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        mLockPatternUtils.reportFailedPasswordAttempt();
72308b2b6bfe2550b65c68ad7b4bef8283f1ff17561Jim Miller        if (showTimeout) {
72408b2b6bfe2550b65c68ad7b4bef8283f1ff17561Jim Miller            showTimeoutDialog();
72508b2b6bfe2550b65c68ad7b4bef8283f1ff17561Jim Miller        }
726258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    }
727258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
728258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    /**
7290ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller     * Shows the primary security screen for the user. This will be either the multi-selector
7300ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller     * or the user's security method.
7310ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller     * @param turningOff true if the device is being turned off
7320ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller     */
7330ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller    void showPrimarySecurityScreen(boolean turningOff) {
7340ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller        SecurityMode securityMode = mSecurityModel.getSecurityMode();
7350ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller        if (DEBUG) Log.v(TAG, "showPrimarySecurityScreen(turningOff=" + turningOff + ")");
736078f5919a9584cc3f1c7eb3a78862bfa40396de9Brian Colonna        if (!turningOff &&
737078f5919a9584cc3f1c7eb3a78862bfa40396de9Brian Colonna                KeyguardUpdateMonitor.getInstance(mContext).isAlternateUnlockEnabled()) {
7380ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller            // If we're not turning off, then allow biometric alternate.
7390ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller            // We'll reload it when the device comes back on.
7400ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller            securityMode = mSecurityModel.getAlternateFor(securityMode);
7410ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller        }
7420ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller        showSecurityScreen(securityMode);
7430ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller    }
74468c2489457631f733f542e14058c6d1274c203deJim Miller
7450ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller    /**
746258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller     * Shows the backup security screen for the current security mode.  This could be used for
747258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller     * password recovery screens but is currently only used for pattern unlock to show the
748258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller     * account unlock screen and biometric unlock to show the user's normal unlock.
749258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller     */
7500ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller    private void showBackupSecurityScreen() {
75161413b5ed215accd7b4f3eaf80edeab2f330aa49Danielle Millett        if (DEBUG) Log.d(TAG, "showBackupSecurity()");
75263f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        SecurityMode backup = mSecurityModel.getBackupSecurityMode(mCurrentSecuritySelection);
75363f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        showSecurityScreen(backup);
754258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    }
755258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
7560a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen    public boolean showNextSecurityScreenIfPresent() {
7570a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen        SecurityMode securityMode = mSecurityModel.getSecurityMode();
7580a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen        // Allow an alternate, such as biometric unlock
7590a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen        securityMode = mSecurityModel.getAlternateFor(securityMode);
7600a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen        if (SecurityMode.None == securityMode) {
7610a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen            return false;
7620a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen        } else {
7630a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen            showSecurityScreen(securityMode); // switch to the alternate security view
7640a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen            return true;
7650a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen        }
7660a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen    }
7670a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen
768258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    private void showNextSecurityScreenOrFinish(boolean authenticated) {
76961413b5ed215accd7b4f3eaf80edeab2f330aa49Danielle Millett        if (DEBUG) Log.d(TAG, "showNextSecurityScreenOrFinish(" + authenticated + ")");
770dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        boolean finish = false;
771e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        if (SecurityMode.None == mCurrentSecuritySelection) {
772258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            SecurityMode securityMode = mSecurityModel.getSecurityMode();
773258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            // Allow an alternate, such as biometric unlock
774000464ac012471d301c6e48a8228291519915e17Jim Miller            securityMode = mSecurityModel.getAlternateFor(securityMode);
775e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            if (SecurityMode.None == securityMode) {
776dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                finish = true; // no security required
777dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            } else {
778e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller                showSecurityScreen(securityMode); // switch to the alternate security view
779dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            }
780dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        } else if (authenticated) {
781e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            switch (mCurrentSecuritySelection) {
782e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller                case Pattern:
783e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller                case Password:
78469bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler                case PIN:
785e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller                case Account:
786e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller                case Biometric:
7874b09dd31fb1cefcaee87e7a206f22ba31527e250Jim Miller                    finish = true;
7884b09dd31fb1cefcaee87e7a206f22ba31527e250Jim Miller                    break;
7894b09dd31fb1cefcaee87e7a206f22ba31527e250Jim Miller
790e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller                case SimPin:
791e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller                case SimPuk:
7924b09dd31fb1cefcaee87e7a206f22ba31527e250Jim Miller                    // Shortcut for SIM PIN/PUK to go to directly to user's security screen or home
7934b09dd31fb1cefcaee87e7a206f22ba31527e250Jim Miller                    SecurityMode securityMode = mSecurityModel.getSecurityMode();
7944b09dd31fb1cefcaee87e7a206f22ba31527e250Jim Miller                    if (securityMode != SecurityMode.None) {
795e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller                        showSecurityScreen(securityMode);
7964b09dd31fb1cefcaee87e7a206f22ba31527e250Jim Miller                    } else {
7974b09dd31fb1cefcaee87e7a206f22ba31527e250Jim Miller                        finish = true;
7984b09dd31fb1cefcaee87e7a206f22ba31527e250Jim Miller                    }
7994b09dd31fb1cefcaee87e7a206f22ba31527e250Jim Miller                    break;
8004b09dd31fb1cefcaee87e7a206f22ba31527e250Jim Miller
8014b09dd31fb1cefcaee87e7a206f22ba31527e250Jim Miller                default:
8020ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller                    Log.v(TAG, "Bad security screen " + mCurrentSecuritySelection + ", fail safe");
8030ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller                    showPrimarySecurityScreen(false);
8044b09dd31fb1cefcaee87e7a206f22ba31527e250Jim Miller                    break;
805dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            }
806dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        } else {
8070ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller            showPrimarySecurityScreen(false);
808dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
809dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        if (finish) {
8100ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller            // If the alternate unlock was suppressed, it can now be safely
8110ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller            // enabled because the user has left keyguard.
8120ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller            KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(true);
81368c2489457631f733f542e14058c6d1274c203deJim Miller
814dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            // If there's a pending runnable because the user interacted with a widget
815dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            // and we're leaving keyguard, then run it.
81634c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock            boolean deferKeyguardDone = false;
81734c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock            if (mDismissAction != null) {
81834c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock                deferKeyguardDone = mDismissAction.onDismiss();
81934c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock                mDismissAction = null;
820dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            }
8217def1db03943251fe8cb57ec514722026425479eCraig Mautner            if (mViewMediatorCallback != null) {
82234c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock                if (deferKeyguardDone) {
82334c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock                    mViewMediatorCallback.keyguardDonePending();
82434c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock                } else {
82534c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock                    mViewMediatorCallback.keyguardDone(true);
82634c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock                }
8277def1db03943251fe8cb57ec514722026425479eCraig Mautner            }
828b5f3b707a7010e8d867da9342ea87cf0a1679692Jim Miller        } else {
829b5f3b707a7010e8d867da9342ea87cf0a1679692Jim Miller            mViewStateManager.showBouncer(true);
830dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
831dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
832dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
8337fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haase    private static class MyOnClickHandler extends OnClickHandler {
8347fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haase
8357fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haase        // weak reference to the hostView to avoid keeping a live reference
8367fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haase        // due to Binder GC linkages to AppWidgetHost. By the same token,
8377fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haase        // this click handler should not keep references to any large
8387fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haase        // objects.
8397fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haase        WeakReference<KeyguardHostView> mThis;
8407fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haase
8417fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haase        MyOnClickHandler(KeyguardHostView hostView) {
8427fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haase            mThis = new WeakReference<KeyguardHostView>(hostView);
8437fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haase        }
8447fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haase
845dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        @Override
846dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        public boolean onClickHandler(final View view,
847dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                final android.app.PendingIntent pendingIntent,
848dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                final Intent fillInIntent) {
8497fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haase            KeyguardHostView hostView = mThis.get();
8507fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haase            if (hostView == null) {
8517fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haase                return false;
8527fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haase            }
853dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            if (pendingIntent.isActivity()) {
8547fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haase                hostView.setOnDismissAction(new OnDismissAction() {
85534c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock                    public boolean onDismiss() {
856dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                        try {
8577fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haase                            // TODO: Unregister this handler if PendingIntent.FLAG_ONE_SHOT?
8587fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haase                            Context context = view.getContext();
8597fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haase                            ActivityOptions opts = ActivityOptions.makeScaleUpAnimation(view,
8607fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haase                                    0, 0,
8617fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haase                                    view.getMeasuredWidth(), view.getMeasuredHeight());
8627fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haase                            context.startIntentSender(
8637fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haase                                    pendingIntent.getIntentSender(), fillInIntent,
8647fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haase                                    Intent.FLAG_ACTIVITY_NEW_TASK,
8657fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haase                                    Intent.FLAG_ACTIVITY_NEW_TASK, 0, opts.toBundle());
86634c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock                        } catch (IntentSender.SendIntentException e) {
86734c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock                            android.util.Log.e(TAG, "Cannot send pending intent: ", e);
86834c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock                        } catch (Exception e) {
86934c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock                            android.util.Log.e(TAG, "Cannot send pending intent due to " +
87034c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock                                    "unknown exception: ", e);
87134c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock                        }
87234c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock                        return false;
873dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                    }
8745f75aa15d7c1c5ea1c1eecd95bf2bb0920173eb2Jim Miller                });
875dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
8767fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haase                if (hostView.mViewStateManager.isChallengeShowing()) {
8777fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haase                    hostView.mViewStateManager.showBouncer(true);
87808898375fba7cc776857ebf0846c7183563a300fJim Miller                } else {
8797fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haase                    hostView.mCallback.dismiss(false);
88008898375fba7cc776857ebf0846c7183563a300fJim Miller                }
881dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                return true;
882dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            } else {
883dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                return super.onClickHandler(view, pendingIntent, fillInIntent);
884dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            }
885dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        };
886dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    };
887dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
88863f9b81795559443e0376985f8aaaa97a359ef94Jim Miller    // Used to ignore callbacks from methods that are no longer current (e.g. face unlock).
88963f9b81795559443e0376985f8aaaa97a359ef94Jim Miller    // This avoids unwanted asynchronous events from messing with the state.
89063f9b81795559443e0376985f8aaaa97a359ef94Jim Miller    private KeyguardSecurityCallback mNullCallback = new KeyguardSecurityCallback() {
89163f9b81795559443e0376985f8aaaa97a359ef94Jim Miller
89263f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        @Override
89363f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        public void userActivity(long timeout) {
89463f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        }
89563f9b81795559443e0376985f8aaaa97a359ef94Jim Miller
89663f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        @Override
89763f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        public void showBackupSecurity() {
89863f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        }
89963f9b81795559443e0376985f8aaaa97a359ef94Jim Miller
90063f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        @Override
90134c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock        public void setOnDismissAction(OnDismissAction action) {
90263f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        }
90363f9b81795559443e0376985f8aaaa97a359ef94Jim Miller
90463f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        @Override
90563f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        public void reportSuccessfulUnlockAttempt() {
90663f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        }
90763f9b81795559443e0376985f8aaaa97a359ef94Jim Miller
90863f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        @Override
90963f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        public void reportFailedUnlockAttempt() {
91063f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        }
91163f9b81795559443e0376985f8aaaa97a359ef94Jim Miller
91263f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        @Override
91363f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        public boolean isVerifyUnlockOnly() {
91463f9b81795559443e0376985f8aaaa97a359ef94Jim Miller            return false;
91563f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        }
91663f9b81795559443e0376985f8aaaa97a359ef94Jim Miller
91763f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        @Override
91863f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        public int getFailedAttempts() {
91963f9b81795559443e0376985f8aaaa97a359ef94Jim Miller            return 0;
92063f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        }
92163f9b81795559443e0376985f8aaaa97a359ef94Jim Miller
92263f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        @Override
92363f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        public void dismiss(boolean securityVerified) {
92463f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        }
92563f9b81795559443e0376985f8aaaa97a359ef94Jim Miller    };
92663f9b81795559443e0376985f8aaaa97a359ef94Jim Miller
9275f75aa15d7c1c5ea1c1eecd95bf2bb0920173eb2Jim Miller    /**
92834c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock     * Sets an action to perform when keyguard is dismissed.
92934c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock     * @param action
9305f75aa15d7c1c5ea1c1eecd95bf2bb0920173eb2Jim Miller     */
93134c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock    protected void setOnDismissAction(OnDismissAction action) {
93234c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock        mDismissAction = action;
9335f75aa15d7c1c5ea1c1eecd95bf2bb0920173eb2Jim Miller    }
9345f75aa15d7c1c5ea1c1eecd95bf2bb0920173eb2Jim Miller
935e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller    private KeyguardSecurityView getSecurityView(SecurityMode securityMode) {
936e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        final int securityViewIdForMode = getSecurityViewIdForMode(securityMode);
937e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        KeyguardSecurityView view = null;
938e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        final int children = mSecurityViewContainer.getChildCount();
939dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        for (int child = 0; child < children; child++) {
940e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            if (mSecurityViewContainer.getChildAt(child).getId() == securityViewIdForMode) {
941e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller                view = ((KeyguardSecurityView)mSecurityViewContainer.getChildAt(child));
942e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller                break;
943dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            }
944dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
94563f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        int layoutId = getLayoutIdFor(securityMode);
94663f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        if (view == null && layoutId != 0) {
947e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            final LayoutInflater inflater = LayoutInflater.from(mContext);
948bdffd5c3a18e67443ebbd16d4f0349d0728285b1Jim Miller            if (DEBUG) Log.v(TAG, "inflating id = " + layoutId);
9499799714f6c69efe50e21a6073b879140e5e792b7Adam Powell            View v = inflater.inflate(layoutId, mSecurityViewContainer, false);
950e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            mSecurityViewContainer.addView(v);
951e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            updateSecurityView(v);
9520b728244dc87b4a453f2191c2cb37a86e91aee0aJim Miller            view = (KeyguardSecurityView)v;
9530ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller        }
9540ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller
9550ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller        if (view instanceof KeyguardSelectorView) {
9560ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller            KeyguardSelectorView selectorView = (KeyguardSelectorView) view;
9570ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller            View carrierText = selectorView.findViewById(R.id.keyguard_selector_fade_container);
9580ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller            selectorView.setCarrierArea(carrierText);
9590ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller        }
96068c2489457631f733f542e14058c6d1274c203deJim Miller
961e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        return view;
962dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
963dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
964258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    /**
965258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller     * Switches to the given security view unless it's already being shown, in which case
966258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller     * this is a no-op.
967258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller     *
968e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller     * @param securityMode
969258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller     */
970e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller    private void showSecurityScreen(SecurityMode securityMode) {
97168c2489457631f733f542e14058c6d1274c203deJim Miller        if (DEBUG) Log.d(TAG, "showSecurityScreen(" + securityMode + ")");
97268c2489457631f733f542e14058c6d1274c203deJim Miller
973e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        if (securityMode == mCurrentSecuritySelection) return;
974dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
975e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        KeyguardSecurityView oldView = getSecurityView(mCurrentSecuritySelection);
976e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        KeyguardSecurityView newView = getSecurityView(securityMode);
977dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
978a71984f3da47c6e6e3164c170735362a3222d3adJim Miller        // Enter full screen mode if we're in SIM or Account screen
9795ecd81154fa039961f65bb4e36d18ac555b0d1d6Jim Miller        boolean fullScreenEnabled = getResources().getBoolean(R.bool.kg_sim_puk_account_full_screen);
980a71984f3da47c6e6e3164c170735362a3222d3adJim Miller        boolean isSimOrAccount = securityMode == SecurityMode.SimPin
981a71984f3da47c6e6e3164c170735362a3222d3adJim Miller                || securityMode == SecurityMode.SimPuk
982a71984f3da47c6e6e3164c170735362a3222d3adJim Miller                || securityMode == SecurityMode.Account;
983a71984f3da47c6e6e3164c170735362a3222d3adJim Miller        mAppWidgetContainer.setVisibility(
984a71984f3da47c6e6e3164c170735362a3222d3adJim Miller                isSimOrAccount && fullScreenEnabled ? View.GONE : View.VISIBLE);
985a71984f3da47c6e6e3164c170735362a3222d3adJim Miller
9869c993bd6ba75eb07e2f8e68cf57c780a83699116Jim Miller        // Don't show camera or search in navbar when SIM or Account screen is showing
9879c993bd6ba75eb07e2f8e68cf57c780a83699116Jim Miller        setSystemUiVisibility(isSimOrAccount ?
9889c993bd6ba75eb07e2f8e68cf57c780a83699116Jim Miller                (getSystemUiVisibility() | View.STATUS_BAR_DISABLE_SEARCH)
9899c993bd6ba75eb07e2f8e68cf57c780a83699116Jim Miller                : (getSystemUiVisibility() & ~View.STATUS_BAR_DISABLE_SEARCH));
9909c993bd6ba75eb07e2f8e68cf57c780a83699116Jim Miller
9912cacda5fc92a28a44a37e25b96093a9cc1346080Jim Miller        if (mSlidingChallengeLayout != null) {
9922cacda5fc92a28a44a37e25b96093a9cc1346080Jim Miller            mSlidingChallengeLayout.setChallengeInteractive(!fullScreenEnabled);
9932cacda5fc92a28a44a37e25b96093a9cc1346080Jim Miller        }
9942cacda5fc92a28a44a37e25b96093a9cc1346080Jim Miller
995dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        // Emulate Activity life cycle
99663f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        if (oldView != null) {
99763f9b81795559443e0376985f8aaaa97a359ef94Jim Miller            oldView.onPause();
99863f9b81795559443e0376985f8aaaa97a359ef94Jim Miller            oldView.setKeyguardCallback(mNullCallback); // ignore requests from old view
99963f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        }
1000a042ac90640c0c3fd3c5349083b86bbfd6319b64Chris Wren        newView.onResume(KeyguardSecurityView.VIEW_REVEALED);
100163f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        newView.setKeyguardCallback(mCallback);
1002dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
1003cd03a26f4f5663b40d4679de102519ccc163fa10Craig Mautner        final boolean needsInput = newView.needsInput();
10047def1db03943251fe8cb57ec514722026425479eCraig Mautner        if (mViewMediatorCallback != null) {
1005cd03a26f4f5663b40d4679de102519ccc163fa10Craig Mautner            mViewMediatorCallback.setNeedsInput(needsInput);
10067def1db03943251fe8cb57ec514722026425479eCraig Mautner        }
1007dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
1008dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        // Find and show this child.
1009e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        final int childCount = mSecurityViewContainer.getChildCount();
10104b09dd31fb1cefcaee87e7a206f22ba31527e250Jim Miller
1011e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        final int securityViewIdForMode = getSecurityViewIdForMode(securityMode);
1012dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        for (int i = 0; i < childCount; i++) {
1013e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            if (mSecurityViewContainer.getChildAt(i).getId() == securityViewIdForMode) {
1014e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller                mSecurityViewContainer.setDisplayedChild(i);
1015dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                break;
1016dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            }
1017dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
1018258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
1019e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        if (securityMode == SecurityMode.None) {
1020e23ab8b1acea211762f1d0c4202f73a9f7700bb5Jim Miller            // Discard current runnable if we're switching back to the selector view
102134c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock            setOnDismissAction(null);
102268c2489457631f733f542e14058c6d1274c203deJim Miller        }
102303eca859067ac0d4e419305de8ab0fdc03b4210fJohn Spurlock        if (securityMode == SecurityMode.Account && !mLockPatternUtils.isPermanentlyLocked()) {
102403eca859067ac0d4e419305de8ab0fdc03b4210fJohn Spurlock            // we're showing account as a backup, provide a way to get back to primary
102503eca859067ac0d4e419305de8ab0fdc03b4210fJohn Spurlock            setBackButtonEnabled(true);
102603eca859067ac0d4e419305de8ab0fdc03b4210fJohn Spurlock        }
1027e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        mCurrentSecuritySelection = securityMode;
1028dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
1029dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
1030dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    @Override
1031dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    public void onScreenTurnedOn() {
1032358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock        if (DEBUG) Log.d(TAG, "screen on, instance " + Integer.toHexString(hashCode()));
10330ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller        showPrimarySecurityScreen(false);
1034a042ac90640c0c3fd3c5349083b86bbfd6319b64Chris Wren        getSecurityView(mCurrentSecuritySelection).onResume(KeyguardSecurityView.SCREEN_ON);
1035d03a5558350cb6adff68aaf97ad4ee946bcd91a1Jim Miller
1036d03a5558350cb6adff68aaf97ad4ee946bcd91a1Jim Miller        // This is a an attempt to fix bug 7137389 where the device comes back on but the entire
1037d03a5558350cb6adff68aaf97ad4ee946bcd91a1Jim Miller        // layout is blank but forcing a layout causes it to reappear (e.g. with with
1038d03a5558350cb6adff68aaf97ad4ee946bcd91a1Jim Miller        // hierarchyviewer).
1039d03a5558350cb6adff68aaf97ad4ee946bcd91a1Jim Miller        requestLayout();
10406fb841fa219eaae3e87f2fdc05e105d7a1813c42Adam Cohen
10416fb841fa219eaae3e87f2fdc05e105d7a1813c42Adam Cohen        if (mViewStateManager != null) {
10426fb841fa219eaae3e87f2fdc05e105d7a1813c42Adam Cohen            mViewStateManager.showUsabilityHints();
10436fb841fa219eaae3e87f2fdc05e105d7a1813c42Adam Cohen        }
1044eec83dcadd1dca722d3070fe5eae7d4e0561aa2bSandeep Siddhartha
1045147f9568afe645d9bfb91f3037f5336d8a2482ccJim Miller        requestFocus();
1046dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
1047dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
1048dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    @Override
1049dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    public void onScreenTurnedOff() {
1050dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock        if (DEBUG) Log.d(TAG, String.format("screen off, instance %s at %s",
1051dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock                Integer.toHexString(hashCode()), SystemClock.uptimeMillis()));
1052078f5919a9584cc3f1c7eb3a78862bfa40396de9Brian Colonna        // Once the screen turns off, we no longer consider this to be first boot and we want the
1053078f5919a9584cc3f1c7eb3a78862bfa40396de9Brian Colonna        // biometric unlock to start next time keyguard is shown.
1054078f5919a9584cc3f1c7eb3a78862bfa40396de9Brian Colonna        KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(true);
10551413889565bc1b9d5d5fb73302460a4f25f4a8c0Michael Jurka        // We use mAppWidgetToShow to show a particular widget after you add it-- once the screen
10561413889565bc1b9d5d5fb73302460a4f25f4a8c0Michael Jurka        // turns off we reset that behavior
10571413889565bc1b9d5d5fb73302460a4f25f4a8c0Michael Jurka        clearAppWidgetToShow();
10589ccf123ee0596ec9cab724f252a4932961c083afJim Miller        if (KeyguardUpdateMonitor.getInstance(mContext).hasBootCompleted()) {
10599ccf123ee0596ec9cab724f252a4932961c083afJim Miller            checkAppWidgetConsistency();
10609ccf123ee0596ec9cab724f252a4932961c083afJim Miller        }
10610ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller        showPrimarySecurityScreen(true);
1062e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        getSecurityView(mCurrentSecuritySelection).onPause();
1063dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock        CameraWidgetFrame cameraPage = findCameraPage();
1064dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock        if (cameraPage != null) {
1065dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock            cameraPage.onScreenTurnedOff();
1066dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock        }
1067eec83dcadd1dca722d3070fe5eae7d4e0561aa2bSandeep Siddhartha
1068147f9568afe645d9bfb91f3037f5336d8a2482ccJim Miller        clearFocus();
1069dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
1070dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
10711413889565bc1b9d5d5fb73302460a4f25f4a8c0Michael Jurka    public void clearAppWidgetToShow() {
10721413889565bc1b9d5d5fb73302460a4f25f4a8c0Michael Jurka        mAppWidgetToShow = AppWidgetManager.INVALID_APPWIDGET_ID;
10731413889565bc1b9d5d5fb73302460a4f25f4a8c0Michael Jurka    }
10741413889565bc1b9d5d5fb73302460a4f25f4a8c0Michael Jurka
1075dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    @Override
1076dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    public void show() {
1077086977094d96ab9352432e0941a05b09cefc92acJim Miller        if (DEBUG) Log.d(TAG, "show()");
1078086977094d96ab9352432e0941a05b09cefc92acJim Miller        showPrimarySecurityScreen(false);
1079dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
1080dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
1081dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    @Override
1082dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    public void verifyUnlock() {
1083dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        SecurityMode securityMode = mSecurityModel.getSecurityMode();
1084dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        if (securityMode == KeyguardSecurityModel.SecurityMode.None) {
10857def1db03943251fe8cb57ec514722026425479eCraig Mautner            if (mViewMediatorCallback != null) {
10867def1db03943251fe8cb57ec514722026425479eCraig Mautner                mViewMediatorCallback.keyguardDone(true);
10877def1db03943251fe8cb57ec514722026425479eCraig Mautner            }
1088dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        } else if (securityMode != KeyguardSecurityModel.SecurityMode.Pattern
108969bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler                && securityMode != KeyguardSecurityModel.SecurityMode.PIN
1090dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                && securityMode != KeyguardSecurityModel.SecurityMode.Password) {
1091dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            // can only verify unlock when in pattern/password mode
10927def1db03943251fe8cb57ec514722026425479eCraig Mautner            if (mViewMediatorCallback != null) {
10937def1db03943251fe8cb57ec514722026425479eCraig Mautner                mViewMediatorCallback.keyguardDone(false);
10947def1db03943251fe8cb57ec514722026425479eCraig Mautner            }
1095dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        } else {
1096dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            // otherwise, go to the unlock screen, see if they can verify it
1097dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            mIsVerifyUnlockOnly = true;
1098e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            showSecurityScreen(securityMode);
1099dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
1100dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
1101dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
1102dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    private int getSecurityViewIdForMode(SecurityMode securityMode) {
1103dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        switch (securityMode) {
1104e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            case None: return R.id.keyguard_selector_view;
1105e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            case Pattern: return R.id.keyguard_pattern_view;
110669bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler            case PIN: return R.id.keyguard_pin_view;
1107e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            case Password: return R.id.keyguard_password_view;
1108e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            case Biometric: return R.id.keyguard_face_unlock_view;
1109e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            case Account: return R.id.keyguard_account_view;
1110e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            case SimPin: return R.id.keyguard_sim_pin_view;
1111e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            case SimPuk: return R.id.keyguard_sim_puk_view;
1112dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
1113dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        return 0;
1114dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
1115dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
1116e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller    private int getLayoutIdFor(SecurityMode securityMode) {
1117e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        switch (securityMode) {
1118e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            case None: return R.layout.keyguard_selector_view;
1119e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            case Pattern: return R.layout.keyguard_pattern_view;
112069bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler            case PIN: return R.layout.keyguard_pin_view;
1121e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            case Password: return R.layout.keyguard_password_view;
1122e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            case Biometric: return R.layout.keyguard_face_unlock_view;
1123e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            case Account: return R.layout.keyguard_account_view;
1124e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            case SimPin: return R.layout.keyguard_sim_pin_view;
1125e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            case SimPuk: return R.layout.keyguard_sim_puk_view;
1126e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            default:
112763f9b81795559443e0376985f8aaaa97a359ef94Jim Miller                return 0;
1128e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        }
1129e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller    }
1130e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller
113151117262c8fadb6d227d137e83ad66996b013141Jim Miller    private boolean addWidget(int appId, int pageIndex, boolean updateDbIfFailed) {
113267a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appId);
113399a3cae55bd1a4ea6d82aa7fa2a67170e7cd5b3eJim Miller        if (appWidgetInfo != null) {
1134a75a883fe9ea1790803148f0a561473073e3f264Jim Miller            AppWidgetHostView view = mAppWidgetHost.createView(mContext, appId, appWidgetInfo);
1135d6523da1ad7bae805a3dbea8d7b398d86cd3c181Jim Miller            addWidget(view, pageIndex);
113667a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka            return true;
113799a3cae55bd1a4ea6d82aa7fa2a67170e7cd5b3eJim Miller        } else {
113851117262c8fadb6d227d137e83ad66996b013141Jim Miller            if (updateDbIfFailed) {
1139a75a883fe9ea1790803148f0a561473073e3f264Jim Miller                Log.w(TAG, "*** AppWidgetInfo for app widget id " + appId + "  was null for user"
1140a75a883fe9ea1790803148f0a561473073e3f264Jim Miller                        + mUserId + ", deleting");
114151117262c8fadb6d227d137e83ad66996b013141Jim Miller                mAppWidgetHost.deleteAppWidgetId(appId);
114251117262c8fadb6d227d137e83ad66996b013141Jim Miller                mLockPatternUtils.removeAppWidget(appId);
114351117262c8fadb6d227d137e83ad66996b013141Jim Miller            }
114467a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka            return false;
114599a3cae55bd1a4ea6d82aa7fa2a67170e7cd5b3eJim Miller        }
1146dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
1147dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
1148dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock    private final CameraWidgetFrame.Callbacks mCameraWidgetCallbacks =
1149dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock        new CameraWidgetFrame.Callbacks() {
1150dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock            @Override
1151dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock            public void onLaunchingCamera() {
115257f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock                setSliderHandleAlpha(0);
1153dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock            }
1154dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock
1155dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock            @Override
115657f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock            public void onCameraLaunchedSuccessfully() {
11576cf53bb3a94ec5a6eebc96a315dac32d042f1945Winson Chung                if (mAppWidgetContainer.isCameraPage(mAppWidgetContainer.getCurrentPage())) {
11584b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock                    mAppWidgetContainer.scrollLeft();
11594b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock                }
116057f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock                setSliderHandleAlpha(1);
1161aaf9b11e6232f159aa6d9863097b09bb435deae3Jim Miller                mShowSecurityWhenReturn = true;
1162dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock            }
1163dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock
116457f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock            @Override
116557f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock            public void onCameraLaunchedUnsuccessfully() {
116657f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock                setSliderHandleAlpha(1);
116757f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock            }
116857f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock
116957f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock            private void setSliderHandleAlpha(float alpha) {
117057f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock                SlidingChallengeLayout slider =
117157f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock                        (SlidingChallengeLayout) findViewById(R.id.sliding_layout);
117257f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock                if (slider != null) {
117357f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock                    slider.setHandleAlpha(alpha);
117457f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock                }
1175dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock            }
1176dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock        };
1177dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock
1178dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock    private final KeyguardActivityLauncher mActivityLauncher = new KeyguardActivityLauncher() {
1179dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock        @Override
1180dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock        Context getContext() {
1181dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock            return mContext;
1182dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock        }
1183dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock
1184dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock        @Override
1185dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock        KeyguardSecurityCallback getCallback() {
1186dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock            return mCallback;
1187dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock        }
1188dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock
1189dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock        @Override
1190dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock        LockPatternUtils getLockPatternUtils() {
1191dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock            return mLockPatternUtils;
1192bdca3c0a21ba15e8bb6d7ef0ca1b7e8024f98f19Jim Miller        }
1193bdca3c0a21ba15e8bb6d7ef0ca1b7e8024f98f19Jim Miller    };
1194dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock
1195eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka    private int numWidgets() {
1196eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka        final int childCount = mAppWidgetContainer.getChildCount();
1197eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka        int widgetCount = 0;
1198eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka        for (int i = 0; i < childCount; i++) {
1199eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka            if (mAppWidgetContainer.isWidgetPage(i)) {
1200eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka                widgetCount++;
1201eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka            }
1202eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka        }
1203eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka        return widgetCount;
1204eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka    }
1205eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka
12064e81bd4bcf60a934d4cd589dab6e2bddb88d7356Jim Miller    private void addDefaultWidgets() {
1207f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller        if (!mSafeModeEnabled && !widgetsDisabled()) {
12088f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            LayoutInflater inflater = LayoutInflater.from(mContext);
120951117262c8fadb6d227d137e83ad66996b013141Jim Miller            View addWidget = inflater.inflate(R.layout.keyguard_add_widget, this, false);
1210eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka            mAppWidgetContainer.addWidget(addWidget, 0);
121151117262c8fadb6d227d137e83ad66996b013141Jim Miller            View addWidgetButton = addWidget.findViewById(R.id.keyguard_add_widget_view);
121251117262c8fadb6d227d137e83ad66996b013141Jim Miller            addWidgetButton.setOnClickListener(new OnClickListener() {
121351117262c8fadb6d227d137e83ad66996b013141Jim Miller                @Override
121451117262c8fadb6d227d137e83ad66996b013141Jim Miller                public void onClick(View v) {
1215192d6d4ee271c0782a3bf5d8c64e42eb22d1a6faMichael Jurka                    // Pass in an invalid widget id... the picker will allocate an ID for us
1216192d6d4ee271c0782a3bf5d8c64e42eb22d1a6faMichael Jurka                    mActivityLauncher.launchWidgetPicker(AppWidgetManager.INVALID_APPWIDGET_ID);
121751117262c8fadb6d227d137e83ad66996b013141Jim Miller                }
121851117262c8fadb6d227d137e83ad66996b013141Jim Miller            });
121951117262c8fadb6d227d137e83ad66996b013141Jim Miller        }
122051117262c8fadb6d227d137e83ad66996b013141Jim Miller
122151117262c8fadb6d227d137e83ad66996b013141Jim Miller        // We currently disable cameras in safe mode because we support loading 3rd party
122251117262c8fadb6d227d137e83ad66996b013141Jim Miller        // cameras we can't trust.  TODO: plumb safe mode into camera creation code and only
122351117262c8fadb6d227d137e83ad66996b013141Jim Miller        // inflate system-provided camera?
1224371f3408d6d9c3c3781d6e35e591f61026b42240John Spurlock        if (!mSafeModeEnabled && !cameraDisabledByDpm() && mUserSetupCompleted
122551117262c8fadb6d227d137e83ad66996b013141Jim Miller                && mContext.getResources().getBoolean(R.bool.kg_enable_camera_default_widget)) {
1226dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock            View cameraWidget =
1227dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock                    CameraWidgetFrame.create(mContext, mCameraWidgetCallbacks, mActivityLauncher);
1228dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock            if (cameraWidget != null) {
1229dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock                mAppWidgetContainer.addWidget(cameraWidget);
1230dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock            }
123186b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock        }
12327221d3ae08cc2be922d26e5d491038512cb6c74dJim Miller    }
12337221d3ae08cc2be922d26e5d491038512cb6c74dJim Miller
12348f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller    /**
12358f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller     * Create KeyguardTransportControlView on demand.
12368f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller     * @return
12378f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller     */
12384894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller    private KeyguardTransportControlView getOrCreateTransportControl() {
12398f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        if (mTransportControl == null) {
12408f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            LayoutInflater inflater = LayoutInflater.from(mContext);
12418f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            mTransportControl = (KeyguardTransportControlView)
12428f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller                    inflater.inflate(R.layout.keyguard_transport_control_view, this, false);
1243f8895248e2ac4dbb46622f3e04c7256f03175b4fAdam Powell            mTransportControl.setTransportControlCallback(new TransportControlCallback() {
1244f8895248e2ac4dbb46622f3e04c7256f03175b4fAdam Powell                public void userActivity() {
1245f8895248e2ac4dbb46622f3e04c7256f03175b4fAdam Powell                    mViewMediatorCallback.userActivity();
1246f8895248e2ac4dbb46622f3e04c7256f03175b4fAdam Powell                }
1247f8895248e2ac4dbb46622f3e04c7256f03175b4fAdam Powell            });
12484e81bd4bcf60a934d4cd589dab6e2bddb88d7356Jim Miller        }
12498f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        return mTransportControl;
12504e81bd4bcf60a934d4cd589dab6e2bddb88d7356Jim Miller    }
12514e81bd4bcf60a934d4cd589dab6e2bddb88d7356Jim Miller
125251117262c8fadb6d227d137e83ad66996b013141Jim Miller    private int getInsertPageIndex() {
125367a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        View addWidget = mAppWidgetContainer.findViewById(R.id.keyguard_add_widget);
125451117262c8fadb6d227d137e83ad66996b013141Jim Miller        int insertionIndex = mAppWidgetContainer.indexOfChild(addWidget);
125551117262c8fadb6d227d137e83ad66996b013141Jim Miller        if (insertionIndex < 0) {
125651117262c8fadb6d227d137e83ad66996b013141Jim Miller            insertionIndex = 0; // no add widget page found
125751117262c8fadb6d227d137e83ad66996b013141Jim Miller        } else {
125851117262c8fadb6d227d137e83ad66996b013141Jim Miller            insertionIndex++; // place after add widget
125967a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        }
126051117262c8fadb6d227d137e83ad66996b013141Jim Miller        return insertionIndex;
126167a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka    }
126267a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka
126367a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka    private void addDefaultStatusWidget(int index) {
126467a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        LayoutInflater inflater = LayoutInflater.from(mContext);
126567a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        View statusWidget = inflater.inflate(R.layout.keyguard_status_view, null, true);
126667a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        mAppWidgetContainer.addWidget(statusWidget, index);
126767a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka    }
126867a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka
12691254f2f42f7173ef51d0034975ab5cb7d44f8209Michael Jurka    private void addWidgetsFromSettings() {
1270f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller        if (mSafeModeEnabled || widgetsDisabled()) {
12712ec4ff435b0af87a6c0f933e6eaf1155e34c430fJim Miller            addDefaultStatusWidget(0);
127251117262c8fadb6d227d137e83ad66996b013141Jim Miller            return;
1273b8ec470617590fa2025db869e8e80dcce8eaec23Jim Miller        }
1274f229e4d3eb8f910c181f96416c6798f6f305a395Jim Miller
127551117262c8fadb6d227d137e83ad66996b013141Jim Miller        int insertionIndex = getInsertPageIndex();
127620c41d5382b70fa5a24e9ef68f19ce0aedea5234Michael Jurka
127720c41d5382b70fa5a24e9ef68f19ce0aedea5234Michael Jurka        // Add user-selected widget
1278aa2859ae61098509495b7938e32a6d59d37561beMichael Jurka        final int[] widgets = mLockPatternUtils.getAppWidgets();
127967a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka
1280aa2859ae61098509495b7938e32a6d59d37561beMichael Jurka        if (widgets == null) {
1281aa2859ae61098509495b7938e32a6d59d37561beMichael Jurka            Log.d(TAG, "Problem reading widgets");
1282aa2859ae61098509495b7938e32a6d59d37561beMichael Jurka        } else {
1283aa2859ae61098509495b7938e32a6d59d37561beMichael Jurka            for (int i = widgets.length -1; i >= 0; i--) {
12841254f2f42f7173ef51d0034975ab5cb7d44f8209Michael Jurka                if (widgets[i] == LockPatternUtils.ID_DEFAULT_STATUS_WIDGET) {
128551117262c8fadb6d227d137e83ad66996b013141Jim Miller                    addDefaultStatusWidget(insertionIndex);
12861254f2f42f7173ef51d0034975ab5cb7d44f8209Michael Jurka                } else {
1287aa2859ae61098509495b7938e32a6d59d37561beMichael Jurka                    // We add the widgets from left to right, starting after the first page after
1288aa2859ae61098509495b7938e32a6d59d37561beMichael Jurka                    // the add page. We count down, since the order will be persisted from right
1289aa2859ae61098509495b7938e32a6d59d37561beMichael Jurka                    // to left, starting after camera.
129051117262c8fadb6d227d137e83ad66996b013141Jim Miller                    addWidget(widgets[i], insertionIndex, true);
1291aa2859ae61098509495b7938e32a6d59d37561beMichael Jurka                }
1292dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            }
1293dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
129451117262c8fadb6d227d137e83ad66996b013141Jim Miller    }
129551117262c8fadb6d227d137e83ad66996b013141Jim Miller
129651117262c8fadb6d227d137e83ad66996b013141Jim Miller    private int allocateIdForDefaultAppWidget() {
129751117262c8fadb6d227d137e83ad66996b013141Jim Miller        int appWidgetId;
129851117262c8fadb6d227d137e83ad66996b013141Jim Miller        Resources res = getContext().getResources();
129951117262c8fadb6d227d137e83ad66996b013141Jim Miller        ComponentName defaultAppWidget = new ComponentName(
130051117262c8fadb6d227d137e83ad66996b013141Jim Miller                res.getString(R.string.widget_default_package_name),
130151117262c8fadb6d227d137e83ad66996b013141Jim Miller                res.getString(R.string.widget_default_class_name));
130251117262c8fadb6d227d137e83ad66996b013141Jim Miller
130351117262c8fadb6d227d137e83ad66996b013141Jim Miller        // Note: we don't support configuring the widget
130451117262c8fadb6d227d137e83ad66996b013141Jim Miller        appWidgetId = mAppWidgetHost.allocateAppWidgetId();
130551117262c8fadb6d227d137e83ad66996b013141Jim Miller
130651117262c8fadb6d227d137e83ad66996b013141Jim Miller        try {
130751117262c8fadb6d227d137e83ad66996b013141Jim Miller            mAppWidgetManager.bindAppWidgetId(appWidgetId, defaultAppWidget);
130851117262c8fadb6d227d137e83ad66996b013141Jim Miller        } catch (IllegalArgumentException e) {
130951117262c8fadb6d227d137e83ad66996b013141Jim Miller            Log.e(TAG, "Error when trying to bind default AppWidget: " + e);
131051117262c8fadb6d227d137e83ad66996b013141Jim Miller            mAppWidgetHost.deleteAppWidgetId(appWidgetId);
131151117262c8fadb6d227d137e83ad66996b013141Jim Miller            appWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
131251117262c8fadb6d227d137e83ad66996b013141Jim Miller        }
131351117262c8fadb6d227d137e83ad66996b013141Jim Miller        return appWidgetId;
131467a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka    }
1315f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller
131667a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka    public void checkAppWidgetConsistency() {
131767a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        final int childCount = mAppWidgetContainer.getChildCount();
131867a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        boolean widgetPageExists = false;
131967a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        for (int i = 0; i < childCount; i++) {
132051117262c8fadb6d227d137e83ad66996b013141Jim Miller            if (mAppWidgetContainer.isWidgetPage(i)) {
132167a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka                widgetPageExists = true;
132267a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka                break;
132367a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka            }
132467a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        }
132567a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        if (!widgetPageExists) {
132651117262c8fadb6d227d137e83ad66996b013141Jim Miller            final int insertPageIndex = getInsertPageIndex();
132751117262c8fadb6d227d137e83ad66996b013141Jim Miller
1328f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller            final boolean userAddedWidgetsEnabled = !widgetsDisabled();
1329f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller
133051117262c8fadb6d227d137e83ad66996b013141Jim Miller            boolean addedDefaultAppWidget = false;
133151117262c8fadb6d227d137e83ad66996b013141Jim Miller
133251117262c8fadb6d227d137e83ad66996b013141Jim Miller            if (!mSafeModeEnabled) {
133351117262c8fadb6d227d137e83ad66996b013141Jim Miller                if (userAddedWidgetsEnabled) {
133451117262c8fadb6d227d137e83ad66996b013141Jim Miller                    int appWidgetId = allocateIdForDefaultAppWidget();
133551117262c8fadb6d227d137e83ad66996b013141Jim Miller                    if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
133651117262c8fadb6d227d137e83ad66996b013141Jim Miller                        addedDefaultAppWidget = addWidget(appWidgetId, insertPageIndex, true);
133751117262c8fadb6d227d137e83ad66996b013141Jim Miller                    }
133851117262c8fadb6d227d137e83ad66996b013141Jim Miller                } else {
133951117262c8fadb6d227d137e83ad66996b013141Jim Miller                    // note: even if widgetsDisabledByDpm() returns true, we still bind/create
134051117262c8fadb6d227d137e83ad66996b013141Jim Miller                    // the default appwidget if possible
134151117262c8fadb6d227d137e83ad66996b013141Jim Miller                    int appWidgetId = mLockPatternUtils.getFallbackAppWidgetId();
134251117262c8fadb6d227d137e83ad66996b013141Jim Miller                    if (appWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
134351117262c8fadb6d227d137e83ad66996b013141Jim Miller                        appWidgetId = allocateIdForDefaultAppWidget();
134451117262c8fadb6d227d137e83ad66996b013141Jim Miller                        if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
134551117262c8fadb6d227d137e83ad66996b013141Jim Miller                            mLockPatternUtils.writeFallbackAppWidgetId(appWidgetId);
134651117262c8fadb6d227d137e83ad66996b013141Jim Miller                        }
134751117262c8fadb6d227d137e83ad66996b013141Jim Miller                    }
134851117262c8fadb6d227d137e83ad66996b013141Jim Miller                    if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
134951117262c8fadb6d227d137e83ad66996b013141Jim Miller                        addedDefaultAppWidget = addWidget(appWidgetId, insertPageIndex, false);
135051117262c8fadb6d227d137e83ad66996b013141Jim Miller                        if (!addedDefaultAppWidget) {
135151117262c8fadb6d227d137e83ad66996b013141Jim Miller                            mAppWidgetHost.deleteAppWidgetId(appWidgetId);
135251117262c8fadb6d227d137e83ad66996b013141Jim Miller                            mLockPatternUtils.writeFallbackAppWidgetId(
135351117262c8fadb6d227d137e83ad66996b013141Jim Miller                                    AppWidgetManager.INVALID_APPWIDGET_ID);
135451117262c8fadb6d227d137e83ad66996b013141Jim Miller                        }
135551117262c8fadb6d227d137e83ad66996b013141Jim Miller                    }
135651117262c8fadb6d227d137e83ad66996b013141Jim Miller                }
135767a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka            }
135851117262c8fadb6d227d137e83ad66996b013141Jim Miller
135967a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka            // Use the built-in status/clock view if we can't inflate the default widget
136051117262c8fadb6d227d137e83ad66996b013141Jim Miller            if (!addedDefaultAppWidget) {
136151117262c8fadb6d227d137e83ad66996b013141Jim Miller                addDefaultStatusWidget(insertPageIndex);
136251117262c8fadb6d227d137e83ad66996b013141Jim Miller            }
136351117262c8fadb6d227d137e83ad66996b013141Jim Miller
136451117262c8fadb6d227d137e83ad66996b013141Jim Miller            // trigger DB updates only if user-added widgets are enabled
136551117262c8fadb6d227d137e83ad66996b013141Jim Miller            if (!mSafeModeEnabled && userAddedWidgetsEnabled) {
136651117262c8fadb6d227d137e83ad66996b013141Jim Miller                mAppWidgetContainer.onAddView(
136751117262c8fadb6d227d137e83ad66996b013141Jim Miller                        mAppWidgetContainer.getChildAt(insertPageIndex), insertPageIndex);
136867a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka            }
136967a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        }
13700207c0992cb05d0acc60540748c8ae6985917abbAdam Cohen    }
13710207c0992cb05d0acc60540748c8ae6985917abbAdam Cohen
137281190befe66e297d93ad0c7661d02d56f8f01f24Jim Miller    private final Runnable mSwitchPageRunnable = new Runnable() {
1373223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        @Override
1374223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        public void run() {
1375223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller           showAppropriateWidgetPage();
1376223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        }
1377223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller    };
1378223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller
1379223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller    static class SavedState extends BaseSavedState {
1380223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        int transportState;
13811413889565bc1b9d5d5fb73302460a4f25f4a8c0Michael Jurka        int appWidgetToShow = AppWidgetManager.INVALID_APPWIDGET_ID;
1382256ae67b9a629178b458dfc01102c9c0b9963d03John Spurlock        Rect insets = new Rect();
1383223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller
1384223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        SavedState(Parcelable superState) {
1385223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller            super(superState);
1386223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        }
1387223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller
1388223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        private SavedState(Parcel in) {
1389223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller            super(in);
1390223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller            this.transportState = in.readInt();
13911413889565bc1b9d5d5fb73302460a4f25f4a8c0Michael Jurka            this.appWidgetToShow = in.readInt();
1392256ae67b9a629178b458dfc01102c9c0b9963d03John Spurlock            this.insets = in.readParcelable(null);
1393223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        }
1394223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller
1395223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        @Override
1396223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        public void writeToParcel(Parcel out, int flags) {
1397223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller            super.writeToParcel(out, flags);
1398223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller            out.writeInt(this.transportState);
13991413889565bc1b9d5d5fb73302460a4f25f4a8c0Michael Jurka            out.writeInt(this.appWidgetToShow);
1400256ae67b9a629178b458dfc01102c9c0b9963d03John Spurlock            out.writeParcelable(insets, 0);
1401223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        }
1402223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller
1403223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        public static final Parcelable.Creator<SavedState> CREATOR
1404223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller                = new Parcelable.Creator<SavedState>() {
1405223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller            public SavedState createFromParcel(Parcel in) {
1406223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller                return new SavedState(in);
1407223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller            }
1408223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller
1409223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller            public SavedState[] newArray(int size) {
1410223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller                return new SavedState[size];
1411223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller            }
1412223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        };
1413223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller    }
1414223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller
1415223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller    @Override
1416223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller    public Parcelable onSaveInstanceState() {
14174894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller        if (DEBUG) Log.d(TAG, "onSaveInstanceState, tstate=" + mTransportState);
1418223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        Parcelable superState = super.onSaveInstanceState();
1419223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        SavedState ss = new SavedState(superState);
14204894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller        // If the transport is showing, force it to show it on restore.
14214894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller        final boolean showing = mTransportControl != null
14224894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller                && mAppWidgetContainer.getWidgetPageIndex(mTransportControl) >= 0;
14234894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller        ss.transportState =  showing ? TRANSPORT_VISIBLE : mTransportState;
14241413889565bc1b9d5d5fb73302460a4f25f4a8c0Michael Jurka        ss.appWidgetToShow = mAppWidgetToShow;
1425256ae67b9a629178b458dfc01102c9c0b9963d03John Spurlock        ss.insets.set(mInsets);
1426223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        return ss;
1427223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller    }
1428223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller
1429223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller    @Override
1430223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller    public void onRestoreInstanceState(Parcelable state) {
1431223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        if (!(state instanceof SavedState)) {
1432223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller            super.onRestoreInstanceState(state);
1433223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller            return;
1434223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        }
1435223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        SavedState ss = (SavedState) state;
1436223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        super.onRestoreInstanceState(ss.getSuperState());
14378f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        mTransportState = (ss.transportState);
14381413889565bc1b9d5d5fb73302460a4f25f4a8c0Michael Jurka        mAppWidgetToShow = ss.appWidgetToShow;
1439256ae67b9a629178b458dfc01102c9c0b9963d03John Spurlock        setInsets(ss.insets);
14404894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller        if (DEBUG) Log.d(TAG, "onRestoreInstanceState, transport=" + mTransportState);
144181190befe66e297d93ad0c7661d02d56f8f01f24Jim Miller        mSwitchPageRunnable.run();
1442223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller    }
1443223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller
14445f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock    @Override
1445256ae67b9a629178b458dfc01102c9c0b9963d03John Spurlock    protected boolean fitSystemWindows(Rect insets) {
1446256ae67b9a629178b458dfc01102c9c0b9963d03John Spurlock        setInsets(insets);
1447256ae67b9a629178b458dfc01102c9c0b9963d03John Spurlock        return true;
1448256ae67b9a629178b458dfc01102c9c0b9963d03John Spurlock    }
1449256ae67b9a629178b458dfc01102c9c0b9963d03John Spurlock
1450256ae67b9a629178b458dfc01102c9c0b9963d03John Spurlock    private void setInsets(Rect insets) {
1451256ae67b9a629178b458dfc01102c9c0b9963d03John Spurlock        mInsets.set(insets);
1452256ae67b9a629178b458dfc01102c9c0b9963d03John Spurlock        if (mSlidingChallengeLayout != null) mSlidingChallengeLayout.setInsets(mInsets);
1453256ae67b9a629178b458dfc01102c9c0b9963d03John Spurlock        if (mMultiPaneChallengeLayout != null) mMultiPaneChallengeLayout.setInsets(mInsets);
145426b7bf6e3cf6be009cd4baf59e083bce37633a4aDaniel Sandler
145526b7bf6e3cf6be009cd4baf59e083bce37633a4aDaniel Sandler        final CameraWidgetFrame cameraWidget = findCameraPage();
145626b7bf6e3cf6be009cd4baf59e083bce37633a4aDaniel Sandler        if (cameraWidget != null) cameraWidget.setInsets(mInsets);
1457256ae67b9a629178b458dfc01102c9c0b9963d03John Spurlock    }
1458256ae67b9a629178b458dfc01102c9c0b9963d03John Spurlock
1459256ae67b9a629178b458dfc01102c9c0b9963d03John Spurlock    @Override
14605f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock    public void onWindowFocusChanged(boolean hasWindowFocus) {
14615f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock        super.onWindowFocusChanged(hasWindowFocus);
14625f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock        if (DEBUG) Log.d(TAG, "Window is " + (hasWindowFocus ? "focused" : "unfocused"));
146376017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka        if (hasWindowFocus && mShowSecurityWhenReturn) {
1464aaf9b11e6232f159aa6d9863097b09bb435deae3Jim Miller            SlidingChallengeLayout slider =
1465aaf9b11e6232f159aa6d9863097b09bb435deae3Jim Miller                (SlidingChallengeLayout) findViewById(R.id.sliding_layout);
1466aaf9b11e6232f159aa6d9863097b09bb435deae3Jim Miller            if (slider != null) {
1467aaf9b11e6232f159aa6d9863097b09bb435deae3Jim Miller                slider.setHandleAlpha(1);
1468aaf9b11e6232f159aa6d9863097b09bb435deae3Jim Miller                slider.showChallenge(true);
1469aaf9b11e6232f159aa6d9863097b09bb435deae3Jim Miller            }
1470aaf9b11e6232f159aa6d9863097b09bb435deae3Jim Miller            mShowSecurityWhenReturn = false;
14715f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock        }
14725f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock    }
14735f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock
14744d20ed3f26d1ec2c47519484bcc968098581c3d6Jim Miller    private void showAppropriateWidgetPage() {
147581190befe66e297d93ad0c7661d02d56f8f01f24Jim Miller        final int state = mTransportState;
147681190befe66e297d93ad0c7661d02d56f8f01f24Jim Miller        final boolean transportAdded = ensureTransportPresentOrRemoved(state);
147781190befe66e297d93ad0c7661d02d56f8f01f24Jim Miller        final int pageToShow = getAppropriateWidgetPage(state);
147881190befe66e297d93ad0c7661d02d56f8f01f24Jim Miller        if (!transportAdded) {
147981190befe66e297d93ad0c7661d02d56f8f01f24Jim Miller            mAppWidgetContainer.setCurrentPage(pageToShow);
148081190befe66e297d93ad0c7661d02d56f8f01f24Jim Miller        } else if (state == TRANSPORT_VISIBLE) {
148181190befe66e297d93ad0c7661d02d56f8f01f24Jim Miller            // If the transport was just added, we need to wait for layout to happen before
148281190befe66e297d93ad0c7661d02d56f8f01f24Jim Miller            // we can set the current page.
148381190befe66e297d93ad0c7661d02d56f8f01f24Jim Miller            post(new Runnable() {
148481190befe66e297d93ad0c7661d02d56f8f01f24Jim Miller                @Override
148581190befe66e297d93ad0c7661d02d56f8f01f24Jim Miller                public void run() {
148681190befe66e297d93ad0c7661d02d56f8f01f24Jim Miller                    mAppWidgetContainer.setCurrentPage(pageToShow);
148781190befe66e297d93ad0c7661d02d56f8f01f24Jim Miller                }
148881190befe66e297d93ad0c7661d02d56f8f01f24Jim Miller            });
148981190befe66e297d93ad0c7661d02d56f8f01f24Jim Miller        }
1490dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
1491dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
14924894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller    /**
14934894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     * Examines the current state and adds the transport to the widget pager when the state changes.
14944894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     *
14954894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     * Showing the initial transport and keeping it around is a bit tricky because the signals
14964894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     * coming from music players aren't always clear. Here's how the states are handled:
14974894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     *
14984894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     * {@link TRANSPORT_GONE} means we have no reason to show the transport - remove it if present.
14994894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     *
15004894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     * {@link TRANSPORT_INVISIBLE} means we have potential to show the transport because a music
15014894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     * player is registered but not currently playing music (or we don't know the state yet). The
15024894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     * code adds it conditionally on play state.
15034894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     *
15044894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     * {@link #TRANSPORT_VISIBLE} means a music player is active and transport should be showing.
15054894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     *
15064894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     * Once the transport is showing, we always show it until keyguard is dismissed. This state is
15074894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     * maintained by onSave/RestoreInstanceState(). This state is cleared in
15084894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     * {@link KeyguardViewManager#hide} when keyguard is dismissed, which causes the transport to be
15094894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     * gone when keyguard is restarted until we get an update with the current state.
15104894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     *
15114894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     * @param state
15124894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     */
151381190befe66e297d93ad0c7661d02d56f8f01f24Jim Miller    private boolean ensureTransportPresentOrRemoved(int state) {
15144894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller        final boolean showing = getWidgetPosition(R.id.keyguard_transport_control) != -1;
15154894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller        final boolean visible = state == TRANSPORT_VISIBLE;
15164894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller        final boolean shouldBeVisible = state == TRANSPORT_INVISIBLE && isMusicPlaying(state);
15174894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller        if (!showing && (visible || shouldBeVisible)) {
15184894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller            // insert to left of camera if it exists, otherwise after right-most widget
15194894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller            int lastWidget = mAppWidgetContainer.getChildCount() - 1;
15204894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller            int position = 0; // handle no widget case
15214894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller            if (lastWidget >= 0) {
15224894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller                position = mAppWidgetContainer.isCameraPage(lastWidget) ?
15234894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller                        lastWidget : lastWidget + 1;
15248f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            }
152581190befe66e297d93ad0c7661d02d56f8f01f24Jim Miller            if (DEBUGXPORT) Log.v(TAG, "add transport at " + position);
15264894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller            mAppWidgetContainer.addWidget(getOrCreateTransportControl(), position);
152781190befe66e297d93ad0c7661d02d56f8f01f24Jim Miller            return true;
15284894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller        } else if (showing && state == TRANSPORT_GONE) {
15298f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            if (DEBUGXPORT) Log.v(TAG, "remove transport");
15304894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller            mAppWidgetContainer.removeWidget(getOrCreateTransportControl());
15318f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            mTransportControl = null;
153243a372f38ad642f86047e8112e3d43edb7300439Adam Powell            KeyguardUpdateMonitor.getInstance(getContext()).dispatchSetBackground(null);
15338f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        }
153481190befe66e297d93ad0c7661d02d56f8f01f24Jim Miller        return false;
15358f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller    }
15368f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller
1537dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock    private CameraWidgetFrame findCameraPage() {
1538dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock        for (int i = mAppWidgetContainer.getChildCount() - 1; i >= 0; i--) {
15396cf53bb3a94ec5a6eebc96a315dac32d042f1945Winson Chung            if (mAppWidgetContainer.isCameraPage(i)) {
1540dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock                return (CameraWidgetFrame) mAppWidgetContainer.getChildAt(i);
1541dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock            }
1542dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock        }
1543dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock        return null;
1544dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock    }
1545dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock
15466cf53bb3a94ec5a6eebc96a315dac32d042f1945Winson Chung    boolean isMusicPage(int pageIndex) {
15476cf53bb3a94ec5a6eebc96a315dac32d042f1945Winson Chung        return pageIndex >= 0 && pageIndex == getWidgetPosition(R.id.keyguard_transport_control);
15486cf53bb3a94ec5a6eebc96a315dac32d042f1945Winson Chung    }
15496cf53bb3a94ec5a6eebc96a315dac32d042f1945Winson Chung
15508f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller    private int getAppropriateWidgetPage(int musicTransportState) {
1551358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock        // assumes at least one widget (besides camera + add)
155276017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka        if (mAppWidgetToShow != AppWidgetManager.INVALID_APPWIDGET_ID) {
155376017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka            final int childCount = mAppWidgetContainer.getChildCount();
155476017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka            for (int i = 0; i < childCount; i++) {
155576017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka                if (mAppWidgetContainer.getWidgetPageAt(i).getContentAppWidgetId()
155676017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka                        == mAppWidgetToShow) {
155776017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka                    return i;
155876017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka                }
155976017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka            }
156076017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka            mAppWidgetToShow = AppWidgetManager.INVALID_APPWIDGET_ID;
156176017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka        }
1562358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock        // if music playing, show transport
15638f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        if (musicTransportState == TRANSPORT_VISIBLE) {
1564358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock            if (DEBUG) Log.d(TAG, "Music playing, show transport");
15654894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller            return mAppWidgetContainer.getWidgetPageIndex(getOrCreateTransportControl());
1566358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock        }
1567358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock
15685f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock        // else show the right-most widget (except for camera)
1569358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock        int rightMost = mAppWidgetContainer.getChildCount() - 1;
15706cf53bb3a94ec5a6eebc96a315dac32d042f1945Winson Chung        if (mAppWidgetContainer.isCameraPage(rightMost)) {
1571358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock            rightMost--;
1572358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock        }
15735f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock        if (DEBUG) Log.d(TAG, "Show right-most page " + rightMost);
1574358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock        return rightMost;
1575358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock    }
1576358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock
157719a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller    private void enableUserSelectorIfNecessary() {
157826e6c2e44235428717d7152b9e6398649452f1d2Jim Miller        if (!UserManager.supportsMultipleUsers()) {
157926e6c2e44235428717d7152b9e6398649452f1d2Jim Miller            return; // device doesn't support multi-user mode
158026e6c2e44235428717d7152b9e6398649452f1d2Jim Miller        }
1581f6ab5f9e3e7562b6ebb61ac149eb3cf9b08c443fJim Miller        final UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
1582d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren        if (um == null) {
1583d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren            Throwable t = new Throwable();
1584d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren            t.fillInStackTrace();
1585d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren            Log.e(TAG, "user service is null.", t);
1586d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren            return;
1587d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren        }
158826e6c2e44235428717d7152b9e6398649452f1d2Jim Miller
15895f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock        // if there are multiple users, we need to enable to multi-user switcher
1590f6ab5f9e3e7562b6ebb61ac149eb3cf9b08c443fJim Miller        final List<UserInfo> users = um.getUsers(true);
1591d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren        if (users == null) {
1592d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren            Throwable t = new Throwable();
1593d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren            t.fillInStackTrace();
1594d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren            Log.e(TAG, "list of users is null.", t);
1595d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren            return;
1596d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren        }
159766b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen
1598f6ab5f9e3e7562b6ebb61ac149eb3cf9b08c443fJim Miller        final View multiUserView = findViewById(R.id.keyguard_user_selector);
1599f6ab5f9e3e7562b6ebb61ac149eb3cf9b08c443fJim Miller        if (multiUserView == null) {
1600f6ab5f9e3e7562b6ebb61ac149eb3cf9b08c443fJim Miller            Throwable t = new Throwable();
1601f6ab5f9e3e7562b6ebb61ac149eb3cf9b08c443fJim Miller            t.fillInStackTrace();
1602f6ab5f9e3e7562b6ebb61ac149eb3cf9b08c443fJim Miller            Log.e(TAG, "can't find user_selector in layout.", t);
1603f6ab5f9e3e7562b6ebb61ac149eb3cf9b08c443fJim Miller            return;
1604f6ab5f9e3e7562b6ebb61ac149eb3cf9b08c443fJim Miller        }
1605f6ab5f9e3e7562b6ebb61ac149eb3cf9b08c443fJim Miller
1606d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren        if (users.size() > 1) {
160791f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren            if (multiUserView instanceof KeyguardMultiUserSelectorView) {
1608f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren                mKeyguardMultiUserSelectorView = (KeyguardMultiUserSelectorView) multiUserView;
1609f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren                mKeyguardMultiUserSelectorView.setVisibility(View.VISIBLE);
1610f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren                mKeyguardMultiUserSelectorView.addUsers(users);
161191f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                UserSwitcherCallback callback = new UserSwitcherCallback() {
161291f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                    @Override
161391f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                    public void hideSecurityView(int duration) {
161491f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                        mSecurityViewContainer.animate().alpha(0).setDuration(duration);
161591f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                    }
161624b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen
161791f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                    @Override
161891f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                    public void showSecurityView() {
161991f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                        mSecurityViewContainer.setAlpha(1.0f);
162091f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                    }
16210a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen
162291f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                    @Override
162391f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                    public void showUnlockHint() {
162491f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                        if (mKeyguardSelectorView != null) {
162591f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                            mKeyguardSelectorView.showUsabilityHint();
162691f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                        }
16270ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller                    }
16280a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen
162991f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                    @Override
163091f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                    public void userActivity() {
163191f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                        if (mViewMediatorCallback != null) {
163291f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                            mViewMediatorCallback.userActivity();
163391f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                        }
163419a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                    }
163591f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren                };
1636f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren                mKeyguardMultiUserSelectorView.setCallback(callback);
1637d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren            } else {
1638d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren                Throwable t = new Throwable();
1639d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren                t.fillInStackTrace();
1640d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren                if (multiUserView == null) {
1641d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren                    Log.e(TAG, "could not find the user_selector.", t);
1642d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren                } else {
1643d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren                    Log.e(TAG, "user_selector is the wrong type.", t);
1644d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren                }
164591f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren            }
164666b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen        }
164766b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen    }
164866b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen
1649dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    @Override
1650dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    public void cleanUp() {
1651128f27632343ed8ad8bba2d96f4ec69c0e369de7Adam Cohen        // Make sure we let go of all widgets and their package contexts promptly. If we don't do
1652128f27632343ed8ad8bba2d96f4ec69c0e369de7Adam Cohen        // this, and the associated application is uninstalled, it can cause a soft reboot.
1653128f27632343ed8ad8bba2d96f4ec69c0e369de7Adam Cohen        int count = mAppWidgetContainer.getChildCount();
1654128f27632343ed8ad8bba2d96f4ec69c0e369de7Adam Cohen        for (int i = 0; i < count; i++) {
1655128f27632343ed8ad8bba2d96f4ec69c0e369de7Adam Cohen            KeyguardWidgetFrame frame = mAppWidgetContainer.getWidgetPageAt(i);
1656128f27632343ed8ad8bba2d96f4ec69c0e369de7Adam Cohen            frame.removeAllViews();
1657128f27632343ed8ad8bba2d96f4ec69c0e369de7Adam Cohen        }
1658dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
1659dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
166095b005c196de2f99513da28fe9108b2dec200140Jim Miller    /**
166195b005c196de2f99513da28fe9108b2dec200140Jim Miller     * In general, we enable unlocking the insecure keyguard with the menu key. However, there are
166295b005c196de2f99513da28fe9108b2dec200140Jim Miller     * some cases where we wish to disable it, notably when the menu button placement or technology
166395b005c196de2f99513da28fe9108b2dec200140Jim Miller     * is prone to false positives.
166495b005c196de2f99513da28fe9108b2dec200140Jim Miller     *
166595b005c196de2f99513da28fe9108b2dec200140Jim Miller     * @return true if the menu key should be enabled
166695b005c196de2f99513da28fe9108b2dec200140Jim Miller     */
166795b005c196de2f99513da28fe9108b2dec200140Jim Miller    private static final String ENABLE_MENU_KEY_FILE = "/data/local/enable_menu_key";
166895b005c196de2f99513da28fe9108b2dec200140Jim Miller    private boolean shouldEnableMenuKey() {
166995b005c196de2f99513da28fe9108b2dec200140Jim Miller        final Resources res = getResources();
16705ecd81154fa039961f65bb4e36d18ac555b0d1d6Jim Miller        final boolean configDisabled = res.getBoolean(R.bool.config_disableMenuKeyInLockScreen);
167195b005c196de2f99513da28fe9108b2dec200140Jim Miller        final boolean isTestHarness = ActivityManager.isRunningInTestHarness();
167295b005c196de2f99513da28fe9108b2dec200140Jim Miller        final boolean fileOverride = (new File(ENABLE_MENU_KEY_FILE)).exists();
167395b005c196de2f99513da28fe9108b2dec200140Jim Miller        return !configDisabled || isTestHarness || fileOverride;
167495b005c196de2f99513da28fe9108b2dec200140Jim Miller    }
167595b005c196de2f99513da28fe9108b2dec200140Jim Miller
167676017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka    public void goToWidget(int appWidgetId) {
167776017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka        mAppWidgetToShow = appWidgetId;
167876017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka        mSwitchPageRunnable.run();
167976017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka    }
168076017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka
168175931e05470992d51d135d09031902fd1b3fdbc7Jim Miller    public boolean handleMenuKey() {
168275931e05470992d51d135d09031902fd1b3fdbc7Jim Miller        // The following enables the MENU key to work for testing automation
168375931e05470992d51d135d09031902fd1b3fdbc7Jim Miller        if (shouldEnableMenuKey()) {
168475931e05470992d51d135d09031902fd1b3fdbc7Jim Miller            showNextSecurityScreenOrFinish(false);
168575931e05470992d51d135d09031902fd1b3fdbc7Jim Miller            return true;
168675931e05470992d51d135d09031902fd1b3fdbc7Jim Miller        }
168775931e05470992d51d135d09031902fd1b3fdbc7Jim Miller        return false;
168875931e05470992d51d135d09031902fd1b3fdbc7Jim Miller    }
168975931e05470992d51d135d09031902fd1b3fdbc7Jim Miller
16900a34d9edf02954d83c2861a8c6836865f8fa00fbJim Miller    public boolean handleBackKey() {
169103eca859067ac0d4e419305de8ab0fdc03b4210fJohn Spurlock        if (mCurrentSecuritySelection == SecurityMode.Account) {
169203eca859067ac0d4e419305de8ab0fdc03b4210fJohn Spurlock            // go back to primary screen and re-disable back
169303eca859067ac0d4e419305de8ab0fdc03b4210fJohn Spurlock            setBackButtonEnabled(false);
169403eca859067ac0d4e419305de8ab0fdc03b4210fJohn Spurlock            showPrimarySecurityScreen(false /*turningOff*/);
169503eca859067ac0d4e419305de8ab0fdc03b4210fJohn Spurlock            return true;
169603eca859067ac0d4e419305de8ab0fdc03b4210fJohn Spurlock        }
16970a34d9edf02954d83c2861a8c6836865f8fa00fbJim Miller        if (mCurrentSecuritySelection != SecurityMode.None) {
16980a34d9edf02954d83c2861a8c6836865f8fa00fbJim Miller            mCallback.dismiss(false);
16990a34d9edf02954d83c2861a8c6836865f8fa00fbJim Miller            return true;
17000a34d9edf02954d83c2861a8c6836865f8fa00fbJim Miller        }
17010a34d9edf02954d83c2861a8c6836865f8fa00fbJim Miller        return false;
17020a34d9edf02954d83c2861a8c6836865f8fa00fbJim Miller    }
17030a34d9edf02954d83c2861a8c6836865f8fa00fbJim Miller
1704ad09bccfe4cc0a3075e97c0911a02b329023a34aCraig Mautner    /**
1705ad09bccfe4cc0a3075e97c0911a02b329023a34aCraig Mautner     *  Dismisses the keyguard by going to the next screen or making it gone.
1706ad09bccfe4cc0a3075e97c0911a02b329023a34aCraig Mautner     */
1707ad09bccfe4cc0a3075e97c0911a02b329023a34aCraig Mautner    public void dismiss() {
1708ad09bccfe4cc0a3075e97c0911a02b329023a34aCraig Mautner        showNextSecurityScreenOrFinish(false);
1709ad09bccfe4cc0a3075e97c0911a02b329023a34aCraig Mautner    }
17104eeb4f664ac6b5901a8e874dcf70c0382295f792Jim Miller
17114eeb4f664ac6b5901a8e874dcf70c0382295f792Jim Miller    public void showAssistant() {
17124eeb4f664ac6b5901a8e874dcf70c0382295f792Jim Miller        final Intent intent = ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
1713f9c5e0fe837a3090820da502ecaabc5accc00aceDianne Hackborn          .getAssistIntent(mContext, true, UserHandle.USER_CURRENT);
17144eeb4f664ac6b5901a8e874dcf70c0382295f792Jim Miller
17154eeb4f664ac6b5901a8e874dcf70c0382295f792Jim Miller        if (intent == null) return;
17164eeb4f664ac6b5901a8e874dcf70c0382295f792Jim Miller
17174eeb4f664ac6b5901a8e874dcf70c0382295f792Jim Miller        final ActivityOptions opts = ActivityOptions.makeCustomAnimation(mContext,
17184eeb4f664ac6b5901a8e874dcf70c0382295f792Jim Miller                R.anim.keyguard_action_assist_enter, R.anim.keyguard_action_assist_exit,
17194eeb4f664ac6b5901a8e874dcf70c0382295f792Jim Miller                getHandler(), null);
17204eeb4f664ac6b5901a8e874dcf70c0382295f792Jim Miller
17214eeb4f664ac6b5901a8e874dcf70c0382295f792Jim Miller        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
17224eeb4f664ac6b5901a8e874dcf70c0382295f792Jim Miller
17236ed3fcafdbdeda9a10a62bbd0e5997017e8e2635Daniel Sandler        mActivityLauncher.launchActivityWithAnimation(
17246ed3fcafdbdeda9a10a62bbd0e5997017e8e2635Daniel Sandler                intent, false, opts.toBundle(), null, null);
17254eeb4f664ac6b5901a8e874dcf70c0382295f792Jim Miller    }
1726caf24fc2c4bb9747eb80138bf3ce0be067851749Jim Miller
1727caf24fc2c4bb9747eb80138bf3ce0be067851749Jim Miller    public void dispatch(MotionEvent event) {
1728caf24fc2c4bb9747eb80138bf3ce0be067851749Jim Miller        mAppWidgetContainer.handleExternalCameraEvent(event);
1729caf24fc2c4bb9747eb80138bf3ce0be067851749Jim Miller    }
1730caf24fc2c4bb9747eb80138bf3ce0be067851749Jim Miller
1731138f25d75665bd07d34294364c5b6f530b33503fJim Miller    public void launchCamera() {
1732138f25d75665bd07d34294364c5b6f530b33503fJim Miller        mActivityLauncher.launchCamera(getHandler(), null);
1733138f25d75665bd07d34294364c5b6f530b33503fJim Miller    }
1734138f25d75665bd07d34294364c5b6f530b33503fJim Miller
1735dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller}
1736