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 import android.util.MathUtils;
22 
23 import com.android.keyguard.KeyguardUpdateMonitor;
24 import com.android.systemui.statusbar.ScrimView;
25 import com.android.systemui.statusbar.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(-1),
36 
37     /**
38      * On the lock screen.
39      */
40     KEYGUARD(0) {
41 
42         @Override
prepare(ScrimState previousState)43         public void prepare(ScrimState previousState) {
44             mBlankScreen = false;
45             if (previousState == ScrimState.AOD) {
46                 mAnimationDuration = StackStateAnimator.ANIMATION_DURATION_WAKEUP;
47                 if (mDisplayRequiresBlanking) {
48                     // DisplayPowerManager will blank the screen, we'll just
49                     // set our scrim to black in this frame to avoid flickering and
50                     // fade it out afterwards.
51                     mBlankScreen = true;
52                 }
53             } else {
54                 mAnimationDuration = ScrimController.ANIMATION_DURATION;
55             }
56             mCurrentBehindAlpha = mScrimBehindAlphaKeyguard;
57             mCurrentInFrontAlpha = 0;
58         }
59 
60         @Override
getBehindAlpha(float busynessFactor)61         public float getBehindAlpha(float busynessFactor) {
62             return MathUtils.map(0 /* start */, 1 /* stop */,
63                    mScrimBehindAlphaKeyguard, ScrimController.GRADIENT_SCRIM_ALPHA_BUSY,
64                    busynessFactor);
65         }
66     },
67 
68     /**
69      * Showing password challenge on the keyguard.
70      */
71     BOUNCER(1) {
72         @Override
prepare(ScrimState previousState)73         public void prepare(ScrimState previousState) {
74             mCurrentBehindAlpha = ScrimController.GRADIENT_SCRIM_ALPHA_BUSY;
75             mCurrentInFrontAlpha = 0f;
76         }
77     },
78 
79     /**
80      * Showing password challenge on top of a FLAG_SHOW_WHEN_LOCKED activity.
81      */
82     BOUNCER_SCRIMMED(2) {
83         @Override
prepare(ScrimState previousState)84         public void prepare(ScrimState previousState) {
85             mCurrentBehindAlpha = 0;
86             mCurrentInFrontAlpha = ScrimController.GRADIENT_SCRIM_ALPHA_BUSY;
87         }
88     },
89 
90     /**
91      * Changing screen brightness from quick settings.
92      */
93     BRIGHTNESS_MIRROR(3) {
94         @Override
prepare(ScrimState previousState)95         public void prepare(ScrimState previousState) {
96             mCurrentBehindAlpha = 0;
97             mCurrentInFrontAlpha = 0;
98         }
99     },
100 
101     /**
102      * Always on display or screen off.
103      */
104     AOD(4) {
105         @Override
prepare(ScrimState previousState)106         public void prepare(ScrimState previousState) {
107             final boolean alwaysOnEnabled = mDozeParameters.getAlwaysOn();
108             mBlankScreen = mDisplayRequiresBlanking;
109             mCurrentBehindAlpha = mWallpaperSupportsAmbientMode
110                     && !mKeyguardUpdateMonitor.hasLockscreenWallpaper() ? 0f : 1f;
111             mCurrentInFrontAlpha = alwaysOnEnabled ? mAodFrontScrimAlpha : 1f;
112             mCurrentInFrontTint = Color.BLACK;
113             mCurrentBehindTint = Color.BLACK;
114             mAnimationDuration = ScrimController.ANIMATION_DURATION_LONG;
115             // DisplayPowerManager may blank the screen for us,
116             // in this case we just need to set our state.
117             mAnimateChange = mDozeParameters.shouldControlScreenOff();
118         }
119 
120         @Override
isLowPowerState()121         public boolean isLowPowerState() {
122             return true;
123         }
124     },
125 
126     /**
127      * When phone wakes up because you received a notification.
128      */
129     PULSING(5) {
130         @Override
prepare(ScrimState previousState)131         public void prepare(ScrimState previousState) {
132             mCurrentInFrontAlpha = 0;
133             mCurrentInFrontTint = Color.BLACK;
134             mCurrentBehindAlpha = mWallpaperSupportsAmbientMode
135                     && !mKeyguardUpdateMonitor.hasLockscreenWallpaper() ? 0f : 1f;
136             mCurrentBehindTint = Color.BLACK;
137             mBlankScreen = mDisplayRequiresBlanking;
138         }
139     },
140 
141     /**
142      * Unlocked on top of an app (launcher or any other activity.)
143      */
144     UNLOCKED(6) {
145         @Override
prepare(ScrimState previousState)146         public void prepare(ScrimState previousState) {
147             mCurrentBehindAlpha = 0;
148             mCurrentInFrontAlpha = 0;
149             mAnimationDuration = StatusBar.FADE_KEYGUARD_DURATION;
150 
151             if (previousState == ScrimState.AOD || previousState == ScrimState.PULSING) {
152                 // Fade from black to transparent when coming directly from AOD
153                 updateScrimColor(mScrimInFront, 1, Color.BLACK);
154                 updateScrimColor(mScrimBehind, 1, Color.BLACK);
155                 // Scrims should still be black at the end of the transition.
156                 mCurrentInFrontTint = Color.BLACK;
157                 mCurrentBehindTint = Color.BLACK;
158                 mBlankScreen = true;
159             } else {
160                 mCurrentInFrontTint = Color.TRANSPARENT;
161                 mCurrentBehindTint = Color.TRANSPARENT;
162                 mBlankScreen = false;
163             }
164         }
165     };
166 
167     boolean mBlankScreen = false;
168     long mAnimationDuration = ScrimController.ANIMATION_DURATION;
169     int mCurrentInFrontTint = Color.TRANSPARENT;
170     int mCurrentBehindTint = Color.TRANSPARENT;
171     boolean mAnimateChange = true;
172     float mCurrentInFrontAlpha;
173     float mCurrentBehindAlpha;
174     float mAodFrontScrimAlpha;
175     float mScrimBehindAlphaKeyguard;
176     ScrimView mScrimInFront;
177     ScrimView mScrimBehind;
178     DozeParameters mDozeParameters;
179     boolean mDisplayRequiresBlanking;
180     boolean mWallpaperSupportsAmbientMode;
181     KeyguardUpdateMonitor mKeyguardUpdateMonitor;
182     int mIndex;
183 
ScrimState(int index)184     ScrimState(int index) {
185         mIndex = index;
186     }
187 
init(ScrimView scrimInFront, ScrimView scrimBehind, DozeParameters dozeParameters)188     public void init(ScrimView scrimInFront, ScrimView scrimBehind, DozeParameters dozeParameters) {
189         mScrimInFront = scrimInFront;
190         mScrimBehind = scrimBehind;
191         mDozeParameters = dozeParameters;
192         mDisplayRequiresBlanking = dozeParameters.getDisplayNeedsBlanking();
193         mKeyguardUpdateMonitor = KeyguardUpdateMonitor.getInstance(scrimInFront.getContext());
194     }
195 
prepare(ScrimState previousState)196     public void prepare(ScrimState previousState) {
197     }
198 
getIndex()199     public int getIndex() {
200         return mIndex;
201     }
202 
getFrontAlpha()203     public float getFrontAlpha() {
204         return mCurrentInFrontAlpha;
205     }
206 
getBehindAlpha(float busyness)207     public float getBehindAlpha(float busyness) {
208         return mCurrentBehindAlpha;
209     }
210 
getFrontTint()211     public int getFrontTint() {
212         return mCurrentInFrontTint;
213     }
214 
getBehindTint()215     public int getBehindTint() {
216         return mCurrentBehindTint;
217     }
218 
getAnimationDuration()219     public long getAnimationDuration() {
220         return mAnimationDuration;
221     }
222 
getBlanksScreen()223     public boolean getBlanksScreen() {
224         return mBlankScreen;
225     }
226 
updateScrimColor(ScrimView scrim, float alpha, int tint)227     public void updateScrimColor(ScrimView scrim, float alpha, int tint) {
228         Trace.traceCounter(Trace.TRACE_TAG_APP,
229                 scrim == mScrimInFront ? "front_scrim_alpha" : "back_scrim_alpha",
230                 (int) (alpha * 255));
231 
232         Trace.traceCounter(Trace.TRACE_TAG_APP,
233                 scrim == mScrimInFront ? "front_scrim_tint" : "back_scrim_tint",
234                 Color.alpha(tint));
235 
236         scrim.setTint(tint);
237         scrim.setViewAlpha(alpha);
238     }
239 
getAnimateChange()240     public boolean getAnimateChange() {
241         return mAnimateChange;
242     }
243 
setAodFrontScrimAlpha(float aodFrontScrimAlpha)244     public void setAodFrontScrimAlpha(float aodFrontScrimAlpha) {
245         mAodFrontScrimAlpha = aodFrontScrimAlpha;
246     }
247 
setScrimBehindAlphaKeyguard(float scrimBehindAlphaKeyguard)248     public void setScrimBehindAlphaKeyguard(float scrimBehindAlphaKeyguard) {
249         mScrimBehindAlphaKeyguard = scrimBehindAlphaKeyguard;
250     }
251 
setWallpaperSupportsAmbientMode(boolean wallpaperSupportsAmbientMode)252     public void setWallpaperSupportsAmbientMode(boolean wallpaperSupportsAmbientMode) {
253         mWallpaperSupportsAmbientMode = wallpaperSupportsAmbientMode;
254     }
255 
isLowPowerState()256     public boolean isLowPowerState() {
257         return false;
258     }
259 }