StatusBarKeyguardViewManager.java revision 75c95044a8c5c073d30dcc9bd21157939f161043
1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
15 */
16
17package com.android.systemui.statusbar.phone;
18
19import android.content.Context;
20import android.os.Bundle;
21import android.os.RemoteException;
22import android.util.Slog;
23import android.view.KeyEvent;
24import android.view.View;
25import android.view.ViewGroup;
26
27import com.android.internal.policy.IKeyguardShowCallback;
28import com.android.internal.widget.LockPatternUtils;
29import com.android.keyguard.KeyguardUpdateMonitor;
30import com.android.keyguard.ViewMediatorCallback;
31
32/**
33 * Manages creating, showing, hiding and resetting the keyguard within the status bar. Calls back
34 * via {@link ViewMediatorCallback} to poke the wake lock and report that the keyguard is done,
35 * which is in turn, reported to this class by the current
36 * {@link com.android.keyguard.KeyguardViewBase}.
37 */
38public class StatusBarKeyguardViewManager {
39    private static String TAG = "StatusBarKeyguardViewManager";
40
41    private final Context mContext;
42
43    private LockPatternUtils mLockPatternUtils;
44    private ViewMediatorCallback mViewMediatorCallback;
45    private PhoneStatusBar mPhoneStatusBar;
46
47    private ViewGroup mContainer;
48    private StatusBarWindowManager mStatusBarWindowManager;
49
50    private boolean mScreenOn = false;
51    private KeyguardBouncer mBouncer;
52    private boolean mShowing;
53    private boolean mOccluded;
54
55    private boolean mFirstUpdate = true;
56    private boolean mLastShowing;
57    private boolean mLastOccluded;
58    private boolean mLastBouncerShowing;
59    private boolean mLastBouncerDismissible;
60
61    public StatusBarKeyguardViewManager(Context context, ViewMediatorCallback callback,
62            LockPatternUtils lockPatternUtils) {
63        mContext = context;
64        mViewMediatorCallback = callback;
65        mLockPatternUtils = lockPatternUtils;
66    }
67
68    public void registerStatusBar(PhoneStatusBar phoneStatusBar,
69            ViewGroup container, StatusBarWindowManager statusBarWindowManager) {
70        mPhoneStatusBar = phoneStatusBar;
71        mContainer = container;
72        mStatusBarWindowManager = statusBarWindowManager;
73        mBouncer = new KeyguardBouncer(mContext, mViewMediatorCallback, mLockPatternUtils,
74                mStatusBarWindowManager, container);
75    }
76
77    /**
78     * Show the keyguard.  Will handle creating and attaching to the view manager
79     * lazily.
80     */
81    public void show(Bundle options) {
82        mShowing = true;
83        mStatusBarWindowManager.setKeyguardShowing(true);
84        reset();
85    }
86
87    /**
88     * Shows the notification keyguard or the bouncer depending on
89     * {@link KeyguardBouncer#needsFullscreenBouncer()}.
90     */
91    private void showBouncerOrKeyguard() {
92        if (mBouncer.needsFullscreenBouncer()) {
93
94            // The keyguard might be showing (already). So we need to hide it.
95            mPhoneStatusBar.hideKeyguard();
96            mBouncer.show();
97        } else {
98            mPhoneStatusBar.showKeyguard();
99            mBouncer.hide();
100            mBouncer.prepare();
101        }
102    }
103
104    private void showBouncer() {
105        if (!mOccluded) {
106            mBouncer.show();
107        }
108        updateStates();
109    }
110
111    /**
112     * Reset the state of the view.
113     */
114    public void reset() {
115        if (mShowing) {
116            if (mOccluded) {
117                mPhoneStatusBar.hideKeyguard();
118                mBouncer.hide();
119            } else {
120                showBouncerOrKeyguard();
121            }
122            updateStates();
123        }
124    }
125
126    public void onScreenTurnedOff() {
127        mScreenOn = false;
128        mPhoneStatusBar.onScreenTurnedOff();
129        mBouncer.onScreenTurnedOff();
130    }
131
132    public void onScreenTurnedOn(final IKeyguardShowCallback callback) {
133        mScreenOn = true;
134        mPhoneStatusBar.onScreenTurnedOn();
135        if (callback != null) {
136            callbackAfterDraw(callback);
137        }
138    }
139
140    private void callbackAfterDraw(final IKeyguardShowCallback callback) {
141        mContainer.post(new Runnable() {
142            @Override
143            public void run() {
144                try {
145                    callback.onShown(mContainer.getWindowToken());
146                } catch (RemoteException e) {
147                    Slog.w(TAG, "Exception calling onShown():", e);
148                }
149            }
150        });
151    }
152
153    public void verifyUnlock() {
154        dismiss();
155    }
156
157    public void setNeedsInput(boolean needsInput) {
158        mStatusBarWindowManager.setKeyguardNeedsInput(needsInput);
159    }
160
161    public void updateUserActivityTimeout() {
162        mStatusBarWindowManager.setKeyguardUserActivityTimeout(mBouncer.getUserActivityTimeout());
163    }
164
165    public void setOccluded(boolean occluded) {
166        mOccluded = occluded;
167        mStatusBarWindowManager.setKeyguardOccluded(occluded);
168        reset();
169    }
170
171    /**
172     * Hides the keyguard view
173     */
174    public void hide() {
175        mShowing = false;
176        mPhoneStatusBar.hideKeyguard();
177        mStatusBarWindowManager.setKeyguardShowing(false);
178        mBouncer.hide();
179        mViewMediatorCallback.keyguardGone();
180        updateStates();
181    }
182
183    /**
184     * Dismisses the keyguard by going to the next screen or making it gone.
185     */
186    public void dismiss() {
187        if (mScreenOn) {
188            showBouncer();
189        }
190    }
191
192    public boolean isSecure() {
193        return mBouncer.isSecure();
194    }
195
196    /**
197     * @return Whether the keyguard is showing
198     */
199    public boolean isShowing() {
200        return mShowing;
201    }
202
203    /**
204     * Notifies this manager that the back button has been pressed.
205     *
206     * @return whether the back press has been handled
207     */
208    public boolean onBackPressed() {
209        if (mBouncer.isShowing()) {
210            mBouncer.hide();
211            mPhoneStatusBar.showKeyguard();
212            updateStates();
213            return true;
214        }
215        return false;
216    }
217
218    private void updateStates() {
219        int vis = mContainer.getSystemUiVisibility();
220        boolean showing = mShowing;
221        boolean occluded = mOccluded;
222        boolean bouncerShowing = mBouncer.isShowing();
223        boolean bouncerDismissible = bouncerShowing && !mBouncer.needsFullscreenBouncer();
224
225        if ((bouncerDismissible || !showing) != (mLastBouncerDismissible || !mLastShowing)
226                || mFirstUpdate) {
227            if (bouncerDismissible || !showing) {
228                mContainer.setSystemUiVisibility(vis & ~View.STATUS_BAR_DISABLE_BACK);
229            } else {
230                mContainer.setSystemUiVisibility(vis | View.STATUS_BAR_DISABLE_BACK);
231            }
232        }
233        if ((!(showing && !occluded) || bouncerShowing)
234                != (!(mLastShowing && !mLastOccluded) || mLastBouncerShowing) || mFirstUpdate) {
235            if (mPhoneStatusBar.getNavigationBarView() != null) {
236                if (!(showing && !occluded) || bouncerShowing) {
237                    mPhoneStatusBar.getNavigationBarView().setVisibility(View.VISIBLE);
238                } else {
239                    mPhoneStatusBar.getNavigationBarView().setVisibility(View.GONE);
240                }
241            }
242        }
243
244        if (bouncerShowing != mLastBouncerShowing || mFirstUpdate) {
245            mStatusBarWindowManager.setBouncerShowing(bouncerShowing);
246            mPhoneStatusBar.setBouncerShowing(bouncerShowing);
247        }
248
249        KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
250        if ((showing && !occluded) != (mLastShowing && !mLastOccluded) || mFirstUpdate) {
251            updateMonitor.sendKeyguardVisibilityChanged(showing && !occluded);
252        }
253        if (bouncerShowing != mLastBouncerShowing || mFirstUpdate) {
254            updateMonitor.sendKeyguardBouncerChanged(bouncerShowing);
255        }
256
257        mFirstUpdate = false;
258        mLastShowing = showing;
259        mLastOccluded = occluded;
260        mLastBouncerShowing = bouncerShowing;
261        mLastBouncerDismissible = bouncerDismissible;
262    }
263
264    public boolean onMenuPressed() {
265        return mBouncer.onMenuPressed();
266    }
267
268    public boolean interceptMediaKey(KeyEvent event) {
269        return mBouncer.interceptMediaKey(event);
270    }
271}
272