1 /* 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 17 package com.android.systemui.statusbar.phone; 18 19 import android.content.Context; 20 import android.content.pm.ActivityInfo; 21 import android.content.res.Resources; 22 import android.graphics.PixelFormat; 23 import android.os.SystemProperties; 24 import android.view.Gravity; 25 import android.view.View; 26 import android.view.ViewGroup; 27 import android.view.WindowManager; 28 29 import com.android.keyguard.R; 30 import com.android.systemui.statusbar.BaseStatusBar; 31 import com.android.systemui.statusbar.StatusBarState; 32 33 /** 34 * Encapsulates all logic for the status bar window state management. 35 */ 36 public class StatusBarWindowManager { 37 38 private final Context mContext; 39 private final WindowManager mWindowManager; 40 private View mStatusBarView; 41 private WindowManager.LayoutParams mLp; 42 private WindowManager.LayoutParams mLpChanged; 43 private int mBarHeight; 44 private final boolean mKeyguardScreenRotation; 45 46 private final State mCurrentState = new State(); 47 48 public StatusBarWindowManager(Context context) { 49 mContext = context; 50 mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); 51 mKeyguardScreenRotation = shouldEnableKeyguardScreenRotation(); 52 } 53 54 private boolean shouldEnableKeyguardScreenRotation() { 55 Resources res = mContext.getResources(); 56 return SystemProperties.getBoolean("lockscreen.rot_override", false) 57 || res.getBoolean(R.bool.config_enableLockScreenRotation); 58 } 59 60 /** 61 * Adds the status bar view to the window manager. 62 * 63 * @param statusBarView The view to add. 64 * @param barHeight The height of the status bar in collapsed state. 65 */ 66 public void add(View statusBarView, int barHeight) { 67 68 // Now that the status bar window encompasses the sliding panel and its 69 // translucent backdrop, the entire thing is made TRANSLUCENT and is 70 // hardware-accelerated. 71 mLp = new WindowManager.LayoutParams( 72 ViewGroup.LayoutParams.MATCH_PARENT, 73 barHeight, 74 WindowManager.LayoutParams.TYPE_STATUS_BAR, 75 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 76 | WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING 77 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH 78 | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH 79 | WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS, 80 PixelFormat.TRANSLUCENT); 81 mLp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED; 82 mLp.gravity = Gravity.TOP; 83 mLp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; 84 mLp.setTitle("StatusBar"); 85 mLp.packageName = mContext.getPackageName(); 86 mStatusBarView = statusBarView; 87 mBarHeight = barHeight; 88 mWindowManager.addView(mStatusBarView, mLp); 89 mLpChanged = new WindowManager.LayoutParams(); 90 mLpChanged.copyFrom(mLp); 91 } 92 93 private void applyKeyguardFlags(State state) { 94 if (state.keyguardShowing) { 95 mLpChanged.flags |= WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER; 96 mLpChanged.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD; 97 } else { 98 mLpChanged.flags &= ~WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER; 99 mLpChanged.privateFlags &= ~WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD; 100 } 101 } 102 103 private void adjustScreenOrientation(State state) { 104 if (state.isKeyguardShowingAndNotOccluded()) { 105 if (mKeyguardScreenRotation) { 106 mLpChanged.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_USER; 107 } else { 108 mLpChanged.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR; 109 } 110 } else { 111 mLpChanged.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 112 } 113 } 114 115 private void applyFocusableFlag(State state) { 116 if (state.isKeyguardShowingAndNotOccluded() && state.keyguardNeedsInput 117 && state.bouncerShowing) { 118 mLpChanged.flags &= ~WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; 119 mLpChanged.flags &= ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; 120 } else if (state.isKeyguardShowingAndNotOccluded() || state.statusBarFocusable) { 121 mLpChanged.flags &= ~WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; 122 mLpChanged.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; 123 } else { 124 mLpChanged.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; 125 mLpChanged.flags &= ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; 126 } 127 } 128 129 private void applyHeight(State state) { 130 boolean expanded = state.isKeyguardShowingAndNotOccluded() || state.statusBarExpanded 131 || state.keyguardFadingAway || state.bouncerShowing; 132 if (expanded) { 133 mLpChanged.height = ViewGroup.LayoutParams.MATCH_PARENT; 134 } else { 135 mLpChanged.height = mBarHeight; 136 } 137 } 138 139 private void applyFitsSystemWindows(State state) { 140 mStatusBarView.setFitsSystemWindows(!state.isKeyguardShowingAndNotOccluded()); 141 } 142 143 private void applyUserActivityTimeout(State state) { 144 if (state.isKeyguardShowingAndNotOccluded() 145 && state.statusBarState == StatusBarState.KEYGUARD 146 && !state.qsExpanded) { 147 mLpChanged.userActivityTimeout = state.keyguardUserActivityTimeout; 148 } else { 149 mLpChanged.userActivityTimeout = -1; 150 } 151 } 152 153 private void applyInputFeatures(State state) { 154 if (state.isKeyguardShowingAndNotOccluded() 155 && state.statusBarState == StatusBarState.KEYGUARD 156 && !state.qsExpanded) { 157 mLpChanged.inputFeatures |= 158 WindowManager.LayoutParams.INPUT_FEATURE_DISABLE_USER_ACTIVITY; 159 } else { 160 mLpChanged.inputFeatures &= 161 ~WindowManager.LayoutParams.INPUT_FEATURE_DISABLE_USER_ACTIVITY; 162 } 163 } 164 165 private void apply(State state) { 166 applyKeyguardFlags(state); 167 applyFocusableFlag(state); 168 adjustScreenOrientation(state); 169 applyHeight(state); 170 applyUserActivityTimeout(state); 171 applyInputFeatures(state); 172 applyFitsSystemWindows(state); 173 if (mLp.copyFrom(mLpChanged) != 0) { 174 mWindowManager.updateViewLayout(mStatusBarView, mLp); 175 } 176 } 177 178 public void setKeyguardShowing(boolean showing) { 179 mCurrentState.keyguardShowing = showing; 180 apply(mCurrentState); 181 } 182 183 public void setKeyguardOccluded(boolean occluded) { 184 mCurrentState.keyguardOccluded = occluded; 185 apply(mCurrentState); 186 } 187 188 public void setKeyguardNeedsInput(boolean needsInput) { 189 mCurrentState.keyguardNeedsInput = needsInput; 190 apply(mCurrentState); 191 } 192 193 public void setStatusBarExpanded(boolean expanded) { 194 mCurrentState.statusBarExpanded = expanded; 195 mCurrentState.statusBarFocusable = expanded; 196 apply(mCurrentState); 197 } 198 199 public void setStatusBarFocusable(boolean focusable) { 200 mCurrentState.statusBarFocusable = focusable; 201 apply(mCurrentState); 202 } 203 204 public void setKeyguardUserActivityTimeout(long timeout) { 205 mCurrentState.keyguardUserActivityTimeout = timeout; 206 apply(mCurrentState); 207 } 208 209 public void setBouncerShowing(boolean showing) { 210 mCurrentState.bouncerShowing = showing; 211 apply(mCurrentState); 212 } 213 214 public void setKeyguardFadingAway(boolean keyguardFadingAway) { 215 mCurrentState.keyguardFadingAway = keyguardFadingAway; 216 apply(mCurrentState); 217 } 218 219 public void setQsExpanded(boolean expanded) { 220 mCurrentState.qsExpanded = expanded; 221 apply(mCurrentState); 222 } 223 224 /** 225 * @param state The {@link StatusBarState} of the status bar. 226 */ 227 public void setStatusBarState(int state) { 228 mCurrentState.statusBarState = state; 229 apply(mCurrentState); 230 } 231 232 private static class State { 233 boolean keyguardShowing; 234 boolean keyguardOccluded; 235 boolean keyguardNeedsInput; 236 boolean statusBarExpanded; 237 boolean statusBarFocusable; 238 long keyguardUserActivityTimeout; 239 boolean bouncerShowing; 240 boolean keyguardFadingAway; 241 boolean qsExpanded; 242 243 /** 244 * The {@link BaseStatusBar} state from the status bar. 245 */ 246 int statusBarState; 247 248 private boolean isKeyguardShowingAndNotOccluded() { 249 return keyguardShowing && !keyguardOccluded; 250 } 251 } 252 } 253