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