blob: 038fefb7cd3a8bbc9699743fb32776685e6747d1 [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;
32import com.android.systemui.statusbar.StatusBarState;
Jorim Jaggi5cf17872014-03-26 18:31:48 +010033
Selim Cinek7025f262015-07-13 16:22:48 -070034import java.io.FileDescriptor;
35import java.io.PrintWriter;
Selim Cinek6a1bd2b2015-06-02 16:02:41 +020036import java.lang.reflect.Field;
37
Jorim Jaggi5cf17872014-03-26 18:31:48 +010038/**
39 * Encapsulates all logic for the status bar window state management.
40 */
41public class StatusBarWindowManager {
42
43 private final Context mContext;
44 private final WindowManager mWindowManager;
45 private View mStatusBarView;
46 private WindowManager.LayoutParams mLp;
Jorim Jaggi95e89ca2014-11-24 20:12:50 +010047 private WindowManager.LayoutParams mLpChanged;
Jorim Jaggi5cf17872014-03-26 18:31:48 +010048 private int mBarHeight;
49 private final boolean mKeyguardScreenRotation;
50
51 private final State mCurrentState = new State();
52
53 public StatusBarWindowManager(Context context) {
54 mContext = context;
55 mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
56 mKeyguardScreenRotation = shouldEnableKeyguardScreenRotation();
57 }
58
59 private boolean shouldEnableKeyguardScreenRotation() {
60 Resources res = mContext.getResources();
61 return SystemProperties.getBoolean("lockscreen.rot_override", false)
62 || res.getBoolean(R.bool.config_enableLockScreenRotation);
63 }
64
65 /**
66 * Adds the status bar view to the window manager.
67 *
68 * @param statusBarView The view to add.
69 * @param barHeight The height of the status bar in collapsed state.
70 */
71 public void add(View statusBarView, int barHeight) {
72
73 // Now that the status bar window encompasses the sliding panel and its
74 // translucent backdrop, the entire thing is made TRANSLUCENT and is
75 // hardware-accelerated.
76 mLp = new WindowManager.LayoutParams(
77 ViewGroup.LayoutParams.MATCH_PARENT,
78 barHeight,
79 WindowManager.LayoutParams.TYPE_STATUS_BAR,
80 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
81 | WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
82 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
83 | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
Adrian Roosea562512014-05-05 13:33:03 +020084 | WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS,
Jorim Jaggi5cf17872014-03-26 18:31:48 +010085 PixelFormat.TRANSLUCENT);
Jorim Jaggi5cf17872014-03-26 18:31:48 +010086 mLp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
Jorim Jaggi76aaef52014-05-08 19:16:49 +020087 mLp.gravity = Gravity.TOP;
Jorim Jaggi5cf17872014-03-26 18:31:48 +010088 mLp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
Jorim Jaggi5cf17872014-03-26 18:31:48 +010089 mLp.setTitle("StatusBar");
90 mLp.packageName = mContext.getPackageName();
91 mStatusBarView = statusBarView;
92 mBarHeight = barHeight;
93 mWindowManager.addView(mStatusBarView, mLp);
Jorim Jaggi95e89ca2014-11-24 20:12:50 +010094 mLpChanged = new WindowManager.LayoutParams();
95 mLpChanged.copyFrom(mLp);
Jorim Jaggi5cf17872014-03-26 18:31:48 +010096 }
97
98 private void applyKeyguardFlags(State state) {
99 if (state.keyguardShowing) {
Jorim Jaggi95e89ca2014-11-24 20:12:50 +0100100 mLpChanged.flags |= WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
101 mLpChanged.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100102 } else {
Jorim Jaggi95e89ca2014-11-24 20:12:50 +0100103 mLpChanged.flags &= ~WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
104 mLpChanged.privateFlags &= ~WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100105 }
106 }
107
108 private void adjustScreenOrientation(State state) {
Jorim Jaggica36cf72014-04-17 20:36:15 +0200109 if (state.isKeyguardShowingAndNotOccluded()) {
110 if (mKeyguardScreenRotation) {
Jorim Jaggi95e89ca2014-11-24 20:12:50 +0100111 mLpChanged.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_USER;
Jorim Jaggica36cf72014-04-17 20:36:15 +0200112 } else {
Jorim Jaggi95e89ca2014-11-24 20:12:50 +0100113 mLpChanged.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
Jorim Jaggica36cf72014-04-17 20:36:15 +0200114 }
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100115 } else {
Jorim Jaggi95e89ca2014-11-24 20:12:50 +0100116 mLpChanged.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100117 }
118 }
119
120 private void applyFocusableFlag(State state) {
Selim Cinek4a21a7f2015-05-19 11:00:38 -0700121 boolean panelFocusable = state.statusBarFocusable && state.panelExpanded;
Adrian Rooseb91ca52015-06-10 15:49:11 -0700122 if (state.keyguardShowing && state.keyguardNeedsInput && state.bouncerShowing) {
Jorim Jaggi95e89ca2014-11-24 20:12:50 +0100123 mLpChanged.flags &= ~WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
124 mLpChanged.flags &= ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
Selim Cinek4a21a7f2015-05-19 11:00:38 -0700125 } else if (state.isKeyguardShowingAndNotOccluded() || panelFocusable) {
Jorim Jaggi95e89ca2014-11-24 20:12:50 +0100126 mLpChanged.flags &= ~WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
127 mLpChanged.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100128 } else {
Jorim Jaggi95e89ca2014-11-24 20:12:50 +0100129 mLpChanged.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
130 mLpChanged.flags &= ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100131 }
132 }
133
134 private void applyHeight(State state) {
Selim Cinek6a1bd2b2015-06-02 16:02:41 +0200135 boolean expanded = isExpanded(state);
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100136 if (expanded) {
Jorim Jaggi95e89ca2014-11-24 20:12:50 +0100137 mLpChanged.height = ViewGroup.LayoutParams.MATCH_PARENT;
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100138 } else {
Jorim Jaggi95e89ca2014-11-24 20:12:50 +0100139 mLpChanged.height = mBarHeight;
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100140 }
141 }
142
Selim Cinek6a1bd2b2015-06-02 16:02:41 +0200143 private boolean isExpanded(State state) {
144 return !state.forceCollapsed && (state.isKeyguardShowingAndNotOccluded()
145 || state.panelVisible || state.keyguardFadingAway || state.bouncerShowing
146 || state.headsUpShowing);
147 }
148
Jorim Jaggia005f1b2014-04-16 19:06:10 +0200149 private void applyFitsSystemWindows(State state) {
150 mStatusBarView.setFitsSystemWindows(!state.isKeyguardShowingAndNotOccluded());
151 }
152
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100153 private void applyUserActivityTimeout(State state) {
Jorim Jaggiecbab362014-04-23 16:13:15 +0200154 if (state.isKeyguardShowingAndNotOccluded()
Jorim Jaggib690f0d2014-07-03 23:25:44 +0200155 && state.statusBarState == StatusBarState.KEYGUARD
156 && !state.qsExpanded) {
Jorim Jaggi6b88cdf2014-12-22 20:56:50 +0100157 mLpChanged.userActivityTimeout = KeyguardViewMediator.AWAKE_INTERVAL_DEFAULT_MS;
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100158 } else {
Jorim Jaggi95e89ca2014-11-24 20:12:50 +0100159 mLpChanged.userActivityTimeout = -1;
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100160 }
161 }
162
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200163 private void applyInputFeatures(State state) {
Jorim Jaggi4222d9a2014-04-23 16:13:15 +0200164 if (state.isKeyguardShowingAndNotOccluded()
Jorim Jaggib690f0d2014-07-03 23:25:44 +0200165 && state.statusBarState == StatusBarState.KEYGUARD
166 && !state.qsExpanded) {
Jorim Jaggi95e89ca2014-11-24 20:12:50 +0100167 mLpChanged.inputFeatures |=
168 WindowManager.LayoutParams.INPUT_FEATURE_DISABLE_USER_ACTIVITY;
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200169 } else {
Jorim Jaggi95e89ca2014-11-24 20:12:50 +0100170 mLpChanged.inputFeatures &=
171 ~WindowManager.LayoutParams.INPUT_FEATURE_DISABLE_USER_ACTIVITY;
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200172 }
173 }
174
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100175 private void apply(State state) {
176 applyKeyguardFlags(state);
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -0700177 applyForceStatusBarVisibleFlag(state);
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100178 applyFocusableFlag(state);
179 adjustScreenOrientation(state);
180 applyHeight(state);
181 applyUserActivityTimeout(state);
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200182 applyInputFeatures(state);
Jorim Jaggia005f1b2014-04-16 19:06:10 +0200183 applyFitsSystemWindows(state);
Selim Cineka59ecc32015-04-07 10:51:49 -0700184 applyModalFlag(state);
Jorim Jaggi95e89ca2014-11-24 20:12:50 +0100185 if (mLp.copyFrom(mLpChanged) != 0) {
186 mWindowManager.updateViewLayout(mStatusBarView, mLp);
187 }
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100188 }
189
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -0700190 private void applyForceStatusBarVisibleFlag(State state) {
191 if (state.forceStatusBarVisible) {
192 mLpChanged.privateFlags |= WindowManager
193 .LayoutParams.PRIVATE_FLAG_FORCE_STATUS_BAR_VISIBLE_TRANSPARENT;
194 } else {
195 mLpChanged.privateFlags &= ~WindowManager
196 .LayoutParams.PRIVATE_FLAG_FORCE_STATUS_BAR_VISIBLE_TRANSPARENT;
197 }
198 }
199
Selim Cineka59ecc32015-04-07 10:51:49 -0700200 private void applyModalFlag(State state) {
201 if (state.headsUpShowing) {
202 mLpChanged.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
203 } else {
204 mLpChanged.flags &= ~WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
205 }
206 }
207
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100208 public void setKeyguardShowing(boolean showing) {
209 mCurrentState.keyguardShowing = showing;
210 apply(mCurrentState);
211 }
212
213 public void setKeyguardOccluded(boolean occluded) {
214 mCurrentState.keyguardOccluded = occluded;
215 apply(mCurrentState);
216 }
217
218 public void setKeyguardNeedsInput(boolean needsInput) {
219 mCurrentState.keyguardNeedsInput = needsInput;
220 apply(mCurrentState);
221 }
222
Selim Cinek4a21a7f2015-05-19 11:00:38 -0700223 public void setPanelVisible(boolean visible) {
224 mCurrentState.panelVisible = visible;
225 mCurrentState.statusBarFocusable = visible;
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100226 apply(mCurrentState);
227 }
228
229 public void setStatusBarFocusable(boolean focusable) {
230 mCurrentState.statusBarFocusable = focusable;
231 apply(mCurrentState);
232 }
233
Jorim Jaggi5fd4d052014-05-13 22:50:20 +0200234 public void setBouncerShowing(boolean showing) {
235 mCurrentState.bouncerShowing = showing;
236 apply(mCurrentState);
237 }
238
Jorim Jaggie29b2db2014-05-30 23:17:03 +0200239 public void setKeyguardFadingAway(boolean keyguardFadingAway) {
240 mCurrentState.keyguardFadingAway = keyguardFadingAway;
241 apply(mCurrentState);
242 }
243
Jorim Jaggib690f0d2014-07-03 23:25:44 +0200244 public void setQsExpanded(boolean expanded) {
245 mCurrentState.qsExpanded = expanded;
246 apply(mCurrentState);
247 }
248
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700249 public void setHeadsUpShowing(boolean showing) {
250 mCurrentState.headsUpShowing = showing;
251 apply(mCurrentState);
252 }
253
Jorim Jaggiecbab362014-04-23 16:13:15 +0200254 /**
255 * @param state The {@link StatusBarState} of the status bar.
256 */
257 public void setStatusBarState(int state) {
258 mCurrentState.statusBarState = state;
259 apply(mCurrentState);
260 }
261
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -0700262 public void setForceStatusBarVisible(boolean forceStatusBarVisible) {
263 mCurrentState.forceStatusBarVisible = forceStatusBarVisible;
264 apply(mCurrentState);
265 }
266
Selim Cinek737bff32015-05-08 16:08:35 -0700267 /**
268 * Force the window to be collapsed, even if it should theoretically be expanded.
269 * Used for when a heads-up comes in but we still need to wait for the touchable regions to
270 * be computed.
271 */
272 public void setForceWindowCollapsed(boolean force) {
273 mCurrentState.forceCollapsed = force;
274 apply(mCurrentState);
275 }
276
Selim Cinek4a21a7f2015-05-19 11:00:38 -0700277 public void setPanelExpanded(boolean isExpanded) {
278 mCurrentState.panelExpanded = isExpanded;
279 apply(mCurrentState);
280 }
281
Selim Cinek7025f262015-07-13 16:22:48 -0700282 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
283 pw.println("StatusBarWindowManager state:");
284 pw.println(mCurrentState);
Selim Cinek6a1bd2b2015-06-02 16:02:41 +0200285 }
286
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100287 private static class State {
288 boolean keyguardShowing;
289 boolean keyguardOccluded;
290 boolean keyguardNeedsInput;
Selim Cinek4a21a7f2015-05-19 11:00:38 -0700291 boolean panelVisible;
292 boolean panelExpanded;
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100293 boolean statusBarFocusable;
Jorim Jaggi5fd4d052014-05-13 22:50:20 +0200294 boolean bouncerShowing;
Jorim Jaggie29b2db2014-05-30 23:17:03 +0200295 boolean keyguardFadingAway;
Jorim Jaggib690f0d2014-07-03 23:25:44 +0200296 boolean qsExpanded;
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700297 boolean headsUpShowing;
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -0700298 boolean forceStatusBarVisible;
Selim Cinek737bff32015-05-08 16:08:35 -0700299 boolean forceCollapsed;
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100300
Jorim Jaggiecbab362014-04-23 16:13:15 +0200301 /**
302 * The {@link BaseStatusBar} state from the status bar.
303 */
304 int statusBarState;
305
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100306 private boolean isKeyguardShowingAndNotOccluded() {
307 return keyguardShowing && !keyguardOccluded;
308 }
Selim Cinek6a1bd2b2015-06-02 16:02:41 +0200309
310 @Override
311 public String toString() {
312 StringBuilder result = new StringBuilder();
313 String newLine = "\n";
314 result.append("Window State {");
315 result.append(newLine);
316
317 Field[] fields = this.getClass().getDeclaredFields();
318
319 // Print field names paired with their values
320 for (Field field : fields) {
321 result.append(" ");
322 try {
323 result.append(field.getName());
324 result.append(": ");
325 //requires access to private field:
326 result.append(field.get(this));
327 } catch (IllegalAccessException ex) {
328 }
329 result.append(newLine);
330 }
331 result.append("}");
332
333 return result.toString();
334 }
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100335 }
336}