KeyguardHostView.java revision 75931e05470992d51d135d09031902fd1b3fdbc7
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
17dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerpackage com.android.internal.policy.impl.keyguard;
18dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
19258341c377b6aa9f1bd29a9b507a97967e432dfeJim Millerimport android.app.Activity;
2095b005c196de2f99513da28fe9108b2dec200140Jim Millerimport android.app.ActivityManager;
21dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.app.ActivityOptions;
22258341c377b6aa9f1bd29a9b507a97967e432dfeJim Millerimport android.app.AlertDialog;
23258341c377b6aa9f1bd29a9b507a97967e432dfeJim Millerimport android.app.admin.DevicePolicyManager;
24dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.appwidget.AppWidgetHost;
25dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.appwidget.AppWidgetHostView;
26dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.appwidget.AppWidgetManager;
27dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.appwidget.AppWidgetProviderInfo;
28fc753c0cf676000b1c2d3cb2728af85a9b49f795Michael Jurkaimport android.content.ComponentName;
29dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.content.Context;
30dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.content.Intent;
31dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.content.IntentSender;
3266b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohenimport android.content.pm.UserInfo;
3395b005c196de2f99513da28fe9108b2dec200140Jim Millerimport android.content.res.Resources;
34dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.graphics.Canvas;
355737534abab477cf32b4dd0aa7a72f70ede0502cJim Millerimport android.graphics.Rect;
36fc753c0cf676000b1c2d3cb2728af85a9b49f795Michael Jurkaimport android.os.Bundle;
37f229e4d3eb8f910c181f96416c6798f6f305a395Jim Millerimport android.os.Looper;
38223ce5c7326f6d13a17ccf2624605bb62864a27aJim Millerimport android.os.Parcel;
39223ce5c7326f6d13a17ccf2624605bb62864a27aJim Millerimport android.os.Parcelable;
40dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlockimport android.os.SystemClock;
41b5f3b707a7010e8d867da9342ea87cf0a1679692Jim Millerimport android.os.UserHandle;
4266b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohenimport android.os.UserManager;
43dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.util.AttributeSet;
44dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.util.Log;
45258341c377b6aa9f1bd29a9b507a97967e432dfeJim Millerimport android.util.Slog;
46dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.view.KeyEvent;
4766b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohenimport android.view.LayoutInflater;
485737534abab477cf32b4dd0aa7a72f70ede0502cJim Millerimport android.view.MotionEvent;
49dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.view.View;
50258341c377b6aa9f1bd29a9b507a97967e432dfeJim Millerimport android.view.WindowManager;
51dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.view.animation.AnimationUtils;
52dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.widget.RemoteViews.OnClickHandler;
53dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
5466b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohenimport com.android.internal.R;
55dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport com.android.internal.policy.impl.keyguard.KeyguardSecurityModel.SecurityMode;
56dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport com.android.internal.widget.LockPatternUtils;
57dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
5895b005c196de2f99513da28fe9108b2dec200140Jim Millerimport java.io.File;
5966b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohenimport java.util.List;
60dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
61dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerpublic class KeyguardHostView extends KeyguardViewBase {
62ff2aa0bc8919c247bfc8e81d3f168e5064f52ffbJim Miller    private static final String TAG = "KeyguardViewHost";
63ff2aa0bc8919c247bfc8e81d3f168e5064f52ffbJim Miller
64dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    // Use this to debug all of keyguard
65a71984f3da47c6e6e3164c170735362a3222d3adJim Miller    public static boolean DEBUG = KeyguardViewMediator.DEBUG;
66dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
67dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    static final int APPWIDGET_HOST_ID = 0x4B455947;
68dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
69dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    private AppWidgetHost mAppWidgetHost;
7067a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka    private AppWidgetManager mAppWidgetManager;
71f2dfc351dec58ad3c16f8496208b4e6e9c667efeJim Miller    private KeyguardWidgetPager mAppWidgetContainer;
726fb841fa219eaae3e87f2fdc05e105d7a1813c42Adam Cohen    private KeyguardSecurityViewFlipper mSecurityViewContainer;
730a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen    private KeyguardSelectorView mKeyguardSelectorView;
744e81bd4bcf60a934d4cd589dab6e2bddb88d7356Jim Miller    private KeyguardTransportControlView mTransportControl;
75dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    private boolean mIsVerifyUnlockOnly;
76258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    private boolean mEnableFallback; // TODO: This should get the value from KeyguardPatternView
7763f9b81795559443e0376985f8aaaa97a359ef94Jim Miller    private SecurityMode mCurrentSecuritySelection = SecurityMode.Invalid;
78dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
79dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    protected Runnable mLaunchRunnable;
80dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
81dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    protected int mFailedAttempts;
82dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    private LockPatternUtils mLockPatternUtils;
83dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
84dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    private KeyguardSecurityModel mSecurityModel;
85d6523da1ad7bae805a3dbea8d7b398d86cd3c181Jim Miller    private KeyguardViewStateManager mViewStateManager;
86dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
875737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller    private Rect mTempRect = new Rect();
88ff2aa0bc8919c247bfc8e81d3f168e5064f52ffbJim Miller
89ff2aa0bc8919c247bfc8e81d3f168e5064f52ffbJim Miller    /*package*/ interface TransportCallback {
90223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        void onListenerDetached();
91223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        void onListenerAttached();
92223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        void onPlayStateChanged();
93ff2aa0bc8919c247bfc8e81d3f168e5064f52ffbJim Miller    }
945737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller
9524b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen    /*package*/ interface UserSwitcherCallback {
9624b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen        void hideSecurityView(int duration);
9724b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen        void showSecurityView();
980a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen        void showUnlockHint();
9919a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        void userActivity();
10024b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen    }
10124b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen
102dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    public KeyguardHostView(Context context) {
103dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        this(context, null);
104dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
105dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
106dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    public KeyguardHostView(Context context, AttributeSet attrs) {
107dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        super(context, attrs);
108000464ac012471d301c6e48a8228291519915e17Jim Miller        mLockPatternUtils = new LockPatternUtils(context);
109f229e4d3eb8f910c181f96416c6798f6f305a395Jim Miller        mAppWidgetHost = new AppWidgetHost(
110f229e4d3eb8f910c181f96416c6798f6f305a395Jim Miller                context, APPWIDGET_HOST_ID, mOnClickHandler, Looper.myLooper());
11167a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        mAppWidgetManager = AppWidgetManager.getInstance(mContext);
112f229e4d3eb8f910c181f96416c6798f6f305a395Jim Miller        mSecurityModel = new KeyguardSecurityModel(context);
11395b005c196de2f99513da28fe9108b2dec200140Jim Miller
114c4842c11932ea4f60fe7ae09b0a59660207e1587Svetoslav Ganov        mViewStateManager = new KeyguardViewStateManager();
115dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
116dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
117dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    @Override
118d2b82f70fede8c2ec4de34d8e6462ed4ece13c56Jim Miller    public boolean onTouchEvent(MotionEvent ev) {
119d2b82f70fede8c2ec4de34d8e6462ed4ece13c56Jim Miller        boolean result = super.onTouchEvent(ev);
1205737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller        mTempRect.set(0, 0, 0, 0);
1215737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller        offsetRectIntoDescendantCoords(mSecurityViewContainer, mTempRect);
1225737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller        ev.offsetLocation(mTempRect.left, mTempRect.top);
1235737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller        result = mSecurityViewContainer.dispatchTouchEvent(ev) || result;
1245737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller        ev.offsetLocation(-mTempRect.left, -mTempRect.top);
1255737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller        return result;
1265737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller    }
1275737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller
1285737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller    @Override
129dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    protected void dispatchDraw(Canvas canvas) {
130dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        super.dispatchDraw(canvas);
1317def1db03943251fe8cb57ec514722026425479eCraig Mautner        if (mViewMediatorCallback != null) {
1327def1db03943251fe8cb57ec514722026425479eCraig Mautner            mViewMediatorCallback.keyguardDoneDrawing();
1337def1db03943251fe8cb57ec514722026425479eCraig Mautner        }
134dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
135dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
136ff2aa0bc8919c247bfc8e81d3f168e5064f52ffbJim Miller    private int getWidgetPosition(int id) {
137ff2aa0bc8919c247bfc8e81d3f168e5064f52ffbJim Miller        final int children = mAppWidgetContainer.getChildCount();
138ff2aa0bc8919c247bfc8e81d3f168e5064f52ffbJim Miller        for (int i = 0; i < children; i++) {
139bdca3c0a21ba15e8bb6d7ef0ca1b7e8024f98f19Jim Miller            if (mAppWidgetContainer.getWidgetPageAt(i).getContent().getId() == id) {
140ff2aa0bc8919c247bfc8e81d3f168e5064f52ffbJim Miller                return i;
141ff2aa0bc8919c247bfc8e81d3f168e5064f52ffbJim Miller            }
142ff2aa0bc8919c247bfc8e81d3f168e5064f52ffbJim Miller        }
143ff2aa0bc8919c247bfc8e81d3f168e5064f52ffbJim Miller        return -1;
144ff2aa0bc8919c247bfc8e81d3f168e5064f52ffbJim Miller    }
145ff2aa0bc8919c247bfc8e81d3f168e5064f52ffbJim Miller
146dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    @Override
147dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    protected void onFinishInflate() {
148d6523da1ad7bae805a3dbea8d7b398d86cd3c181Jim Miller        // Grab instances of and make any necessary changes to the main layouts. Create
149d6523da1ad7bae805a3dbea8d7b398d86cd3c181Jim Miller        // view state manager and wire up necessary listeners / callbacks.
150f2dfc351dec58ad3c16f8496208b4e6e9c667efeJim Miller        mAppWidgetContainer = (KeyguardWidgetPager) findViewById(R.id.app_widget_container);
151838906b165e4d3cb2c512b2db344aa50cb5d4751Jim Miller        mAppWidgetContainer.setVisibility(VISIBLE);
152838906b165e4d3cb2c512b2db344aa50cb5d4751Jim Miller        mAppWidgetContainer.setCallbacks(mWidgetCallbacks);
153d6523da1ad7bae805a3dbea8d7b398d86cd3c181Jim Miller        mAppWidgetContainer.setMinScale(0.5f);
154d6523da1ad7bae805a3dbea8d7b398d86cd3c181Jim Miller
15519a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        SlidingChallengeLayout slider =
156d6523da1ad7bae805a3dbea8d7b398d86cd3c181Jim Miller                (SlidingChallengeLayout) findViewById(R.id.sliding_layout);
15719a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        if (slider != null) {
15819a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller            slider.setOnChallengeScrolledListener(mViewStateManager);
15919a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        }
160d6523da1ad7bae805a3dbea8d7b398d86cd3c181Jim Miller        mAppWidgetContainer.setViewStateManager(mViewStateManager);
1611254f2f42f7173ef51d0034975ab5cb7d44f8209Michael Jurka        mAppWidgetContainer.setLockPatternUtils(mLockPatternUtils);
162d6523da1ad7bae805a3dbea8d7b398d86cd3c181Jim Miller
163d6523da1ad7bae805a3dbea8d7b398d86cd3c181Jim Miller        mViewStateManager.setPagedView(mAppWidgetContainer);
16419a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        mViewStateManager.setChallengeLayout(slider != null ? slider :
16519a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                (ChallengeLayout) findViewById(R.id.multi_pane_challenge));
1666fb841fa219eaae3e87f2fdc05e105d7a1813c42Adam Cohen        mSecurityViewContainer = (KeyguardSecurityViewFlipper) findViewById(R.id.view_flipper);
1670a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen        mKeyguardSelectorView = (KeyguardSelectorView) findViewById(R.id.keyguard_selector_view);
1686fb841fa219eaae3e87f2fdc05e105d7a1813c42Adam Cohen        mViewStateManager.setSecurityViewContainer(mSecurityViewContainer);
169ff2aa0bc8919c247bfc8e81d3f168e5064f52ffbJim Miller
1706fb841fa219eaae3e87f2fdc05e105d7a1813c42Adam Cohen        mViewStateManager.showUsabilityHints();
171d6523da1ad7bae805a3dbea8d7b398d86cd3c181Jim Miller
172d6523da1ad7bae805a3dbea8d7b398d86cd3c181Jim Miller        if (!(mContext instanceof Activity)) {
173d6523da1ad7bae805a3dbea8d7b398d86cd3c181Jim Miller            setSystemUiVisibility(getSystemUiVisibility() | View.STATUS_BAR_DISABLE_BACK);
174d6523da1ad7bae805a3dbea8d7b398d86cd3c181Jim Miller        }
17568c2489457631f733f542e14058c6d1274c203deJim Miller
17667a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        addDefaultWidgets();
17767a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        addWidgetsFromSettings();
17867a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        mSwitchPageRunnable.run();
1799b1db682c32d103974b0f1193b50e77e254d5589Jim Miller
18067a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        showPrimarySecurityScreen(false);
1819b1db682c32d103974b0f1193b50e77e254d5589Jim Miller        updateSecurityViews();
182e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller    }
183dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
184e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller    private void updateSecurityViews() {
185e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        int children = mSecurityViewContainer.getChildCount();
186e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        for (int i = 0; i < children; i++) {
187e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            updateSecurityView(mSecurityViewContainer.getChildAt(i));
188e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        }
189e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller    }
190dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
191e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller    private void updateSecurityView(View view) {
192e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        if (view instanceof KeyguardSecurityView) {
193e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            KeyguardSecurityView ksv = (KeyguardSecurityView) view;
194e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            ksv.setKeyguardCallback(mCallback);
195e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            ksv.setLockPatternUtils(mLockPatternUtils);
196e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        } else {
197e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            Log.w(TAG, "View " + view + " is not a KeyguardSecurityView");
198dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
199dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
200dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
201dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    void setLockPatternUtils(LockPatternUtils utils) {
202dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        mSecurityModel.setLockPatternUtils(utils);
203dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        mLockPatternUtils = utils;
204e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        updateSecurityViews();
205dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
206dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
207dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    @Override
208dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    protected void onAttachedToWindow() {
209dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        super.onAttachedToWindow();
210dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        mAppWidgetHost.startListening();
2117221d3ae08cc2be922d26e5d491038512cb6c74dJim Miller    }
2127221d3ae08cc2be922d26e5d491038512cb6c74dJim Miller
213dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    @Override
214dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    protected void onDetachedFromWindow() {
215dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        super.onDetachedFromWindow();
216dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        mAppWidgetHost.stopListening();
217dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
218dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
219f229e4d3eb8f910c181f96416c6798f6f305a395Jim Miller    private AppWidgetHost getAppWidgetHost() {
220dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        return mAppWidgetHost;
221dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
222dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
223d6523da1ad7bae805a3dbea8d7b398d86cd3c181Jim Miller    void addWidget(AppWidgetHostView view, int pageIndex) {
224d6523da1ad7bae805a3dbea8d7b398d86cd3c181Jim Miller        mAppWidgetContainer.addWidget(view, pageIndex);
225dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
226dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
227838906b165e4d3cb2c512b2db344aa50cb5d4751Jim Miller    private KeyguardWidgetPager.Callbacks mWidgetCallbacks
228838906b165e4d3cb2c512b2db344aa50cb5d4751Jim Miller            = new KeyguardWidgetPager.Callbacks() {
229c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown        @Override
230c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown        public void userActivity() {
231c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown            if (mViewMediatorCallback != null) {
232c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown                mViewMediatorCallback.userActivity();
233c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown            }
234c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown        }
235c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown
236c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown        @Override
237c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown        public void onUserActivityTimeoutChanged() {
238c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown            if (mViewMediatorCallback != null) {
239c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown                mViewMediatorCallback.onUserActivityTimeoutChanged();
240c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown            }
241c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown        }
242c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown    };
243c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown
244c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown    @Override
245c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown    public long getUserActivityTimeout() {
246c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown        // Currently only considering user activity timeouts needed by widgets.
247c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown        // Could also take into account longer timeouts for certain security views.
248838906b165e4d3cb2c512b2db344aa50cb5d4751Jim Miller        if (mAppWidgetContainer != null) {
249838906b165e4d3cb2c512b2db344aa50cb5d4751Jim Miller            return mAppWidgetContainer.getUserActivityTimeout();
250c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown        }
251c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown        return -1;
252c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown    }
253c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown
254dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    private KeyguardSecurityCallback mCallback = new KeyguardSecurityCallback() {
255dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
256dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        public void userActivity(long timeout) {
2577def1db03943251fe8cb57ec514722026425479eCraig Mautner            if (mViewMediatorCallback != null) {
2583dc524bc31a1578693ca958ef442dfa092b7aa7fJeff Brown                mViewMediatorCallback.userActivity(timeout);
2597def1db03943251fe8cb57ec514722026425479eCraig Mautner            }
260dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
261dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
262dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        public void dismiss(boolean authenticated) {
263dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            showNextSecurityScreenOrFinish(authenticated);
264dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
265dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
266dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        public boolean isVerifyUnlockOnly() {
267258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            return mIsVerifyUnlockOnly;
268dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
269dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
270dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        public void reportSuccessfulUnlockAttempt() {
271258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            KeyguardUpdateMonitor.getInstance(mContext).clearFailedUnlockAttempts();
2727641506e3cc493ac4e6f5037fd76516754e61c6eJim Miller            mLockPatternUtils.reportSuccessfulPasswordAttempt();
273dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
274dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
275dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        public void reportFailedUnlockAttempt() {
2767641506e3cc493ac4e6f5037fd76516754e61c6eJim Miller            if (mCurrentSecuritySelection == SecurityMode.Biometric) {
2777641506e3cc493ac4e6f5037fd76516754e61c6eJim Miller                KeyguardUpdateMonitor.getInstance(mContext).reportFailedBiometricUnlockAttempt();
2787641506e3cc493ac4e6f5037fd76516754e61c6eJim Miller            } else {
2797641506e3cc493ac4e6f5037fd76516754e61c6eJim Miller                KeyguardHostView.this.reportFailedUnlockAttempt();
2807641506e3cc493ac4e6f5037fd76516754e61c6eJim Miller            }
281dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
282dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
283dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        public int getFailedAttempts() {
284258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            return KeyguardUpdateMonitor.getInstance(mContext).getFailedUnlockAttempts();
285dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
286dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
287258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        @Override
288258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        public void showBackupSecurity() {
2890ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller            KeyguardHostView.this.showBackupSecurityScreen();
290dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
291dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
2925f75aa15d7c1c5ea1c1eecd95bf2bb0920173eb2Jim Miller        @Override
2935f75aa15d7c1c5ea1c1eecd95bf2bb0920173eb2Jim Miller        public void setOnDismissRunnable(Runnable runnable) {
2945f75aa15d7c1c5ea1c1eecd95bf2bb0920173eb2Jim Miller            KeyguardHostView.this.setOnDismissRunnable(runnable);
2955f75aa15d7c1c5ea1c1eecd95bf2bb0920173eb2Jim Miller        }
2965f75aa15d7c1c5ea1c1eecd95bf2bb0920173eb2Jim Miller
297dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    };
298dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
299258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    private void showDialog(String title, String message) {
300258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        final AlertDialog dialog = new AlertDialog.Builder(mContext)
301258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            .setTitle(title)
302258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            .setMessage(message)
303258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            .setNeutralButton(com.android.internal.R.string.ok, null)
304258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            .create();
305258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        if (!(mContext instanceof Activity)) {
306258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
307258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        }
308258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        dialog.show();
309258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    }
310258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
311258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    private void showTimeoutDialog() {
312258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        int timeoutInSeconds = (int) LockPatternUtils.FAILED_ATTEMPT_TIMEOUT_MS / 1000;
313258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        int messageId = 0;
314258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
315258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        switch (mSecurityModel.getSecurityMode()) {
316258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            case Pattern:
317258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                messageId = R.string.kg_too_many_failed_pattern_attempts_dialog_message;
318258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                break;
31969bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler            case PIN:
32069bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler                messageId = R.string.kg_too_many_failed_pin_attempts_dialog_message;
32169bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler                break;
32269bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler            case Password:
32369bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler                messageId = R.string.kg_too_many_failed_password_attempts_dialog_message;
324258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                break;
325258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        }
326258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
327258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        if (messageId != 0) {
328258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            final String message = mContext.getString(messageId,
329258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                    KeyguardUpdateMonitor.getInstance(mContext).getFailedUnlockAttempts(),
330258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                    timeoutInSeconds);
331258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            showDialog(null, message);
332258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        }
333258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    }
334258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
335258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    private void showAlmostAtWipeDialog(int attempts, int remaining) {
336258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        int timeoutInSeconds = (int) LockPatternUtils.FAILED_ATTEMPT_TIMEOUT_MS / 1000;
337258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        String message = mContext.getString(R.string.kg_failed_attempts_almost_at_wipe,
338258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                attempts, remaining);
339258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        showDialog(null, message);
340258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    }
341258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
342258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    private void showWipeDialog(int attempts) {
343258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        String message = mContext.getString(R.string.kg_failed_attempts_now_wiping, attempts);
344258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        showDialog(null, message);
345258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    }
346258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
347258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    private void showAlmostAtAccountLoginDialog() {
348258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        final int timeoutInSeconds = (int) LockPatternUtils.FAILED_ATTEMPT_TIMEOUT_MS / 1000;
349258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        final int count = LockPatternUtils.FAILED_ATTEMPTS_BEFORE_RESET
350258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                - LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT;
351258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        String message = mContext.getString(R.string.kg_failed_attempts_almost_at_login,
352258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                count, LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT, timeoutInSeconds);
353258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        showDialog(null, message);
354258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    }
355258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
356258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    private void reportFailedUnlockAttempt() {
357258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        final KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(mContext);
358258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        final int failedAttempts = monitor.getFailedUnlockAttempts() + 1; // +1 for this time
359258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
360258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        if (DEBUG) Log.d(TAG, "reportFailedPatternAttempt: #" + failedAttempts);
361258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
362258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        SecurityMode mode = mSecurityModel.getSecurityMode();
363258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        final boolean usingPattern = mode == KeyguardSecurityModel.SecurityMode.Pattern;
364258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
365258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        final int failedAttemptsBeforeWipe = mLockPatternUtils.getDevicePolicyManager()
366599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                .getMaximumFailedPasswordsForWipe(null, mLockPatternUtils.getCurrentUser());
367258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
368258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        final int failedAttemptWarning = LockPatternUtils.FAILED_ATTEMPTS_BEFORE_RESET
369258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                - LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT;
370258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
371258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        final int remainingBeforeWipe = failedAttemptsBeforeWipe > 0 ?
372258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                (failedAttemptsBeforeWipe - failedAttempts)
373258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                : Integer.MAX_VALUE; // because DPM returns 0 if no restriction
374258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
37508b2b6bfe2550b65c68ad7b4bef8283f1ff17561Jim Miller        boolean showTimeout = false;
376258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        if (remainingBeforeWipe < LockPatternUtils.FAILED_ATTEMPTS_BEFORE_WIPE_GRACE) {
377258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            // If we reach this code, it means the user has installed a DevicePolicyManager
378258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            // that requests device wipe after N attempts.  Once we get below the grace
379258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            // period, we'll post this dialog every time as a clear warning until the
380258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            // bombshell hits and the device is wiped.
381258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            if (remainingBeforeWipe > 0) {
382258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                showAlmostAtWipeDialog(failedAttempts, remainingBeforeWipe);
383258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            } else {
384258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                // Too many attempts. The device will be wiped shortly.
385258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                Slog.i(TAG, "Too many unlock attempts; device will be wiped!");
386258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                showWipeDialog(failedAttempts);
387258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            }
388258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        } else {
38908b2b6bfe2550b65c68ad7b4bef8283f1ff17561Jim Miller            showTimeout =
390258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                (failedAttempts % LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT) == 0;
391258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            if (usingPattern && mEnableFallback) {
392258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                if (failedAttempts == failedAttemptWarning) {
393258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                    showAlmostAtAccountLoginDialog();
394258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                    showTimeout = false; // don't show both dialogs
395258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                } else if (failedAttempts >= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_RESET) {
396258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                    mLockPatternUtils.setPermanentlyLocked(true);
397e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller                    showSecurityScreen(SecurityMode.Account);
398258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                    // don't show timeout dialog because we show account unlock screen next
399258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                    showTimeout = false;
400258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                }
401258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            }
402258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        }
403258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        monitor.reportFailedUnlockAttempt();
404258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        mLockPatternUtils.reportFailedPasswordAttempt();
40508b2b6bfe2550b65c68ad7b4bef8283f1ff17561Jim Miller        if (showTimeout) {
40608b2b6bfe2550b65c68ad7b4bef8283f1ff17561Jim Miller            showTimeoutDialog();
40708b2b6bfe2550b65c68ad7b4bef8283f1ff17561Jim Miller        }
408258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    }
409258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
410258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    /**
4110ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller     * Shows the primary security screen for the user. This will be either the multi-selector
4120ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller     * or the user's security method.
4130ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller     * @param turningOff true if the device is being turned off
4140ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller     */
4150ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller    void showPrimarySecurityScreen(boolean turningOff) {
4160ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller        SecurityMode securityMode = mSecurityModel.getSecurityMode();
4170ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller        if (DEBUG) Log.v(TAG, "showPrimarySecurityScreen(turningOff=" + turningOff + ")");
418078f5919a9584cc3f1c7eb3a78862bfa40396de9Brian Colonna        if (!turningOff &&
419078f5919a9584cc3f1c7eb3a78862bfa40396de9Brian Colonna                KeyguardUpdateMonitor.getInstance(mContext).isAlternateUnlockEnabled()) {
4200ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller            // If we're not turning off, then allow biometric alternate.
4210ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller            // We'll reload it when the device comes back on.
4220ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller            securityMode = mSecurityModel.getAlternateFor(securityMode);
4230ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller        }
4240ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller        showSecurityScreen(securityMode);
4250ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller    }
42668c2489457631f733f542e14058c6d1274c203deJim Miller
4270ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller    /**
428258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller     * Shows the backup security screen for the current security mode.  This could be used for
429258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller     * password recovery screens but is currently only used for pattern unlock to show the
430258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller     * account unlock screen and biometric unlock to show the user's normal unlock.
431258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller     */
4320ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller    private void showBackupSecurityScreen() {
43361413b5ed215accd7b4f3eaf80edeab2f330aa49Danielle Millett        if (DEBUG) Log.d(TAG, "showBackupSecurity()");
43463f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        SecurityMode backup = mSecurityModel.getBackupSecurityMode(mCurrentSecuritySelection);
43563f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        showSecurityScreen(backup);
436258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    }
437258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
4380a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen    public boolean showNextSecurityScreenIfPresent() {
4390a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen        SecurityMode securityMode = mSecurityModel.getSecurityMode();
4400a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen        // Allow an alternate, such as biometric unlock
4410a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen        securityMode = mSecurityModel.getAlternateFor(securityMode);
4420a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen        if (SecurityMode.None == securityMode) {
4430a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen            return false;
4440a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen        } else {
4450a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen            showSecurityScreen(securityMode); // switch to the alternate security view
4460a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen            return true;
4470a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen        }
4480a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen    }
4490a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen
450258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    private void showNextSecurityScreenOrFinish(boolean authenticated) {
45161413b5ed215accd7b4f3eaf80edeab2f330aa49Danielle Millett        if (DEBUG) Log.d(TAG, "showNextSecurityScreenOrFinish(" + authenticated + ")");
452dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        boolean finish = false;
453e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        if (SecurityMode.None == mCurrentSecuritySelection) {
454258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            SecurityMode securityMode = mSecurityModel.getSecurityMode();
455258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            // Allow an alternate, such as biometric unlock
456000464ac012471d301c6e48a8228291519915e17Jim Miller            securityMode = mSecurityModel.getAlternateFor(securityMode);
457e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            if (SecurityMode.None == securityMode) {
458dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                finish = true; // no security required
459dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            } else {
460e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller                showSecurityScreen(securityMode); // switch to the alternate security view
461dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            }
462dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        } else if (authenticated) {
463e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            switch (mCurrentSecuritySelection) {
464e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller                case Pattern:
465e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller                case Password:
46669bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler                case PIN:
467e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller                case Account:
468e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller                case Biometric:
4694b09dd31fb1cefcaee87e7a206f22ba31527e250Jim Miller                    finish = true;
4704b09dd31fb1cefcaee87e7a206f22ba31527e250Jim Miller                    break;
4714b09dd31fb1cefcaee87e7a206f22ba31527e250Jim Miller
472e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller                case SimPin:
473e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller                case SimPuk:
4744b09dd31fb1cefcaee87e7a206f22ba31527e250Jim Miller                    // Shortcut for SIM PIN/PUK to go to directly to user's security screen or home
4754b09dd31fb1cefcaee87e7a206f22ba31527e250Jim Miller                    SecurityMode securityMode = mSecurityModel.getSecurityMode();
4764b09dd31fb1cefcaee87e7a206f22ba31527e250Jim Miller                    if (securityMode != SecurityMode.None) {
477e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller                        showSecurityScreen(securityMode);
4784b09dd31fb1cefcaee87e7a206f22ba31527e250Jim Miller                    } else {
4794b09dd31fb1cefcaee87e7a206f22ba31527e250Jim Miller                        finish = true;
4804b09dd31fb1cefcaee87e7a206f22ba31527e250Jim Miller                    }
4814b09dd31fb1cefcaee87e7a206f22ba31527e250Jim Miller                    break;
4824b09dd31fb1cefcaee87e7a206f22ba31527e250Jim Miller
4834b09dd31fb1cefcaee87e7a206f22ba31527e250Jim Miller                default:
4840ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller                    Log.v(TAG, "Bad security screen " + mCurrentSecuritySelection + ", fail safe");
4850ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller                    showPrimarySecurityScreen(false);
4864b09dd31fb1cefcaee87e7a206f22ba31527e250Jim Miller                    break;
487dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            }
488dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        } else {
4890ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller            showPrimarySecurityScreen(false);
490dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
491dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        if (finish) {
4920ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller            // If the alternate unlock was suppressed, it can now be safely
4930ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller            // enabled because the user has left keyguard.
4940ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller            KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(true);
49568c2489457631f733f542e14058c6d1274c203deJim Miller
496dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            // If there's a pending runnable because the user interacted with a widget
497dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            // and we're leaving keyguard, then run it.
498dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            if (mLaunchRunnable != null) {
499dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                mLaunchRunnable.run();
500dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                mLaunchRunnable = null;
501dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            }
5027def1db03943251fe8cb57ec514722026425479eCraig Mautner            if (mViewMediatorCallback != null) {
5037def1db03943251fe8cb57ec514722026425479eCraig Mautner                mViewMediatorCallback.keyguardDone(true);
5047def1db03943251fe8cb57ec514722026425479eCraig Mautner            }
505b5f3b707a7010e8d867da9342ea87cf0a1679692Jim Miller        } else {
506b5f3b707a7010e8d867da9342ea87cf0a1679692Jim Miller            mViewStateManager.showBouncer(true);
507dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
508dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
509dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
510dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    private OnClickHandler mOnClickHandler = new OnClickHandler() {
511dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        @Override
512dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        public boolean onClickHandler(final View view,
513dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                final android.app.PendingIntent pendingIntent,
514dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                final Intent fillInIntent) {
515dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            if (pendingIntent.isActivity()) {
5165f75aa15d7c1c5ea1c1eecd95bf2bb0920173eb2Jim Miller                setOnDismissRunnable(new Runnable() {
517dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                    public void run() {
518dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                        try {
519dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                              // TODO: Unregister this handler if PendingIntent.FLAG_ONE_SHOT?
520dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                              Context context = view.getContext();
521dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                              ActivityOptions opts = ActivityOptions.makeScaleUpAnimation(view,
522dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                                      0, 0,
523dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                                      view.getMeasuredWidth(), view.getMeasuredHeight());
524dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                              context.startIntentSender(
525dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                                      pendingIntent.getIntentSender(), fillInIntent,
526dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                                      Intent.FLAG_ACTIVITY_NEW_TASK,
527dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                                      Intent.FLAG_ACTIVITY_NEW_TASK, 0, opts.toBundle());
528dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                          } catch (IntentSender.SendIntentException e) {
529dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                              android.util.Log.e(TAG, "Cannot send pending intent: ", e);
530dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                          } catch (Exception e) {
531dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                              android.util.Log.e(TAG, "Cannot send pending intent due to " +
532dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                                      "unknown exception: ", e);
533dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                          }
534dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                    }
5355f75aa15d7c1c5ea1c1eecd95bf2bb0920173eb2Jim Miller                });
536dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
537dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                mCallback.dismiss(false);
538dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                return true;
539dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            } else {
540dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                return super.onClickHandler(view, pendingIntent, fillInIntent);
541dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            }
542dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        };
543dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    };
544dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
54563f9b81795559443e0376985f8aaaa97a359ef94Jim Miller    // Used to ignore callbacks from methods that are no longer current (e.g. face unlock).
54663f9b81795559443e0376985f8aaaa97a359ef94Jim Miller    // This avoids unwanted asynchronous events from messing with the state.
54763f9b81795559443e0376985f8aaaa97a359ef94Jim Miller    private KeyguardSecurityCallback mNullCallback = new KeyguardSecurityCallback() {
54863f9b81795559443e0376985f8aaaa97a359ef94Jim Miller
54963f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        @Override
55063f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        public void userActivity(long timeout) {
55163f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        }
55263f9b81795559443e0376985f8aaaa97a359ef94Jim Miller
55363f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        @Override
55463f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        public void showBackupSecurity() {
55563f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        }
55663f9b81795559443e0376985f8aaaa97a359ef94Jim Miller
55763f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        @Override
55863f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        public void setOnDismissRunnable(Runnable runnable) {
55963f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        }
56063f9b81795559443e0376985f8aaaa97a359ef94Jim Miller
56163f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        @Override
56263f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        public void reportSuccessfulUnlockAttempt() {
56363f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        }
56463f9b81795559443e0376985f8aaaa97a359ef94Jim Miller
56563f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        @Override
56663f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        public void reportFailedUnlockAttempt() {
56763f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        }
56863f9b81795559443e0376985f8aaaa97a359ef94Jim Miller
56963f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        @Override
57063f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        public boolean isVerifyUnlockOnly() {
57163f9b81795559443e0376985f8aaaa97a359ef94Jim Miller            return false;
57263f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        }
57363f9b81795559443e0376985f8aaaa97a359ef94Jim Miller
57463f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        @Override
57563f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        public int getFailedAttempts() {
57663f9b81795559443e0376985f8aaaa97a359ef94Jim Miller            return 0;
57763f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        }
57863f9b81795559443e0376985f8aaaa97a359ef94Jim Miller
57963f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        @Override
58063f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        public void dismiss(boolean securityVerified) {
58163f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        }
58263f9b81795559443e0376985f8aaaa97a359ef94Jim Miller    };
58363f9b81795559443e0376985f8aaaa97a359ef94Jim Miller
584dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    @Override
585dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    public void reset() {
586258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        mIsVerifyUnlockOnly = false;
587ff2aa0bc8919c247bfc8e81d3f168e5064f52ffbJim Miller        mAppWidgetContainer.setCurrentPage(getWidgetPosition(R.id.keyguard_status_view));
588dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
589dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
5905f75aa15d7c1c5ea1c1eecd95bf2bb0920173eb2Jim Miller    /**
5915f75aa15d7c1c5ea1c1eecd95bf2bb0920173eb2Jim Miller     *  Sets a runnable to run when keyguard is dismissed
5925f75aa15d7c1c5ea1c1eecd95bf2bb0920173eb2Jim Miller     * @param runnable
5935f75aa15d7c1c5ea1c1eecd95bf2bb0920173eb2Jim Miller     */
5945f75aa15d7c1c5ea1c1eecd95bf2bb0920173eb2Jim Miller    protected void setOnDismissRunnable(Runnable runnable) {
5955f75aa15d7c1c5ea1c1eecd95bf2bb0920173eb2Jim Miller        mLaunchRunnable = runnable;
5965f75aa15d7c1c5ea1c1eecd95bf2bb0920173eb2Jim Miller    }
5975f75aa15d7c1c5ea1c1eecd95bf2bb0920173eb2Jim Miller
598e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller    private KeyguardSecurityView getSecurityView(SecurityMode securityMode) {
599e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        final int securityViewIdForMode = getSecurityViewIdForMode(securityMode);
600e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        KeyguardSecurityView view = null;
601e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        final int children = mSecurityViewContainer.getChildCount();
602dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        for (int child = 0; child < children; child++) {
603e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            if (mSecurityViewContainer.getChildAt(child).getId() == securityViewIdForMode) {
604e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller                view = ((KeyguardSecurityView)mSecurityViewContainer.getChildAt(child));
605e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller                break;
606dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            }
607dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
60863f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        int layoutId = getLayoutIdFor(securityMode);
60963f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        if (view == null && layoutId != 0) {
610e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            final LayoutInflater inflater = LayoutInflater.from(mContext);
611bdffd5c3a18e67443ebbd16d4f0349d0728285b1Jim Miller            if (DEBUG) Log.v(TAG, "inflating id = " + layoutId);
61263f9b81795559443e0376985f8aaaa97a359ef94Jim Miller            View v = inflater.inflate(layoutId, this, false);
613e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            mSecurityViewContainer.addView(v);
614e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            updateSecurityView(v);
6150b728244dc87b4a453f2191c2cb37a86e91aee0aJim Miller            view = (KeyguardSecurityView)v;
6160ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller        }
6170ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller
6180ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller        if (view instanceof KeyguardSelectorView) {
6190ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller            KeyguardSelectorView selectorView = (KeyguardSelectorView) view;
6200ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller            View carrierText = selectorView.findViewById(R.id.keyguard_selector_fade_container);
6210ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller            selectorView.setCarrierArea(carrierText);
6220ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller        }
62368c2489457631f733f542e14058c6d1274c203deJim Miller
624e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        return view;
625dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
626dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
627258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    /**
628258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller     * Switches to the given security view unless it's already being shown, in which case
629258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller     * this is a no-op.
630258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller     *
631e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller     * @param securityMode
632258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller     */
633e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller    private void showSecurityScreen(SecurityMode securityMode) {
63468c2489457631f733f542e14058c6d1274c203deJim Miller        if (DEBUG) Log.d(TAG, "showSecurityScreen(" + securityMode + ")");
63568c2489457631f733f542e14058c6d1274c203deJim Miller
636e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        if (securityMode == mCurrentSecuritySelection) return;
637dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
638e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        KeyguardSecurityView oldView = getSecurityView(mCurrentSecuritySelection);
639e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        KeyguardSecurityView newView = getSecurityView(securityMode);
640dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
641a71984f3da47c6e6e3164c170735362a3222d3adJim Miller        // Enter full screen mode if we're in SIM or Account screen
642a71984f3da47c6e6e3164c170735362a3222d3adJim Miller        boolean fullScreenEnabled = getResources().getBoolean(
643a71984f3da47c6e6e3164c170735362a3222d3adJim Miller                com.android.internal.R.bool.kg_sim_puk_account_full_screen);
644a71984f3da47c6e6e3164c170735362a3222d3adJim Miller        boolean isSimOrAccount = securityMode == SecurityMode.SimPin
645a71984f3da47c6e6e3164c170735362a3222d3adJim Miller                || securityMode == SecurityMode.SimPuk
646a71984f3da47c6e6e3164c170735362a3222d3adJim Miller                || securityMode == SecurityMode.Account;
647a71984f3da47c6e6e3164c170735362a3222d3adJim Miller        mAppWidgetContainer.setVisibility(
648a71984f3da47c6e6e3164c170735362a3222d3adJim Miller                isSimOrAccount && fullScreenEnabled ? View.GONE : View.VISIBLE);
649a71984f3da47c6e6e3164c170735362a3222d3adJim Miller
650dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        // Emulate Activity life cycle
65163f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        if (oldView != null) {
65263f9b81795559443e0376985f8aaaa97a359ef94Jim Miller            oldView.onPause();
65363f9b81795559443e0376985f8aaaa97a359ef94Jim Miller            oldView.setKeyguardCallback(mNullCallback); // ignore requests from old view
65463f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        }
655dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        newView.onResume();
65663f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        newView.setKeyguardCallback(mCallback);
657dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
658cd03a26f4f5663b40d4679de102519ccc163fa10Craig Mautner        final boolean needsInput = newView.needsInput();
6597def1db03943251fe8cb57ec514722026425479eCraig Mautner        if (mViewMediatorCallback != null) {
660cd03a26f4f5663b40d4679de102519ccc163fa10Craig Mautner            mViewMediatorCallback.setNeedsInput(needsInput);
6617def1db03943251fe8cb57ec514722026425479eCraig Mautner        }
662dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
663dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        // Find and show this child.
664e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        final int childCount = mSecurityViewContainer.getChildCount();
6654b09dd31fb1cefcaee87e7a206f22ba31527e250Jim Miller
66622ae05d50c7011b389a5dba7a2f717e407328bf8Jim Miller        mSecurityViewContainer.setInAnimation(
66722ae05d50c7011b389a5dba7a2f717e407328bf8Jim Miller                AnimationUtils.loadAnimation(mContext, R.anim.keyguard_security_fade_in));
66822ae05d50c7011b389a5dba7a2f717e407328bf8Jim Miller        mSecurityViewContainer.setOutAnimation(
66922ae05d50c7011b389a5dba7a2f717e407328bf8Jim Miller                AnimationUtils.loadAnimation(mContext, R.anim.keyguard_security_fade_out));
670e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        final int securityViewIdForMode = getSecurityViewIdForMode(securityMode);
671dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        for (int i = 0; i < childCount; i++) {
672e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            if (mSecurityViewContainer.getChildAt(i).getId() == securityViewIdForMode) {
673e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller                mSecurityViewContainer.setDisplayedChild(i);
674dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                break;
675dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            }
676dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
677258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
678e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        if (securityMode == SecurityMode.None) {
679e23ab8b1acea211762f1d0c4202f73a9f7700bb5Jim Miller            // Discard current runnable if we're switching back to the selector view
680258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            setOnDismissRunnable(null);
68168c2489457631f733f542e14058c6d1274c203deJim Miller        }
682e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        mCurrentSecuritySelection = securityMode;
683dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
684dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
685dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    @Override
686dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    public void onScreenTurnedOn() {
687358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock        if (DEBUG) Log.d(TAG, "screen on, instance " + Integer.toHexString(hashCode()));
6880ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller        showPrimarySecurityScreen(false);
689e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        getSecurityView(mCurrentSecuritySelection).onResume();
690d03a5558350cb6adff68aaf97ad4ee946bcd91a1Jim Miller
691d03a5558350cb6adff68aaf97ad4ee946bcd91a1Jim Miller        // This is a an attempt to fix bug 7137389 where the device comes back on but the entire
692d03a5558350cb6adff68aaf97ad4ee946bcd91a1Jim Miller        // layout is blank but forcing a layout causes it to reappear (e.g. with with
693d03a5558350cb6adff68aaf97ad4ee946bcd91a1Jim Miller        // hierarchyviewer).
694d03a5558350cb6adff68aaf97ad4ee946bcd91a1Jim Miller        requestLayout();
6956fb841fa219eaae3e87f2fdc05e105d7a1813c42Adam Cohen
6966fb841fa219eaae3e87f2fdc05e105d7a1813c42Adam Cohen        if (mViewStateManager != null) {
6976fb841fa219eaae3e87f2fdc05e105d7a1813c42Adam Cohen            mViewStateManager.showUsabilityHints();
6986fb841fa219eaae3e87f2fdc05e105d7a1813c42Adam Cohen        }
699dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
700dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
701dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    @Override
702dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    public void onScreenTurnedOff() {
703dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock        if (DEBUG) Log.d(TAG, String.format("screen off, instance %s at %s",
704dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock                Integer.toHexString(hashCode()), SystemClock.uptimeMillis()));
705078f5919a9584cc3f1c7eb3a78862bfa40396de9Brian Colonna        // Once the screen turns off, we no longer consider this to be first boot and we want the
706078f5919a9584cc3f1c7eb3a78862bfa40396de9Brian Colonna        // biometric unlock to start next time keyguard is shown.
707078f5919a9584cc3f1c7eb3a78862bfa40396de9Brian Colonna        KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(true);
7085f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock        saveStickyWidgetIndex();
70967a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        checkAppWidgetConsistency();
7100ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller        showPrimarySecurityScreen(true);
711e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        getSecurityView(mCurrentSecuritySelection).onPause();
712dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock        CameraWidgetFrame cameraPage = findCameraPage();
713dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock        if (cameraPage != null) {
714dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock            cameraPage.onScreenTurnedOff();
715dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock        }
716dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
717dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
718dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    @Override
719dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    public void show() {
720086977094d96ab9352432e0941a05b09cefc92acJim Miller        if (DEBUG) Log.d(TAG, "show()");
721086977094d96ab9352432e0941a05b09cefc92acJim Miller        showPrimarySecurityScreen(false);
722dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
723dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
724dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    private boolean isSecure() {
725dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        SecurityMode mode = mSecurityModel.getSecurityMode();
726dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        switch (mode) {
727dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            case Pattern:
728dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                return mLockPatternUtils.isLockPatternEnabled();
729dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            case Password:
73069bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler            case PIN:
731dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                return mLockPatternUtils.isLockPasswordEnabled();
732dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            case SimPin:
733dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            case SimPuk:
734dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            case Account:
735dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                return true;
736dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            case None:
737dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                return false;
738dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            default:
739dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                throw new IllegalStateException("Unknown security mode " + mode);
740dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
741dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
742dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
743dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    @Override
744dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    public void wakeWhenReadyTq(int keyCode) {
745dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        if (DEBUG) Log.d(TAG, "onWakeKey");
746dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        if (keyCode == KeyEvent.KEYCODE_MENU && isSecure()) {
747dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            if (DEBUG) Log.d(TAG, "switching screens to unlock screen because wake key was MENU");
748e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            showSecurityScreen(SecurityMode.None);
749dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        } else {
750dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            if (DEBUG) Log.d(TAG, "poking wake lock immediately");
7517def1db03943251fe8cb57ec514722026425479eCraig Mautner        }
7527def1db03943251fe8cb57ec514722026425479eCraig Mautner        if (mViewMediatorCallback != null) {
7533dc524bc31a1578693ca958ef442dfa092b7aa7fJeff Brown            mViewMediatorCallback.wakeUp();
754dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
755dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
756dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
757dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    @Override
758dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    public void verifyUnlock() {
759dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        SecurityMode securityMode = mSecurityModel.getSecurityMode();
760dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        if (securityMode == KeyguardSecurityModel.SecurityMode.None) {
7617def1db03943251fe8cb57ec514722026425479eCraig Mautner            if (mViewMediatorCallback != null) {
7627def1db03943251fe8cb57ec514722026425479eCraig Mautner                mViewMediatorCallback.keyguardDone(true);
7637def1db03943251fe8cb57ec514722026425479eCraig Mautner            }
764dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        } else if (securityMode != KeyguardSecurityModel.SecurityMode.Pattern
76569bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler                && securityMode != KeyguardSecurityModel.SecurityMode.PIN
766dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                && securityMode != KeyguardSecurityModel.SecurityMode.Password) {
767dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            // can only verify unlock when in pattern/password mode
7687def1db03943251fe8cb57ec514722026425479eCraig Mautner            if (mViewMediatorCallback != null) {
7697def1db03943251fe8cb57ec514722026425479eCraig Mautner                mViewMediatorCallback.keyguardDone(false);
7707def1db03943251fe8cb57ec514722026425479eCraig Mautner            }
771dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        } else {
772dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            // otherwise, go to the unlock screen, see if they can verify it
773dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            mIsVerifyUnlockOnly = true;
774e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            showSecurityScreen(securityMode);
775dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
776dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
777dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
778dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    private int getSecurityViewIdForMode(SecurityMode securityMode) {
779dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        switch (securityMode) {
780e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            case None: return R.id.keyguard_selector_view;
781e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            case Pattern: return R.id.keyguard_pattern_view;
78269bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler            case PIN: return R.id.keyguard_pin_view;
783e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            case Password: return R.id.keyguard_password_view;
784e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            case Biometric: return R.id.keyguard_face_unlock_view;
785e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            case Account: return R.id.keyguard_account_view;
786e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            case SimPin: return R.id.keyguard_sim_pin_view;
787e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            case SimPuk: return R.id.keyguard_sim_puk_view;
788dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
789dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        return 0;
790dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
791dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
792e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller    private int getLayoutIdFor(SecurityMode securityMode) {
793e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        switch (securityMode) {
794e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            case None: return R.layout.keyguard_selector_view;
795e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            case Pattern: return R.layout.keyguard_pattern_view;
79669bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler            case PIN: return R.layout.keyguard_pin_view;
797e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            case Password: return R.layout.keyguard_password_view;
798e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            case Biometric: return R.layout.keyguard_face_unlock_view;
799e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            case Account: return R.layout.keyguard_account_view;
800e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            case SimPin: return R.layout.keyguard_sim_pin_view;
801e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            case SimPuk: return R.layout.keyguard_sim_puk_view;
802e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller            default:
80363f9b81795559443e0376985f8aaaa97a359ef94Jim Miller                return 0;
804e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller        }
805e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller    }
806e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller
80767a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka    private boolean addWidget(int appId, int pageIndex) {
80867a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appId);
80999a3cae55bd1a4ea6d82aa7fa2a67170e7cd5b3eJim Miller        if (appWidgetInfo != null) {
81099a3cae55bd1a4ea6d82aa7fa2a67170e7cd5b3eJim Miller            AppWidgetHostView view = getAppWidgetHost().createView(mContext, appId, appWidgetInfo);
811d6523da1ad7bae805a3dbea8d7b398d86cd3c181Jim Miller            addWidget(view, pageIndex);
81267a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka            return true;
81399a3cae55bd1a4ea6d82aa7fa2a67170e7cd5b3eJim Miller        } else {
8141254f2f42f7173ef51d0034975ab5cb7d44f8209Michael Jurka            Log.w(TAG, "AppWidgetInfo for app widget id " + appId + " was null, deleting");
8151254f2f42f7173ef51d0034975ab5cb7d44f8209Michael Jurka            mLockPatternUtils.removeAppWidget(appId);
81667a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka            return false;
81799a3cae55bd1a4ea6d82aa7fa2a67170e7cd5b3eJim Miller        }
818dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
819dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
820dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock    private final CameraWidgetFrame.Callbacks mCameraWidgetCallbacks =
821dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock        new CameraWidgetFrame.Callbacks() {
822dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock            @Override
823dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock            public void onLaunchingCamera() {
824dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock                SlidingChallengeLayout slider = locateSlider();
825dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock                if (slider != null) {
8266e36f1019cb6d7098b49e036e1640c8cfc6880cfJohn Spurlock                    slider.setHandleAlpha(0);
827dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock                }
828dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock            }
829dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock
830dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock            @Override
831dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock            public void onCameraLaunched() {
8324b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock                if (isCameraPage(mAppWidgetContainer.getCurrentPage())) {
8334b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock                    mAppWidgetContainer.scrollLeft();
8344b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock                }
835dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock                SlidingChallengeLayout slider = locateSlider();
836dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock                if (slider != null) {
8376e36f1019cb6d7098b49e036e1640c8cfc6880cfJohn Spurlock                    slider.setHandleAlpha(1);
838358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock                    slider.showChallenge(true);
839dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock                }
840dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock            }
841dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock
842dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock            private SlidingChallengeLayout locateSlider() {
843dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock                return (SlidingChallengeLayout) findViewById(R.id.sliding_layout);
844dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock            }
845dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock        };
846dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock
847dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock    private final KeyguardActivityLauncher mActivityLauncher = new KeyguardActivityLauncher() {
848dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock        @Override
849dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock        Context getContext() {
850dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock            return mContext;
851dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock        }
852dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock
853dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock        @Override
854dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock        KeyguardSecurityCallback getCallback() {
855dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock            return mCallback;
856dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock        }
857dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock
858dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock        @Override
859dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock        LockPatternUtils getLockPatternUtils() {
860dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock            return mLockPatternUtils;
861bdca3c0a21ba15e8bb6d7ef0ca1b7e8024f98f19Jim Miller        }
862bdca3c0a21ba15e8bb6d7ef0ca1b7e8024f98f19Jim Miller    };
863dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock
8644e81bd4bcf60a934d4cd589dab6e2bddb88d7356Jim Miller    private void addDefaultWidgets() {
8654e81bd4bcf60a934d4cd589dab6e2bddb88d7356Jim Miller        LayoutInflater inflater = LayoutInflater.from(mContext);
866223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        inflater.inflate(R.layout.keyguard_transport_control_view, this, true);
8674e81bd4bcf60a934d4cd589dab6e2bddb88d7356Jim Miller
868d6523da1ad7bae805a3dbea8d7b398d86cd3c181Jim Miller        View addWidget = inflater.inflate(R.layout.keyguard_add_widget, null, true);
869d6523da1ad7bae805a3dbea8d7b398d86cd3c181Jim Miller        mAppWidgetContainer.addWidget(addWidget);
87086b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock        if (mContext.getResources().getBoolean(R.bool.kg_enable_camera_default_widget)) {
871dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock            View cameraWidget =
872dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock                    CameraWidgetFrame.create(mContext, mCameraWidgetCallbacks, mActivityLauncher);
873dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock            if (cameraWidget != null) {
874dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock                mAppWidgetContainer.addWidget(cameraWidget);
875dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock            }
87686b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock        }
877838906b165e4d3cb2c512b2db344aa50cb5d4751Jim Miller
878b5f3b707a7010e8d867da9342ea87cf0a1679692Jim Miller        View addWidgetButton = addWidget.findViewById(R.id.keyguard_add_widget_view);
879b5f3b707a7010e8d867da9342ea87cf0a1679692Jim Miller        addWidgetButton.setOnClickListener(new OnClickListener() {
880b5f3b707a7010e8d867da9342ea87cf0a1679692Jim Miller            @Override
881b5f3b707a7010e8d867da9342ea87cf0a1679692Jim Miller            public void onClick(View v) {
882b5f3b707a7010e8d867da9342ea87cf0a1679692Jim Miller                mCallback.setOnDismissRunnable(new Runnable() {
883b5f3b707a7010e8d867da9342ea87cf0a1679692Jim Miller
884b5f3b707a7010e8d867da9342ea87cf0a1679692Jim Miller                    @Override
885b5f3b707a7010e8d867da9342ea87cf0a1679692Jim Miller                    public void run() {
88667a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka                        launchPickActivityIntent();
887b5f3b707a7010e8d867da9342ea87cf0a1679692Jim Miller                    }
888b5f3b707a7010e8d867da9342ea87cf0a1679692Jim Miller                });
889b5f3b707a7010e8d867da9342ea87cf0a1679692Jim Miller                mCallback.dismiss(false);
890b5f3b707a7010e8d867da9342ea87cf0a1679692Jim Miller            }
891b5f3b707a7010e8d867da9342ea87cf0a1679692Jim Miller        });
892b5f3b707a7010e8d867da9342ea87cf0a1679692Jim Miller
89319a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        enableUserSelectorIfNecessary();
8947221d3ae08cc2be922d26e5d491038512cb6c74dJim Miller        initializeTransportControl();
8957221d3ae08cc2be922d26e5d491038512cb6c74dJim Miller    }
8967221d3ae08cc2be922d26e5d491038512cb6c74dJim Miller
89767a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka    private void launchPickActivityIntent() {
898fc753c0cf676000b1c2d3cb2728af85a9b49f795Michael Jurka        // Create intent to pick widget
899fc753c0cf676000b1c2d3cb2728af85a9b49f795Michael Jurka        Intent pickIntent = new Intent(AppWidgetManager.ACTION_KEYGUARD_APPWIDGET_PICK);
900fc753c0cf676000b1c2d3cb2728af85a9b49f795Michael Jurka
901fc753c0cf676000b1c2d3cb2728af85a9b49f795Michael Jurka        int appWidgetId = mAppWidgetHost.allocateAppWidgetId();
902fc753c0cf676000b1c2d3cb2728af85a9b49f795Michael Jurka        if (appWidgetId != -1) {
903fc753c0cf676000b1c2d3cb2728af85a9b49f795Michael Jurka            pickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
904fc753c0cf676000b1c2d3cb2728af85a9b49f795Michael Jurka            pickIntent.putExtra(AppWidgetManager.EXTRA_CUSTOM_SORT, false);
905fc753c0cf676000b1c2d3cb2728af85a9b49f795Michael Jurka            pickIntent.putExtra(AppWidgetManager.EXTRA_CATEGORY_FILTER,
906fc753c0cf676000b1c2d3cb2728af85a9b49f795Michael Jurka                    AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD);
907fc753c0cf676000b1c2d3cb2728af85a9b49f795Michael Jurka
908fc753c0cf676000b1c2d3cb2728af85a9b49f795Michael Jurka            pickIntent.putExtra(Intent.EXTRA_INTENT, getBaseIntent());
909fc753c0cf676000b1c2d3cb2728af85a9b49f795Michael Jurka            pickIntent.addFlags(
910fc753c0cf676000b1c2d3cb2728af85a9b49f795Michael Jurka                    Intent.FLAG_ACTIVITY_NEW_TASK
911fc753c0cf676000b1c2d3cb2728af85a9b49f795Michael Jurka                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
912fc753c0cf676000b1c2d3cb2728af85a9b49f795Michael Jurka                    | Intent.FLAG_ACTIVITY_CLEAR_TOP
913fc753c0cf676000b1c2d3cb2728af85a9b49f795Michael Jurka                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
914fc753c0cf676000b1c2d3cb2728af85a9b49f795Michael Jurka            mContext.startActivityAsUser(pickIntent,
915fc753c0cf676000b1c2d3cb2728af85a9b49f795Michael Jurka                    new UserHandle(UserHandle.USER_CURRENT));
916fc753c0cf676000b1c2d3cb2728af85a9b49f795Michael Jurka        } else {
917fc753c0cf676000b1c2d3cb2728af85a9b49f795Michael Jurka            Log.e(TAG, "Unable to allocate an AppWidget id in lock screen");
918fc753c0cf676000b1c2d3cb2728af85a9b49f795Michael Jurka        }
919fc753c0cf676000b1c2d3cb2728af85a9b49f795Michael Jurka    }
920fc753c0cf676000b1c2d3cb2728af85a9b49f795Michael Jurka
921fc753c0cf676000b1c2d3cb2728af85a9b49f795Michael Jurka    private Intent getBaseIntent() {
922fc753c0cf676000b1c2d3cb2728af85a9b49f795Michael Jurka        Intent baseIntent = new Intent(Intent.ACTION_MAIN, null);
923fc753c0cf676000b1c2d3cb2728af85a9b49f795Michael Jurka        baseIntent.addCategory(Intent.CATEGORY_DEFAULT);
924fc753c0cf676000b1c2d3cb2728af85a9b49f795Michael Jurka
925fc753c0cf676000b1c2d3cb2728af85a9b49f795Michael Jurka        Bundle options = new Bundle();
926fc753c0cf676000b1c2d3cb2728af85a9b49f795Michael Jurka        options.putInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY,
927fc753c0cf676000b1c2d3cb2728af85a9b49f795Michael Jurka                AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD);
928fc753c0cf676000b1c2d3cb2728af85a9b49f795Michael Jurka        baseIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options);
929fc753c0cf676000b1c2d3cb2728af85a9b49f795Michael Jurka        return baseIntent;
930fc753c0cf676000b1c2d3cb2728af85a9b49f795Michael Jurka    }
931fc753c0cf676000b1c2d3cb2728af85a9b49f795Michael Jurka
932bdca3c0a21ba15e8bb6d7ef0ca1b7e8024f98f19Jim Miller    private void removeTransportFromWidgetPager() {
933bdca3c0a21ba15e8bb6d7ef0ca1b7e8024f98f19Jim Miller        int page = getWidgetPosition(R.id.keyguard_transport_control);
934bdca3c0a21ba15e8bb6d7ef0ca1b7e8024f98f19Jim Miller        if (page != -1) {
935bdca3c0a21ba15e8bb6d7ef0ca1b7e8024f98f19Jim Miller            mAppWidgetContainer.removeWidget(mTransportControl);
936bdca3c0a21ba15e8bb6d7ef0ca1b7e8024f98f19Jim Miller
937bdca3c0a21ba15e8bb6d7ef0ca1b7e8024f98f19Jim Miller            // XXX keep view attached so we still get show/hide events from AudioManager
938bdca3c0a21ba15e8bb6d7ef0ca1b7e8024f98f19Jim Miller            KeyguardHostView.this.addView(mTransportControl);
939bdca3c0a21ba15e8bb6d7ef0ca1b7e8024f98f19Jim Miller            mTransportControl.setVisibility(View.GONE);
940e0566da2dab8c3b9ddca43131f21ef58b79049c8Jim Miller            mViewStateManager.setTransportState(KeyguardViewStateManager.TRANSPORT_GONE);
941bdca3c0a21ba15e8bb6d7ef0ca1b7e8024f98f19Jim Miller            mTransportControl.post(mSwitchPageRunnable);
942bdca3c0a21ba15e8bb6d7ef0ca1b7e8024f98f19Jim Miller        }
943bdca3c0a21ba15e8bb6d7ef0ca1b7e8024f98f19Jim Miller    }
944bdca3c0a21ba15e8bb6d7ef0ca1b7e8024f98f19Jim Miller
945bdca3c0a21ba15e8bb6d7ef0ca1b7e8024f98f19Jim Miller    private void addTransportToWidgetPager() {
946bdca3c0a21ba15e8bb6d7ef0ca1b7e8024f98f19Jim Miller        if (getWidgetPosition(R.id.keyguard_transport_control) == -1) {
947bdca3c0a21ba15e8bb6d7ef0ca1b7e8024f98f19Jim Miller            KeyguardHostView.this.removeView(mTransportControl);
948bdca3c0a21ba15e8bb6d7ef0ca1b7e8024f98f19Jim Miller            // insert to left of camera if it exists, otherwise after right-most widget
949bdca3c0a21ba15e8bb6d7ef0ca1b7e8024f98f19Jim Miller            int lastWidget = mAppWidgetContainer.getChildCount() - 1;
950bdca3c0a21ba15e8bb6d7ef0ca1b7e8024f98f19Jim Miller            int position = 0; // handle no widget case
951bdca3c0a21ba15e8bb6d7ef0ca1b7e8024f98f19Jim Miller            if (lastWidget >= 0) {
952bdca3c0a21ba15e8bb6d7ef0ca1b7e8024f98f19Jim Miller                position = isCameraPage(lastWidget) ? lastWidget : lastWidget + 1;
953bdca3c0a21ba15e8bb6d7ef0ca1b7e8024f98f19Jim Miller            }
954bdca3c0a21ba15e8bb6d7ef0ca1b7e8024f98f19Jim Miller            mAppWidgetContainer.addWidget(mTransportControl, position);
955bdca3c0a21ba15e8bb6d7ef0ca1b7e8024f98f19Jim Miller            mTransportControl.setVisibility(View.VISIBLE);
956bdca3c0a21ba15e8bb6d7ef0ca1b7e8024f98f19Jim Miller        }
957bdca3c0a21ba15e8bb6d7ef0ca1b7e8024f98f19Jim Miller    }
958bdca3c0a21ba15e8bb6d7ef0ca1b7e8024f98f19Jim Miller
9597221d3ae08cc2be922d26e5d491038512cb6c74dJim Miller    private void initializeTransportControl() {
9604e81bd4bcf60a934d4cd589dab6e2bddb88d7356Jim Miller        mTransportControl =
9614e81bd4bcf60a934d4cd589dab6e2bddb88d7356Jim Miller            (KeyguardTransportControlView) findViewById(R.id.keyguard_transport_control);
962223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        mTransportControl.setVisibility(View.GONE);
9634e81bd4bcf60a934d4cd589dab6e2bddb88d7356Jim Miller
9644e81bd4bcf60a934d4cd589dab6e2bddb88d7356Jim Miller        // This code manages showing/hiding the transport control. We keep it around and only
9654e81bd4bcf60a934d4cd589dab6e2bddb88d7356Jim Miller        // add it to the hierarchy if it needs to be present.
9664e81bd4bcf60a934d4cd589dab6e2bddb88d7356Jim Miller        if (mTransportControl != null) {
9674e81bd4bcf60a934d4cd589dab6e2bddb88d7356Jim Miller            mTransportControl.setKeyguardCallback(new TransportCallback() {
9684e81bd4bcf60a934d4cd589dab6e2bddb88d7356Jim Miller                @Override
969223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller                public void onListenerDetached() {
970bdca3c0a21ba15e8bb6d7ef0ca1b7e8024f98f19Jim Miller                    removeTransportFromWidgetPager();
971bdca3c0a21ba15e8bb6d7ef0ca1b7e8024f98f19Jim Miller                    mTransportControl.post(mSwitchPageRunnable);
9724e81bd4bcf60a934d4cd589dab6e2bddb88d7356Jim Miller                }
9734e81bd4bcf60a934d4cd589dab6e2bddb88d7356Jim Miller
9744e81bd4bcf60a934d4cd589dab6e2bddb88d7356Jim Miller                @Override
975223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller                public void onListenerAttached() {
976bdca3c0a21ba15e8bb6d7ef0ca1b7e8024f98f19Jim Miller                    // Transport will be added when playstate changes...
977bdca3c0a21ba15e8bb6d7ef0ca1b7e8024f98f19Jim Miller                    mTransportControl.post(mSwitchPageRunnable);
9784e81bd4bcf60a934d4cd589dab6e2bddb88d7356Jim Miller                }
979223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller
980223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller                @Override
981223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller                public void onPlayStateChanged() {
982223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller                    mTransportControl.post(mSwitchPageRunnable);
983223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller                }
9844e81bd4bcf60a934d4cd589dab6e2bddb88d7356Jim Miller            });
9854e81bd4bcf60a934d4cd589dab6e2bddb88d7356Jim Miller        }
9864e81bd4bcf60a934d4cd589dab6e2bddb88d7356Jim Miller    }
9874e81bd4bcf60a934d4cd589dab6e2bddb88d7356Jim Miller
98867a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka    private int getAddPageIndex() {
98967a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        View addWidget = mAppWidgetContainer.findViewById(R.id.keyguard_add_widget);
99067a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        int addPageIndex = mAppWidgetContainer.indexOfChild(addWidget);
99167a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        // This shouldn't happen, but just to be safe!
99267a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        if (addPageIndex < 0) {
99367a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka            addPageIndex = 0;
99467a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        }
99567a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        return addPageIndex;
99667a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka    }
99767a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka
99867a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka    private void addDefaultStatusWidget(int index) {
99967a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        LayoutInflater inflater = LayoutInflater.from(mContext);
100067a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        View statusWidget = inflater.inflate(R.layout.keyguard_status_view, null, true);
100167a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        mAppWidgetContainer.addWidget(statusWidget, index);
100267a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka    }
100367a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka
10041254f2f42f7173ef51d0034975ab5cb7d44f8209Michael Jurka    private void addWidgetsFromSettings() {
1005f73fbf79a1db4bc5ccc829c8a84f3431ab986cbcJim Miller        DevicePolicyManager dpm =
1006f73fbf79a1db4bc5ccc829c8a84f3431ab986cbcJim Miller                (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
100748b9b0d068844af9eb37c215484831c4d6b831b0Jim Miller        if (dpm != null) {
100848b9b0d068844af9eb37c215484831c4d6b831b0Jim Miller            final int currentUser = mLockPatternUtils.getCurrentUser();
100948b9b0d068844af9eb37c215484831c4d6b831b0Jim Miller            final int disabledFeatures = dpm.getKeyguardDisabledFeatures(null, currentUser);
101048b9b0d068844af9eb37c215484831c4d6b831b0Jim Miller            if ((disabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_WIDGETS_ALL) != 0) {
101148b9b0d068844af9eb37c215484831c4d6b831b0Jim Miller                Log.v(TAG, "Keyguard widgets disabled because of device policy admin");
101248b9b0d068844af9eb37c215484831c4d6b831b0Jim Miller                return;
101348b9b0d068844af9eb37c215484831c4d6b831b0Jim Miller            }
1014b8ec470617590fa2025db869e8e80dcce8eaec23Jim Miller        }
1015f229e4d3eb8f910c181f96416c6798f6f305a395Jim Miller
101667a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        int addPageIndex = getAddPageIndex();
101720c41d5382b70fa5a24e9ef68f19ce0aedea5234Michael Jurka
101820c41d5382b70fa5a24e9ef68f19ce0aedea5234Michael Jurka        // Add user-selected widget
1019aa2859ae61098509495b7938e32a6d59d37561beMichael Jurka        final int[] widgets = mLockPatternUtils.getAppWidgets();
102067a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka
1021aa2859ae61098509495b7938e32a6d59d37561beMichael Jurka        if (widgets == null) {
1022aa2859ae61098509495b7938e32a6d59d37561beMichael Jurka            Log.d(TAG, "Problem reading widgets");
1023aa2859ae61098509495b7938e32a6d59d37561beMichael Jurka        } else {
1024aa2859ae61098509495b7938e32a6d59d37561beMichael Jurka            for (int i = widgets.length -1; i >= 0; i--) {
10251254f2f42f7173ef51d0034975ab5cb7d44f8209Michael Jurka                if (widgets[i] == LockPatternUtils.ID_DEFAULT_STATUS_WIDGET) {
102667a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka                    addDefaultStatusWidget(addPageIndex + 1);
10271254f2f42f7173ef51d0034975ab5cb7d44f8209Michael Jurka                } else {
1028aa2859ae61098509495b7938e32a6d59d37561beMichael Jurka                    // We add the widgets from left to right, starting after the first page after
1029aa2859ae61098509495b7938e32a6d59d37561beMichael Jurka                    // the add page. We count down, since the order will be persisted from right
1030aa2859ae61098509495b7938e32a6d59d37561beMichael Jurka                    // to left, starting after camera.
1031aa2859ae61098509495b7938e32a6d59d37561beMichael Jurka                    addWidget(widgets[i], addPageIndex + 1);
1032aa2859ae61098509495b7938e32a6d59d37561beMichael Jurka                }
1033dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            }
1034dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
103567a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        checkAppWidgetConsistency();
103667a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka    }
103767a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka
103867a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka    public void checkAppWidgetConsistency() {
103967a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        final int childCount = mAppWidgetContainer.getChildCount();
104067a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        boolean widgetPageExists = false;
104167a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        for (int i = 0; i < childCount; i++) {
104267a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka            if (isWidgetPage(i)) {
104367a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka                widgetPageExists = true;
104467a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka                break;
104567a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka            }
104667a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        }
104767a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        if (!widgetPageExists) {
104867a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka            final int addPageIndex = getAddPageIndex();
104967a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka
105067a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka            Resources res = getContext().getResources();
105167a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka            ComponentName defaultAppWidget = new ComponentName(
105267a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka                    res.getString(R.string.widget_default_package_name),
105367a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka                    res.getString(R.string.widget_default_class_name));
105467a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka
105567a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka            // Note: we don't support configuring the widget
105667a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka            int appWidgetId = mAppWidgetHost.allocateAppWidgetId();
105767a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka            boolean bindSuccessful = false;
105867a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka            try {
105967a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka                mAppWidgetManager.bindAppWidgetId(appWidgetId, defaultAppWidget);
106067a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka                bindSuccessful = true;
106167a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka            } catch (IllegalArgumentException e) {
106267a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka                Log.e(TAG, "Error when trying to bind default AppWidget: " + e);
106367a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka            }
106467a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka            // Use the built-in status/clock view if we can't inflate the default widget
106567a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka            if (!(bindSuccessful && addWidget(appWidgetId, addPageIndex + 1))) {
106667a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka                addDefaultStatusWidget(addPageIndex + 1);
106767a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka            }
106867a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka            mAppWidgetContainer.onAddView(
106967a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka                    mAppWidgetContainer.getChildAt(addPageIndex + 1), addPageIndex + 1);
107067a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        }
10710207c0992cb05d0acc60540748c8ae6985917abbAdam Cohen    }
10720207c0992cb05d0acc60540748c8ae6985917abbAdam Cohen
1073223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller    Runnable mSwitchPageRunnable = new Runnable() {
1074223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        @Override
1075223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        public void run() {
1076223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller           showAppropriateWidgetPage();
1077223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        }
1078223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller    };
1079223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller
1080223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller    static class SavedState extends BaseSavedState {
1081223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        int transportState;
1082223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller
1083223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        SavedState(Parcelable superState) {
1084223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller            super(superState);
1085223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        }
1086223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller
1087223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        private SavedState(Parcel in) {
1088223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller            super(in);
1089223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller            this.transportState = in.readInt();
1090223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        }
1091223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller
1092223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        @Override
1093223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        public void writeToParcel(Parcel out, int flags) {
1094223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller            super.writeToParcel(out, flags);
1095223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller            out.writeInt(this.transportState);
1096223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        }
1097223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller
1098223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        public static final Parcelable.Creator<SavedState> CREATOR
1099223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller                = new Parcelable.Creator<SavedState>() {
1100223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller            public SavedState createFromParcel(Parcel in) {
1101223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller                return new SavedState(in);
1102223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller            }
1103223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller
1104223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller            public SavedState[] newArray(int size) {
1105223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller                return new SavedState[size];
1106223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller            }
1107223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        };
1108223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller    }
1109223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller
1110223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller    @Override
1111223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller    public Parcelable onSaveInstanceState() {
11125f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock        if (DEBUG) Log.d(TAG, "onSaveInstanceState");
11135f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock        saveStickyWidgetIndex();
1114223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        Parcelable superState = super.onSaveInstanceState();
1115223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        SavedState ss = new SavedState(superState);
1116e0566da2dab8c3b9ddca43131f21ef58b79049c8Jim Miller        ss.transportState = mViewStateManager.getTransportState();
1117223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        return ss;
1118223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller    }
1119223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller
1120223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller    @Override
1121223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller    public void onRestoreInstanceState(Parcelable state) {
11225f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock        if (DEBUG) Log.d(TAG, "onRestoreInstanceState");
1123223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        if (!(state instanceof SavedState)) {
1124223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller            super.onRestoreInstanceState(state);
1125223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller            return;
1126223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        }
1127223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        SavedState ss = (SavedState) state;
1128223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        super.onRestoreInstanceState(ss.getSuperState());
1129e0566da2dab8c3b9ddca43131f21ef58b79049c8Jim Miller        mViewStateManager.setTransportState(ss.transportState);
1130223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        post(mSwitchPageRunnable);
1131223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller    }
1132223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller
11335f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock    @Override
11345f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock    public void onWindowFocusChanged(boolean hasWindowFocus) {
11355f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock        super.onWindowFocusChanged(hasWindowFocus);
11365f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock        if (DEBUG) Log.d(TAG, "Window is " + (hasWindowFocus ? "focused" : "unfocused"));
11375f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock        if (!hasWindowFocus) {
11385f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock            saveStickyWidgetIndex();
11395f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock        }
11405f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock    }
11415f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock
11420207c0992cb05d0acc60540748c8ae6985917abbAdam Cohen    private void showAppropriateWidgetPage() {
1143e0566da2dab8c3b9ddca43131f21ef58b79049c8Jim Miller        int state = mViewStateManager.getTransportState();
1144e0566da2dab8c3b9ddca43131f21ef58b79049c8Jim Miller        boolean isMusicPlaying = mTransportControl.isMusicPlaying()
1145e0566da2dab8c3b9ddca43131f21ef58b79049c8Jim Miller                || state == KeyguardViewStateManager.TRANSPORT_VISIBLE;
11465f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock        if (isMusicPlaying) {
1147e0566da2dab8c3b9ddca43131f21ef58b79049c8Jim Miller            mViewStateManager.setTransportState(KeyguardViewStateManager.TRANSPORT_VISIBLE);
1148bdca3c0a21ba15e8bb6d7ef0ca1b7e8024f98f19Jim Miller            addTransportToWidgetPager();
1149e0566da2dab8c3b9ddca43131f21ef58b79049c8Jim Miller        } else if (state == KeyguardViewStateManager.TRANSPORT_VISIBLE) {
1150e0566da2dab8c3b9ddca43131f21ef58b79049c8Jim Miller            mViewStateManager.setTransportState(KeyguardViewStateManager.TRANSPORT_INVISIBLE);
11510207c0992cb05d0acc60540748c8ae6985917abbAdam Cohen        }
11525f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock        int pageToShow = getAppropriateWidgetPage(isMusicPlaying);
1153223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        mAppWidgetContainer.setCurrentPage(pageToShow);
1154dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
1155dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
1156dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock    private CameraWidgetFrame findCameraPage() {
1157dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock        for (int i = mAppWidgetContainer.getChildCount() - 1; i >= 0; i--) {
1158dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock            if (isCameraPage(i)) {
1159dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock                return (CameraWidgetFrame) mAppWidgetContainer.getChildAt(i);
1160dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock            }
1161dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock        }
1162dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock        return null;
1163dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock    }
1164dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock
116567a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka    private boolean isWidgetPage(int pageIndex) {
116667a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        View v = mAppWidgetContainer.getChildAt(pageIndex);
116767a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        if (v != null && v instanceof KeyguardWidgetFrame) {
116867a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka            KeyguardWidgetFrame kwf = (KeyguardWidgetFrame) v;
116967a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka            return kwf.getContentAppWidgetId() != AppWidgetManager.INVALID_APPWIDGET_ID;
117067a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        }
117167a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        return false;
117267a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka    }
117367a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka
11745f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock    private boolean isCameraPage(int pageIndex) {
11755f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock        View v = mAppWidgetContainer.getChildAt(pageIndex);
11765f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock        return v != null && v instanceof CameraWidgetFrame;
11775f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock    }
11785f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock
11795f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock    private boolean isAddPage(int pageIndex) {
1180358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock        View v = mAppWidgetContainer.getChildAt(pageIndex);
11815f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock        return v != null && v.getId() == R.id.keyguard_add_widget;
1182358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock    }
1183358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock
11845f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock    private int getAppropriateWidgetPage(boolean isMusicPlaying) {
1185358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock        // assumes at least one widget (besides camera + add)
1186358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock
1187358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock        // if music playing, show transport
11885f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock        if (isMusicPlaying) {
1189358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock            if (DEBUG) Log.d(TAG, "Music playing, show transport");
1190bdca3c0a21ba15e8bb6d7ef0ca1b7e8024f98f19Jim Miller            return mAppWidgetContainer.getWidgetPageIndex(mTransportControl);
1191358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock        }
1192358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock
11935f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock        // if we have a valid sticky widget, show it
11945f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock        int stickyWidgetIndex = mLockPatternUtils.getStickyAppWidgetIndex();
1195358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock        if (stickyWidgetIndex > -1
1196358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock                && stickyWidgetIndex < mAppWidgetContainer.getChildCount()
11975f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock                && !isAddPage(stickyWidgetIndex)
11985f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock                && !isCameraPage(stickyWidgetIndex)) {
11995f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock            if (DEBUG) Log.d(TAG, "Valid sticky widget found, show page " + stickyWidgetIndex);
1200358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock            return stickyWidgetIndex;
1201358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock        }
1202358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock
12035f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock        // else show the right-most widget (except for camera)
1204358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock        int rightMost = mAppWidgetContainer.getChildCount() - 1;
12055f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock        if (isCameraPage(rightMost)) {
1206358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock            rightMost--;
1207358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock        }
12085f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock        if (DEBUG) Log.d(TAG, "Show right-most page " + rightMost);
1209358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock        return rightMost;
1210358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock    }
1211358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock
12125f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock    private void saveStickyWidgetIndex() {
12135f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock        int stickyWidgetIndex = mAppWidgetContainer.getCurrentPage();
12145f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock        if (isAddPage(stickyWidgetIndex)) {
12155f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock            stickyWidgetIndex++;
12165f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock        }
12175f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock        if (isCameraPage(stickyWidgetIndex)) {
12185f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock            stickyWidgetIndex--;
12195f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock        }
12205f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock        if (stickyWidgetIndex < 0 || stickyWidgetIndex >= mAppWidgetContainer.getChildCount()) {
12215f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock            stickyWidgetIndex = -1;
12225f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock        }
12235f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock        if (DEBUG) Log.d(TAG, "saveStickyWidgetIndex: " + stickyWidgetIndex);
12245f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock        mLockPatternUtils.setStickyAppWidgetIndex(stickyWidgetIndex);
12255f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock    }
12265f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock
122719a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller    private void enableUserSelectorIfNecessary() {
122826e6c2e44235428717d7152b9e6398649452f1d2Jim Miller        if (!UserManager.supportsMultipleUsers()) {
122926e6c2e44235428717d7152b9e6398649452f1d2Jim Miller            return; // device doesn't support multi-user mode
123026e6c2e44235428717d7152b9e6398649452f1d2Jim Miller        }
123126e6c2e44235428717d7152b9e6398649452f1d2Jim Miller
12325f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock        // if there are multiple users, we need to enable to multi-user switcher
123366b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen        UserManager mUm = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
1234920ace0bbc2d4133dbec991d2636c99a57d6245eAmith Yamasani        List<UserInfo> users = mUm.getUsers(true);
123566b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen
123666b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen        if (users.size() > 1) {
123728c5ee9ea9b1dd6253a4ba782a5711263524bd41Chris Wren            KeyguardMultiUserSelectorView multiUser =
123828c5ee9ea9b1dd6253a4ba782a5711263524bd41Chris Wren                    (KeyguardMultiUserSelectorView) findViewById(R.id.keyguard_user_selector);
123919a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller            multiUser.setVisibility(View.VISIBLE);
124028c5ee9ea9b1dd6253a4ba782a5711263524bd41Chris Wren            multiUser.addUsers(mUm.getUsers(true));
124124b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen            UserSwitcherCallback callback = new UserSwitcherCallback() {
124224b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen                @Override
124324b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen                public void hideSecurityView(int duration) {
124424b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen                    mSecurityViewContainer.animate().alpha(0).setDuration(duration);
124524b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen                }
124624b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen
124724b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen                @Override
124824b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen                public void showSecurityView() {
124924b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen                    mSecurityViewContainer.setAlpha(1.0f);
125024b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen                }
12510a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen
12520a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen                @Override
12530a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen                public void showUnlockHint() {
12540ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller                    if (mKeyguardSelectorView != null) {
12556fb841fa219eaae3e87f2fdc05e105d7a1813c42Adam Cohen                        mKeyguardSelectorView.showUsabilityHint();
12560ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller                    }
12570a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen                }
12580a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen
125919a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                @Override
126019a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                public void userActivity() {
126119a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                    if (mViewMediatorCallback != null) {
126219a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                        mViewMediatorCallback.userActivity();
126319a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                    }
126419a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                }
126524b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen            };
126624b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen            multiUser.setCallback(callback);
126766b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen        }
126866b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen    }
126966b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen
1270dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    @Override
1271dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    public void cleanUp() {
1272dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
1273dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
1274dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
127595b005c196de2f99513da28fe9108b2dec200140Jim Miller    /**
127695b005c196de2f99513da28fe9108b2dec200140Jim Miller     * In general, we enable unlocking the insecure keyguard with the menu key. However, there are
127795b005c196de2f99513da28fe9108b2dec200140Jim Miller     * some cases where we wish to disable it, notably when the menu button placement or technology
127895b005c196de2f99513da28fe9108b2dec200140Jim Miller     * is prone to false positives.
127995b005c196de2f99513da28fe9108b2dec200140Jim Miller     *
128095b005c196de2f99513da28fe9108b2dec200140Jim Miller     * @return true if the menu key should be enabled
128195b005c196de2f99513da28fe9108b2dec200140Jim Miller     */
128295b005c196de2f99513da28fe9108b2dec200140Jim Miller    private static final String ENABLE_MENU_KEY_FILE = "/data/local/enable_menu_key";
128395b005c196de2f99513da28fe9108b2dec200140Jim Miller    private boolean shouldEnableMenuKey() {
128495b005c196de2f99513da28fe9108b2dec200140Jim Miller        final Resources res = getResources();
1285258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        final boolean configDisabled = res.getBoolean(
1286258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                com.android.internal.R.bool.config_disableMenuKeyInLockScreen);
128795b005c196de2f99513da28fe9108b2dec200140Jim Miller        final boolean isTestHarness = ActivityManager.isRunningInTestHarness();
128895b005c196de2f99513da28fe9108b2dec200140Jim Miller        final boolean fileOverride = (new File(ENABLE_MENU_KEY_FILE)).exists();
128995b005c196de2f99513da28fe9108b2dec200140Jim Miller        return !configDisabled || isTestHarness || fileOverride;
129095b005c196de2f99513da28fe9108b2dec200140Jim Miller    }
129195b005c196de2f99513da28fe9108b2dec200140Jim Miller
129275931e05470992d51d135d09031902fd1b3fdbc7Jim Miller
129395b005c196de2f99513da28fe9108b2dec200140Jim Miller
12946bcd73203ada36b446b05fa33f9834ac989c0621Jim Miller    public void goToUserSwitcher() {
12956bcd73203ada36b446b05fa33f9834ac989c0621Jim Miller        mAppWidgetContainer.setCurrentPage(getWidgetPosition(R.id.keyguard_multi_user_selector));
12966bcd73203ada36b446b05fa33f9834ac989c0621Jim Miller    }
12976bcd73203ada36b446b05fa33f9834ac989c0621Jim Miller
129875931e05470992d51d135d09031902fd1b3fdbc7Jim Miller    public boolean handleMenuKey() {
129975931e05470992d51d135d09031902fd1b3fdbc7Jim Miller        // The following enables the MENU key to work for testing automation
130075931e05470992d51d135d09031902fd1b3fdbc7Jim Miller        if (shouldEnableMenuKey()) {
130175931e05470992d51d135d09031902fd1b3fdbc7Jim Miller            showNextSecurityScreenOrFinish(false);
130275931e05470992d51d135d09031902fd1b3fdbc7Jim Miller            return true;
130375931e05470992d51d135d09031902fd1b3fdbc7Jim Miller        }
130475931e05470992d51d135d09031902fd1b3fdbc7Jim Miller        return false;
130575931e05470992d51d135d09031902fd1b3fdbc7Jim Miller    }
130675931e05470992d51d135d09031902fd1b3fdbc7Jim Miller
13070a34d9edf02954d83c2861a8c6836865f8fa00fbJim Miller    public boolean handleBackKey() {
13080a34d9edf02954d83c2861a8c6836865f8fa00fbJim Miller        if (mCurrentSecuritySelection != SecurityMode.None) {
13090a34d9edf02954d83c2861a8c6836865f8fa00fbJim Miller            mCallback.dismiss(false);
13100a34d9edf02954d83c2861a8c6836865f8fa00fbJim Miller            return true;
13110a34d9edf02954d83c2861a8c6836865f8fa00fbJim Miller        }
13120a34d9edf02954d83c2861a8c6836865f8fa00fbJim Miller        return false;
13130a34d9edf02954d83c2861a8c6836865f8fa00fbJim Miller    }
13140a34d9edf02954d83c2861a8c6836865f8fa00fbJim Miller
1315ad09bccfe4cc0a3075e97c0911a02b329023a34aCraig Mautner    /**
1316ad09bccfe4cc0a3075e97c0911a02b329023a34aCraig Mautner     *  Dismisses the keyguard by going to the next screen or making it gone.
1317ad09bccfe4cc0a3075e97c0911a02b329023a34aCraig Mautner     */
1318ad09bccfe4cc0a3075e97c0911a02b329023a34aCraig Mautner    public void dismiss() {
1319ad09bccfe4cc0a3075e97c0911a02b329023a34aCraig Mautner        showNextSecurityScreenOrFinish(false);
1320ad09bccfe4cc0a3075e97c0911a02b329023a34aCraig Mautner    }
1321dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller}
1322