blob: 4f1c652fd80fac652df20dbf60c90bad12ecc3a7 [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
34/**
35 * Encapsulates all logic for the status bar window state management.
36 */
37public class StatusBarWindowManager {
38
39 private final Context mContext;
40 private final WindowManager mWindowManager;
41 private View mStatusBarView;
42 private WindowManager.LayoutParams mLp;
Jorim Jaggi95e89ca2014-11-24 20:12:50 +010043 private WindowManager.LayoutParams mLpChanged;
Jorim Jaggi5cf17872014-03-26 18:31:48 +010044 private int mBarHeight;
45 private final boolean mKeyguardScreenRotation;
46
47 private final State mCurrentState = new State();
48
49 public StatusBarWindowManager(Context context) {
50 mContext = context;
51 mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
52 mKeyguardScreenRotation = shouldEnableKeyguardScreenRotation();
53 }
54
55 private boolean shouldEnableKeyguardScreenRotation() {
56 Resources res = mContext.getResources();
57 return SystemProperties.getBoolean("lockscreen.rot_override", false)
58 || res.getBoolean(R.bool.config_enableLockScreenRotation);
59 }
60
61 /**
62 * Adds the status bar view to the window manager.
63 *
64 * @param statusBarView The view to add.
65 * @param barHeight The height of the status bar in collapsed state.
66 */
67 public void add(View statusBarView, int barHeight) {
68
69 // Now that the status bar window encompasses the sliding panel and its
70 // translucent backdrop, the entire thing is made TRANSLUCENT and is
71 // hardware-accelerated.
72 mLp = new WindowManager.LayoutParams(
73 ViewGroup.LayoutParams.MATCH_PARENT,
74 barHeight,
75 WindowManager.LayoutParams.TYPE_STATUS_BAR,
76 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
77 | WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
78 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
79 | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
Adrian Roosea562512014-05-05 13:33:03 +020080 | WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS,
Jorim Jaggi5cf17872014-03-26 18:31:48 +010081 PixelFormat.TRANSLUCENT);
Jorim Jaggi5cf17872014-03-26 18:31:48 +010082 mLp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
Jorim Jaggi76aaef52014-05-08 19:16:49 +020083 mLp.gravity = Gravity.TOP;
Jorim Jaggi5cf17872014-03-26 18:31:48 +010084 mLp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
Jorim Jaggi5cf17872014-03-26 18:31:48 +010085 mLp.setTitle("StatusBar");
86 mLp.packageName = mContext.getPackageName();
87 mStatusBarView = statusBarView;
88 mBarHeight = barHeight;
89 mWindowManager.addView(mStatusBarView, mLp);
Jorim Jaggi95e89ca2014-11-24 20:12:50 +010090 mLpChanged = new WindowManager.LayoutParams();
91 mLpChanged.copyFrom(mLp);
Jorim Jaggi5cf17872014-03-26 18:31:48 +010092 }
93
94 private void applyKeyguardFlags(State state) {
95 if (state.keyguardShowing) {
Jorim Jaggi95e89ca2014-11-24 20:12:50 +010096 mLpChanged.flags |= WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
97 mLpChanged.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
Jorim Jaggi5cf17872014-03-26 18:31:48 +010098 } else {
Jorim Jaggi95e89ca2014-11-24 20:12:50 +010099 mLpChanged.flags &= ~WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
100 mLpChanged.privateFlags &= ~WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100101 }
102 }
103
104 private void adjustScreenOrientation(State state) {
Jorim Jaggica36cf72014-04-17 20:36:15 +0200105 if (state.isKeyguardShowingAndNotOccluded()) {
106 if (mKeyguardScreenRotation) {
Jorim Jaggi95e89ca2014-11-24 20:12:50 +0100107 mLpChanged.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_USER;
Jorim Jaggica36cf72014-04-17 20:36:15 +0200108 } else {
Jorim Jaggi95e89ca2014-11-24 20:12:50 +0100109 mLpChanged.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
Jorim Jaggica36cf72014-04-17 20:36:15 +0200110 }
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100111 } else {
Jorim Jaggi95e89ca2014-11-24 20:12:50 +0100112 mLpChanged.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100113 }
114 }
115
116 private void applyFocusableFlag(State state) {
Selim Cinek4a21a7f2015-05-19 11:00:38 -0700117 boolean panelFocusable = state.statusBarFocusable && state.panelExpanded;
Jorim Jaggi5fd4d052014-05-13 22:50:20 +0200118 if (state.isKeyguardShowingAndNotOccluded() && state.keyguardNeedsInput
Selim Cinek4a21a7f2015-05-19 11:00:38 -0700119 && state.bouncerShowing || BaseStatusBar.ENABLE_REMOTE_INPUT && panelFocusable) {
Jorim Jaggi95e89ca2014-11-24 20:12:50 +0100120 mLpChanged.flags &= ~WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
121 mLpChanged.flags &= ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
Selim Cinek4a21a7f2015-05-19 11:00:38 -0700122 } else if (state.isKeyguardShowingAndNotOccluded() || panelFocusable) {
Jorim Jaggi95e89ca2014-11-24 20:12:50 +0100123 mLpChanged.flags &= ~WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
124 mLpChanged.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100125 } else {
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 }
129 }
130
131 private void applyHeight(State state) {
Selim Cinek737bff32015-05-08 16:08:35 -0700132 boolean expanded = !state.forceCollapsed && (state.isKeyguardShowingAndNotOccluded()
Selim Cinek4a21a7f2015-05-19 11:00:38 -0700133 || state.panelVisible || state.keyguardFadingAway || state.bouncerShowing
Selim Cinek737bff32015-05-08 16:08:35 -0700134 || state.headsUpShowing);
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100135 if (expanded) {
Jorim Jaggi95e89ca2014-11-24 20:12:50 +0100136 mLpChanged.height = ViewGroup.LayoutParams.MATCH_PARENT;
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100137 } else {
Jorim Jaggi95e89ca2014-11-24 20:12:50 +0100138 mLpChanged.height = mBarHeight;
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100139 }
140 }
141
Jorim Jaggia005f1b2014-04-16 19:06:10 +0200142 private void applyFitsSystemWindows(State state) {
143 mStatusBarView.setFitsSystemWindows(!state.isKeyguardShowingAndNotOccluded());
144 }
145
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100146 private void applyUserActivityTimeout(State state) {
Jorim Jaggiecbab362014-04-23 16:13:15 +0200147 if (state.isKeyguardShowingAndNotOccluded()
Jorim Jaggib690f0d2014-07-03 23:25:44 +0200148 && state.statusBarState == StatusBarState.KEYGUARD
149 && !state.qsExpanded) {
Jorim Jaggi6b88cdf2014-12-22 20:56:50 +0100150 mLpChanged.userActivityTimeout = KeyguardViewMediator.AWAKE_INTERVAL_DEFAULT_MS;
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100151 } else {
Jorim Jaggi95e89ca2014-11-24 20:12:50 +0100152 mLpChanged.userActivityTimeout = -1;
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100153 }
154 }
155
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200156 private void applyInputFeatures(State state) {
Jorim Jaggi4222d9a2014-04-23 16:13:15 +0200157 if (state.isKeyguardShowingAndNotOccluded()
Jorim Jaggib690f0d2014-07-03 23:25:44 +0200158 && state.statusBarState == StatusBarState.KEYGUARD
159 && !state.qsExpanded) {
Jorim Jaggi95e89ca2014-11-24 20:12:50 +0100160 mLpChanged.inputFeatures |=
161 WindowManager.LayoutParams.INPUT_FEATURE_DISABLE_USER_ACTIVITY;
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200162 } else {
Jorim Jaggi95e89ca2014-11-24 20:12:50 +0100163 mLpChanged.inputFeatures &=
164 ~WindowManager.LayoutParams.INPUT_FEATURE_DISABLE_USER_ACTIVITY;
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200165 }
166 }
167
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100168 private void apply(State state) {
169 applyKeyguardFlags(state);
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -0700170 applyForceStatusBarVisibleFlag(state);
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100171 applyFocusableFlag(state);
172 adjustScreenOrientation(state);
173 applyHeight(state);
174 applyUserActivityTimeout(state);
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200175 applyInputFeatures(state);
Jorim Jaggia005f1b2014-04-16 19:06:10 +0200176 applyFitsSystemWindows(state);
Selim Cineka59ecc32015-04-07 10:51:49 -0700177 applyModalFlag(state);
Jorim Jaggi95e89ca2014-11-24 20:12:50 +0100178 if (mLp.copyFrom(mLpChanged) != 0) {
179 mWindowManager.updateViewLayout(mStatusBarView, mLp);
180 }
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100181 }
182
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -0700183 private void applyForceStatusBarVisibleFlag(State state) {
184 if (state.forceStatusBarVisible) {
185 mLpChanged.privateFlags |= WindowManager
186 .LayoutParams.PRIVATE_FLAG_FORCE_STATUS_BAR_VISIBLE_TRANSPARENT;
187 } else {
188 mLpChanged.privateFlags &= ~WindowManager
189 .LayoutParams.PRIVATE_FLAG_FORCE_STATUS_BAR_VISIBLE_TRANSPARENT;
190 }
191 }
192
Selim Cineka59ecc32015-04-07 10:51:49 -0700193 private void applyModalFlag(State state) {
194 if (state.headsUpShowing) {
195 mLpChanged.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
196 } else {
197 mLpChanged.flags &= ~WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
198 }
199 }
200
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100201 public void setKeyguardShowing(boolean showing) {
202 mCurrentState.keyguardShowing = showing;
203 apply(mCurrentState);
204 }
205
206 public void setKeyguardOccluded(boolean occluded) {
207 mCurrentState.keyguardOccluded = occluded;
208 apply(mCurrentState);
209 }
210
211 public void setKeyguardNeedsInput(boolean needsInput) {
212 mCurrentState.keyguardNeedsInput = needsInput;
213 apply(mCurrentState);
214 }
215
Selim Cinek4a21a7f2015-05-19 11:00:38 -0700216 public void setPanelVisible(boolean visible) {
217 mCurrentState.panelVisible = visible;
218 mCurrentState.statusBarFocusable = visible;
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100219 apply(mCurrentState);
220 }
221
222 public void setStatusBarFocusable(boolean focusable) {
223 mCurrentState.statusBarFocusable = focusable;
224 apply(mCurrentState);
225 }
226
Jorim Jaggi5fd4d052014-05-13 22:50:20 +0200227 public void setBouncerShowing(boolean showing) {
228 mCurrentState.bouncerShowing = showing;
229 apply(mCurrentState);
230 }
231
Jorim Jaggie29b2db2014-05-30 23:17:03 +0200232 public void setKeyguardFadingAway(boolean keyguardFadingAway) {
233 mCurrentState.keyguardFadingAway = keyguardFadingAway;
234 apply(mCurrentState);
235 }
236
Jorim Jaggib690f0d2014-07-03 23:25:44 +0200237 public void setQsExpanded(boolean expanded) {
238 mCurrentState.qsExpanded = expanded;
239 apply(mCurrentState);
240 }
241
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700242 public void setHeadsUpShowing(boolean showing) {
243 mCurrentState.headsUpShowing = showing;
244 apply(mCurrentState);
245 }
246
Jorim Jaggiecbab362014-04-23 16:13:15 +0200247 /**
248 * @param state The {@link StatusBarState} of the status bar.
249 */
250 public void setStatusBarState(int state) {
251 mCurrentState.statusBarState = state;
252 apply(mCurrentState);
253 }
254
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -0700255 public void setForceStatusBarVisible(boolean forceStatusBarVisible) {
256 mCurrentState.forceStatusBarVisible = forceStatusBarVisible;
257 apply(mCurrentState);
258 }
259
Selim Cinek737bff32015-05-08 16:08:35 -0700260 /**
261 * Force the window to be collapsed, even if it should theoretically be expanded.
262 * Used for when a heads-up comes in but we still need to wait for the touchable regions to
263 * be computed.
264 */
265 public void setForceWindowCollapsed(boolean force) {
266 mCurrentState.forceCollapsed = force;
267 apply(mCurrentState);
268 }
269
Selim Cinek4a21a7f2015-05-19 11:00:38 -0700270 public void setPanelExpanded(boolean isExpanded) {
271 mCurrentState.panelExpanded = isExpanded;
272 apply(mCurrentState);
273 }
274
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100275 private static class State {
276 boolean keyguardShowing;
277 boolean keyguardOccluded;
278 boolean keyguardNeedsInput;
Selim Cinek4a21a7f2015-05-19 11:00:38 -0700279 boolean panelVisible;
280 boolean panelExpanded;
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100281 boolean statusBarFocusable;
Jorim Jaggi5fd4d052014-05-13 22:50:20 +0200282 boolean bouncerShowing;
Jorim Jaggie29b2db2014-05-30 23:17:03 +0200283 boolean keyguardFadingAway;
Jorim Jaggib690f0d2014-07-03 23:25:44 +0200284 boolean qsExpanded;
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700285 boolean headsUpShowing;
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -0700286 boolean forceStatusBarVisible;
Selim Cinek737bff32015-05-08 16:08:35 -0700287 boolean forceCollapsed;
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100288
Jorim Jaggiecbab362014-04-23 16:13:15 +0200289 /**
290 * The {@link BaseStatusBar} state from the status bar.
291 */
292 int statusBarState;
293
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100294 private boolean isKeyguardShowingAndNotOccluded() {
295 return keyguardShowing && !keyguardOccluded;
296 }
297 }
298}