1dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller/*
2dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller * Copyright (C) 2012 The Android Open Source Project
3dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller *
4dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller * Licensed under the Apache License, Version 2.0 (the "License");
5dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller * you may not use this file except in compliance with the License.
6dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller * You may obtain a copy of the License at
7dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller *
8dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller *      http://www.apache.org/licenses/LICENSE-2.0
9dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller *
10dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller * Unless required by applicable law or agreed to in writing, software
11dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller * distributed under the License is distributed on an "AS IS" BASIS,
12dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller * See the License for the specific language governing permissions and
14dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller * limitations under the License.
15dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller */
16dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
175ecd81154fa039961f65bb4e36d18ac555b0d1d6Jim Millerpackage com.android.keyguard;
185ecd81154fa039961f65bb4e36d18ac555b0d1d6Jim Miller
194d20ed3f26d1ec2c47519484bcc968098581c3d6Jim Millerimport com.android.internal.widget.LockPatternUtils;
204d20ed3f26d1ec2c47519484bcc968098581c3d6Jim Millerimport com.android.keyguard.KeyguardSecurityModel.SecurityMode;
214d20ed3f26d1ec2c47519484bcc968098581c3d6Jim Millerimport com.android.keyguard.KeyguardUpdateMonitor.DisplayClientState;
224d20ed3f26d1ec2c47519484bcc968098581c3d6Jim Miller
2395b005c196de2f99513da28fe9108b2dec200140Jim Millerimport android.app.ActivityManager;
24dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.app.ActivityOptions;
25258341c377b6aa9f1bd29a9b507a97967e432dfeJim Millerimport android.app.admin.DevicePolicyManager;
26dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.appwidget.AppWidgetHost;
27dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.appwidget.AppWidgetHostView;
28dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.appwidget.AppWidgetManager;
29dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.appwidget.AppWidgetProviderInfo;
30fc753c0cf676000b1c2d3cb2728af85a9b49f795Michael Jurkaimport android.content.ComponentName;
31dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.content.Context;
32dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.content.Intent;
33dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.content.IntentSender;
34a75a883fe9ea1790803148f0a561473073e3f264Jim Millerimport android.content.pm.PackageManager.NameNotFoundException;
3595b005c196de2f99513da28fe9108b2dec200140Jim Millerimport android.content.res.Resources;
365737534abab477cf32b4dd0aa7a72f70ede0502cJim Millerimport android.graphics.Rect;
378f09fd2e3123c7713d50886dc3745d330a1879c5Jim Millerimport android.media.RemoteControlClient;
385e612cf07872dc0989a4b9f09e2a38a2ee12186dJim Millerimport android.os.Bundle;
39f229e4d3eb8f910c181f96416c6798f6f305a395Jim Millerimport android.os.Looper;
40223ce5c7326f6d13a17ccf2624605bb62864a27aJim Millerimport android.os.Parcel;
41223ce5c7326f6d13a17ccf2624605bb62864a27aJim Millerimport android.os.Parcelable;
424eeb4f664ac6b5901a8e874dcf70c0382295f792Jim Millerimport android.os.UserHandle;
4366b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohenimport android.os.UserManager;
44fff5614caecb0d2944b1bc206aaab0d3acb17670Michael Jurkaimport android.provider.Settings;
45dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.util.AttributeSet;
46dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.util.Log;
4762b25a5bf0750483f36ac79c88177ee2ab630f8eAndres Moralesimport android.util.Slog;
4866b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohenimport android.view.LayoutInflater;
495737534abab477cf32b4dd0aa7a72f70ede0502cJim Millerimport android.view.MotionEvent;
50dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.view.View;
51dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.widget.RemoteViews.OnClickHandler;
52dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
537fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haaseimport java.lang.ref.WeakReference;
54dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
55dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerpublic class KeyguardHostView extends KeyguardViewBase {
5651117262c8fadb6d227d137e83ad66996b013141Jim Miller    private static final String TAG = "KeyguardHostView";
575cf17879a31b7b78c09ec50b727f921840dcf783Jorim Jaggi    public static boolean DEBUG = KeyguardConstants.DEBUG;
583eb4971b679464e206cb666de1cf0e5a538c8d7dJim Miller    public static boolean DEBUGXPORT = true; // debug music transport control
59eec83dcadd1dca722d3070fe5eae7d4e0561aa2bSandeep Siddhartha
604894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller    // Transport control states.
618f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller    static final int TRANSPORT_GONE = 0;
628f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller    static final int TRANSPORT_INVISIBLE = 1;
638f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller    static final int TRANSPORT_VISIBLE = 2;
648f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller
658f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller    private int mTransportState = TRANSPORT_GONE;
66ff2aa0bc8919c247bfc8e81d3f168e5064f52ffbJim Miller
67192d6d4ee271c0782a3bf5d8c64e42eb22d1a6faMichael Jurka    // Found in KeyguardAppWidgetPickActivity.java
68dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    static final int APPWIDGET_HOST_ID = 0x4B455947;
69eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka    private final int MAX_WIDGETS = 5;
70eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka
71dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    private AppWidgetHost mAppWidgetHost;
7267a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka    private AppWidgetManager mAppWidgetManager;
73f2dfc351dec58ad3c16f8496208b4e6e9c667efeJim Miller    private KeyguardWidgetPager mAppWidgetContainer;
74939f04f971dfc5fde717a313ecd61de4e60d4aa8RoboErik    // TODO remove transport control references, these don't exist anymore
754e81bd4bcf60a934d4cd589dab6e2bddb88d7356Jim Miller    private KeyguardTransportControlView mTransportControl;
7676017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka    private int mAppWidgetToShow;
77dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
78dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    protected int mFailedAttempts;
79dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
80d6523da1ad7bae805a3dbea8d7b398d86cd3c181Jim Miller    private KeyguardViewStateManager mViewStateManager;
81dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
825737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller    private Rect mTempRect = new Rect();
8351117262c8fadb6d227d137e83ad66996b013141Jim Miller    private int mDisabledFeatures;
8451117262c8fadb6d227d137e83ad66996b013141Jim Miller    private boolean mCameraDisabled;
8551117262c8fadb6d227d137e83ad66996b013141Jim Miller    private boolean mSafeModeEnabled;
86fff5614caecb0d2944b1bc206aaab0d3acb17670Michael Jurka    private boolean mUserSetupCompleted;
87f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren
88a75a883fe9ea1790803148f0a561473073e3f264Jim Miller    // User for whom this host view was created.  Final because we should never change the
89a75a883fe9ea1790803148f0a561473073e3f264Jim Miller    // id without reconstructing an instance of KeyguardHostView. See note below...
90a75a883fe9ea1790803148f0a561473073e3f264Jim Miller    private final int mUserId;
91fff5614caecb0d2944b1bc206aaab0d3acb17670Michael Jurka
92f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren    private KeyguardMultiUserSelectorView mKeyguardMultiUserSelectorView;
93f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren
948f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller    protected int mClientGeneration;
955737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller
96e51cf7aeb6157017801a802b4c1d74cbf51b7a01Jim Miller    protected boolean mShowSecurityWhenReturn;
97e51cf7aeb6157017801a802b4c1d74cbf51b7a01Jim Miller
98256ae67b9a629178b458dfc01102c9c0b9963d03John Spurlock    private final Rect mInsets = new Rect();
99256ae67b9a629178b458dfc01102c9c0b9963d03John Spurlock
1007fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haase    private MyOnClickHandler mOnClickHandler = new MyOnClickHandler(this);
1017fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haase
1029ccf123ee0596ec9cab724f252a4932961c083afJim Miller    private Runnable mPostBootCompletedRunnable;
1039ccf123ee0596ec9cab724f252a4932961c083afJim Miller
10424b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen    /*package*/ interface UserSwitcherCallback {
10524b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen        void hideSecurityView(int duration);
10624b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen        void showSecurityView();
1070a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen        void showUnlockHint();
10819a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        void userActivity();
10924b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen    }
11024b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen
111f8895248e2ac4dbb46622f3e04c7256f03175b4fAdam Powell    interface TransportControlCallback {
112f8895248e2ac4dbb46622f3e04c7256f03175b4fAdam Powell        void userActivity();
113f8895248e2ac4dbb46622f3e04c7256f03175b4fAdam Powell    }
114f8895248e2ac4dbb46622f3e04c7256f03175b4fAdam Powell
115380ecb81db52a9d0197ca969951d07b91c20d2b9Jorim Jaggi    public interface OnDismissAction {
116e5afd24f4630d30665d4ed05ec8229ff73008cdaAdrian Roos        /**
117e5afd24f4630d30665d4ed05ec8229ff73008cdaAdrian Roos         * @return true if the dismiss should be deferred
118e5afd24f4630d30665d4ed05ec8229ff73008cdaAdrian Roos         */
11914adfe425e67c9ec12b0841a62c5c03ce00838eaJohn Spurlock        boolean onDismiss();
12014adfe425e67c9ec12b0841a62c5c03ce00838eaJohn Spurlock    }
12114adfe425e67c9ec12b0841a62c5c03ce00838eaJohn Spurlock
122dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    public KeyguardHostView(Context context) {
123dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        this(context, null);
124dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
125dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
126dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    public KeyguardHostView(Context context, AttributeSet attrs) {
127dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        super(context, attrs);
1284894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller
1294894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller        if (DEBUG) Log.e(TAG, "KeyguardHostView()");
1304894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller
131000464ac012471d301c6e48a8228291519915e17Jim Miller        mLockPatternUtils = new LockPatternUtils(context);
132a75a883fe9ea1790803148f0a561473073e3f264Jim Miller
133a75a883fe9ea1790803148f0a561473073e3f264Jim Miller        // Note: This depends on KeyguardHostView getting reconstructed every time the
134a75a883fe9ea1790803148f0a561473073e3f264Jim Miller        // user switches, since mUserId will be used for the entire session.
135a75a883fe9ea1790803148f0a561473073e3f264Jim Miller        // Once created, keyguard should *never* re-use this instance with another user.
136a75a883fe9ea1790803148f0a561473073e3f264Jim Miller        // In other words, mUserId should never change - hence it's marked final.
137c566b43d02596cba437e9a2723e9f989297cca72Amith Yamasani        mUserId = mLockPatternUtils.getCurrentUser();
138a75a883fe9ea1790803148f0a561473073e3f264Jim Miller
139105beddcb98efc24f37259881d9b4c267aa0d198Jim Miller        DevicePolicyManager dpm =
140105beddcb98efc24f37259881d9b4c267aa0d198Jim Miller                (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
141105beddcb98efc24f37259881d9b4c267aa0d198Jim Miller        if (dpm != null) {
142105beddcb98efc24f37259881d9b4c267aa0d198Jim Miller            mDisabledFeatures = getDisabledFeatures(dpm);
143105beddcb98efc24f37259881d9b4c267aa0d198Jim Miller            mCameraDisabled = dpm.getCameraDisabled(null);
144105beddcb98efc24f37259881d9b4c267aa0d198Jim Miller        }
145105beddcb98efc24f37259881d9b4c267aa0d198Jim Miller
146105beddcb98efc24f37259881d9b4c267aa0d198Jim Miller        mSafeModeEnabled = LockPatternUtils.isSafeModeEnabled();
147105beddcb98efc24f37259881d9b4c267aa0d198Jim Miller
148105beddcb98efc24f37259881d9b4c267aa0d198Jim Miller        // These need to be created with the user context...
149a75a883fe9ea1790803148f0a561473073e3f264Jim Miller        Context userContext = null;
150a75a883fe9ea1790803148f0a561473073e3f264Jim Miller        try {
151a75a883fe9ea1790803148f0a561473073e3f264Jim Miller            final String packageName = "system";
152a75a883fe9ea1790803148f0a561473073e3f264Jim Miller            userContext = mContext.createPackageContextAsUser(packageName, 0,
153a75a883fe9ea1790803148f0a561473073e3f264Jim Miller                    new UserHandle(mUserId));
154a75a883fe9ea1790803148f0a561473073e3f264Jim Miller
155a75a883fe9ea1790803148f0a561473073e3f264Jim Miller        } catch (NameNotFoundException e) {
156a75a883fe9ea1790803148f0a561473073e3f264Jim Miller            e.printStackTrace();
157a75a883fe9ea1790803148f0a561473073e3f264Jim Miller            // This should never happen, but it's better to have no widgets than to crash.
158a75a883fe9ea1790803148f0a561473073e3f264Jim Miller            userContext = context;
159a75a883fe9ea1790803148f0a561473073e3f264Jim Miller        }
160a75a883fe9ea1790803148f0a561473073e3f264Jim Miller
161a75a883fe9ea1790803148f0a561473073e3f264Jim Miller        mAppWidgetHost = new AppWidgetHost(userContext, APPWIDGET_HOST_ID, mOnClickHandler,
162a75a883fe9ea1790803148f0a561473073e3f264Jim Miller                Looper.myLooper());
163a75a883fe9ea1790803148f0a561473073e3f264Jim Miller
164105beddcb98efc24f37259881d9b4c267aa0d198Jim Miller        mAppWidgetManager = AppWidgetManager.getInstance(userContext);
165fc2dbb2f3a148ee90727c4319adf56c04002f3faMichael Jurka
166fc2dbb2f3a148ee90727c4319adf56c04002f3faMichael Jurka        mViewStateManager = new KeyguardViewStateManager(this);
167fc2dbb2f3a148ee90727c4319adf56c04002f3faMichael Jurka
168fff5614caecb0d2944b1bc206aaab0d3acb17670Michael Jurka        mUserSetupCompleted = Settings.Secure.getIntForUser(mContext.getContentResolver(),
169fff5614caecb0d2944b1bc206aaab0d3acb17670Michael Jurka                Settings.Secure.USER_SETUP_COMPLETE, 0, UserHandle.USER_CURRENT) != 0;
17051117262c8fadb6d227d137e83ad66996b013141Jim Miller
1718f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        // Ensure we have the current state *before* we call showAppropriateWidgetPage()
1728f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        getInitialTransportState();
1738f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller
17451117262c8fadb6d227d137e83ad66996b013141Jim Miller        if (mSafeModeEnabled) {
17551117262c8fadb6d227d137e83ad66996b013141Jim Miller            Log.v(TAG, "Keyguard widgets disabled by safe mode");
17651117262c8fadb6d227d137e83ad66996b013141Jim Miller        }
17751117262c8fadb6d227d137e83ad66996b013141Jim Miller        if ((mDisabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_WIDGETS_ALL) != 0) {
17851117262c8fadb6d227d137e83ad66996b013141Jim Miller            Log.v(TAG, "Keyguard widgets disabled by DPM");
17951117262c8fadb6d227d137e83ad66996b013141Jim Miller        }
18051117262c8fadb6d227d137e83ad66996b013141Jim Miller        if ((mDisabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) != 0) {
18151117262c8fadb6d227d137e83ad66996b013141Jim Miller            Log.v(TAG, "Keyguard secure camera disabled by DPM");
18251117262c8fadb6d227d137e83ad66996b013141Jim Miller        }
183dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
184dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
1858f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller    private void getInitialTransportState() {
1868f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        DisplayClientState dcs = KeyguardUpdateMonitor.getInstance(mContext)
1878f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller                .getCachedDisplayClientState();
1888f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        mTransportState = (dcs.clearing ? TRANSPORT_GONE :
1898f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            (isMusicPlaying(dcs.playbackState) ? TRANSPORT_VISIBLE : TRANSPORT_INVISIBLE));
1904894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller
19181190befe66e297d93ad0c7661d02d56f8f01f24Jim Miller        if (DEBUGXPORT) Log.v(TAG, "Initial transport state: "
192dfb57cdcfc6a1fd48395c13af98ecc2722fd5254Jim Miller                + mTransportState + ", pbstate=" + dcs.playbackState);
1938f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller    }
1948f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller
19575b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka    private void cleanupAppWidgetIds() {
1969ccf123ee0596ec9cab724f252a4932961c083afJim Miller        if (mSafeModeEnabled || widgetsDisabled()) return;
1979ccf123ee0596ec9cab724f252a4932961c083afJim Miller
1989ccf123ee0596ec9cab724f252a4932961c083afJim Miller        // Clean up appWidgetIds that are bound to lockscreen, but not actually used
1999ccf123ee0596ec9cab724f252a4932961c083afJim Miller        // This is only to clean up after another bug: we used to not call
2009ccf123ee0596ec9cab724f252a4932961c083afJim Miller        // deleteAppWidgetId when a user manually deleted a widget in keyguard. This code
2019ccf123ee0596ec9cab724f252a4932961c083afJim Miller        // shouldn't have to run more than once per user. AppWidgetProviders rely on callbacks
2029ccf123ee0596ec9cab724f252a4932961c083afJim Miller        // that are triggered by deleteAppWidgetId, which is why we're doing this
2039ccf123ee0596ec9cab724f252a4932961c083afJim Miller        int[] appWidgetIdsInKeyguardSettings = mLockPatternUtils.getAppWidgets();
2049ccf123ee0596ec9cab724f252a4932961c083afJim Miller        int[] appWidgetIdsBoundToHost = mAppWidgetHost.getAppWidgetIds();
2059ccf123ee0596ec9cab724f252a4932961c083afJim Miller        for (int i = 0; i < appWidgetIdsBoundToHost.length; i++) {
2069ccf123ee0596ec9cab724f252a4932961c083afJim Miller            int appWidgetId = appWidgetIdsBoundToHost[i];
2079ccf123ee0596ec9cab724f252a4932961c083afJim Miller            if (!contains(appWidgetIdsInKeyguardSettings, appWidgetId)) {
2089ccf123ee0596ec9cab724f252a4932961c083afJim Miller                Log.d(TAG, "Found a appWidgetId that's not being used by keyguard, deleting id "
2099ccf123ee0596ec9cab724f252a4932961c083afJim Miller                        + appWidgetId);
2109ccf123ee0596ec9cab724f252a4932961c083afJim Miller                mAppWidgetHost.deleteAppWidgetId(appWidgetId);
21175b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka            }
21275b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka        }
21375b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka    }
21475b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka
21575b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka    private static boolean contains(int[] array, int target) {
21675b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka        for (int value : array) {
21775b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka            if (value == target) {
21875b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka                return true;
21975b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka            }
22075b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka        }
22175b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka        return false;
22275b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka    }
22375b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka
224efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen    private KeyguardUpdateMonitorCallback mUpdateMonitorCallbacks =
225efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen            new KeyguardUpdateMonitorCallback() {
226efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen        @Override
227efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen        public void onBootCompleted() {
2289ccf123ee0596ec9cab724f252a4932961c083afJim Miller            if (mPostBootCompletedRunnable != null) {
2299ccf123ee0596ec9cab724f252a4932961c083afJim Miller                mPostBootCompletedRunnable.run();
2309ccf123ee0596ec9cab724f252a4932961c083afJim Miller                mPostBootCompletedRunnable = null;
231545043e59e906525af646b1ecad1797258797590Michael Jurka            }
232efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen        }
233f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren        @Override
234f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren        public void onUserSwitchComplete(int userId) {
235f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren            if (mKeyguardMultiUserSelectorView != null) {
236f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren                mKeyguardMultiUserSelectorView.finalizeActiveUserView(true);
237f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren            }
238f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren        }
239efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen    };
240efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen
2418f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller    private static final boolean isMusicPlaying(int playbackState) {
2428f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        // This should agree with the list in AudioService.isPlaystateActive()
2438f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        switch (playbackState) {
2448f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            case RemoteControlClient.PLAYSTATE_PLAYING:
2458f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            case RemoteControlClient.PLAYSTATE_BUFFERING:
2468f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            case RemoteControlClient.PLAYSTATE_FAST_FORWARDING:
2478f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            case RemoteControlClient.PLAYSTATE_REWINDING:
2488f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            case RemoteControlClient.PLAYSTATE_SKIPPING_BACKWARDS:
2498f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            case RemoteControlClient.PLAYSTATE_SKIPPING_FORWARDS:
2508f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller                return true;
2518f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            default:
2528f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller                return false;
2538f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        }
2548f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller    }
2558f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller
2562cacda5fc92a28a44a37e25b96093a9cc1346080Jim Miller    private SlidingChallengeLayout mSlidingChallengeLayout;
257257f283b0e4cc1c1fa4e7f2472d3ee4ab3b451d0John Spurlock    private MultiPaneChallengeLayout mMultiPaneChallengeLayout;
2582cacda5fc92a28a44a37e25b96093a9cc1346080Jim Miller
259dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    @Override
260d2b82f70fede8c2ec4de34d8e6462ed4ece13c56Jim Miller    public boolean onTouchEvent(MotionEvent ev) {
261d2b82f70fede8c2ec4de34d8e6462ed4ece13c56Jim Miller        boolean result = super.onTouchEvent(ev);
2625737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller        mTempRect.set(0, 0, 0, 0);
2633eb4971b679464e206cb666de1cf0e5a538c8d7dJim Miller        offsetRectIntoDescendantCoords(getSecurityContainer(), mTempRect);
2645737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller        ev.offsetLocation(mTempRect.left, mTempRect.top);
2653eb4971b679464e206cb666de1cf0e5a538c8d7dJim Miller        result = getSecurityContainer().dispatchTouchEvent(ev) || result;
2665737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller        ev.offsetLocation(-mTempRect.left, -mTempRect.top);
2675737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller        return result;
2685737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller    }
2695737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller
270ff2aa0bc8919c247bfc8e81d3f168e5064f52ffbJim Miller    private int getWidgetPosition(int id) {
271982d21b9dc73eebd4b68a63579cf8be78c788c32Jim Miller        final KeyguardWidgetPager appWidgetContainer = mAppWidgetContainer;
272982d21b9dc73eebd4b68a63579cf8be78c788c32Jim Miller        final int children = appWidgetContainer.getChildCount();
273ff2aa0bc8919c247bfc8e81d3f168e5064f52ffbJim Miller        for (int i = 0; i < children; i++) {
274982d21b9dc73eebd4b68a63579cf8be78c788c32Jim Miller            final View content = appWidgetContainer.getWidgetPageAt(i).getContent();
275982d21b9dc73eebd4b68a63579cf8be78c788c32Jim Miller            if (content != null && content.getId() == id) {
276ff2aa0bc8919c247bfc8e81d3f168e5064f52ffbJim Miller                return i;
277982d21b9dc73eebd4b68a63579cf8be78c788c32Jim Miller            } else if (content == null) {
278982d21b9dc73eebd4b68a63579cf8be78c788c32Jim Miller                // Attempt to track down bug #8886916
279982d21b9dc73eebd4b68a63579cf8be78c788c32Jim Miller                Log.w(TAG, "*** Null content at " + "i=" + i + ",id=" + id + ",N=" + children);
280ff2aa0bc8919c247bfc8e81d3f168e5064f52ffbJim Miller            }
281ff2aa0bc8919c247bfc8e81d3f168e5064f52ffbJim Miller        }
282ff2aa0bc8919c247bfc8e81d3f168e5064f52ffbJim Miller        return -1;
283ff2aa0bc8919c247bfc8e81d3f168e5064f52ffbJim Miller    }
284ff2aa0bc8919c247bfc8e81d3f168e5064f52ffbJim Miller
285dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    @Override
286dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    protected void onFinishInflate() {
2873eb4971b679464e206cb666de1cf0e5a538c8d7dJim Miller        super.onFinishInflate();
2883eb4971b679464e206cb666de1cf0e5a538c8d7dJim Miller
289d6523da1ad7bae805a3dbea8d7b398d86cd3c181Jim Miller        // Grab instances of and make any necessary changes to the main layouts. Create
290d6523da1ad7bae805a3dbea8d7b398d86cd3c181Jim Miller        // view state manager and wire up necessary listeners / callbacks.
291f3b9ec8230298e8f707c2fc44a74fb9346ec3d12Winson Chung        View deleteDropTarget = findViewById(R.id.keyguard_widget_pager_delete_target);
292f2dfc351dec58ad3c16f8496208b4e6e9c667efeJim Miller        mAppWidgetContainer = (KeyguardWidgetPager) findViewById(R.id.app_widget_container);
293838906b165e4d3cb2c512b2db344aa50cb5d4751Jim Miller        mAppWidgetContainer.setVisibility(VISIBLE);
294838906b165e4d3cb2c512b2db344aa50cb5d4751Jim Miller        mAppWidgetContainer.setCallbacks(mWidgetCallbacks);
295f3b9ec8230298e8f707c2fc44a74fb9346ec3d12Winson Chung        mAppWidgetContainer.setDeleteDropTarget(deleteDropTarget);
296d6523da1ad7bae805a3dbea8d7b398d86cd3c181Jim Miller        mAppWidgetContainer.setMinScale(0.5f);
297d6523da1ad7bae805a3dbea8d7b398d86cd3c181Jim Miller
2982cacda5fc92a28a44a37e25b96093a9cc1346080Jim Miller        mSlidingChallengeLayout = (SlidingChallengeLayout) findViewById(R.id.sliding_layout);
2992cacda5fc92a28a44a37e25b96093a9cc1346080Jim Miller        if (mSlidingChallengeLayout != null) {
3002cacda5fc92a28a44a37e25b96093a9cc1346080Jim Miller            mSlidingChallengeLayout.setOnChallengeScrolledListener(mViewStateManager);
30119a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        }
302d6523da1ad7bae805a3dbea8d7b398d86cd3c181Jim Miller        mAppWidgetContainer.setViewStateManager(mViewStateManager);
3031254f2f42f7173ef51d0034975ab5cb7d44f8209Michael Jurka        mAppWidgetContainer.setLockPatternUtils(mLockPatternUtils);
304d6523da1ad7bae805a3dbea8d7b398d86cd3c181Jim Miller
305257f283b0e4cc1c1fa4e7f2472d3ee4ab3b451d0John Spurlock        mMultiPaneChallengeLayout =
306257f283b0e4cc1c1fa4e7f2472d3ee4ab3b451d0John Spurlock                (MultiPaneChallengeLayout) findViewById(R.id.multi_pane_challenge);
3072cacda5fc92a28a44a37e25b96093a9cc1346080Jim Miller        ChallengeLayout challenge = mSlidingChallengeLayout != null ? mSlidingChallengeLayout :
308257f283b0e4cc1c1fa4e7f2472d3ee4ab3b451d0John Spurlock                mMultiPaneChallengeLayout;
30948275d2de99ff2556031929c48f295d3f93447b6Winson Chung        challenge.setOnBouncerStateChangedListener(mViewStateManager);
31070c2f8736437ebb6073c3b6dab2e08e6dd9f39a6Winson Chung        mAppWidgetContainer.setBouncerAnimationDuration(challenge.getBouncerAnimationDuration());
311d6523da1ad7bae805a3dbea8d7b398d86cd3c181Jim Miller        mViewStateManager.setPagedView(mAppWidgetContainer);
31248275d2de99ff2556031929c48f295d3f93447b6Winson Chung        mViewStateManager.setChallengeLayout(challenge);
3137751ff6cd079e59e3c1f2404198774cd371ea69fJim Miller
3143eb4971b679464e206cb666de1cf0e5a538c8d7dJim Miller        mViewStateManager.setSecurityViewContainer(getSecurityContainer());
31568c2489457631f733f542e14058c6d1274c203deJim Miller
3169ccf123ee0596ec9cab724f252a4932961c083afJim Miller        if (KeyguardUpdateMonitor.getInstance(mContext).hasBootCompleted()) {
3179ccf123ee0596ec9cab724f252a4932961c083afJim Miller            updateAndAddWidgets();
3189ccf123ee0596ec9cab724f252a4932961c083afJim Miller        } else {
3199ccf123ee0596ec9cab724f252a4932961c083afJim Miller            // We can't add widgets until after boot completes because AppWidgetHost may try
3209ccf123ee0596ec9cab724f252a4932961c083afJim Miller            // to contact the providers.  Do it later.
3219ccf123ee0596ec9cab724f252a4932961c083afJim Miller            mPostBootCompletedRunnable = new Runnable() {
3229ccf123ee0596ec9cab724f252a4932961c083afJim Miller                @Override
3239ccf123ee0596ec9cab724f252a4932961c083afJim Miller                public void run() {
3249ccf123ee0596ec9cab724f252a4932961c083afJim Miller                    updateAndAddWidgets();
3259ccf123ee0596ec9cab724f252a4932961c083afJim Miller                }
3269ccf123ee0596ec9cab724f252a4932961c083afJim Miller            };
3279ccf123ee0596ec9cab724f252a4932961c083afJim Miller        }
3289ccf123ee0596ec9cab724f252a4932961c083afJim Miller
3293eb4971b679464e206cb666de1cf0e5a538c8d7dJim Miller        getSecurityContainer().updateSecurityViews(mViewStateManager.isBouncing());
3309ccf123ee0596ec9cab724f252a4932961c083afJim Miller        enableUserSelectorIfNecessary();
3319ccf123ee0596ec9cab724f252a4932961c083afJim Miller    }
33251117262c8fadb6d227d137e83ad66996b013141Jim Miller
3339ccf123ee0596ec9cab724f252a4932961c083afJim Miller    private void updateAndAddWidgets() {
3349ccf123ee0596ec9cab724f252a4932961c083afJim Miller        cleanupAppWidgetIds();
3359ccf123ee0596ec9cab724f252a4932961c083afJim Miller        addDefaultWidgets();
33667a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        addWidgetsFromSettings();
3379ccf123ee0596ec9cab724f252a4932961c083afJim Miller        maybeEnableAddButton();
33851117262c8fadb6d227d137e83ad66996b013141Jim Miller        checkAppWidgetConsistency();
3395547b55bae92e6674e528d671f7700d7f5a9b3d0Jim Miller
3405547b55bae92e6674e528d671f7700d7f5a9b3d0Jim Miller        // Don't let the user drag the challenge down if widgets are disabled.
3415547b55bae92e6674e528d671f7700d7f5a9b3d0Jim Miller        if (mSlidingChallengeLayout != null) {
3425547b55bae92e6674e528d671f7700d7f5a9b3d0Jim Miller            mSlidingChallengeLayout.setEnableChallengeDragging(!widgetsDisabled());
3435547b55bae92e6674e528d671f7700d7f5a9b3d0Jim Miller        }
3445547b55bae92e6674e528d671f7700d7f5a9b3d0Jim Miller
3459ccf123ee0596ec9cab724f252a4932961c083afJim Miller        // Select the appropriate page
34667a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        mSwitchPageRunnable.run();
3479ccf123ee0596ec9cab724f252a4932961c083afJim Miller
34845adaa70203a155beb786f22b251fe66b8d6fafdAdam Cohen        // This needs to be called after the pages are all added.
34945adaa70203a155beb786f22b251fe66b8d6fafdAdam Cohen        mViewStateManager.showUsabilityHints();
3509ccf123ee0596ec9cab724f252a4932961c083afJim Miller    }
35145adaa70203a155beb786f22b251fe66b8d6fafdAdam Cohen
3529ccf123ee0596ec9cab724f252a4932961c083afJim Miller    private void maybeEnableAddButton() {
3539ccf123ee0596ec9cab724f252a4932961c083afJim Miller        if (!shouldEnableAddWidget()) {
3549ccf123ee0596ec9cab724f252a4932961c083afJim Miller            mAppWidgetContainer.setAddWidgetEnabled(false);
3559ccf123ee0596ec9cab724f252a4932961c083afJim Miller        }
356e46efc046074ecb49439ed9a557e5c79c0582468Jim Miller    }
357dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
358fff5614caecb0d2944b1bc206aaab0d3acb17670Michael Jurka    private boolean shouldEnableAddWidget() {
359fff5614caecb0d2944b1bc206aaab0d3acb17670Michael Jurka        return numWidgets() < MAX_WIDGETS && mUserSetupCompleted;
360fff5614caecb0d2944b1bc206aaab0d3acb17670Michael Jurka    }
361fff5614caecb0d2944b1bc206aaab0d3acb17670Michael Jurka
3623eb4971b679464e206cb666de1cf0e5a538c8d7dJim Miller    @Override
363ba7d94b8f3c41fd5b933b185e7463a56589e04d2Jim Miller    public boolean dismiss(boolean authenticated) {
3643eb4971b679464e206cb666de1cf0e5a538c8d7dJim Miller        boolean finished = super.dismiss(authenticated);
3653eb4971b679464e206cb666de1cf0e5a538c8d7dJim Miller        if (!finished) {
3663eb4971b679464e206cb666de1cf0e5a538c8d7dJim Miller            mViewStateManager.showBouncer(true);
3673eb4971b679464e206cb666de1cf0e5a538c8d7dJim Miller
3683eb4971b679464e206cb666de1cf0e5a538c8d7dJim Miller            // Enter full screen mode if we're in SIM or Account screen
3693eb4971b679464e206cb666de1cf0e5a538c8d7dJim Miller            SecurityMode securityMode = getSecurityContainer().getSecurityMode();
3703eb4971b679464e206cb666de1cf0e5a538c8d7dJim Miller            boolean isFullScreen = getResources().getBoolean(R.bool.kg_sim_puk_account_full_screen);
3713eb4971b679464e206cb666de1cf0e5a538c8d7dJim Miller            boolean isSimOrAccount = securityMode == SecurityMode.SimPin
3723eb4971b679464e206cb666de1cf0e5a538c8d7dJim Miller                    || securityMode == SecurityMode.SimPuk
3733eb4971b679464e206cb666de1cf0e5a538c8d7dJim Miller                    || securityMode == SecurityMode.Account;
3743eb4971b679464e206cb666de1cf0e5a538c8d7dJim Miller            mAppWidgetContainer.setVisibility(
3753eb4971b679464e206cb666de1cf0e5a538c8d7dJim Miller                    isSimOrAccount && isFullScreen ? View.GONE : View.VISIBLE);
3763eb4971b679464e206cb666de1cf0e5a538c8d7dJim Miller
3773eb4971b679464e206cb666de1cf0e5a538c8d7dJim Miller            // Don't show camera or search in navbar when SIM or Account screen is showing
3783eb4971b679464e206cb666de1cf0e5a538c8d7dJim Miller            setSystemUiVisibility(isSimOrAccount ?
3793eb4971b679464e206cb666de1cf0e5a538c8d7dJim Miller                    (getSystemUiVisibility() | View.STATUS_BAR_DISABLE_SEARCH)
3803eb4971b679464e206cb666de1cf0e5a538c8d7dJim Miller                    : (getSystemUiVisibility() & ~View.STATUS_BAR_DISABLE_SEARCH));
3813eb4971b679464e206cb666de1cf0e5a538c8d7dJim Miller
3823eb4971b679464e206cb666de1cf0e5a538c8d7dJim Miller            if (mSlidingChallengeLayout != null) {
3833eb4971b679464e206cb666de1cf0e5a538c8d7dJim Miller                mSlidingChallengeLayout.setChallengeInteractive(!isFullScreen);
3843eb4971b679464e206cb666de1cf0e5a538c8d7dJim Miller            }
3853eb4971b679464e206cb666de1cf0e5a538c8d7dJim Miller        }
3863eb4971b679464e206cb666de1cf0e5a538c8d7dJim Miller        return finished;
3873eb4971b679464e206cb666de1cf0e5a538c8d7dJim Miller    }
3883eb4971b679464e206cb666de1cf0e5a538c8d7dJim Miller
38951117262c8fadb6d227d137e83ad66996b013141Jim Miller    private int getDisabledFeatures(DevicePolicyManager dpm) {
39051117262c8fadb6d227d137e83ad66996b013141Jim Miller        int disabledFeatures = DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_NONE;
39151117262c8fadb6d227d137e83ad66996b013141Jim Miller        if (dpm != null) {
39251117262c8fadb6d227d137e83ad66996b013141Jim Miller            final int currentUser = mLockPatternUtils.getCurrentUser();
39351117262c8fadb6d227d137e83ad66996b013141Jim Miller            disabledFeatures = dpm.getKeyguardDisabledFeatures(null, currentUser);
39451117262c8fadb6d227d137e83ad66996b013141Jim Miller        }
39551117262c8fadb6d227d137e83ad66996b013141Jim Miller        return disabledFeatures;
39651117262c8fadb6d227d137e83ad66996b013141Jim Miller    }
39751117262c8fadb6d227d137e83ad66996b013141Jim Miller
398f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller    private boolean widgetsDisabled() {
399461b345886bc3c82b8e264158a7a754d59ea41ceJim Miller        boolean disabledByLowRamDevice = ActivityManager.isLowRamDeviceStatic();
400f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller        boolean disabledByDpm =
401f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller                (mDisabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_WIDGETS_ALL) != 0;
402f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller        boolean disabledByUser = !mLockPatternUtils.getWidgetsEnabled();
403461b345886bc3c82b8e264158a7a754d59ea41ceJim Miller        return disabledByLowRamDevice || disabledByDpm || disabledByUser;
40451117262c8fadb6d227d137e83ad66996b013141Jim Miller    }
40551117262c8fadb6d227d137e83ad66996b013141Jim Miller
40651117262c8fadb6d227d137e83ad66996b013141Jim Miller    private boolean cameraDisabledByDpm() {
40751117262c8fadb6d227d137e83ad66996b013141Jim Miller        return mCameraDisabled
40851117262c8fadb6d227d137e83ad66996b013141Jim Miller                || (mDisabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) != 0;
40951117262c8fadb6d227d137e83ad66996b013141Jim Miller    }
41051117262c8fadb6d227d137e83ad66996b013141Jim Miller
4115e612cf07872dc0989a4b9f09e2a38a2ee12186dJim Miller    @Override
4125cf17879a31b7b78c09ec50b727f921840dcf783Jorim Jaggi    public void setLockPatternUtils(LockPatternUtils utils) {
4135e612cf07872dc0989a4b9f09e2a38a2ee12186dJim Miller        super.setLockPatternUtils(utils);
4143eb4971b679464e206cb666de1cf0e5a538c8d7dJim Miller        getSecurityContainer().updateSecurityViews(mViewStateManager.isBouncing());
415dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
416dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
417dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    @Override
418dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    protected void onAttachedToWindow() {
419dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        super.onAttachedToWindow();
420a75a883fe9ea1790803148f0a561473073e3f264Jim Miller        mAppWidgetHost.startListening();
421efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen        KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mUpdateMonitorCallbacks);
4227221d3ae08cc2be922d26e5d491038512cb6c74dJim Miller    }
4237221d3ae08cc2be922d26e5d491038512cb6c74dJim Miller
424dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    @Override
425dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    protected void onDetachedFromWindow() {
426dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        super.onDetachedFromWindow();
427a75a883fe9ea1790803148f0a561473073e3f264Jim Miller        mAppWidgetHost.stopListening();
428efb3ffb029efcc180b3233b6f25d2dba11e28f03Adam Cohen        KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mUpdateMonitorCallbacks);
429dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
430dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
431d6523da1ad7bae805a3dbea8d7b398d86cd3c181Jim Miller    void addWidget(AppWidgetHostView view, int pageIndex) {
432d6523da1ad7bae805a3dbea8d7b398d86cd3c181Jim Miller        mAppWidgetContainer.addWidget(view, pageIndex);
433dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
434dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
435838906b165e4d3cb2c512b2db344aa50cb5d4751Jim Miller    private KeyguardWidgetPager.Callbacks mWidgetCallbacks
436838906b165e4d3cb2c512b2db344aa50cb5d4751Jim Miller            = new KeyguardWidgetPager.Callbacks() {
437c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown        @Override
438c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown        public void userActivity() {
43908c83ef48880b98ec45dd83867a29852160a96ebAdam Cohen            KeyguardHostView.this.userActivity();
440c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown        }
441c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown
442c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown        @Override
443c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown        public void onUserActivityTimeoutChanged() {
44408c83ef48880b98ec45dd83867a29852160a96ebAdam Cohen            KeyguardHostView.this.onUserActivityTimeoutChanged();
445c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown        }
446eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka
447eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka        @Override
44840f8211e6849c4c7948d7fc19127f29f0cebbeb9Winson Chung        public void onAddView(View v) {
449fff5614caecb0d2944b1bc206aaab0d3acb17670Michael Jurka            if (!shouldEnableAddWidget()) {
4504752e7d1a9ff83d946890b0020de091f4346a7aeWinson Chung                mAppWidgetContainer.setAddWidgetEnabled(false);
45140f8211e6849c4c7948d7fc19127f29f0cebbeb9Winson Chung            }
4524752e7d1a9ff83d946890b0020de091f4346a7aeWinson Chung        }
45340f8211e6849c4c7948d7fc19127f29f0cebbeb9Winson Chung
45440f8211e6849c4c7948d7fc19127f29f0cebbeb9Winson Chung        @Override
45575b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka        public void onRemoveView(View v, boolean deletePermanently) {
45675b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka            if (deletePermanently) {
45775b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka                final int appWidgetId = ((KeyguardWidgetFrame) v).getContentAppWidgetId();
45875b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka                if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID &&
45975b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka                        appWidgetId != LockPatternUtils.ID_DEFAULT_STATUS_WIDGET) {
46075b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka                    mAppWidgetHost.deleteAppWidgetId(appWidgetId);
46175b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka                }
46275b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka            }
463eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka        }
4644752e7d1a9ff83d946890b0020de091f4346a7aeWinson Chung
4654752e7d1a9ff83d946890b0020de091f4346a7aeWinson Chung        @Override
4664752e7d1a9ff83d946890b0020de091f4346a7aeWinson Chung        public void onRemoveViewAnimationCompleted() {
467fff5614caecb0d2944b1bc206aaab0d3acb17670Michael Jurka            if (shouldEnableAddWidget()) {
4684752e7d1a9ff83d946890b0020de091f4346a7aeWinson Chung                mAppWidgetContainer.setAddWidgetEnabled(true);
4694752e7d1a9ff83d946890b0020de091f4346a7aeWinson Chung            }
4704752e7d1a9ff83d946890b0020de091f4346a7aeWinson Chung        }
471c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown    };
472c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown
4735e612cf07872dc0989a4b9f09e2a38a2ee12186dJim Miller    @Override
4745e612cf07872dc0989a4b9f09e2a38a2ee12186dJim Miller    public void onUserSwitching(boolean switching) {
475f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren        if (!switching && mKeyguardMultiUserSelectorView != null) {
476f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren            mKeyguardMultiUserSelectorView.finalizeActiveUserView(false);
477f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren        }
478f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren    }
479f41c61bc1551c98c681fe3e6ae197fefed2bc856Chris Wren
48008c83ef48880b98ec45dd83867a29852160a96ebAdam Cohen    public void userActivity() {
48108c83ef48880b98ec45dd83867a29852160a96ebAdam Cohen        if (mViewMediatorCallback != null) {
48208c83ef48880b98ec45dd83867a29852160a96ebAdam Cohen            mViewMediatorCallback.userActivity();
48308c83ef48880b98ec45dd83867a29852160a96ebAdam Cohen        }
48408c83ef48880b98ec45dd83867a29852160a96ebAdam Cohen    }
48508c83ef48880b98ec45dd83867a29852160a96ebAdam Cohen
48608c83ef48880b98ec45dd83867a29852160a96ebAdam Cohen    public void onUserActivityTimeoutChanged() {
48708c83ef48880b98ec45dd83867a29852160a96ebAdam Cohen        if (mViewMediatorCallback != null) {
48808c83ef48880b98ec45dd83867a29852160a96ebAdam Cohen            mViewMediatorCallback.onUserActivityTimeoutChanged();
48908c83ef48880b98ec45dd83867a29852160a96ebAdam Cohen        }
49008c83ef48880b98ec45dd83867a29852160a96ebAdam Cohen    }
49108c83ef48880b98ec45dd83867a29852160a96ebAdam Cohen
492c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown    @Override
493c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown    public long getUserActivityTimeout() {
494c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown        // Currently only considering user activity timeouts needed by widgets.
495c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown        // Could also take into account longer timeouts for certain security views.
496838906b165e4d3cb2c512b2db344aa50cb5d4751Jim Miller        if (mAppWidgetContainer != null) {
497838906b165e4d3cb2c512b2db344aa50cb5d4751Jim Miller            return mAppWidgetContainer.getUserActivityTimeout();
498c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown        }
499c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown        return -1;
500c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown    }
501c7505bc9dddcb0655302c1598e966bf121586ebeJeff Brown
5027fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haase    private static class MyOnClickHandler extends OnClickHandler {
5037fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haase
5047fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haase        // weak reference to the hostView to avoid keeping a live reference
5057fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haase        // due to Binder GC linkages to AppWidgetHost. By the same token,
5067fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haase        // this click handler should not keep references to any large
5077fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haase        // objects.
5087751ff6cd079e59e3c1f2404198774cd371ea69fJim Miller        WeakReference<KeyguardHostView> mKeyguardHostView;
5097fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haase
5107fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haase        MyOnClickHandler(KeyguardHostView hostView) {
5117751ff6cd079e59e3c1f2404198774cd371ea69fJim Miller            mKeyguardHostView = new WeakReference<KeyguardHostView>(hostView);
5127fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haase        }
5137fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haase
514dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        @Override
515dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        public boolean onClickHandler(final View view,
516dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                final android.app.PendingIntent pendingIntent,
517dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                final Intent fillInIntent) {
5187751ff6cd079e59e3c1f2404198774cd371ea69fJim Miller            KeyguardHostView hostView = mKeyguardHostView.get();
5197fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haase            if (hostView == null) {
5207fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haase                return false;
5217fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haase            }
522dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            if (pendingIntent.isActivity()) {
5237fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haase                hostView.setOnDismissAction(new OnDismissAction() {
52434c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock                    public boolean onDismiss() {
525dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                        try {
5267fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haase                            // TODO: Unregister this handler if PendingIntent.FLAG_ONE_SHOT?
5277fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haase                            Context context = view.getContext();
5287fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haase                            ActivityOptions opts = ActivityOptions.makeScaleUpAnimation(view,
5297fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haase                                    0, 0,
5307fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haase                                    view.getMeasuredWidth(), view.getMeasuredHeight());
5317fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haase                            context.startIntentSender(
5327fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haase                                    pendingIntent.getIntentSender(), fillInIntent,
5337fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haase                                    Intent.FLAG_ACTIVITY_NEW_TASK,
5347fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haase                                    Intent.FLAG_ACTIVITY_NEW_TASK, 0, opts.toBundle());
53534c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock                        } catch (IntentSender.SendIntentException e) {
53634c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock                            android.util.Log.e(TAG, "Cannot send pending intent: ", e);
53734c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock                        } catch (Exception e) {
53834c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock                            android.util.Log.e(TAG, "Cannot send pending intent due to " +
53934c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock                                    "unknown exception: ", e);
54034c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock                        }
54134c4fe523ad96fb59cec28832b38806d04a6bebfJohn Spurlock                        return false;
542dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                    }
5435f75aa15d7c1c5ea1c1eecd95bf2bb0920173eb2Jim Miller                });
544dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
5457fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haase                if (hostView.mViewStateManager.isChallengeShowing()) {
5467fc27ea451dac0c89c8c4e6b80182ed1a7620a87Chet Haase                    hostView.mViewStateManager.showBouncer(true);
54708898375fba7cc776857ebf0846c7183563a300fJim Miller                } else {
5487751ff6cd079e59e3c1f2404198774cd371ea69fJim Miller                    hostView.dismiss();
54908898375fba7cc776857ebf0846c7183563a300fJim Miller                }
550dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                return true;
551dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            } else {
552dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                return super.onClickHandler(view, pendingIntent, fillInIntent);
553dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            }
554dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        };
555dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    };
556dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
557dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    @Override
558a005f1b6853e8852c328f4fdc02fb8f9c9ae1cd6Jorim Jaggi    public void onResume() {
559a005f1b6853e8852c328f4fdc02fb8f9c9ae1cd6Jorim Jaggi        super.onResume();
5606fb841fa219eaae3e87f2fdc05e105d7a1813c42Adam Cohen        if (mViewStateManager != null) {
5616fb841fa219eaae3e87f2fdc05e105d7a1813c42Adam Cohen            mViewStateManager.showUsabilityHints();
5626fb841fa219eaae3e87f2fdc05e105d7a1813c42Adam Cohen        }
563dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
564dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
565dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    @Override
566a005f1b6853e8852c328f4fdc02fb8f9c9ae1cd6Jorim Jaggi    public void onPause() {
567a005f1b6853e8852c328f4fdc02fb8f9c9ae1cd6Jorim Jaggi        super.onPause();
5681413889565bc1b9d5d5fb73302460a4f25f4a8c0Michael Jurka        // We use mAppWidgetToShow to show a particular widget after you add it-- once the screen
5691413889565bc1b9d5d5fb73302460a4f25f4a8c0Michael Jurka        // turns off we reset that behavior
5701413889565bc1b9d5d5fb73302460a4f25f4a8c0Michael Jurka        clearAppWidgetToShow();
5719ccf123ee0596ec9cab724f252a4932961c083afJim Miller        if (KeyguardUpdateMonitor.getInstance(mContext).hasBootCompleted()) {
5729ccf123ee0596ec9cab724f252a4932961c083afJim Miller            checkAppWidgetConsistency();
5739ccf123ee0596ec9cab724f252a4932961c083afJim Miller        }
574dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock        CameraWidgetFrame cameraPage = findCameraPage();
575dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock        if (cameraPage != null) {
576dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock            cameraPage.onScreenTurnedOff();
577dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock        }
578dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
579dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
5801413889565bc1b9d5d5fb73302460a4f25f4a8c0Michael Jurka    public void clearAppWidgetToShow() {
5811413889565bc1b9d5d5fb73302460a4f25f4a8c0Michael Jurka        mAppWidgetToShow = AppWidgetManager.INVALID_APPWIDGET_ID;
5821413889565bc1b9d5d5fb73302460a4f25f4a8c0Michael Jurka    }
5831413889565bc1b9d5d5fb73302460a4f25f4a8c0Michael Jurka
58451117262c8fadb6d227d137e83ad66996b013141Jim Miller    private boolean addWidget(int appId, int pageIndex, boolean updateDbIfFailed) {
58567a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appId);
58699a3cae55bd1a4ea6d82aa7fa2a67170e7cd5b3eJim Miller        if (appWidgetInfo != null) {
587a75a883fe9ea1790803148f0a561473073e3f264Jim Miller            AppWidgetHostView view = mAppWidgetHost.createView(mContext, appId, appWidgetInfo);
588d6523da1ad7bae805a3dbea8d7b398d86cd3c181Jim Miller            addWidget(view, pageIndex);
58967a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka            return true;
59099a3cae55bd1a4ea6d82aa7fa2a67170e7cd5b3eJim Miller        } else {
59151117262c8fadb6d227d137e83ad66996b013141Jim Miller            if (updateDbIfFailed) {
592a75a883fe9ea1790803148f0a561473073e3f264Jim Miller                Log.w(TAG, "*** AppWidgetInfo for app widget id " + appId + "  was null for user"
593a75a883fe9ea1790803148f0a561473073e3f264Jim Miller                        + mUserId + ", deleting");
59451117262c8fadb6d227d137e83ad66996b013141Jim Miller                mAppWidgetHost.deleteAppWidgetId(appId);
59551117262c8fadb6d227d137e83ad66996b013141Jim Miller                mLockPatternUtils.removeAppWidget(appId);
59651117262c8fadb6d227d137e83ad66996b013141Jim Miller            }
59767a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka            return false;
59899a3cae55bd1a4ea6d82aa7fa2a67170e7cd5b3eJim Miller        }
599dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
600dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
601dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock    private final CameraWidgetFrame.Callbacks mCameraWidgetCallbacks =
602dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock        new CameraWidgetFrame.Callbacks() {
603dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock            @Override
604dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock            public void onLaunchingCamera() {
60557f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock                setSliderHandleAlpha(0);
606dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock            }
607dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock
608dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock            @Override
60957f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock            public void onCameraLaunchedSuccessfully() {
6106cf53bb3a94ec5a6eebc96a315dac32d042f1945Winson Chung                if (mAppWidgetContainer.isCameraPage(mAppWidgetContainer.getCurrentPage())) {
6114b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock                    mAppWidgetContainer.scrollLeft();
6124b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock                }
61357f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock                setSliderHandleAlpha(1);
614aaf9b11e6232f159aa6d9863097b09bb435deae3Jim Miller                mShowSecurityWhenReturn = true;
615dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock            }
616dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock
61757f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock            @Override
61857f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock            public void onCameraLaunchedUnsuccessfully() {
61957f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock                setSliderHandleAlpha(1);
62057f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock            }
62157f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock
62257f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock            private void setSliderHandleAlpha(float alpha) {
62357f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock                SlidingChallengeLayout slider =
62457f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock                        (SlidingChallengeLayout) findViewById(R.id.sliding_layout);
62557f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock                if (slider != null) {
62657f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock                    slider.setHandleAlpha(alpha);
62757f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock                }
628dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock            }
629dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock        };
630dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock
631eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka    private int numWidgets() {
632eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka        final int childCount = mAppWidgetContainer.getChildCount();
633eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka        int widgetCount = 0;
634eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka        for (int i = 0; i < childCount; i++) {
635eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka            if (mAppWidgetContainer.isWidgetPage(i)) {
636eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka                widgetCount++;
637eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka            }
638eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka        }
639eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka        return widgetCount;
640eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka    }
641eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka
6424e81bd4bcf60a934d4cd589dab6e2bddb88d7356Jim Miller    private void addDefaultWidgets() {
643f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller        if (!mSafeModeEnabled && !widgetsDisabled()) {
6448f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            LayoutInflater inflater = LayoutInflater.from(mContext);
64551117262c8fadb6d227d137e83ad66996b013141Jim Miller            View addWidget = inflater.inflate(R.layout.keyguard_add_widget, this, false);
646eb963f046dadd1304379db0b14c17e47c89913f4Michael Jurka            mAppWidgetContainer.addWidget(addWidget, 0);
64751117262c8fadb6d227d137e83ad66996b013141Jim Miller            View addWidgetButton = addWidget.findViewById(R.id.keyguard_add_widget_view);
64851117262c8fadb6d227d137e83ad66996b013141Jim Miller            addWidgetButton.setOnClickListener(new OnClickListener() {
64951117262c8fadb6d227d137e83ad66996b013141Jim Miller                @Override
65051117262c8fadb6d227d137e83ad66996b013141Jim Miller                public void onClick(View v) {
651192d6d4ee271c0782a3bf5d8c64e42eb22d1a6faMichael Jurka                    // Pass in an invalid widget id... the picker will allocate an ID for us
6523eb4971b679464e206cb666de1cf0e5a538c8d7dJim Miller                    getActivityLauncher().launchWidgetPicker(AppWidgetManager.INVALID_APPWIDGET_ID);
65351117262c8fadb6d227d137e83ad66996b013141Jim Miller                }
65451117262c8fadb6d227d137e83ad66996b013141Jim Miller            });
65551117262c8fadb6d227d137e83ad66996b013141Jim Miller        }
65651117262c8fadb6d227d137e83ad66996b013141Jim Miller
65751117262c8fadb6d227d137e83ad66996b013141Jim Miller        // We currently disable cameras in safe mode because we support loading 3rd party
65851117262c8fadb6d227d137e83ad66996b013141Jim Miller        // cameras we can't trust.  TODO: plumb safe mode into camera creation code and only
65951117262c8fadb6d227d137e83ad66996b013141Jim Miller        // inflate system-provided camera?
660371f3408d6d9c3c3781d6e35e591f61026b42240John Spurlock        if (!mSafeModeEnabled && !cameraDisabledByDpm() && mUserSetupCompleted
66151117262c8fadb6d227d137e83ad66996b013141Jim Miller                && mContext.getResources().getBoolean(R.bool.kg_enable_camera_default_widget)) {
6623eb4971b679464e206cb666de1cf0e5a538c8d7dJim Miller            View cameraWidget = CameraWidgetFrame.create(mContext, mCameraWidgetCallbacks,
6633eb4971b679464e206cb666de1cf0e5a538c8d7dJim Miller                    getActivityLauncher());
664dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock            if (cameraWidget != null) {
665dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock                mAppWidgetContainer.addWidget(cameraWidget);
666dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock            }
66786b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock        }
6687221d3ae08cc2be922d26e5d491038512cb6c74dJim Miller    }
6697221d3ae08cc2be922d26e5d491038512cb6c74dJim Miller
6708f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller    /**
6718f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller     * Create KeyguardTransportControlView on demand.
6728f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller     * @return
6738f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller     */
6744894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller    private KeyguardTransportControlView getOrCreateTransportControl() {
6758f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        if (mTransportControl == null) {
6768f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            LayoutInflater inflater = LayoutInflater.from(mContext);
6778f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            mTransportControl = (KeyguardTransportControlView)
6788f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller                    inflater.inflate(R.layout.keyguard_transport_control_view, this, false);
679f8895248e2ac4dbb46622f3e04c7256f03175b4fAdam Powell            mTransportControl.setTransportControlCallback(new TransportControlCallback() {
680f8895248e2ac4dbb46622f3e04c7256f03175b4fAdam Powell                public void userActivity() {
681f8895248e2ac4dbb46622f3e04c7256f03175b4fAdam Powell                    mViewMediatorCallback.userActivity();
682f8895248e2ac4dbb46622f3e04c7256f03175b4fAdam Powell                }
683f8895248e2ac4dbb46622f3e04c7256f03175b4fAdam Powell            });
6844e81bd4bcf60a934d4cd589dab6e2bddb88d7356Jim Miller        }
6858f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        return mTransportControl;
6864e81bd4bcf60a934d4cd589dab6e2bddb88d7356Jim Miller    }
6874e81bd4bcf60a934d4cd589dab6e2bddb88d7356Jim Miller
68851117262c8fadb6d227d137e83ad66996b013141Jim Miller    private int getInsertPageIndex() {
68967a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        View addWidget = mAppWidgetContainer.findViewById(R.id.keyguard_add_widget);
69051117262c8fadb6d227d137e83ad66996b013141Jim Miller        int insertionIndex = mAppWidgetContainer.indexOfChild(addWidget);
69151117262c8fadb6d227d137e83ad66996b013141Jim Miller        if (insertionIndex < 0) {
69251117262c8fadb6d227d137e83ad66996b013141Jim Miller            insertionIndex = 0; // no add widget page found
69351117262c8fadb6d227d137e83ad66996b013141Jim Miller        } else {
69451117262c8fadb6d227d137e83ad66996b013141Jim Miller            insertionIndex++; // place after add widget
69567a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        }
69651117262c8fadb6d227d137e83ad66996b013141Jim Miller        return insertionIndex;
69767a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka    }
69867a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka
69967a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka    private void addDefaultStatusWidget(int index) {
70067a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        LayoutInflater inflater = LayoutInflater.from(mContext);
70167a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        View statusWidget = inflater.inflate(R.layout.keyguard_status_view, null, true);
70267a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        mAppWidgetContainer.addWidget(statusWidget, index);
70367a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka    }
70467a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka
7051254f2f42f7173ef51d0034975ab5cb7d44f8209Michael Jurka    private void addWidgetsFromSettings() {
706f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller        if (mSafeModeEnabled || widgetsDisabled()) {
7072ec4ff435b0af87a6c0f933e6eaf1155e34c430fJim Miller            addDefaultStatusWidget(0);
70851117262c8fadb6d227d137e83ad66996b013141Jim Miller            return;
709b8ec470617590fa2025db869e8e80dcce8eaec23Jim Miller        }
710f229e4d3eb8f910c181f96416c6798f6f305a395Jim Miller
71151117262c8fadb6d227d137e83ad66996b013141Jim Miller        int insertionIndex = getInsertPageIndex();
71220c41d5382b70fa5a24e9ef68f19ce0aedea5234Michael Jurka
71320c41d5382b70fa5a24e9ef68f19ce0aedea5234Michael Jurka        // Add user-selected widget
714aa2859ae61098509495b7938e32a6d59d37561beMichael Jurka        final int[] widgets = mLockPatternUtils.getAppWidgets();
71567a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka
716aa2859ae61098509495b7938e32a6d59d37561beMichael Jurka        if (widgets == null) {
717aa2859ae61098509495b7938e32a6d59d37561beMichael Jurka            Log.d(TAG, "Problem reading widgets");
718aa2859ae61098509495b7938e32a6d59d37561beMichael Jurka        } else {
719aa2859ae61098509495b7938e32a6d59d37561beMichael Jurka            for (int i = widgets.length -1; i >= 0; i--) {
7201254f2f42f7173ef51d0034975ab5cb7d44f8209Michael Jurka                if (widgets[i] == LockPatternUtils.ID_DEFAULT_STATUS_WIDGET) {
72151117262c8fadb6d227d137e83ad66996b013141Jim Miller                    addDefaultStatusWidget(insertionIndex);
7221254f2f42f7173ef51d0034975ab5cb7d44f8209Michael Jurka                } else {
723aa2859ae61098509495b7938e32a6d59d37561beMichael Jurka                    // We add the widgets from left to right, starting after the first page after
724aa2859ae61098509495b7938e32a6d59d37561beMichael Jurka                    // the add page. We count down, since the order will be persisted from right
725aa2859ae61098509495b7938e32a6d59d37561beMichael Jurka                    // to left, starting after camera.
72651117262c8fadb6d227d137e83ad66996b013141Jim Miller                    addWidget(widgets[i], insertionIndex, true);
727aa2859ae61098509495b7938e32a6d59d37561beMichael Jurka                }
728dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            }
729dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
73051117262c8fadb6d227d137e83ad66996b013141Jim Miller    }
73151117262c8fadb6d227d137e83ad66996b013141Jim Miller
73251117262c8fadb6d227d137e83ad66996b013141Jim Miller    private int allocateIdForDefaultAppWidget() {
73351117262c8fadb6d227d137e83ad66996b013141Jim Miller        int appWidgetId;
73451117262c8fadb6d227d137e83ad66996b013141Jim Miller        Resources res = getContext().getResources();
73551117262c8fadb6d227d137e83ad66996b013141Jim Miller        ComponentName defaultAppWidget = new ComponentName(
73651117262c8fadb6d227d137e83ad66996b013141Jim Miller                res.getString(R.string.widget_default_package_name),
73751117262c8fadb6d227d137e83ad66996b013141Jim Miller                res.getString(R.string.widget_default_class_name));
73851117262c8fadb6d227d137e83ad66996b013141Jim Miller
73951117262c8fadb6d227d137e83ad66996b013141Jim Miller        // Note: we don't support configuring the widget
74051117262c8fadb6d227d137e83ad66996b013141Jim Miller        appWidgetId = mAppWidgetHost.allocateAppWidgetId();
74151117262c8fadb6d227d137e83ad66996b013141Jim Miller
74251117262c8fadb6d227d137e83ad66996b013141Jim Miller        try {
74351117262c8fadb6d227d137e83ad66996b013141Jim Miller            mAppWidgetManager.bindAppWidgetId(appWidgetId, defaultAppWidget);
74451117262c8fadb6d227d137e83ad66996b013141Jim Miller        } catch (IllegalArgumentException e) {
74551117262c8fadb6d227d137e83ad66996b013141Jim Miller            Log.e(TAG, "Error when trying to bind default AppWidget: " + e);
74651117262c8fadb6d227d137e83ad66996b013141Jim Miller            mAppWidgetHost.deleteAppWidgetId(appWidgetId);
74751117262c8fadb6d227d137e83ad66996b013141Jim Miller            appWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
74851117262c8fadb6d227d137e83ad66996b013141Jim Miller        }
74951117262c8fadb6d227d137e83ad66996b013141Jim Miller        return appWidgetId;
75067a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka    }
751f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller
75267a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka    public void checkAppWidgetConsistency() {
75367a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        final int childCount = mAppWidgetContainer.getChildCount();
75467a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        boolean widgetPageExists = false;
75567a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        for (int i = 0; i < childCount; i++) {
75651117262c8fadb6d227d137e83ad66996b013141Jim Miller            if (mAppWidgetContainer.isWidgetPage(i)) {
75767a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka                widgetPageExists = true;
75867a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka                break;
75967a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka            }
76067a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        }
76167a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        if (!widgetPageExists) {
76251117262c8fadb6d227d137e83ad66996b013141Jim Miller            final int insertPageIndex = getInsertPageIndex();
76351117262c8fadb6d227d137e83ad66996b013141Jim Miller
764f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller            final boolean userAddedWidgetsEnabled = !widgetsDisabled();
765f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller
76651117262c8fadb6d227d137e83ad66996b013141Jim Miller            boolean addedDefaultAppWidget = false;
76751117262c8fadb6d227d137e83ad66996b013141Jim Miller
76851117262c8fadb6d227d137e83ad66996b013141Jim Miller            if (!mSafeModeEnabled) {
76951117262c8fadb6d227d137e83ad66996b013141Jim Miller                if (userAddedWidgetsEnabled) {
77051117262c8fadb6d227d137e83ad66996b013141Jim Miller                    int appWidgetId = allocateIdForDefaultAppWidget();
77151117262c8fadb6d227d137e83ad66996b013141Jim Miller                    if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
77251117262c8fadb6d227d137e83ad66996b013141Jim Miller                        addedDefaultAppWidget = addWidget(appWidgetId, insertPageIndex, true);
77351117262c8fadb6d227d137e83ad66996b013141Jim Miller                    }
77451117262c8fadb6d227d137e83ad66996b013141Jim Miller                } else {
77551117262c8fadb6d227d137e83ad66996b013141Jim Miller                    // note: even if widgetsDisabledByDpm() returns true, we still bind/create
77651117262c8fadb6d227d137e83ad66996b013141Jim Miller                    // the default appwidget if possible
77751117262c8fadb6d227d137e83ad66996b013141Jim Miller                    int appWidgetId = mLockPatternUtils.getFallbackAppWidgetId();
77851117262c8fadb6d227d137e83ad66996b013141Jim Miller                    if (appWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
77951117262c8fadb6d227d137e83ad66996b013141Jim Miller                        appWidgetId = allocateIdForDefaultAppWidget();
78051117262c8fadb6d227d137e83ad66996b013141Jim Miller                        if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
78151117262c8fadb6d227d137e83ad66996b013141Jim Miller                            mLockPatternUtils.writeFallbackAppWidgetId(appWidgetId);
78251117262c8fadb6d227d137e83ad66996b013141Jim Miller                        }
78351117262c8fadb6d227d137e83ad66996b013141Jim Miller                    }
78451117262c8fadb6d227d137e83ad66996b013141Jim Miller                    if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
78551117262c8fadb6d227d137e83ad66996b013141Jim Miller                        addedDefaultAppWidget = addWidget(appWidgetId, insertPageIndex, false);
78651117262c8fadb6d227d137e83ad66996b013141Jim Miller                        if (!addedDefaultAppWidget) {
78751117262c8fadb6d227d137e83ad66996b013141Jim Miller                            mAppWidgetHost.deleteAppWidgetId(appWidgetId);
78851117262c8fadb6d227d137e83ad66996b013141Jim Miller                            mLockPatternUtils.writeFallbackAppWidgetId(
78951117262c8fadb6d227d137e83ad66996b013141Jim Miller                                    AppWidgetManager.INVALID_APPWIDGET_ID);
79051117262c8fadb6d227d137e83ad66996b013141Jim Miller                        }
79151117262c8fadb6d227d137e83ad66996b013141Jim Miller                    }
79251117262c8fadb6d227d137e83ad66996b013141Jim Miller                }
79367a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka            }
79451117262c8fadb6d227d137e83ad66996b013141Jim Miller
79567a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka            // Use the built-in status/clock view if we can't inflate the default widget
79651117262c8fadb6d227d137e83ad66996b013141Jim Miller            if (!addedDefaultAppWidget) {
79751117262c8fadb6d227d137e83ad66996b013141Jim Miller                addDefaultStatusWidget(insertPageIndex);
79851117262c8fadb6d227d137e83ad66996b013141Jim Miller            }
79951117262c8fadb6d227d137e83ad66996b013141Jim Miller
80051117262c8fadb6d227d137e83ad66996b013141Jim Miller            // trigger DB updates only if user-added widgets are enabled
80151117262c8fadb6d227d137e83ad66996b013141Jim Miller            if (!mSafeModeEnabled && userAddedWidgetsEnabled) {
80251117262c8fadb6d227d137e83ad66996b013141Jim Miller                mAppWidgetContainer.onAddView(
80351117262c8fadb6d227d137e83ad66996b013141Jim Miller                        mAppWidgetContainer.getChildAt(insertPageIndex), insertPageIndex);
80467a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka            }
80567a871d85732e582c70a2a1d85ef4419eb658a12Michael Jurka        }
8060207c0992cb05d0acc60540748c8ae6985917abbAdam Cohen    }
8070207c0992cb05d0acc60540748c8ae6985917abbAdam Cohen
80881190befe66e297d93ad0c7661d02d56f8f01f24Jim Miller    private final Runnable mSwitchPageRunnable = new Runnable() {
809223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        @Override
810223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        public void run() {
811223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller           showAppropriateWidgetPage();
812223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        }
813223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller    };
814223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller
815223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller    static class SavedState extends BaseSavedState {
816223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        int transportState;
8171413889565bc1b9d5d5fb73302460a4f25f4a8c0Michael Jurka        int appWidgetToShow = AppWidgetManager.INVALID_APPWIDGET_ID;
818256ae67b9a629178b458dfc01102c9c0b9963d03John Spurlock        Rect insets = new Rect();
819223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller
820223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        SavedState(Parcelable superState) {
821223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller            super(superState);
822223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        }
823223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller
824223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        private SavedState(Parcel in) {
825223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller            super(in);
826223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller            this.transportState = in.readInt();
8271413889565bc1b9d5d5fb73302460a4f25f4a8c0Michael Jurka            this.appWidgetToShow = in.readInt();
828256ae67b9a629178b458dfc01102c9c0b9963d03John Spurlock            this.insets = in.readParcelable(null);
829223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        }
830223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller
831223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        @Override
832223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        public void writeToParcel(Parcel out, int flags) {
833223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller            super.writeToParcel(out, flags);
834223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller            out.writeInt(this.transportState);
8351413889565bc1b9d5d5fb73302460a4f25f4a8c0Michael Jurka            out.writeInt(this.appWidgetToShow);
836256ae67b9a629178b458dfc01102c9c0b9963d03John Spurlock            out.writeParcelable(insets, 0);
837223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        }
838223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller
839223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        public static final Parcelable.Creator<SavedState> CREATOR
840223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller                = new Parcelable.Creator<SavedState>() {
841223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller            public SavedState createFromParcel(Parcel in) {
842223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller                return new SavedState(in);
843223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller            }
844223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller
845223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller            public SavedState[] newArray(int size) {
846223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller                return new SavedState[size];
847223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller            }
848223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        };
849223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller    }
850223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller
851223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller    @Override
852223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller    public Parcelable onSaveInstanceState() {
8534894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller        if (DEBUG) Log.d(TAG, "onSaveInstanceState, tstate=" + mTransportState);
854223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        Parcelable superState = super.onSaveInstanceState();
855223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        SavedState ss = new SavedState(superState);
8564894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller        // If the transport is showing, force it to show it on restore.
8574894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller        final boolean showing = mTransportControl != null
8584894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller                && mAppWidgetContainer.getWidgetPageIndex(mTransportControl) >= 0;
8594894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller        ss.transportState =  showing ? TRANSPORT_VISIBLE : mTransportState;
8601413889565bc1b9d5d5fb73302460a4f25f4a8c0Michael Jurka        ss.appWidgetToShow = mAppWidgetToShow;
861256ae67b9a629178b458dfc01102c9c0b9963d03John Spurlock        ss.insets.set(mInsets);
862223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        return ss;
863223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller    }
864223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller
865223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller    @Override
866223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller    public void onRestoreInstanceState(Parcelable state) {
867223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        if (!(state instanceof SavedState)) {
868223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller            super.onRestoreInstanceState(state);
869223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller            return;
870223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        }
871223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        SavedState ss = (SavedState) state;
872223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller        super.onRestoreInstanceState(ss.getSuperState());
8738f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        mTransportState = (ss.transportState);
8741413889565bc1b9d5d5fb73302460a4f25f4a8c0Michael Jurka        mAppWidgetToShow = ss.appWidgetToShow;
875256ae67b9a629178b458dfc01102c9c0b9963d03John Spurlock        setInsets(ss.insets);
8764894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller        if (DEBUG) Log.d(TAG, "onRestoreInstanceState, transport=" + mTransportState);
87781190befe66e297d93ad0c7661d02d56f8f01f24Jim Miller        mSwitchPageRunnable.run();
878223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller    }
879223ce5c7326f6d13a17ccf2624605bb62864a27aJim Miller
8805f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock    @Override
881256ae67b9a629178b458dfc01102c9c0b9963d03John Spurlock    protected boolean fitSystemWindows(Rect insets) {
882256ae67b9a629178b458dfc01102c9c0b9963d03John Spurlock        setInsets(insets);
883256ae67b9a629178b458dfc01102c9c0b9963d03John Spurlock        return true;
884256ae67b9a629178b458dfc01102c9c0b9963d03John Spurlock    }
885256ae67b9a629178b458dfc01102c9c0b9963d03John Spurlock
886256ae67b9a629178b458dfc01102c9c0b9963d03John Spurlock    private void setInsets(Rect insets) {
887256ae67b9a629178b458dfc01102c9c0b9963d03John Spurlock        mInsets.set(insets);
888256ae67b9a629178b458dfc01102c9c0b9963d03John Spurlock        if (mSlidingChallengeLayout != null) mSlidingChallengeLayout.setInsets(mInsets);
889256ae67b9a629178b458dfc01102c9c0b9963d03John Spurlock        if (mMultiPaneChallengeLayout != null) mMultiPaneChallengeLayout.setInsets(mInsets);
89026b7bf6e3cf6be009cd4baf59e083bce37633a4aDaniel Sandler
89126b7bf6e3cf6be009cd4baf59e083bce37633a4aDaniel Sandler        final CameraWidgetFrame cameraWidget = findCameraPage();
89226b7bf6e3cf6be009cd4baf59e083bce37633a4aDaniel Sandler        if (cameraWidget != null) cameraWidget.setInsets(mInsets);
893256ae67b9a629178b458dfc01102c9c0b9963d03John Spurlock    }
894256ae67b9a629178b458dfc01102c9c0b9963d03John Spurlock
895256ae67b9a629178b458dfc01102c9c0b9963d03John Spurlock    @Override
8965f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock    public void onWindowFocusChanged(boolean hasWindowFocus) {
8975f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock        super.onWindowFocusChanged(hasWindowFocus);
8985f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock        if (DEBUG) Log.d(TAG, "Window is " + (hasWindowFocus ? "focused" : "unfocused"));
89976017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka        if (hasWindowFocus && mShowSecurityWhenReturn) {
900aaf9b11e6232f159aa6d9863097b09bb435deae3Jim Miller            SlidingChallengeLayout slider =
901aaf9b11e6232f159aa6d9863097b09bb435deae3Jim Miller                (SlidingChallengeLayout) findViewById(R.id.sliding_layout);
902aaf9b11e6232f159aa6d9863097b09bb435deae3Jim Miller            if (slider != null) {
903aaf9b11e6232f159aa6d9863097b09bb435deae3Jim Miller                slider.setHandleAlpha(1);
904aaf9b11e6232f159aa6d9863097b09bb435deae3Jim Miller                slider.showChallenge(true);
905aaf9b11e6232f159aa6d9863097b09bb435deae3Jim Miller            }
906aaf9b11e6232f159aa6d9863097b09bb435deae3Jim Miller            mShowSecurityWhenReturn = false;
9075f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock        }
9085f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock    }
9095f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock
9104d20ed3f26d1ec2c47519484bcc968098581c3d6Jim Miller    private void showAppropriateWidgetPage() {
91181190befe66e297d93ad0c7661d02d56f8f01f24Jim Miller        final int state = mTransportState;
91281190befe66e297d93ad0c7661d02d56f8f01f24Jim Miller        final boolean transportAdded = ensureTransportPresentOrRemoved(state);
91381190befe66e297d93ad0c7661d02d56f8f01f24Jim Miller        final int pageToShow = getAppropriateWidgetPage(state);
91481190befe66e297d93ad0c7661d02d56f8f01f24Jim Miller        if (!transportAdded) {
91581190befe66e297d93ad0c7661d02d56f8f01f24Jim Miller            mAppWidgetContainer.setCurrentPage(pageToShow);
91681190befe66e297d93ad0c7661d02d56f8f01f24Jim Miller        } else if (state == TRANSPORT_VISIBLE) {
91781190befe66e297d93ad0c7661d02d56f8f01f24Jim Miller            // If the transport was just added, we need to wait for layout to happen before
91881190befe66e297d93ad0c7661d02d56f8f01f24Jim Miller            // we can set the current page.
91981190befe66e297d93ad0c7661d02d56f8f01f24Jim Miller            post(new Runnable() {
92081190befe66e297d93ad0c7661d02d56f8f01f24Jim Miller                @Override
92181190befe66e297d93ad0c7661d02d56f8f01f24Jim Miller                public void run() {
92281190befe66e297d93ad0c7661d02d56f8f01f24Jim Miller                    mAppWidgetContainer.setCurrentPage(pageToShow);
92381190befe66e297d93ad0c7661d02d56f8f01f24Jim Miller                }
92481190befe66e297d93ad0c7661d02d56f8f01f24Jim Miller            });
92581190befe66e297d93ad0c7661d02d56f8f01f24Jim Miller        }
926dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
927dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
9284894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller    /**
9294894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     * Examines the current state and adds the transport to the widget pager when the state changes.
9304894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     *
9314894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     * Showing the initial transport and keeping it around is a bit tricky because the signals
9324894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     * coming from music players aren't always clear. Here's how the states are handled:
9334894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     *
9344894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     * {@link TRANSPORT_GONE} means we have no reason to show the transport - remove it if present.
9354894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     *
9364894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     * {@link TRANSPORT_INVISIBLE} means we have potential to show the transport because a music
9374894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     * player is registered but not currently playing music (or we don't know the state yet). The
9384894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     * code adds it conditionally on play state.
9394894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     *
9404894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     * {@link #TRANSPORT_VISIBLE} means a music player is active and transport should be showing.
9414894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     *
9424894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     * Once the transport is showing, we always show it until keyguard is dismissed. This state is
9434894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     * maintained by onSave/RestoreInstanceState(). This state is cleared in
9444894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     * {@link KeyguardViewManager#hide} when keyguard is dismissed, which causes the transport to be
9454894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     * gone when keyguard is restarted until we get an update with the current state.
9464894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     *
9474894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     * @param state
9484894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller     */
94981190befe66e297d93ad0c7661d02d56f8f01f24Jim Miller    private boolean ensureTransportPresentOrRemoved(int state) {
9504894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller        final boolean showing = getWidgetPosition(R.id.keyguard_transport_control) != -1;
9514894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller        final boolean visible = state == TRANSPORT_VISIBLE;
9524894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller        final boolean shouldBeVisible = state == TRANSPORT_INVISIBLE && isMusicPlaying(state);
9534894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller        if (!showing && (visible || shouldBeVisible)) {
9544894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller            // insert to left of camera if it exists, otherwise after right-most widget
9554894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller            int lastWidget = mAppWidgetContainer.getChildCount() - 1;
9564894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller            int position = 0; // handle no widget case
9574894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller            if (lastWidget >= 0) {
9584894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller                position = mAppWidgetContainer.isCameraPage(lastWidget) ?
9594894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller                        lastWidget : lastWidget + 1;
9608f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            }
96181190befe66e297d93ad0c7661d02d56f8f01f24Jim Miller            if (DEBUGXPORT) Log.v(TAG, "add transport at " + position);
9624894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller            mAppWidgetContainer.addWidget(getOrCreateTransportControl(), position);
96381190befe66e297d93ad0c7661d02d56f8f01f24Jim Miller            return true;
9644894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller        } else if (showing && state == TRANSPORT_GONE) {
9658f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            if (DEBUGXPORT) Log.v(TAG, "remove transport");
9664894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller            mAppWidgetContainer.removeWidget(getOrCreateTransportControl());
9678f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller            mTransportControl = null;
96843a372f38ad642f86047e8112e3d43edb7300439Adam Powell            KeyguardUpdateMonitor.getInstance(getContext()).dispatchSetBackground(null);
9698f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        }
97081190befe66e297d93ad0c7661d02d56f8f01f24Jim Miller        return false;
9718f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller    }
9728f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller
973dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock    private CameraWidgetFrame findCameraPage() {
974dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock        for (int i = mAppWidgetContainer.getChildCount() - 1; i >= 0; i--) {
9756cf53bb3a94ec5a6eebc96a315dac32d042f1945Winson Chung            if (mAppWidgetContainer.isCameraPage(i)) {
976dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock                return (CameraWidgetFrame) mAppWidgetContainer.getChildAt(i);
977dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock            }
978dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock        }
979dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock        return null;
980dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock    }
981dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock
9826cf53bb3a94ec5a6eebc96a315dac32d042f1945Winson Chung    boolean isMusicPage(int pageIndex) {
9836cf53bb3a94ec5a6eebc96a315dac32d042f1945Winson Chung        return pageIndex >= 0 && pageIndex == getWidgetPosition(R.id.keyguard_transport_control);
9846cf53bb3a94ec5a6eebc96a315dac32d042f1945Winson Chung    }
9856cf53bb3a94ec5a6eebc96a315dac32d042f1945Winson Chung
9868f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller    private int getAppropriateWidgetPage(int musicTransportState) {
987358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock        // assumes at least one widget (besides camera + add)
98876017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka        if (mAppWidgetToShow != AppWidgetManager.INVALID_APPWIDGET_ID) {
98976017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka            final int childCount = mAppWidgetContainer.getChildCount();
99076017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka            for (int i = 0; i < childCount; i++) {
99176017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka                if (mAppWidgetContainer.getWidgetPageAt(i).getContentAppWidgetId()
99276017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka                        == mAppWidgetToShow) {
99376017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka                    return i;
99476017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka                }
99576017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka            }
99676017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka            mAppWidgetToShow = AppWidgetManager.INVALID_APPWIDGET_ID;
99776017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka        }
998358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock        // if music playing, show transport
9998f09fd2e3123c7713d50886dc3745d330a1879c5Jim Miller        if (musicTransportState == TRANSPORT_VISIBLE) {
1000358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock            if (DEBUG) Log.d(TAG, "Music playing, show transport");
10014894a016f41f7ccbaf3b2d03395ff6838bb0828cJim Miller            return mAppWidgetContainer.getWidgetPageIndex(getOrCreateTransportControl());
1002358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock        }
1003358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock
10045f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock        // else show the right-most widget (except for camera)
1005358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock        int rightMost = mAppWidgetContainer.getChildCount() - 1;
10066cf53bb3a94ec5a6eebc96a315dac32d042f1945Winson Chung        if (mAppWidgetContainer.isCameraPage(rightMost)) {
1007358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock            rightMost--;
1008358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock        }
10095f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock        if (DEBUG) Log.d(TAG, "Show right-most page " + rightMost);
1010358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock        return rightMost;
1011358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock    }
1012358148e386a20801430aaf6f3f7ca02807cd71c3John Spurlock
101319a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller    private void enableUserSelectorIfNecessary() {
1014f6ab5f9e3e7562b6ebb61ac149eb3cf9b08c443fJim Miller        final UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
1015d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren        if (um == null) {
1016d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren            Throwable t = new Throwable();
1017d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren            t.fillInStackTrace();
1018d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren            Log.e(TAG, "user service is null.", t);
1019d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren            return;
1020d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren        }
102126e6c2e44235428717d7152b9e6398649452f1d2Jim Miller
10225f050e5c2c1616c7f0795c4f13e42a5d150b8015John Spurlock        // if there are multiple users, we need to enable to multi-user switcher
10231a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy        if (!um.isUserSwitcherEnabled()) {
1024d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren            return;
1025d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren        }
102666b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen
1027f6ab5f9e3e7562b6ebb61ac149eb3cf9b08c443fJim Miller        final View multiUserView = findViewById(R.id.keyguard_user_selector);
1028f6ab5f9e3e7562b6ebb61ac149eb3cf9b08c443fJim Miller        if (multiUserView == null) {
10291a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy            if (DEBUG) Log.d(TAG, "can't find user_selector in layout.");
1030f6ab5f9e3e7562b6ebb61ac149eb3cf9b08c443fJim Miller            return;
1031f6ab5f9e3e7562b6ebb61ac149eb3cf9b08c443fJim Miller        }
1032f6ab5f9e3e7562b6ebb61ac149eb3cf9b08c443fJim Miller
10331a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy        if (multiUserView instanceof KeyguardMultiUserSelectorView) {
10341a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy            mKeyguardMultiUserSelectorView = (KeyguardMultiUserSelectorView) multiUserView;
10351a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy            mKeyguardMultiUserSelectorView.setVisibility(View.VISIBLE);
10361a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy            mKeyguardMultiUserSelectorView.addUsers(um.getUsers(true));
10371a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy            UserSwitcherCallback callback = new UserSwitcherCallback() {
10381a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy                @Override
10391a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy                public void hideSecurityView(int duration) {
10401a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy                    getSecurityContainer().animate().alpha(0).setDuration(duration);
10411a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy                }
104224b351ab748cf1b2e41d106508604ba09f62d859Adam Cohen
10431a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy                @Override
10441a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy                public void showSecurityView() {
10451a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy                    getSecurityContainer().setAlpha(1.0f);
10461a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy                }
10470a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen
10481a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy                @Override
10491a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy                public void showUnlockHint() {
10501a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy                    if (getSecurityContainer() != null) {
10511a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy                        getSecurityContainer().showUsabilityHint();
10520ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller                    }
10531a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy                }
10540a8d32673b3d34153c287916f0ca8d4439f3087eAdam Cohen
10551a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy                @Override
10561a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy                public void userActivity() {
10571a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy                    if (mViewMediatorCallback != null) {
10581a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy                        mViewMediatorCallback.userActivity();
105919a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                    }
1060d2dec00a0a072dd0e71b2194ce919cd134d926edChris Wren                }
10611a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy            };
10621a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy            mKeyguardMultiUserSelectorView.setCallback(callback);
10631a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy        } else {
10641a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy            Throwable t = new Throwable();
10651a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy            t.fillInStackTrace();
10661a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy            if (multiUserView == null) {
10671a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy                Log.e(TAG, "could not find the user_selector.", t);
10681a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy            } else {
10691a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy                Log.e(TAG, "user_selector is the wrong type.", t);
107091f080c77739e32f377e1a9cb5c8d0ec5d50138fChris Wren            }
107166b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen        }
107266b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen    }
107366b9fb1662b304d24984af1ac4cc02f2ae8f4cc3Adam Cohen
1074dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    @Override
1075dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    public void cleanUp() {
1076128f27632343ed8ad8bba2d96f4ec69c0e369de7Adam Cohen        // Make sure we let go of all widgets and their package contexts promptly. If we don't do
1077128f27632343ed8ad8bba2d96f4ec69c0e369de7Adam Cohen        // this, and the associated application is uninstalled, it can cause a soft reboot.
1078128f27632343ed8ad8bba2d96f4ec69c0e369de7Adam Cohen        int count = mAppWidgetContainer.getChildCount();
1079128f27632343ed8ad8bba2d96f4ec69c0e369de7Adam Cohen        for (int i = 0; i < count; i++) {
1080128f27632343ed8ad8bba2d96f4ec69c0e369de7Adam Cohen            KeyguardWidgetFrame frame = mAppWidgetContainer.getWidgetPageAt(i);
1081128f27632343ed8ad8bba2d96f4ec69c0e369de7Adam Cohen            frame.removeAllViews();
1082128f27632343ed8ad8bba2d96f4ec69c0e369de7Adam Cohen        }
10836f29b30dc28a66b8e1fb71884c777d995cab56aaJim Miller        getSecurityContainer().onPause(); // clean up any actions in progress
1084dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
1085dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
108676017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka    public void goToWidget(int appWidgetId) {
108776017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka        mAppWidgetToShow = appWidgetId;
108876017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka        mSwitchPageRunnable.run();
108976017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka    }
109076017cad4f7af95380ee5eaf6dc610bb46088a9cMichael Jurka
10913eb4971b679464e206cb666de1cf0e5a538c8d7dJim Miller    @Override
10923eb4971b679464e206cb666de1cf0e5a538c8d7dJim Miller    protected void showBouncer(boolean show) {
10933eb4971b679464e206cb666de1cf0e5a538c8d7dJim Miller        super.showBouncer(show);
10943eb4971b679464e206cb666de1cf0e5a538c8d7dJim Miller        mViewStateManager.showBouncer(show);
10954eeb4f664ac6b5901a8e874dcf70c0382295f792Jim Miller    }
1096caf24fc2c4bb9747eb80138bf3ce0be067851749Jim Miller
10975e612cf07872dc0989a4b9f09e2a38a2ee12186dJim Miller    @Override
10985e612cf07872dc0989a4b9f09e2a38a2ee12186dJim Miller    public void onExternalMotionEvent(MotionEvent event) {
1099caf24fc2c4bb9747eb80138bf3ce0be067851749Jim Miller        mAppWidgetContainer.handleExternalCameraEvent(event);
1100caf24fc2c4bb9747eb80138bf3ce0be067851749Jim Miller    }
1101caf24fc2c4bb9747eb80138bf3ce0be067851749Jim Miller
11025e612cf07872dc0989a4b9f09e2a38a2ee12186dJim Miller    @Override
11035e612cf07872dc0989a4b9f09e2a38a2ee12186dJim Miller    protected void onCreateOptions(Bundle options) {
11045e612cf07872dc0989a4b9f09e2a38a2ee12186dJim Miller        if (options != null) {
11055e612cf07872dc0989a4b9f09e2a38a2ee12186dJim Miller            int widgetToShow = options.getInt(LockPatternUtils.KEYGUARD_SHOW_APPWIDGET,
11065e612cf07872dc0989a4b9f09e2a38a2ee12186dJim Miller                    AppWidgetManager.INVALID_APPWIDGET_ID);
11075e612cf07872dc0989a4b9f09e2a38a2ee12186dJim Miller            if (widgetToShow != AppWidgetManager.INVALID_APPWIDGET_ID) {
11085e612cf07872dc0989a4b9f09e2a38a2ee12186dJim Miller                goToWidget(widgetToShow);
11095e612cf07872dc0989a4b9f09e2a38a2ee12186dJim Miller            }
11105e612cf07872dc0989a4b9f09e2a38a2ee12186dJim Miller        }
11115e612cf07872dc0989a4b9f09e2a38a2ee12186dJim Miller    }
11125e612cf07872dc0989a4b9f09e2a38a2ee12186dJim Miller
1113dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller}
1114