StatusBarKeyguardViewManager.java revision 44cf91960d74eccec45b9adec291ddb8baf84b4d
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.os.SystemClock; 23import android.util.Slog; 24import android.view.KeyEvent; 25import android.view.View; 26import android.view.ViewGroup; 27 28import com.android.internal.policy.IKeyguardShowCallback; 29import com.android.internal.widget.LockPatternUtils; 30import com.android.keyguard.KeyguardUpdateMonitor; 31import com.android.keyguard.ViewMediatorCallback; 32 33import static com.android.keyguard.KeyguardHostView.OnDismissAction; 34 35/** 36 * Manages creating, showing, hiding and resetting the keyguard within the status bar. Calls back 37 * via {@link ViewMediatorCallback} to poke the wake lock and report that the keyguard is done, 38 * which is in turn, reported to this class by the current 39 * {@link com.android.keyguard.KeyguardViewBase}. 40 */ 41public class StatusBarKeyguardViewManager { 42 private static String TAG = "StatusBarKeyguardViewManager"; 43 44 private final Context mContext; 45 46 private LockPatternUtils mLockPatternUtils; 47 private ViewMediatorCallback mViewMediatorCallback; 48 private PhoneStatusBar mPhoneStatusBar; 49 private ScrimController mScrimController; 50 51 private ViewGroup mContainer; 52 private StatusBarWindowManager mStatusBarWindowManager; 53 54 private boolean mScreenOn = false; 55 private KeyguardBouncer mBouncer; 56 private boolean mShowing; 57 private boolean mOccluded; 58 59 private boolean mFirstUpdate = true; 60 private boolean mLastShowing; 61 private boolean mLastOccluded; 62 private boolean mLastBouncerShowing; 63 private boolean mLastBouncerDismissible; 64 65 public StatusBarKeyguardViewManager(Context context, ViewMediatorCallback callback, 66 LockPatternUtils lockPatternUtils) { 67 mContext = context; 68 mViewMediatorCallback = callback; 69 mLockPatternUtils = lockPatternUtils; 70 } 71 72 public void registerStatusBar(PhoneStatusBar phoneStatusBar, 73 ViewGroup container, StatusBarWindowManager statusBarWindowManager, 74 ScrimController scrimController) { 75 mPhoneStatusBar = phoneStatusBar; 76 mContainer = container; 77 mStatusBarWindowManager = statusBarWindowManager; 78 mScrimController = scrimController; 79 mBouncer = new KeyguardBouncer(mContext, mViewMediatorCallback, mLockPatternUtils, 80 mStatusBarWindowManager, container); 81 } 82 83 /** 84 * Show the keyguard. Will handle creating and attaching to the view manager 85 * lazily. 86 */ 87 public void show(Bundle options) { 88 mShowing = true; 89 mStatusBarWindowManager.setKeyguardShowing(true); 90 reset(); 91 } 92 93 /** 94 * Shows the notification keyguard or the bouncer depending on 95 * {@link KeyguardBouncer#needsFullscreenBouncer()}. 96 */ 97 private void showBouncerOrKeyguard() { 98 if (mBouncer.needsFullscreenBouncer()) { 99 100 // The keyguard might be showing (already). So we need to hide it. 101 mPhoneStatusBar.hideKeyguard(); 102 mBouncer.show(); 103 } else { 104 mPhoneStatusBar.showKeyguard(); 105 mBouncer.hide(false /* destroyView */); 106 mBouncer.prepare(); 107 } 108 } 109 110 private void showBouncer() { 111 if (!mOccluded) { 112 mBouncer.show(); 113 } 114 updateStates(); 115 } 116 117 public void dismissWithAction(OnDismissAction r) { 118 if (!mOccluded) { 119 mBouncer.showWithDismissAction(r); 120 } 121 updateStates(); 122 } 123 124 /** 125 * Reset the state of the view. 126 */ 127 public void reset() { 128 if (mShowing) { 129 if (mOccluded) { 130 mPhoneStatusBar.hideKeyguard(); 131 mBouncer.hide(false /* destroyView */); 132 } else { 133 showBouncerOrKeyguard(); 134 } 135 updateStates(); 136 } 137 } 138 139 public void onScreenTurnedOff() { 140 mScreenOn = false; 141 mPhoneStatusBar.onScreenTurnedOff(); 142 mBouncer.onScreenTurnedOff(); 143 } 144 145 public void onScreenTurnedOn(final IKeyguardShowCallback callback) { 146 mScreenOn = true; 147 mPhoneStatusBar.onScreenTurnedOn(); 148 if (callback != null) { 149 callbackAfterDraw(callback); 150 } 151 } 152 153 private void callbackAfterDraw(final IKeyguardShowCallback callback) { 154 mContainer.post(new Runnable() { 155 @Override 156 public void run() { 157 try { 158 callback.onShown(mContainer.getWindowToken()); 159 } catch (RemoteException e) { 160 Slog.w(TAG, "Exception calling onShown():", e); 161 } 162 } 163 }); 164 } 165 166 public void verifyUnlock() { 167 dismiss(); 168 } 169 170 public void setNeedsInput(boolean needsInput) { 171 mStatusBarWindowManager.setKeyguardNeedsInput(needsInput); 172 } 173 174 public void updateUserActivityTimeout() { 175 mStatusBarWindowManager.setKeyguardUserActivityTimeout(mBouncer.getUserActivityTimeout()); 176 } 177 178 public void setOccluded(boolean occluded) { 179 mOccluded = occluded; 180 mStatusBarWindowManager.setKeyguardOccluded(occluded); 181 reset(); 182 } 183 184 public boolean isOccluded() { 185 return mOccluded; 186 } 187 188 /** 189 * Hides the keyguard view 190 */ 191 public void hide(long startTime, long fadeoutDuration) { 192 mShowing = false; 193 194 long uptimeMillis = SystemClock.uptimeMillis(); 195 long delay = startTime - uptimeMillis; 196 if (delay < 0) { 197 delay = 0; 198 } 199 200 mPhoneStatusBar.setKeyguardFadingAway(delay, fadeoutDuration); 201 mPhoneStatusBar.hideKeyguard(); 202 mStatusBarWindowManager.setKeyguardFadingAway(true); 203 mStatusBarWindowManager.setKeyguardShowing(false); 204 mBouncer.animateHide(delay, fadeoutDuration); 205 mScrimController.animateKeyguardFadingOut(delay, fadeoutDuration, new Runnable() { 206 @Override 207 public void run() { 208 mStatusBarWindowManager.setKeyguardFadingAway(false); 209 mPhoneStatusBar.finishKeyguardFadingAway(); 210 } 211 }); 212 mViewMediatorCallback.keyguardGone(); 213 updateStates(); 214 } 215 216 /** 217 * Dismisses the keyguard by going to the next screen or making it gone. 218 */ 219 public void dismiss() { 220 if (mScreenOn) { 221 showBouncer(); 222 } 223 } 224 225 public boolean isSecure() { 226 return mBouncer.isSecure(); 227 } 228 229 /** 230 * @return Whether the keyguard is showing 231 */ 232 public boolean isShowing() { 233 return mShowing; 234 } 235 236 /** 237 * Notifies this manager that the back button has been pressed. 238 * 239 * @return whether the back press has been handled 240 */ 241 public boolean onBackPressed() { 242 if (mBouncer.isShowing()) { 243 mBouncer.hide(false /* destroyView */); 244 mPhoneStatusBar.showKeyguard(); 245 updateStates(); 246 return true; 247 } 248 return false; 249 } 250 251 private void updateStates() { 252 int vis = mContainer.getSystemUiVisibility(); 253 boolean showing = mShowing; 254 boolean occluded = mOccluded; 255 boolean bouncerShowing = mBouncer.isShowing(); 256 boolean bouncerDismissible = bouncerShowing && !mBouncer.needsFullscreenBouncer(); 257 258 if ((bouncerDismissible || !showing) != (mLastBouncerDismissible || !mLastShowing) 259 || mFirstUpdate) { 260 if (bouncerDismissible || !showing) { 261 mContainer.setSystemUiVisibility(vis & ~View.STATUS_BAR_DISABLE_BACK); 262 } else { 263 mContainer.setSystemUiVisibility(vis | View.STATUS_BAR_DISABLE_BACK); 264 } 265 } 266 if ((!(showing && !occluded) || bouncerShowing) 267 != (!(mLastShowing && !mLastOccluded) || mLastBouncerShowing) || mFirstUpdate) { 268 if (mPhoneStatusBar.getNavigationBarView() != null) { 269 if (!(showing && !occluded) || bouncerShowing) { 270 mPhoneStatusBar.getNavigationBarView().setVisibility(View.VISIBLE); 271 } else { 272 mPhoneStatusBar.getNavigationBarView().setVisibility(View.GONE); 273 } 274 } 275 } 276 277 if (bouncerShowing != mLastBouncerShowing || mFirstUpdate) { 278 mStatusBarWindowManager.setBouncerShowing(bouncerShowing); 279 mPhoneStatusBar.setBouncerShowing(bouncerShowing); 280 mScrimController.setBouncerShowing(bouncerShowing); 281 } 282 283 KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext); 284 if ((showing && !occluded) != (mLastShowing && !mLastOccluded) || mFirstUpdate) { 285 updateMonitor.sendKeyguardVisibilityChanged(showing && !occluded); 286 } 287 if (bouncerShowing != mLastBouncerShowing || mFirstUpdate) { 288 updateMonitor.sendKeyguardBouncerChanged(bouncerShowing); 289 } 290 291 mFirstUpdate = false; 292 mLastShowing = showing; 293 mLastOccluded = occluded; 294 mLastBouncerShowing = bouncerShowing; 295 mLastBouncerDismissible = bouncerDismissible; 296 } 297 298 public boolean onMenuPressed() { 299 return mBouncer.onMenuPressed(); 300 } 301 302 public boolean interceptMediaKey(KeyEvent event) { 303 return mBouncer.interceptMediaKey(event); 304 } 305} 306