OSDN Git Service

Remove dead code #8: Remove old keyguard "bouncer"
[android-x86/frameworks-base.git] / packages / SystemUI / src / com / android / systemui / statusbar / phone / StatusBarKeyguardViewManager.java
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
17 package com.android.systemui.statusbar.phone;
18
19 import android.content.ComponentCallbacks2;
20 import android.content.Context;
21 import android.os.Bundle;
22 import android.os.RemoteException;
23 import android.os.SystemClock;
24 import android.util.Slog;
25 import android.view.KeyEvent;
26 import android.view.View;
27 import android.view.ViewGroup;
28 import android.view.WindowManagerGlobal;
29
30 import com.android.internal.policy.IKeyguardShowCallback;
31 import com.android.internal.widget.LockPatternUtils;
32 import com.android.keyguard.KeyguardUpdateMonitor;
33 import com.android.keyguard.ViewMediatorCallback;
34
35 import static com.android.keyguard.KeyguardHostView.OnDismissAction;
36
37 /**
38  * Manages creating, showing, hiding and resetting the keyguard within the status bar. Calls back
39  * via {@link ViewMediatorCallback} to poke the wake lock and report that the keyguard is done,
40  * which is in turn, reported to this class by the current
41  * {@link com.android.keyguard.KeyguardViewBase}.
42  */
43 public class StatusBarKeyguardViewManager {
44
45     // When hiding the Keyguard with timing supplied from WindowManager, better be early than late.
46     private static final long HIDE_TIMING_CORRECTION_MS = -3 * 16;
47
48     // Delay for showing the navigation bar when the bouncer appears. This should be kept in sync
49     // with the appear animations of the PIN/pattern/password views.
50     private static final long NAV_BAR_SHOW_DELAY_BOUNCER = 320;
51
52     private static String TAG = "StatusBarKeyguardViewManager";
53
54     private final Context mContext;
55
56     private LockPatternUtils mLockPatternUtils;
57     private ViewMediatorCallback mViewMediatorCallback;
58     private PhoneStatusBar mPhoneStatusBar;
59     private ScrimController mScrimController;
60
61     private ViewGroup mContainer;
62     private StatusBarWindowManager mStatusBarWindowManager;
63
64     private boolean mScreenOn = false;
65     private KeyguardBouncer mBouncer;
66     private boolean mShowing;
67     private boolean mOccluded;
68
69     private boolean mFirstUpdate = true;
70     private boolean mLastShowing;
71     private boolean mLastOccluded;
72     private boolean mLastBouncerShowing;
73     private boolean mLastBouncerDismissible;
74     private OnDismissAction mAfterKeyguardGoneAction;
75
76     public StatusBarKeyguardViewManager(Context context, ViewMediatorCallback callback,
77             LockPatternUtils lockPatternUtils) {
78         mContext = context;
79         mViewMediatorCallback = callback;
80         mLockPatternUtils = lockPatternUtils;
81     }
82
83     public void registerStatusBar(PhoneStatusBar phoneStatusBar,
84             ViewGroup container, StatusBarWindowManager statusBarWindowManager,
85             ScrimController scrimController) {
86         mPhoneStatusBar = phoneStatusBar;
87         mContainer = container;
88         mStatusBarWindowManager = statusBarWindowManager;
89         mScrimController = scrimController;
90         mBouncer = new KeyguardBouncer(mContext, mViewMediatorCallback, mLockPatternUtils,
91                 mStatusBarWindowManager, container);
92     }
93
94     /**
95      * Show the keyguard.  Will handle creating and attaching to the view manager
96      * lazily.
97      */
98     public void show(Bundle options) {
99         mShowing = true;
100         mStatusBarWindowManager.setKeyguardShowing(true);
101         reset();
102     }
103
104     /**
105      * Shows the notification keyguard or the bouncer depending on
106      * {@link KeyguardBouncer#needsFullscreenBouncer()}.
107      */
108     private void showBouncerOrKeyguard() {
109         if (mBouncer.needsFullscreenBouncer()) {
110
111             // The keyguard might be showing (already). So we need to hide it.
112             mPhoneStatusBar.hideKeyguard();
113             mBouncer.show(true /* resetSecuritySelection */);
114         } else {
115             mPhoneStatusBar.showKeyguard();
116             mBouncer.hide(false /* destroyView */);
117             mBouncer.prepare();
118         }
119     }
120
121     private void showBouncer() {
122         if (mShowing) {
123             mBouncer.show(false /* resetSecuritySelection */);
124         }
125         updateStates();
126     }
127
128     public void dismissWithAction(OnDismissAction r, boolean afterKeyguardGone) {
129         if (mShowing) {
130             if (!afterKeyguardGone) {
131                 mBouncer.showWithDismissAction(r);
132             } else {
133                 mBouncer.show(false /* resetSecuritySelection */);
134                 mAfterKeyguardGoneAction = r;
135             }
136         }
137         updateStates();
138     }
139
140     /**
141      * Reset the state of the view.
142      */
143     public void reset() {
144         if (mShowing) {
145             if (mOccluded) {
146                 mPhoneStatusBar.hideKeyguard();
147                 mBouncer.hide(false /* destroyView */);
148             } else {
149                 showBouncerOrKeyguard();
150             }
151             updateStates();
152         }
153     }
154
155     public void onScreenTurnedOff() {
156         mScreenOn = false;
157         mPhoneStatusBar.onScreenTurnedOff();
158         mBouncer.onScreenTurnedOff();
159     }
160
161     public void onScreenTurnedOn(final IKeyguardShowCallback callback) {
162         mScreenOn = true;
163         mPhoneStatusBar.onScreenTurnedOn();
164         if (callback != null) {
165             callbackAfterDraw(callback);
166         }
167     }
168
169     private void callbackAfterDraw(final IKeyguardShowCallback callback) {
170         mContainer.post(new Runnable() {
171             @Override
172             public void run() {
173                 try {
174                     callback.onShown(mContainer.getWindowToken());
175                 } catch (RemoteException e) {
176                     Slog.w(TAG, "Exception calling onShown():", e);
177                 }
178             }
179         });
180     }
181
182     public void verifyUnlock() {
183         dismiss();
184     }
185
186     public void setNeedsInput(boolean needsInput) {
187         mStatusBarWindowManager.setKeyguardNeedsInput(needsInput);
188     }
189
190     public void setOccluded(boolean occluded) {
191         if (occluded && !mOccluded && mShowing) {
192             if (mPhoneStatusBar.isInLaunchTransition()) {
193                 mOccluded = true;
194                 mPhoneStatusBar.fadeKeyguardAfterLaunchTransition(null /* beforeFading */,
195                         new Runnable() {
196                             @Override
197                             public void run() {
198                                 mStatusBarWindowManager.setKeyguardOccluded(mOccluded);
199                                 reset();
200                             }
201                         });
202                 return;
203             }
204         }
205         mOccluded = occluded;
206         mStatusBarWindowManager.setKeyguardOccluded(occluded);
207         reset();
208     }
209
210     public boolean isOccluded() {
211         return mOccluded;
212     }
213
214     /**
215      * Starts the animation before we dismiss Keyguard, i.e. an disappearing animation on the
216      * security view of the bouncer.
217      *
218      * @param finishRunnable the runnable to be run after the animation finished, or {@code null} if
219      *                       no action should be run
220      */
221     public void startPreHideAnimation(Runnable finishRunnable) {
222         if (mBouncer.isShowing()) {
223             mBouncer.startPreHideAnimation(finishRunnable);
224         } else if (finishRunnable != null) {
225             finishRunnable.run();
226         }
227     }
228
229     /**
230      * Hides the keyguard view
231      */
232     public void hide(long startTime, final long fadeoutDuration) {
233         mShowing = false;
234
235         long uptimeMillis = SystemClock.uptimeMillis();
236         long delay = Math.max(0, startTime + HIDE_TIMING_CORRECTION_MS - uptimeMillis);
237
238         if (mPhoneStatusBar.isInLaunchTransition() ) {
239             mPhoneStatusBar.fadeKeyguardAfterLaunchTransition(new Runnable() {
240                 @Override
241                 public void run() {
242                     mStatusBarWindowManager.setKeyguardShowing(false);
243                     mStatusBarWindowManager.setKeyguardFadingAway(true);
244                     mBouncer.hide(true /* destroyView */);
245                     updateStates();
246                     mScrimController.animateKeyguardFadingOut(
247                             PhoneStatusBar.FADE_KEYGUARD_START_DELAY,
248                             PhoneStatusBar.FADE_KEYGUARD_DURATION, null);
249                 }
250             }, new Runnable() {
251                 @Override
252                 public void run() {
253                     mPhoneStatusBar.hideKeyguard();
254                     mStatusBarWindowManager.setKeyguardFadingAway(false);
255                     mViewMediatorCallback.keyguardGone();
256                     executeAfterKeyguardGoneAction();
257                 }
258             });
259         } else {
260             mPhoneStatusBar.setKeyguardFadingAway(delay, fadeoutDuration);
261             boolean staying = mPhoneStatusBar.hideKeyguard();
262             if (!staying) {
263                 mStatusBarWindowManager.setKeyguardFadingAway(true);
264                 mScrimController.animateKeyguardFadingOut(delay, fadeoutDuration, new Runnable() {
265                     @Override
266                     public void run() {
267                         mStatusBarWindowManager.setKeyguardFadingAway(false);
268                         mPhoneStatusBar.finishKeyguardFadingAway();
269                         WindowManagerGlobal.getInstance().trimMemory(
270                                 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
271                     }
272                 });
273             } else {
274                 mScrimController.animateGoingToFullShade(delay, fadeoutDuration);
275                 mPhoneStatusBar.finishKeyguardFadingAway();
276             }
277             mStatusBarWindowManager.setKeyguardShowing(false);
278             mBouncer.hide(true /* destroyView */);
279             mViewMediatorCallback.keyguardGone();
280             executeAfterKeyguardGoneAction();
281             updateStates();
282         }
283
284     }
285
286     private void executeAfterKeyguardGoneAction() {
287         if (mAfterKeyguardGoneAction != null) {
288             mAfterKeyguardGoneAction.onDismiss();
289             mAfterKeyguardGoneAction = null;
290         }
291     }
292
293     /**
294      * Dismisses the keyguard by going to the next screen or making it gone.
295      */
296     public void dismiss() {
297         if (mScreenOn) {
298             showBouncer();
299         }
300     }
301
302     public boolean isSecure() {
303         return mBouncer.isSecure();
304     }
305
306     /**
307      * @return Whether the keyguard is showing
308      */
309     public boolean isShowing() {
310         return mShowing;
311     }
312
313     /**
314      * Notifies this manager that the back button has been pressed.
315      *
316      * @return whether the back press has been handled
317      */
318     public boolean onBackPressed() {
319         if (mBouncer.isShowing()) {
320             reset();
321             return true;
322         }
323         return false;
324     }
325
326     public boolean isBouncerShowing() {
327         return mBouncer.isShowing();
328     }
329
330     private long getNavBarShowDelay() {
331         if (mPhoneStatusBar.isKeyguardFadingAway()) {
332             return mPhoneStatusBar.getKeyguardFadingAwayDelay();
333         } else {
334
335             // Keyguard is not going away, thus we are showing the navigation bar because the
336             // bouncer is appearing.
337             return NAV_BAR_SHOW_DELAY_BOUNCER;
338         }
339     }
340
341     private Runnable mMakeNavigationBarVisibleRunnable = new Runnable() {
342         @Override
343         public void run() {
344             mPhoneStatusBar.getNavigationBarView().setVisibility(View.VISIBLE);
345         }
346     };
347
348     private void updateStates() {
349         int vis = mContainer.getSystemUiVisibility();
350         boolean showing = mShowing;
351         boolean occluded = mOccluded;
352         boolean bouncerShowing = mBouncer.isShowing();
353         boolean bouncerDismissible = !mBouncer.isFullscreenBouncer();
354
355         if ((bouncerDismissible || !showing) != (mLastBouncerDismissible || !mLastShowing)
356                 || mFirstUpdate) {
357             if (bouncerDismissible || !showing) {
358                 mContainer.setSystemUiVisibility(vis & ~View.STATUS_BAR_DISABLE_BACK);
359             } else {
360                 mContainer.setSystemUiVisibility(vis | View.STATUS_BAR_DISABLE_BACK);
361             }
362         }
363         if ((!(showing && !occluded) || bouncerShowing)
364                 != (!(mLastShowing && !mLastOccluded) || mLastBouncerShowing) || mFirstUpdate) {
365             if (mPhoneStatusBar.getNavigationBarView() != null) {
366                 if (!(showing && !occluded) || bouncerShowing) {
367                     mContainer.postOnAnimationDelayed(mMakeNavigationBarVisibleRunnable,
368                             getNavBarShowDelay());
369                 } else {
370                     mContainer.removeCallbacks(mMakeNavigationBarVisibleRunnable);
371                     mPhoneStatusBar.getNavigationBarView().setVisibility(View.GONE);
372                 }
373             }
374         }
375
376         if (bouncerShowing != mLastBouncerShowing || mFirstUpdate) {
377             mStatusBarWindowManager.setBouncerShowing(bouncerShowing);
378             mPhoneStatusBar.setBouncerShowing(bouncerShowing);
379             mScrimController.setBouncerShowing(bouncerShowing);
380         }
381
382         KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
383         if ((showing && !occluded) != (mLastShowing && !mLastOccluded) || mFirstUpdate) {
384             updateMonitor.sendKeyguardVisibilityChanged(showing && !occluded);
385         }
386         if (bouncerShowing != mLastBouncerShowing || mFirstUpdate) {
387             updateMonitor.sendKeyguardBouncerChanged(bouncerShowing);
388         }
389
390         mFirstUpdate = false;
391         mLastShowing = showing;
392         mLastOccluded = occluded;
393         mLastBouncerShowing = bouncerShowing;
394         mLastBouncerDismissible = bouncerDismissible;
395     }
396
397     public boolean onMenuPressed() {
398         return mBouncer.onMenuPressed();
399     }
400
401     public boolean interceptMediaKey(KeyEvent event) {
402         return mBouncer.interceptMediaKey(event);
403     }
404
405     public void onActivityDrawn() {
406         if (mPhoneStatusBar.isCollapsing()) {
407             mPhoneStatusBar.addPostCollapseAction(new Runnable() {
408                 @Override
409                 public void run() {
410                     mViewMediatorCallback.readyForKeyguardDone();
411                 }
412             });
413         } else {
414             mViewMediatorCallback.readyForKeyguardDone();
415         }
416     }
417
418     public boolean shouldDisableWindowAnimationsForUnlock() {
419         return mPhoneStatusBar.isInLaunchTransition();
420     }
421
422     public boolean isGoingToNotificationShade() {
423         return mPhoneStatusBar.isGoingToNotificationShade();
424     }
425
426     public boolean isSecure(int userId) {
427         return mBouncer.isSecure() || mLockPatternUtils.isSecure(userId);
428     }
429
430     public boolean isInputRestricted() {
431         return mViewMediatorCallback.isInputRestricted();
432     }
433 }