blob: ada745079fefebe2543acdf3a09d50b59a164d54 [file] [log] [blame]
Jorim Jaggi5cf17872014-03-26 18:31:48 +01001/*
2 * Copyright (C) 2014 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
17package com.android.systemui.statusbar.phone;
18
Jorim Jaggi5cf17872014-03-26 18:31:48 +010019import android.content.Context;
20import android.content.pm.ActivityInfo;
21import android.content.res.Resources;
22import android.graphics.PixelFormat;
23import android.os.SystemProperties;
24import android.view.Gravity;
25import android.view.View;
26import android.view.ViewGroup;
27import android.view.WindowManager;
28
29import com.android.keyguard.R;
Jorim Jaggi6b88cdf2014-12-22 20:56:50 +010030import com.android.systemui.keyguard.KeyguardViewMediator;
Jorim Jaggiecbab362014-04-23 16:13:15 +020031import com.android.systemui.statusbar.BaseStatusBar;
Adrian Roosd28ccd72016-01-06 15:23:14 +010032import com.android.systemui.statusbar.RemoteInputController;
Jorim Jaggiecbab362014-04-23 16:13:15 +020033import com.android.systemui.statusbar.StatusBarState;
Jorim Jaggi5cf17872014-03-26 18:31:48 +010034
Selim Cinek7025f262015-07-13 16:22:48 -070035import java.io.FileDescriptor;
36import java.io.PrintWriter;
Selim Cinek6a1bd2b2015-06-02 16:02:41 +020037import java.lang.reflect.Field;
38
Jorim Jaggi5cf17872014-03-26 18:31:48 +010039/**
40 * Encapsulates all logic for the status bar window state management.
41 */
Adrian Roosd28ccd72016-01-06 15:23:14 +010042public class StatusBarWindowManager implements RemoteInputController.Callback {
Jorim Jaggi5cf17872014-03-26 18:31:48 +010043
44 private final Context mContext;
45 private final WindowManager mWindowManager;
46 private View mStatusBarView;
47 private WindowManager.LayoutParams mLp;
Jorim Jaggi95e89ca2014-11-24 20:12:50 +010048 private WindowManager.LayoutParams mLpChanged;
Jorim Jaggi5cf17872014-03-26 18:31:48 +010049 private int mBarHeight;
50 private final boolean mKeyguardScreenRotation;
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -070051 private final float mScreenBrightnessDoze;
Jorim Jaggi5cf17872014-03-26 18:31:48 +010052 private final State mCurrentState = new State();
53
54 public StatusBarWindowManager(Context context) {
55 mContext = context;
56 mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
57 mKeyguardScreenRotation = shouldEnableKeyguardScreenRotation();
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -070058 mScreenBrightnessDoze = mContext.getResources().getInteger(
59 com.android.internal.R.integer.config_screenBrightnessDoze) / 255f;
Jorim Jaggi5cf17872014-03-26 18:31:48 +010060 }
61
62 private boolean shouldEnableKeyguardScreenRotation() {
63 Resources res = mContext.getResources();
64 return SystemProperties.getBoolean("lockscreen.rot_override", false)
65 || res.getBoolean(R.bool.config_enableLockScreenRotation);
66 }
67
68 /**
69 * Adds the status bar view to the window manager.
70 *
71 * @param statusBarView The view to add.
72 * @param barHeight The height of the status bar in collapsed state.
73 */
74 public void add(View statusBarView, int barHeight) {
75
76 // Now that the status bar window encompasses the sliding panel and its
77 // translucent backdrop, the entire thing is made TRANSLUCENT and is
78 // hardware-accelerated.
79 mLp = new WindowManager.LayoutParams(
80 ViewGroup.LayoutParams.MATCH_PARENT,
81 barHeight,
82 WindowManager.LayoutParams.TYPE_STATUS_BAR,
83 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
84 | WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
85 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
86 | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
Adrian Roosea562512014-05-05 13:33:03 +020087 | WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS,
Jorim Jaggi5cf17872014-03-26 18:31:48 +010088 PixelFormat.TRANSLUCENT);
Jorim Jaggi5cf17872014-03-26 18:31:48 +010089 mLp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
Jorim Jaggi76aaef52014-05-08 19:16:49 +020090 mLp.gravity = Gravity.TOP;
Jorim Jaggi5cf17872014-03-26 18:31:48 +010091 mLp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
Jorim Jaggi5cf17872014-03-26 18:31:48 +010092 mLp.setTitle("StatusBar");
93 mLp.packageName = mContext.getPackageName();
94 mStatusBarView = statusBarView;
95 mBarHeight = barHeight;
96 mWindowManager.addView(mStatusBarView, mLp);
Jorim Jaggi95e89ca2014-11-24 20:12:50 +010097 mLpChanged = new WindowManager.LayoutParams();
98 mLpChanged.copyFrom(mLp);
Jorim Jaggi5cf17872014-03-26 18:31:48 +010099 }
100
101 private void applyKeyguardFlags(State state) {
102 if (state.keyguardShowing) {
Jorim Jaggi95e89ca2014-11-24 20:12:50 +0100103 mLpChanged.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100104 } else {
Jorim Jaggi95e89ca2014-11-24 20:12:50 +0100105 mLpChanged.privateFlags &= ~WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100106 }
Adrian Roosd5c2db62016-03-08 16:11:31 -0800107
108 if (state.keyguardShowing && !state.backdropShowing) {
109 mLpChanged.flags |= WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
110 } else {
111 mLpChanged.flags &= ~WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
112 }
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100113 }
114
115 private void adjustScreenOrientation(State state) {
Jorim Jaggica36cf72014-04-17 20:36:15 +0200116 if (state.isKeyguardShowingAndNotOccluded()) {
117 if (mKeyguardScreenRotation) {
Jorim Jaggi95e89ca2014-11-24 20:12:50 +0100118 mLpChanged.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_USER;
Jorim Jaggica36cf72014-04-17 20:36:15 +0200119 } else {
Jorim Jaggi95e89ca2014-11-24 20:12:50 +0100120 mLpChanged.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
Jorim Jaggica36cf72014-04-17 20:36:15 +0200121 }
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100122 } else {
Jorim Jaggi95e89ca2014-11-24 20:12:50 +0100123 mLpChanged.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100124 }
125 }
126
127 private void applyFocusableFlag(State state) {
Selim Cinek4a21a7f2015-05-19 11:00:38 -0700128 boolean panelFocusable = state.statusBarFocusable && state.panelExpanded;
Jorim Jaggiaa806142015-05-20 18:04:16 -0700129 if (state.keyguardShowing && state.keyguardNeedsInput && state.bouncerShowing
Adrian Roos1c0ca502015-10-07 12:20:42 -0700130 || BaseStatusBar.ENABLE_REMOTE_INPUT && state.remoteInputActive) {
Jorim Jaggi95e89ca2014-11-24 20:12:50 +0100131 mLpChanged.flags &= ~WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
132 mLpChanged.flags &= ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
Selim Cinek4a21a7f2015-05-19 11:00:38 -0700133 } else if (state.isKeyguardShowingAndNotOccluded() || panelFocusable) {
Jorim Jaggi95e89ca2014-11-24 20:12:50 +0100134 mLpChanged.flags &= ~WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
135 mLpChanged.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100136 } else {
Jorim Jaggi95e89ca2014-11-24 20:12:50 +0100137 mLpChanged.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
138 mLpChanged.flags &= ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100139 }
Adrian Roosdc5b4532016-01-06 20:49:41 +0100140
141 if (state.remoteInputActive) {
142 mLpChanged.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN;
143 } else {
144 mLpChanged.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
145 }
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100146 }
147
148 private void applyHeight(State state) {
Selim Cinek6a1bd2b2015-06-02 16:02:41 +0200149 boolean expanded = isExpanded(state);
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100150 if (expanded) {
Jorim Jaggi95e89ca2014-11-24 20:12:50 +0100151 mLpChanged.height = ViewGroup.LayoutParams.MATCH_PARENT;
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100152 } else {
Jorim Jaggi95e89ca2014-11-24 20:12:50 +0100153 mLpChanged.height = mBarHeight;
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100154 }
155 }
156
Selim Cinek6a1bd2b2015-06-02 16:02:41 +0200157 private boolean isExpanded(State state) {
158 return !state.forceCollapsed && (state.isKeyguardShowingAndNotOccluded()
159 || state.panelVisible || state.keyguardFadingAway || state.bouncerShowing
160 || state.headsUpShowing);
161 }
162
Jorim Jaggia005f1b2014-04-16 19:06:10 +0200163 private void applyFitsSystemWindows(State state) {
164 mStatusBarView.setFitsSystemWindows(!state.isKeyguardShowingAndNotOccluded());
165 }
166
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100167 private void applyUserActivityTimeout(State state) {
Jorim Jaggiecbab362014-04-23 16:13:15 +0200168 if (state.isKeyguardShowingAndNotOccluded()
Jorim Jaggib690f0d2014-07-03 23:25:44 +0200169 && state.statusBarState == StatusBarState.KEYGUARD
170 && !state.qsExpanded) {
Jorim Jaggi6b88cdf2014-12-22 20:56:50 +0100171 mLpChanged.userActivityTimeout = KeyguardViewMediator.AWAKE_INTERVAL_DEFAULT_MS;
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100172 } else {
Jorim Jaggi95e89ca2014-11-24 20:12:50 +0100173 mLpChanged.userActivityTimeout = -1;
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100174 }
175 }
176
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200177 private void applyInputFeatures(State state) {
Jorim Jaggi4222d9a2014-04-23 16:13:15 +0200178 if (state.isKeyguardShowingAndNotOccluded()
Jorim Jaggib690f0d2014-07-03 23:25:44 +0200179 && state.statusBarState == StatusBarState.KEYGUARD
Vadim Tryshev6069c402016-03-09 14:24:29 -0800180 && !state.qsExpanded && !state.forceUserActivity) {
Jorim Jaggi95e89ca2014-11-24 20:12:50 +0100181 mLpChanged.inputFeatures |=
182 WindowManager.LayoutParams.INPUT_FEATURE_DISABLE_USER_ACTIVITY;
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200183 } else {
Jorim Jaggi95e89ca2014-11-24 20:12:50 +0100184 mLpChanged.inputFeatures &=
185 ~WindowManager.LayoutParams.INPUT_FEATURE_DISABLE_USER_ACTIVITY;
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200186 }
187 }
188
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100189 private void apply(State state) {
190 applyKeyguardFlags(state);
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -0700191 applyForceStatusBarVisibleFlag(state);
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100192 applyFocusableFlag(state);
193 adjustScreenOrientation(state);
194 applyHeight(state);
195 applyUserActivityTimeout(state);
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200196 applyInputFeatures(state);
Jorim Jaggia005f1b2014-04-16 19:06:10 +0200197 applyFitsSystemWindows(state);
Selim Cineka59ecc32015-04-07 10:51:49 -0700198 applyModalFlag(state);
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700199 applyBrightness(state);
Jorim Jaggi95e89ca2014-11-24 20:12:50 +0100200 if (mLp.copyFrom(mLpChanged) != 0) {
201 mWindowManager.updateViewLayout(mStatusBarView, mLp);
202 }
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100203 }
204
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -0700205 private void applyForceStatusBarVisibleFlag(State state) {
206 if (state.forceStatusBarVisible) {
207 mLpChanged.privateFlags |= WindowManager
208 .LayoutParams.PRIVATE_FLAG_FORCE_STATUS_BAR_VISIBLE_TRANSPARENT;
209 } else {
210 mLpChanged.privateFlags &= ~WindowManager
211 .LayoutParams.PRIVATE_FLAG_FORCE_STATUS_BAR_VISIBLE_TRANSPARENT;
212 }
213 }
214
Selim Cineka59ecc32015-04-07 10:51:49 -0700215 private void applyModalFlag(State state) {
216 if (state.headsUpShowing) {
217 mLpChanged.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
218 } else {
219 mLpChanged.flags &= ~WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
220 }
221 }
222
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700223 private void applyBrightness(State state) {
224 if (state.forceDozeBrightness) {
225 mLpChanged.screenBrightness = mScreenBrightnessDoze;
226 } else {
227 mLpChanged.screenBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE;
228 }
229 }
230
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100231 public void setKeyguardShowing(boolean showing) {
232 mCurrentState.keyguardShowing = showing;
233 apply(mCurrentState);
234 }
235
236 public void setKeyguardOccluded(boolean occluded) {
237 mCurrentState.keyguardOccluded = occluded;
238 apply(mCurrentState);
239 }
240
241 public void setKeyguardNeedsInput(boolean needsInput) {
242 mCurrentState.keyguardNeedsInput = needsInput;
243 apply(mCurrentState);
244 }
245
Selim Cinek4a21a7f2015-05-19 11:00:38 -0700246 public void setPanelVisible(boolean visible) {
247 mCurrentState.panelVisible = visible;
248 mCurrentState.statusBarFocusable = visible;
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100249 apply(mCurrentState);
250 }
251
252 public void setStatusBarFocusable(boolean focusable) {
253 mCurrentState.statusBarFocusable = focusable;
254 apply(mCurrentState);
255 }
256
Jorim Jaggi5fd4d052014-05-13 22:50:20 +0200257 public void setBouncerShowing(boolean showing) {
258 mCurrentState.bouncerShowing = showing;
259 apply(mCurrentState);
260 }
261
Adrian Roosd5c2db62016-03-08 16:11:31 -0800262 public void setBackdropShowing(boolean showing) {
263 mCurrentState.backdropShowing = showing;
264 apply(mCurrentState);
265 }
266
Jorim Jaggie29b2db2014-05-30 23:17:03 +0200267 public void setKeyguardFadingAway(boolean keyguardFadingAway) {
268 mCurrentState.keyguardFadingAway = keyguardFadingAway;
269 apply(mCurrentState);
270 }
271
Jorim Jaggib690f0d2014-07-03 23:25:44 +0200272 public void setQsExpanded(boolean expanded) {
273 mCurrentState.qsExpanded = expanded;
274 apply(mCurrentState);
275 }
276
Vadim Tryshev6069c402016-03-09 14:24:29 -0800277 public void setForceUserActivity(boolean forceUserActivity) {
278 mCurrentState.forceUserActivity = forceUserActivity;
279 apply(mCurrentState);
280 }
281
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700282 public void setHeadsUpShowing(boolean showing) {
283 mCurrentState.headsUpShowing = showing;
284 apply(mCurrentState);
285 }
286
Jorim Jaggiecbab362014-04-23 16:13:15 +0200287 /**
288 * @param state The {@link StatusBarState} of the status bar.
289 */
290 public void setStatusBarState(int state) {
291 mCurrentState.statusBarState = state;
292 apply(mCurrentState);
293 }
294
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -0700295 public void setForceStatusBarVisible(boolean forceStatusBarVisible) {
296 mCurrentState.forceStatusBarVisible = forceStatusBarVisible;
297 apply(mCurrentState);
298 }
299
Selim Cinek737bff32015-05-08 16:08:35 -0700300 /**
301 * Force the window to be collapsed, even if it should theoretically be expanded.
302 * Used for when a heads-up comes in but we still need to wait for the touchable regions to
303 * be computed.
304 */
305 public void setForceWindowCollapsed(boolean force) {
306 mCurrentState.forceCollapsed = force;
307 apply(mCurrentState);
308 }
309
Selim Cinek4a21a7f2015-05-19 11:00:38 -0700310 public void setPanelExpanded(boolean isExpanded) {
311 mCurrentState.panelExpanded = isExpanded;
312 apply(mCurrentState);
313 }
314
Adrian Roosd28ccd72016-01-06 15:23:14 +0100315 @Override
316 public void onRemoteInputActive(boolean remoteInputActive) {
Adrian Roos1c0ca502015-10-07 12:20:42 -0700317 mCurrentState.remoteInputActive = remoteInputActive;
318 apply(mCurrentState);
319 }
320
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700321 /**
322 * Set whether the screen brightness is forced to the value we use for doze mode by the status
323 * bar window.
324 */
325 public void setForceDozeBrightness(boolean forceDozeBrightness) {
326 mCurrentState.forceDozeBrightness = forceDozeBrightness;
327 apply(mCurrentState);
328 }
329
Selim Cinek7025f262015-07-13 16:22:48 -0700330 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
331 pw.println("StatusBarWindowManager state:");
332 pw.println(mCurrentState);
Selim Cinek6a1bd2b2015-06-02 16:02:41 +0200333 }
334
Adrian Roosd5c2db62016-03-08 16:11:31 -0800335 public boolean isShowingWallpaper() {
336 return !mCurrentState.backdropShowing;
337 }
338
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100339 private static class State {
340 boolean keyguardShowing;
341 boolean keyguardOccluded;
342 boolean keyguardNeedsInput;
Selim Cinek4a21a7f2015-05-19 11:00:38 -0700343 boolean panelVisible;
344 boolean panelExpanded;
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100345 boolean statusBarFocusable;
Jorim Jaggi5fd4d052014-05-13 22:50:20 +0200346 boolean bouncerShowing;
Jorim Jaggie29b2db2014-05-30 23:17:03 +0200347 boolean keyguardFadingAway;
Jorim Jaggib690f0d2014-07-03 23:25:44 +0200348 boolean qsExpanded;
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700349 boolean headsUpShowing;
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -0700350 boolean forceStatusBarVisible;
Selim Cinek737bff32015-05-08 16:08:35 -0700351 boolean forceCollapsed;
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700352 boolean forceDozeBrightness;
Vadim Tryshev6069c402016-03-09 14:24:29 -0800353 boolean forceUserActivity;
Adrian Roosd5c2db62016-03-08 16:11:31 -0800354 boolean backdropShowing;
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100355
Jorim Jaggiecbab362014-04-23 16:13:15 +0200356 /**
357 * The {@link BaseStatusBar} state from the status bar.
358 */
359 int statusBarState;
360
Adrian Roos1c0ca502015-10-07 12:20:42 -0700361 boolean remoteInputActive;
362
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100363 private boolean isKeyguardShowingAndNotOccluded() {
364 return keyguardShowing && !keyguardOccluded;
365 }
Selim Cinek6a1bd2b2015-06-02 16:02:41 +0200366
367 @Override
368 public String toString() {
369 StringBuilder result = new StringBuilder();
370 String newLine = "\n";
371 result.append("Window State {");
372 result.append(newLine);
373
374 Field[] fields = this.getClass().getDeclaredFields();
375
376 // Print field names paired with their values
377 for (Field field : fields) {
378 result.append(" ");
379 try {
380 result.append(field.getName());
381 result.append(": ");
382 //requires access to private field:
383 result.append(field.get(this));
384 } catch (IllegalAccessException ex) {
385 }
386 result.append(newLine);
387 }
388 result.append("}");
389
390 return result.toString();
391 }
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100392 }
393}