StatusBarKeyguardViewManager.java revision b601162a60663329355720083bfa199909dbf6ef
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        mBouncer.onScreenTurnedOff();
129    }
130
131    public void onScreenTurnedOn(final IKeyguardShowCallback callback) {
132        mScreenOn = true;
133        if (callback != null) {
134            callbackAfterDraw(callback);
135        }
136    }
137
138    private void callbackAfterDraw(final IKeyguardShowCallback callback) {
139        mContainer.post(new Runnable() {
140            @Override
141            public void run() {
142                try {
143                    callback.onShown(mContainer.getWindowToken());
144                } catch (RemoteException e) {
145                    Slog.w(TAG, "Exception calling onShown():", e);
146                }
147            }
148        });
149    }
150
151    public void verifyUnlock() {
152        dismiss();
153    }
154
155    public void setNeedsInput(boolean needsInput) {
156        mStatusBarWindowManager.setKeyguardNeedsInput(needsInput);
157    }
158
159    public void updateUserActivityTimeout() {
160        mStatusBarWindowManager.setKeyguardUserActivityTimeout(mBouncer.getUserActivityTimeout());
161    }
162
163    public void setOccluded(boolean occluded) {
164        mOccluded = occluded;
165        mStatusBarWindowManager.setKeyguardOccluded(occluded);
166        reset();
167    }
168
169    /**
170     * Hides the keyguard view
171     */
172    public void hide() {
173        mShowing = false;
174        mPhoneStatusBar.hideKeyguard();
175        mStatusBarWindowManager.setKeyguardShowing(false);
176        mBouncer.hide();
177        mViewMediatorCallback.keyguardGone();
178        updateStates();
179    }
180
181    /**
182     * Dismisses the keyguard by going to the next screen or making it gone.
183     */
184    public void dismiss() {
185        if (mScreenOn) {
186            showBouncer();
187        }
188    }
189
190    public boolean isSecure() {
191        return mBouncer.isSecure();
192    }
193
194    /**
195     * @return Whether the keyguard is showing
196     */
197    public boolean isShowing() {
198        return mShowing;
199    }
200
201    /**
202     * Notifies this manager that the back button has been pressed.
203     *
204     * @return whether the back press has been handled
205     */
206    public boolean onBackPressed() {
207        if (mBouncer.isShowing()) {
208            mBouncer.hide();
209            mPhoneStatusBar.showKeyguard();
210            updateStates();
211            return true;
212        }
213        return false;
214    }
215
216    private void updateStates() {
217        int vis = mContainer.getSystemUiVisibility();
218        boolean showing = mShowing;
219        boolean occluded = mOccluded;
220        boolean bouncerShowing = mBouncer.isShowing();
221        boolean bouncerDismissible = bouncerShowing && !mBouncer.needsFullscreenBouncer();
222
223        if ((bouncerDismissible || !showing) != (mLastBouncerDismissible || !mLastShowing)
224                || mFirstUpdate) {
225            if (bouncerDismissible || !showing) {
226                mContainer.setSystemUiVisibility(vis & ~View.STATUS_BAR_DISABLE_BACK);
227            } else {
228                mContainer.setSystemUiVisibility(vis | View.STATUS_BAR_DISABLE_BACK);
229            }
230        }
231        if ((!(showing && !occluded) || bouncerShowing)
232                != (!(mLastShowing && !mLastOccluded) || mLastBouncerShowing) || mFirstUpdate) {
233            if (mPhoneStatusBar.getNavigationBarView() != null) {
234                if (!(showing && !occluded) || bouncerShowing) {
235                    mPhoneStatusBar.getNavigationBarView().setVisibility(View.VISIBLE);
236                } else {
237                    mPhoneStatusBar.getNavigationBarView().setVisibility(View.GONE);
238                }
239            }
240        }
241
242        if (bouncerShowing != mLastBouncerShowing || mFirstUpdate) {
243            mStatusBarWindowManager.setBouncerShowing(bouncerShowing);
244            mPhoneStatusBar.setBouncerShowing(bouncerShowing);
245        }
246
247        KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
248        if ((showing && !occluded) != (mLastShowing && !mLastOccluded) || mFirstUpdate) {
249            updateMonitor.sendKeyguardVisibilityChanged(showing && !occluded);
250        }
251        if (bouncerShowing != mLastBouncerShowing || mFirstUpdate) {
252            updateMonitor.sendKeyguardBouncerChanged(bouncerShowing);
253        }
254
255        mFirstUpdate = false;
256        mLastShowing = showing;
257        mLastOccluded = occluded;
258        mLastBouncerShowing = bouncerShowing;
259        mLastBouncerDismissible = bouncerDismissible;
260    }
261
262    public boolean onMenuPressed() {
263        return mBouncer.onMenuPressed();
264    }
265
266    public boolean interceptMediaKey(KeyEvent event) {
267        return mBouncer.interceptMediaKey(event);
268    }
269}
270