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