Home | History | Annotate | Download | only in phone
      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 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 || state.bouncerShowing;
    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