1 /* 2 * Copyright (C) 2017 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.graphics.Color; 20 import android.os.Trace; 21 22 import com.android.systemui.dock.DockManager; 23 import com.android.systemui.res.R; 24 import com.android.systemui.scrim.ScrimView; 25 import com.android.systemui.statusbar.notification.stack.StackStateAnimator; 26 27 /** 28 * Possible states of the ScrimController state machine. 29 */ 30 public enum ScrimState { 31 32 /** 33 * Initial state. 34 */ 35 UNINITIALIZED, 36 37 /** 38 * When turned off by sensors (prox, presence.) 39 */ 40 OFF { 41 @Override prepare(ScrimState previousState)42 public void prepare(ScrimState previousState) { 43 mFrontTint = mBackgroundColor; 44 mBehindTint = mBackgroundColor; 45 46 mFrontAlpha = 1f; 47 mBehindAlpha = 1f; 48 49 if (previousState == AOD) { 50 mAnimateChange = false; 51 } else { 52 mAnimationDuration = ScrimController.ANIMATION_DURATION_LONG; 53 } 54 } 55 56 @Override isLowPowerState()57 public boolean isLowPowerState() { 58 return true; 59 } 60 }, 61 62 /** 63 * On the lock screen. 64 */ 65 KEYGUARD { 66 @Override prepare(ScrimState previousState)67 public void prepare(ScrimState previousState) { 68 mBlankScreen = false; 69 if (previousState == ScrimState.AOD) { 70 mAnimationDuration = StackStateAnimator.ANIMATION_DURATION_WAKEUP_SCRIM; 71 if (mDisplayRequiresBlanking) { 72 // DisplayPowerManager will blank the screen, we'll just 73 // set our scrim to black in this frame to avoid flickering and 74 // fade it out afterwards. 75 mBlankScreen = true; 76 } 77 } else if (previousState == ScrimState.KEYGUARD) { 78 mAnimationDuration = StackStateAnimator.ANIMATION_DURATION_WAKEUP_SCRIM; 79 } else { 80 mAnimationDuration = ScrimController.ANIMATION_DURATION; 81 } 82 mFrontTint = mBackgroundColor; 83 mBehindTint = mBackgroundColor; 84 mNotifTint = mClipQsScrim ? mBackgroundColor : Color.TRANSPARENT; 85 86 mFrontAlpha = 0; 87 mBehindAlpha = mClipQsScrim ? 1 : mScrimBehindAlphaKeyguard; 88 mNotifAlpha = mClipQsScrim ? mScrimBehindAlphaKeyguard : 0; 89 if (mClipQsScrim) { 90 updateScrimColor(mScrimBehind, 1f /* alpha */, mBackgroundColor); 91 } 92 } 93 }, 94 95 AUTH_SCRIMMED_SHADE { 96 @Override prepare(ScrimState previousState)97 public void prepare(ScrimState previousState) { 98 // notif scrim alpha values are determined by ScrimController#applyState 99 // based on the shade expansion 100 101 mFrontTint = mBackgroundColor; 102 mFrontAlpha = .66f; 103 104 mBehindTint = mBackgroundColor; 105 mBehindAlpha = 1f; 106 } 107 }, 108 109 AUTH_SCRIMMED { 110 @Override prepare(ScrimState previousState)111 public void prepare(ScrimState previousState) { 112 mNotifTint = previousState.mNotifTint; 113 mNotifAlpha = previousState.mNotifAlpha; 114 115 mBehindTint = previousState.mBehindTint; 116 mBehindAlpha = previousState.mBehindAlpha; 117 118 mFrontTint = mBackgroundColor; 119 mFrontAlpha = .66f; 120 } 121 }, 122 123 /** 124 * Showing password challenge on the keyguard. 125 */ 126 BOUNCER { 127 @Override prepare(ScrimState previousState)128 public void prepare(ScrimState previousState) { 129 mBehindAlpha = mClipQsScrim ? 1 : mDefaultScrimAlpha; 130 mBehindTint = mClipQsScrim ? mBackgroundColor : mSurfaceColor; 131 mNotifAlpha = mClipQsScrim ? mDefaultScrimAlpha : 0; 132 mNotifTint = Color.TRANSPARENT; 133 mFrontAlpha = 0f; 134 } 135 136 @Override setSurfaceColor(int surfaceColor)137 public void setSurfaceColor(int surfaceColor) { 138 super.setSurfaceColor(surfaceColor); 139 if (!mClipQsScrim) { 140 mBehindTint = mSurfaceColor; 141 } 142 } 143 }, 144 145 /** 146 * Showing password challenge on top of a FLAG_SHOW_WHEN_LOCKED activity. 147 */ 148 BOUNCER_SCRIMMED { 149 @Override prepare(ScrimState previousState)150 public void prepare(ScrimState previousState) { 151 mBehindAlpha = 0; 152 mFrontAlpha = mDefaultScrimAlpha; 153 } 154 }, 155 156 SHADE_LOCKED { 157 @Override prepare(ScrimState previousState)158 public void prepare(ScrimState previousState) { 159 mBehindAlpha = mClipQsScrim ? 1 : mDefaultScrimAlpha; 160 mNotifAlpha = 1f; 161 mFrontAlpha = 0f; 162 mBehindTint = mClipQsScrim ? Color.TRANSPARENT : mBackgroundColor; 163 164 if (mClipQsScrim) { 165 updateScrimColor(mScrimBehind, 1f /* alpha */, mBackgroundColor); 166 } 167 } 168 }, 169 170 /** 171 * Changing screen brightness from quick settings. 172 */ 173 BRIGHTNESS_MIRROR { 174 @Override prepare(ScrimState previousState)175 public void prepare(ScrimState previousState) { 176 mBehindAlpha = 0; 177 mFrontAlpha = 0; 178 } 179 }, 180 181 /** 182 * Always on display or screen off. 183 */ 184 AOD { 185 @Override prepare(ScrimState previousState)186 public void prepare(ScrimState previousState) { 187 final boolean alwaysOnEnabled = mDozeParameters.getAlwaysOn(); 188 final boolean quickPickupEnabled = mDozeParameters.isQuickPickupEnabled(); 189 final boolean isDocked = mDockManager.isDocked(); 190 mBlankScreen = mDisplayRequiresBlanking; 191 192 mFrontTint = mBackgroundColor; 193 mFrontAlpha = (alwaysOnEnabled || isDocked || quickPickupEnabled) 194 ? mAodFrontScrimAlpha : 1f; 195 196 mBehindTint = mBackgroundColor; 197 mBehindAlpha = ScrimController.TRANSPARENT; 198 199 mAnimationDuration = ScrimController.ANIMATION_DURATION_LONG; 200 if (previousState == OFF) { 201 mAnimateChange = false; 202 } else { 203 // DisplayPowerManager may blank the screen for us, or we might blank it by 204 // animating the screen off via the LightRevelScrim. In either case we just need to 205 // set our state. 206 mAnimateChange = mDozeParameters.shouldControlScreenOff() 207 && !mDozeParameters.shouldShowLightRevealScrim(); 208 } 209 } 210 211 @Override getMaxLightRevealScrimAlpha()212 public float getMaxLightRevealScrimAlpha() { 213 return mWallpaperSupportsAmbientMode && !mHasBackdrop ? 0f : 1f; 214 } 215 216 @Override isLowPowerState()217 public boolean isLowPowerState() { 218 return true; 219 } 220 221 @Override shouldBlendWithMainColor()222 public boolean shouldBlendWithMainColor() { 223 return false; 224 } 225 }, 226 227 /** 228 * When phone wakes up because you received a notification. 229 */ 230 PULSING { 231 @Override prepare(ScrimState previousState)232 public void prepare(ScrimState previousState) { 233 mFrontAlpha = mAodFrontScrimAlpha; 234 mBehindTint = mBackgroundColor; 235 mFrontTint = mBackgroundColor; 236 mBlankScreen = mDisplayRequiresBlanking; 237 mAnimationDuration = mWakeLockScreenSensorActive 238 ? ScrimController.ANIMATION_DURATION_LONG : ScrimController.ANIMATION_DURATION; 239 } 240 @Override getMaxLightRevealScrimAlpha()241 public float getMaxLightRevealScrimAlpha() { 242 return mWakeLockScreenSensorActive ? ScrimController.WAKE_SENSOR_SCRIM_ALPHA 243 : AOD.getMaxLightRevealScrimAlpha(); 244 } 245 }, 246 247 /** 248 * Unlocked on top of an app (launcher or any other activity.) 249 */ 250 UNLOCKED { 251 @Override prepare(ScrimState previousState)252 public void prepare(ScrimState previousState) { 253 // State that UI will sync to. 254 mBehindAlpha = mClipQsScrim ? 1 : 0; 255 mNotifAlpha = 0; 256 mFrontAlpha = 0; 257 mAnimationDuration = mKeyguardFadingAway 258 ? mKeyguardFadingAwayDuration 259 : CentralSurfaces.FADE_KEYGUARD_DURATION; 260 261 boolean fromAod = previousState == AOD || previousState == PULSING; 262 // If launch/occlude animations were playing, they already animated the scrim 263 // alpha to 0f as part of the animation. If we animate it now, we'll set it back 264 // to 1f and animate it back to 0f, causing an unwanted scrim flash. 265 mAnimateChange = !mLaunchingAffordanceWithPreview 266 && !mOccludeAnimationPlaying 267 && !fromAod; 268 269 mFrontTint = Color.TRANSPARENT; 270 mBehindTint = mBackgroundColor; 271 mBlankScreen = false; 272 273 if (mDisplayRequiresBlanking && previousState == ScrimState.AOD) { 274 // Set all scrims black, before they fade transparent. 275 updateScrimColor(mScrimInFront, 1f /* alpha */, mBackgroundColor /* tint */); 276 updateScrimColor(mScrimBehind, 1f /* alpha */, mBackgroundColor /* tint */); 277 278 // Scrims should still be black at the end of the transition. 279 mFrontTint = mBackgroundColor; 280 mBehindTint = mBackgroundColor; 281 mBlankScreen = true; 282 } 283 284 if (mClipQsScrim) { 285 updateScrimColor(mScrimBehind, 1f /* alpha */, mBackgroundColor); 286 } 287 } 288 }, 289 290 DREAMING { 291 @Override prepare(ScrimState previousState)292 public void prepare(ScrimState previousState) { 293 mFrontTint = Color.TRANSPARENT; 294 mBehindTint = mBackgroundColor; 295 mNotifTint = mClipQsScrim ? mBackgroundColor : Color.TRANSPARENT; 296 297 mFrontAlpha = 0; 298 mBehindAlpha = mClipQsScrim ? 1 : 0; 299 mNotifAlpha = 0; 300 301 mBlankScreen = false; 302 303 if (mClipQsScrim) { 304 updateScrimColor(mScrimBehind, 1f /* alpha */, mBackgroundColor); 305 } 306 } 307 }, 308 309 /** 310 * Device is on the lockscreen and user has swiped from the right edge to enter the glanceable 311 * hub UI. From this state, the user can swipe from the left edge to go back to the lock screen, 312 * as well as swipe down for the notifications and up for the bouncer. 313 */ 314 GLANCEABLE_HUB { 315 @Override prepare(ScrimState previousState)316 public void prepare(ScrimState previousState) { 317 // No scrims should be visible by default in this state. 318 mBehindAlpha = 0; 319 mNotifAlpha = 0; 320 mFrontAlpha = 0; 321 322 mFrontTint = Color.TRANSPARENT; 323 mBehindTint = mBackgroundColor; 324 mNotifTint = mClipQsScrim ? mBackgroundColor : Color.TRANSPARENT; 325 } 326 }, 327 328 /** 329 * Device is dreaming and user has swiped from the right edge to enter the glanceable hub UI. 330 * From this state, the user can swipe from the left edge to go back to the dream, as well as 331 * swipe down for the notifications and up for the bouncer. 332 * 333 * This is a separate state from {@link #GLANCEABLE_HUB} because the scrims behave differently 334 * when the dream is running. 335 */ 336 GLANCEABLE_HUB_OVER_DREAM { 337 @Override prepare(ScrimState previousState)338 public void prepare(ScrimState previousState) { 339 // No scrims should be visible by default in this state. 340 mBehindAlpha = 0; 341 mNotifAlpha = 0; 342 mFrontAlpha = 0; 343 344 mFrontTint = Color.TRANSPARENT; 345 mBehindTint = mBackgroundColor; 346 mNotifTint = mClipQsScrim ? mBackgroundColor : Color.TRANSPARENT; 347 } 348 }; 349 350 boolean mBlankScreen = false; 351 long mAnimationDuration = ScrimController.ANIMATION_DURATION; 352 int mFrontTint = Color.TRANSPARENT; 353 int mBehindTint = Color.TRANSPARENT; 354 int mNotifTint = Color.TRANSPARENT; 355 int mSurfaceColor = Color.TRANSPARENT; 356 357 boolean mAnimateChange = true; 358 float mAodFrontScrimAlpha; 359 float mFrontAlpha; 360 float mBehindAlpha; 361 float mNotifAlpha; 362 363 float mScrimBehindAlphaKeyguard; 364 float mDefaultScrimAlpha; 365 ScrimView mScrimInFront; 366 ScrimView mScrimBehind; 367 368 DozeParameters mDozeParameters; 369 DockManager mDockManager; 370 boolean mDisplayRequiresBlanking; 371 boolean mWallpaperSupportsAmbientMode; 372 boolean mHasBackdrop; 373 boolean mLaunchingAffordanceWithPreview; 374 boolean mOccludeAnimationPlaying; 375 boolean mWakeLockScreenSensorActive; 376 boolean mKeyguardFadingAway; 377 long mKeyguardFadingAwayDuration; 378 boolean mClipQsScrim; 379 int mBackgroundColor; 380 init(ScrimView scrimInFront, ScrimView scrimBehind, DozeParameters dozeParameters, DockManager dockManager)381 public void init(ScrimView scrimInFront, ScrimView scrimBehind, DozeParameters dozeParameters, 382 DockManager dockManager) { 383 mBackgroundColor = scrimBehind.getContext().getColor(R.color.shade_scrim_background_dark); 384 mScrimInFront = scrimInFront; 385 mScrimBehind = scrimBehind; 386 387 mDozeParameters = dozeParameters; 388 mDockManager = dockManager; 389 mDisplayRequiresBlanking = dozeParameters.getDisplayNeedsBlanking(); 390 } 391 392 /** Prepare state for transition. */ prepare(ScrimState previousState)393 public void prepare(ScrimState previousState) { 394 } 395 396 /** 397 * Whether a particular state should enable blending with extracted theme colors. 398 */ shouldBlendWithMainColor()399 public boolean shouldBlendWithMainColor() { 400 return true; 401 } 402 getFrontAlpha()403 public float getFrontAlpha() { 404 return mFrontAlpha; 405 } 406 getBehindAlpha()407 public float getBehindAlpha() { 408 return mBehindAlpha; 409 } 410 getMaxLightRevealScrimAlpha()411 public float getMaxLightRevealScrimAlpha() { 412 return 1f; 413 } 414 getNotifAlpha()415 public float getNotifAlpha() { 416 return mNotifAlpha; 417 } 418 getFrontTint()419 public int getFrontTint() { 420 return mFrontTint; 421 } 422 getBehindTint()423 public int getBehindTint() { 424 return mBehindTint; 425 } 426 getNotifTint()427 public int getNotifTint() { 428 return mNotifTint; 429 } 430 getAnimationDuration()431 public long getAnimationDuration() { 432 return mAnimationDuration; 433 } 434 getBlanksScreen()435 public boolean getBlanksScreen() { 436 return mBlankScreen; 437 } 438 updateScrimColor(ScrimView scrim, float alpha, int tint)439 public void updateScrimColor(ScrimView scrim, float alpha, int tint) { 440 if (ScrimController.DEBUG_MODE) { 441 tint = scrim == mScrimInFront ? ScrimController.DEBUG_FRONT_TINT 442 : ScrimController.DEBUG_BEHIND_TINT; 443 } 444 Trace.traceCounter(Trace.TRACE_TAG_APP, 445 scrim == mScrimInFront ? "front_scrim_alpha" : "back_scrim_alpha", 446 (int) (alpha * 255)); 447 448 Trace.traceCounter(Trace.TRACE_TAG_APP, 449 scrim == mScrimInFront ? "front_scrim_tint" : "back_scrim_tint", 450 Color.alpha(tint)); 451 452 scrim.setTint(tint); 453 scrim.setViewAlpha(alpha); 454 } 455 getAnimateChange()456 public boolean getAnimateChange() { 457 return mAnimateChange; 458 } 459 setAodFrontScrimAlpha(float aodFrontScrimAlpha)460 public void setAodFrontScrimAlpha(float aodFrontScrimAlpha) { 461 mAodFrontScrimAlpha = aodFrontScrimAlpha; 462 } 463 setScrimBehindAlphaKeyguard(float scrimBehindAlphaKeyguard)464 public void setScrimBehindAlphaKeyguard(float scrimBehindAlphaKeyguard) { 465 mScrimBehindAlphaKeyguard = scrimBehindAlphaKeyguard; 466 } 467 setDefaultScrimAlpha(float defaultScrimAlpha)468 public void setDefaultScrimAlpha(float defaultScrimAlpha) { 469 mDefaultScrimAlpha = defaultScrimAlpha; 470 } 471 setSurfaceColor(int surfaceColor)472 public void setSurfaceColor(int surfaceColor) { 473 mSurfaceColor = surfaceColor; 474 } 475 setWallpaperSupportsAmbientMode(boolean wallpaperSupportsAmbientMode)476 public void setWallpaperSupportsAmbientMode(boolean wallpaperSupportsAmbientMode) { 477 mWallpaperSupportsAmbientMode = wallpaperSupportsAmbientMode; 478 } 479 setLaunchingAffordanceWithPreview(boolean launchingAffordanceWithPreview)480 public void setLaunchingAffordanceWithPreview(boolean launchingAffordanceWithPreview) { 481 mLaunchingAffordanceWithPreview = launchingAffordanceWithPreview; 482 } 483 setOccludeAnimationPlaying(boolean occludeAnimationPlaying)484 public void setOccludeAnimationPlaying(boolean occludeAnimationPlaying) { 485 mOccludeAnimationPlaying = occludeAnimationPlaying; 486 } 487 isLowPowerState()488 public boolean isLowPowerState() { 489 return false; 490 } 491 setHasBackdrop(boolean hasBackdrop)492 public void setHasBackdrop(boolean hasBackdrop) { 493 mHasBackdrop = hasBackdrop; 494 } 495 setWakeLockScreenSensorActive(boolean active)496 public void setWakeLockScreenSensorActive(boolean active) { 497 mWakeLockScreenSensorActive = active; 498 } 499 setKeyguardFadingAway(boolean fadingAway, long duration)500 public void setKeyguardFadingAway(boolean fadingAway, long duration) { 501 mKeyguardFadingAway = fadingAway; 502 mKeyguardFadingAwayDuration = duration; 503 } 504 setClipQsScrim(boolean clipsQsScrim)505 public void setClipQsScrim(boolean clipsQsScrim) { 506 mClipQsScrim = clipsQsScrim; 507 } 508 } 509