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; 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; 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 & behind scrim alpha values are determined by ScrimController#applyState 94 // based on the shade expansion 95 96 mFrontTint = Color.BLACK; 97 mFrontAlpha = .66f; 98 } 99 }, 100 101 AUTH_SCRIMMED { 102 @Override prepare(ScrimState previousState)103 public void prepare(ScrimState previousState) { 104 mNotifTint = previousState.mNotifTint; 105 mNotifAlpha = previousState.mNotifAlpha; 106 107 mBehindTint = previousState.mBehindTint; 108 mBehindAlpha = previousState.mBehindAlpha; 109 110 mFrontTint = Color.BLACK; 111 mFrontAlpha = .66f; 112 } 113 }, 114 115 /** 116 * Showing password challenge on the keyguard. 117 */ 118 BOUNCER { 119 @Override prepare(ScrimState previousState)120 public void prepare(ScrimState previousState) { 121 mBehindAlpha = mClipQsScrim ? 1 : mDefaultScrimAlpha; 122 mBehindTint = mClipQsScrim ? Color.BLACK : Color.TRANSPARENT; 123 mNotifAlpha = mClipQsScrim ? mDefaultScrimAlpha : 0; 124 mNotifTint = Color.TRANSPARENT; 125 mFrontAlpha = 0f; 126 } 127 }, 128 129 /** 130 * Showing password challenge on top of a FLAG_SHOW_WHEN_LOCKED activity. 131 */ 132 BOUNCER_SCRIMMED { 133 @Override prepare(ScrimState previousState)134 public void prepare(ScrimState previousState) { 135 mBehindAlpha = 0; 136 mFrontAlpha = mDefaultScrimAlpha; 137 } 138 }, 139 140 SHADE_LOCKED { 141 @Override prepare(ScrimState previousState)142 public void prepare(ScrimState previousState) { 143 mBehindAlpha = mClipQsScrim ? 1 : mDefaultScrimAlpha; 144 mNotifAlpha = 1f; 145 mFrontAlpha = 0f; 146 mBehindTint = Color.BLACK; 147 148 if (mClipQsScrim) { 149 updateScrimColor(mScrimBehind, 1f /* alpha */, Color.BLACK); 150 } 151 } 152 153 // to make sure correct color is returned before "prepare" is called 154 @Override getBehindTint()155 public int getBehindTint() { 156 return Color.BLACK; 157 } 158 }, 159 160 /** 161 * Changing screen brightness from quick settings. 162 */ 163 BRIGHTNESS_MIRROR { 164 @Override prepare(ScrimState previousState)165 public void prepare(ScrimState previousState) { 166 mBehindAlpha = 0; 167 mFrontAlpha = 0; 168 } 169 }, 170 171 /** 172 * Always on display or screen off. 173 */ 174 AOD { 175 @Override prepare(ScrimState previousState)176 public void prepare(ScrimState previousState) { 177 final boolean alwaysOnEnabled = mDozeParameters.getAlwaysOn(); 178 final boolean quickPickupEnabled = mDozeParameters.isQuickPickupEnabled(); 179 final boolean isDocked = mDockManager.isDocked(); 180 mBlankScreen = mDisplayRequiresBlanking; 181 182 mFrontTint = Color.BLACK; 183 mFrontAlpha = (alwaysOnEnabled || isDocked || quickPickupEnabled) 184 ? mAodFrontScrimAlpha : 1f; 185 186 mBehindTint = Color.BLACK; 187 mBehindAlpha = ScrimController.TRANSPARENT; 188 189 mAnimationDuration = ScrimController.ANIMATION_DURATION_LONG; 190 // DisplayPowerManager may blank the screen for us, or we might blank it for ourselves 191 // by animating the screen off via the LightRevelScrim. In either case we just need to 192 // set our state. 193 mAnimateChange = mDozeParameters.shouldControlScreenOff() 194 && !mDozeParameters.shouldControlUnlockedScreenOff(); 195 } 196 197 @Override getMaxLightRevealScrimAlpha()198 public float getMaxLightRevealScrimAlpha() { 199 return mWallpaperSupportsAmbientMode && !mHasBackdrop ? 0f : 1f; 200 } 201 202 @Override isLowPowerState()203 public boolean isLowPowerState() { 204 return true; 205 } 206 }, 207 208 /** 209 * When phone wakes up because you received a notification. 210 */ 211 PULSING { 212 @Override prepare(ScrimState previousState)213 public void prepare(ScrimState previousState) { 214 mFrontAlpha = mAodFrontScrimAlpha; 215 mBehindTint = Color.BLACK; 216 mFrontTint = Color.BLACK; 217 mBlankScreen = mDisplayRequiresBlanking; 218 mAnimationDuration = mWakeLockScreenSensorActive 219 ? ScrimController.ANIMATION_DURATION_LONG : ScrimController.ANIMATION_DURATION; 220 } 221 @Override getMaxLightRevealScrimAlpha()222 public float getMaxLightRevealScrimAlpha() { 223 return mWakeLockScreenSensorActive ? ScrimController.WAKE_SENSOR_SCRIM_ALPHA 224 : AOD.getMaxLightRevealScrimAlpha(); 225 } 226 }, 227 228 /** 229 * Unlocked on top of an app (launcher or any other activity.) 230 */ 231 UNLOCKED { 232 @Override prepare(ScrimState previousState)233 public void prepare(ScrimState previousState) { 234 // State that UI will sync to. 235 mBehindAlpha = mClipQsScrim ? 1 : 0; 236 mNotifAlpha = 0; 237 mFrontAlpha = 0; 238 239 mAnimationDuration = mKeyguardFadingAway 240 ? mKeyguardFadingAwayDuration 241 : StatusBar.FADE_KEYGUARD_DURATION; 242 243 boolean fromAod = previousState == AOD || previousState == PULSING; 244 mAnimateChange = !mLaunchingAffordanceWithPreview && !fromAod; 245 246 mFrontTint = Color.TRANSPARENT; 247 mBehindTint = Color.BLACK; 248 mBlankScreen = false; 249 250 if (previousState == ScrimState.AOD) { 251 // Set all scrims black, before they fade transparent. 252 updateScrimColor(mScrimInFront, 1f /* alpha */, Color.BLACK /* tint */); 253 updateScrimColor(mScrimBehind, 1f /* alpha */, Color.BLACK /* tint */); 254 255 // Scrims should still be black at the end of the transition. 256 mFrontTint = Color.BLACK; 257 mBehindTint = Color.BLACK; 258 mBlankScreen = true; 259 } 260 261 if (mClipQsScrim) { 262 updateScrimColor(mScrimBehind, 1f /* alpha */, Color.BLACK); 263 } 264 } 265 }; 266 267 boolean mBlankScreen = false; 268 long mAnimationDuration = ScrimController.ANIMATION_DURATION; 269 int mFrontTint = Color.TRANSPARENT; 270 int mBehindTint = Color.TRANSPARENT; 271 int mNotifTint = Color.TRANSPARENT; 272 273 boolean mAnimateChange = true; 274 float mAodFrontScrimAlpha; 275 float mFrontAlpha; 276 float mBehindAlpha; 277 float mNotifAlpha; 278 279 float mScrimBehindAlphaKeyguard; 280 float mDefaultScrimAlpha; 281 ScrimView mScrimInFront; 282 ScrimView mScrimBehind; 283 284 DozeParameters mDozeParameters; 285 DockManager mDockManager; 286 boolean mDisplayRequiresBlanking; 287 boolean mWallpaperSupportsAmbientMode; 288 boolean mHasBackdrop; 289 boolean mLaunchingAffordanceWithPreview; 290 boolean mWakeLockScreenSensorActive; 291 boolean mKeyguardFadingAway; 292 long mKeyguardFadingAwayDuration; 293 boolean mClipQsScrim; 294 init(ScrimView scrimInFront, ScrimView scrimBehind, DozeParameters dozeParameters, DockManager dockManager)295 public void init(ScrimView scrimInFront, ScrimView scrimBehind, DozeParameters dozeParameters, 296 DockManager dockManager) { 297 mScrimInFront = scrimInFront; 298 mScrimBehind = scrimBehind; 299 300 mDozeParameters = dozeParameters; 301 mDockManager = dockManager; 302 mDisplayRequiresBlanking = dozeParameters.getDisplayNeedsBlanking(); 303 } 304 305 /** Prepare state for transition. */ prepare(ScrimState previousState)306 public void prepare(ScrimState previousState) { 307 } 308 getFrontAlpha()309 public float getFrontAlpha() { 310 return mFrontAlpha; 311 } 312 getBehindAlpha()313 public float getBehindAlpha() { 314 return mBehindAlpha; 315 } 316 getMaxLightRevealScrimAlpha()317 public float getMaxLightRevealScrimAlpha() { 318 return 1f; 319 } 320 getNotifAlpha()321 public float getNotifAlpha() { 322 return mNotifAlpha; 323 } 324 getFrontTint()325 public int getFrontTint() { 326 return mFrontTint; 327 } 328 getBehindTint()329 public int getBehindTint() { 330 return mBehindTint; 331 } 332 getNotifTint()333 public int getNotifTint() { 334 return mNotifTint; 335 } 336 getAnimationDuration()337 public long getAnimationDuration() { 338 return mAnimationDuration; 339 } 340 getBlanksScreen()341 public boolean getBlanksScreen() { 342 return mBlankScreen; 343 } 344 updateScrimColor(ScrimView scrim, float alpha, int tint)345 public void updateScrimColor(ScrimView scrim, float alpha, int tint) { 346 Trace.traceCounter(Trace.TRACE_TAG_APP, 347 scrim == mScrimInFront ? "front_scrim_alpha" : "back_scrim_alpha", 348 (int) (alpha * 255)); 349 350 Trace.traceCounter(Trace.TRACE_TAG_APP, 351 scrim == mScrimInFront ? "front_scrim_tint" : "back_scrim_tint", 352 Color.alpha(tint)); 353 354 scrim.setTint(tint); 355 scrim.setViewAlpha(alpha); 356 } 357 getAnimateChange()358 public boolean getAnimateChange() { 359 return mAnimateChange; 360 } 361 setAodFrontScrimAlpha(float aodFrontScrimAlpha)362 public void setAodFrontScrimAlpha(float aodFrontScrimAlpha) { 363 mAodFrontScrimAlpha = aodFrontScrimAlpha; 364 } 365 setScrimBehindAlphaKeyguard(float scrimBehindAlphaKeyguard)366 public void setScrimBehindAlphaKeyguard(float scrimBehindAlphaKeyguard) { 367 mScrimBehindAlphaKeyguard = scrimBehindAlphaKeyguard; 368 } 369 setDefaultScrimAlpha(float defaultScrimAlpha)370 public void setDefaultScrimAlpha(float defaultScrimAlpha) { 371 mDefaultScrimAlpha = defaultScrimAlpha; 372 } 373 setWallpaperSupportsAmbientMode(boolean wallpaperSupportsAmbientMode)374 public void setWallpaperSupportsAmbientMode(boolean wallpaperSupportsAmbientMode) { 375 mWallpaperSupportsAmbientMode = wallpaperSupportsAmbientMode; 376 } 377 setLaunchingAffordanceWithPreview(boolean launchingAffordanceWithPreview)378 public void setLaunchingAffordanceWithPreview(boolean launchingAffordanceWithPreview) { 379 mLaunchingAffordanceWithPreview = launchingAffordanceWithPreview; 380 } 381 isLowPowerState()382 public boolean isLowPowerState() { 383 return false; 384 } 385 setHasBackdrop(boolean hasBackdrop)386 public void setHasBackdrop(boolean hasBackdrop) { 387 mHasBackdrop = hasBackdrop; 388 } 389 setWakeLockScreenSensorActive(boolean active)390 public void setWakeLockScreenSensorActive(boolean active) { 391 mWakeLockScreenSensorActive = active; 392 } 393 setKeyguardFadingAway(boolean fadingAway, long duration)394 public void setKeyguardFadingAway(boolean fadingAway, long duration) { 395 mKeyguardFadingAway = fadingAway; 396 mKeyguardFadingAwayDuration = duration; 397 } 398 setClipQsScrim(boolean clipsQsScrim)399 public void setClipQsScrim(boolean clipsQsScrim) { 400 mClipQsScrim = clipsQsScrim; 401 } 402 }