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.statusbar.ScrimView;
23 import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
24 
25 /**
26  * Possible states of the ScrimController state machine.
27  */
28 public enum ScrimState {
29 
30     /**
31      * Initial state.
32      */
33     UNINITIALIZED(-1),
34 
35     /**
36      * On the lock screen.
37      */
38     KEYGUARD(0) {
39 
40         @Override
prepare(ScrimState previousState)41         public void prepare(ScrimState previousState) {
42             mBlankScreen = false;
43             if (previousState == ScrimState.AOD) {
44                 mAnimationDuration = StackStateAnimator.ANIMATION_DURATION_WAKEUP;
45                 if (mDisplayRequiresBlanking) {
46                     // DisplayPowerManager will blank the screen, we'll just
47                     // set our scrim to black in this frame to avoid flickering and
48                     // fade it out afterwards.
49                     mBlankScreen = true;
50                 }
51             } else if (previousState == ScrimState.KEYGUARD) {
52                 mAnimationDuration = StackStateAnimator.ANIMATION_DURATION_WAKEUP;
53             } else {
54                 mAnimationDuration = ScrimController.ANIMATION_DURATION;
55             }
56             mCurrentInFrontTint = Color.BLACK;
57             mCurrentBehindTint = Color.BLACK;
58             mCurrentBehindAlpha = mScrimBehindAlphaKeyguard;
59             mCurrentInFrontAlpha = 0;
60         }
61     },
62 
63     /**
64      * Showing password challenge on the keyguard.
65      */
66     BOUNCER(1) {
67         @Override
prepare(ScrimState previousState)68         public void prepare(ScrimState previousState) {
69             mCurrentBehindAlpha = ScrimController.GRADIENT_SCRIM_ALPHA_BUSY;
70             mCurrentInFrontAlpha = 0f;
71         }
72     },
73 
74     /**
75      * Showing password challenge on top of a FLAG_SHOW_WHEN_LOCKED activity.
76      */
77     BOUNCER_SCRIMMED(2) {
78         @Override
prepare(ScrimState previousState)79         public void prepare(ScrimState previousState) {
80             mCurrentBehindAlpha = 0;
81             mCurrentInFrontAlpha = ScrimController.GRADIENT_SCRIM_ALPHA_BUSY;
82         }
83     },
84 
85     /**
86      * Changing screen brightness from quick settings.
87      */
88     BRIGHTNESS_MIRROR(3) {
89         @Override
prepare(ScrimState previousState)90         public void prepare(ScrimState previousState) {
91             mCurrentBehindAlpha = 0;
92             mCurrentInFrontAlpha = 0;
93         }
94     },
95 
96     /**
97      * Always on display or screen off.
98      */
99     AOD(4) {
100         @Override
prepare(ScrimState previousState)101         public void prepare(ScrimState previousState) {
102             final boolean alwaysOnEnabled = mDozeParameters.getAlwaysOn();
103             mBlankScreen = mDisplayRequiresBlanking;
104             mCurrentInFrontAlpha = alwaysOnEnabled ? mAodFrontScrimAlpha : 1f;
105             mCurrentInFrontTint = Color.BLACK;
106             mCurrentBehindTint = Color.BLACK;
107             mAnimationDuration = ScrimController.ANIMATION_DURATION_LONG;
108             // DisplayPowerManager may blank the screen for us,
109             // in this case we just need to set our state.
110             mAnimateChange = mDozeParameters.shouldControlScreenOff();
111         }
112 
113         @Override
getBehindAlpha()114         public float getBehindAlpha() {
115             return mWallpaperSupportsAmbientMode && !mHasBackdrop ? 0f : 1f;
116         }
117 
118         @Override
isLowPowerState()119         public boolean isLowPowerState() {
120             return true;
121         }
122     },
123 
124     /**
125      * When phone wakes up because you received a notification.
126      */
127     PULSING(5) {
128         @Override
prepare(ScrimState previousState)129         public void prepare(ScrimState previousState) {
130             mCurrentInFrontAlpha = mAodFrontScrimAlpha;
131             mCurrentBehindTint = Color.BLACK;
132             mCurrentInFrontTint = Color.BLACK;
133             mBlankScreen = mDisplayRequiresBlanking;
134             mAnimationDuration = mWakeLockScreenSensorActive
135                     ? ScrimController.ANIMATION_DURATION_LONG : ScrimController.ANIMATION_DURATION;
136 
137             // Wake sensor will show the wallpaper, let's fade from black. Otherwise it will
138             // feel like the screen is flashing if the wallpaper is light.
139             if (mWakeLockScreenSensorActive && previousState == AOD) {
140                 updateScrimColor(mScrimBehind, 1f /* alpha */, Color.BLACK);
141             }
142         }
143 
144         @Override
getBehindAlpha()145         public float getBehindAlpha() {
146             return mWakeLockScreenSensorActive ? ScrimController.WAKE_SENSOR_SCRIM_ALPHA
147                     : AOD.getBehindAlpha();
148         }
149     },
150 
151     /**
152      * Unlocked on top of an app (launcher or any other activity.)
153      */
154     UNLOCKED(6) {
155         @Override
prepare(ScrimState previousState)156         public void prepare(ScrimState previousState) {
157             mCurrentBehindAlpha = 0;
158             mCurrentInFrontAlpha = 0;
159             mAnimationDuration = mKeyguardFadingAway
160                     ? mKeyguardFadingAwayDuration
161                     : StatusBar.FADE_KEYGUARD_DURATION;
162 
163             mAnimateChange = !mLaunchingAffordanceWithPreview;
164 
165             if (previousState == ScrimState.AOD) {
166                 // Fade from black to transparent when coming directly from AOD
167                 updateScrimColor(mScrimInFront, 1, Color.BLACK);
168                 updateScrimColor(mScrimBehind, 1, Color.BLACK);
169                 // Scrims should still be black at the end of the transition.
170                 mCurrentInFrontTint = Color.BLACK;
171                 mCurrentBehindTint = Color.BLACK;
172                 mBlankScreen = true;
173             } else {
174                 mCurrentInFrontTint = Color.TRANSPARENT;
175                 mCurrentBehindTint = Color.TRANSPARENT;
176                 mBlankScreen = false;
177             }
178         }
179     },
180 
181     /**
182      * Unlocked with a bubble expanded.
183      */
184     BUBBLE_EXPANDED(7) {
185         @Override
prepare(ScrimState previousState)186         public void prepare(ScrimState previousState) {
187             mCurrentInFrontTint = Color.TRANSPARENT;
188             mCurrentBehindTint = Color.TRANSPARENT;
189             mAnimationDuration = ScrimController.ANIMATION_DURATION;
190             mCurrentBehindAlpha = ScrimController.GRADIENT_SCRIM_ALPHA_BUSY;
191             mBlankScreen = false;
192         }
193     };
194 
195     boolean mBlankScreen = false;
196     long mAnimationDuration = ScrimController.ANIMATION_DURATION;
197     int mCurrentInFrontTint = Color.TRANSPARENT;
198     int mCurrentBehindTint = Color.TRANSPARENT;
199     boolean mAnimateChange = true;
200     float mCurrentInFrontAlpha;
201     float mCurrentBehindAlpha;
202     float mAodFrontScrimAlpha;
203     float mScrimBehindAlphaKeyguard;
204     ScrimView mScrimInFront;
205     ScrimView mScrimBehind;
206     DozeParameters mDozeParameters;
207     boolean mDisplayRequiresBlanking;
208     boolean mWallpaperSupportsAmbientMode;
209     int mIndex;
210     boolean mHasBackdrop;
211     boolean mLaunchingAffordanceWithPreview;
212     boolean mWakeLockScreenSensorActive;
213     boolean mKeyguardFadingAway;
214     long mKeyguardFadingAwayDuration;
215 
ScrimState(int index)216     ScrimState(int index) {
217         mIndex = index;
218     }
219 
init(ScrimView scrimInFront, ScrimView scrimBehind, DozeParameters dozeParameters)220     public void init(ScrimView scrimInFront, ScrimView scrimBehind, DozeParameters dozeParameters) {
221         mScrimInFront = scrimInFront;
222         mScrimBehind = scrimBehind;
223         mDozeParameters = dozeParameters;
224         mDisplayRequiresBlanking = dozeParameters.getDisplayNeedsBlanking();
225     }
226 
prepare(ScrimState previousState)227     public void prepare(ScrimState previousState) {
228     }
229 
getIndex()230     public int getIndex() {
231         return mIndex;
232     }
233 
getFrontAlpha()234     public float getFrontAlpha() {
235         return mCurrentInFrontAlpha;
236     }
237 
getBehindAlpha()238     public float getBehindAlpha() {
239         return mCurrentBehindAlpha;
240     }
241 
getFrontTint()242     public int getFrontTint() {
243         return mCurrentInFrontTint;
244     }
245 
getBehindTint()246     public int getBehindTint() {
247         return mCurrentBehindTint;
248     }
249 
getAnimationDuration()250     public long getAnimationDuration() {
251         return mAnimationDuration;
252     }
253 
getBlanksScreen()254     public boolean getBlanksScreen() {
255         return mBlankScreen;
256     }
257 
updateScrimColor(ScrimView scrim, float alpha, int tint)258     public void updateScrimColor(ScrimView scrim, float alpha, int tint) {
259         Trace.traceCounter(Trace.TRACE_TAG_APP,
260                 scrim == mScrimInFront ? "front_scrim_alpha" : "back_scrim_alpha",
261                 (int) (alpha * 255));
262 
263         Trace.traceCounter(Trace.TRACE_TAG_APP,
264                 scrim == mScrimInFront ? "front_scrim_tint" : "back_scrim_tint",
265                 Color.alpha(tint));
266 
267         scrim.setTint(tint);
268         scrim.setViewAlpha(alpha);
269     }
270 
getAnimateChange()271     public boolean getAnimateChange() {
272         return mAnimateChange;
273     }
274 
setAodFrontScrimAlpha(float aodFrontScrimAlpha)275     public void setAodFrontScrimAlpha(float aodFrontScrimAlpha) {
276         mAodFrontScrimAlpha = aodFrontScrimAlpha;
277     }
278 
setScrimBehindAlphaKeyguard(float scrimBehindAlphaKeyguard)279     public void setScrimBehindAlphaKeyguard(float scrimBehindAlphaKeyguard) {
280         mScrimBehindAlphaKeyguard = scrimBehindAlphaKeyguard;
281     }
282 
setWallpaperSupportsAmbientMode(boolean wallpaperSupportsAmbientMode)283     public void setWallpaperSupportsAmbientMode(boolean wallpaperSupportsAmbientMode) {
284         mWallpaperSupportsAmbientMode = wallpaperSupportsAmbientMode;
285     }
286 
setLaunchingAffordanceWithPreview(boolean launchingAffordanceWithPreview)287     public void setLaunchingAffordanceWithPreview(boolean launchingAffordanceWithPreview) {
288         mLaunchingAffordanceWithPreview = launchingAffordanceWithPreview;
289     }
290 
isLowPowerState()291     public boolean isLowPowerState() {
292         return false;
293     }
294 
setHasBackdrop(boolean hasBackdrop)295     public void setHasBackdrop(boolean hasBackdrop) {
296         mHasBackdrop = hasBackdrop;
297     }
298 
setWakeLockScreenSensorActive(boolean active)299     public void setWakeLockScreenSensorActive(boolean active) {
300         mWakeLockScreenSensorActive = active;
301     }
302 
setKeyguardFadingAway(boolean fadingAway, long duration)303     public void setKeyguardFadingAway(boolean fadingAway, long duration) {
304         mKeyguardFadingAway = fadingAway;
305         mKeyguardFadingAwayDuration = duration;
306     }
307 }