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