1 /*
2  * Copyright (C) 2017 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.launcher3.util;
18 
19 import android.view.View;
20 import android.view.Window;
21 
22 import com.android.launcher3.Utilities;
23 
24 import java.util.Arrays;
25 
26 /**
27  * Utility class to manage various window flags to control system UI.
28  */
29 public class SystemUiController {
30 
31     // Various UI states in increasing order of priority
32     public static final int UI_STATE_BASE_WINDOW = 0;
33     public static final int UI_STATE_SCRIM_VIEW = 1;
34     public static final int UI_STATE_WIDGET_BOTTOM_SHEET = 2;
35     public static final int UI_STATE_OVERVIEW = 3;
36 
37     public static final int FLAG_LIGHT_NAV = 1 << 0;
38     public static final int FLAG_DARK_NAV = 1 << 1;
39     public static final int FLAG_LIGHT_STATUS = 1 << 2;
40     public static final int FLAG_DARK_STATUS = 1 << 3;
41 
42     private final Window mWindow;
43     private final int[] mStates = new int[4];
44 
SystemUiController(Window window)45     public SystemUiController(Window window) {
46         mWindow = window;
47     }
48 
updateUiState(int uiState, boolean isLight)49     public void updateUiState(int uiState, boolean isLight) {
50         updateUiState(uiState, isLight
51                 ? (FLAG_LIGHT_NAV | FLAG_LIGHT_STATUS) : (FLAG_DARK_NAV | FLAG_DARK_STATUS));
52     }
53 
updateUiState(int uiState, int flags)54     public void updateUiState(int uiState, int flags) {
55         if (mStates[uiState] == flags) {
56             return;
57         }
58         mStates[uiState] = flags;
59 
60         int oldFlags = mWindow.getDecorView().getSystemUiVisibility();
61         // Apply the state flags in priority order
62         int newFlags = oldFlags;
63         for (int stateFlag : mStates) {
64             newFlags = getSysUiVisibilityFlags(stateFlag, newFlags);
65         }
66         if (newFlags != oldFlags) {
67             mWindow.getDecorView().setSystemUiVisibility(newFlags);
68         }
69     }
70 
71     /**
72      * Returns the sysui visibility for the base layer
73      */
getBaseSysuiVisibility()74     public int getBaseSysuiVisibility() {
75         return getSysUiVisibilityFlags(
76                 mStates[UI_STATE_BASE_WINDOW], mWindow.getDecorView().getSystemUiVisibility());
77     }
78 
getSysUiVisibilityFlags(int stateFlag, int currentVisibility)79     private int getSysUiVisibilityFlags(int stateFlag, int currentVisibility) {
80         if (Utilities.ATLEAST_OREO) {
81             if ((stateFlag & FLAG_LIGHT_NAV) != 0) {
82                 currentVisibility |= View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;
83             } else if ((stateFlag & FLAG_DARK_NAV) != 0) {
84                 currentVisibility &= ~(View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR);
85             }
86         }
87 
88         if ((stateFlag & FLAG_LIGHT_STATUS) != 0) {
89             currentVisibility |= View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
90         } else if ((stateFlag & FLAG_DARK_STATUS) != 0) {
91             currentVisibility &= ~(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
92         }
93         return currentVisibility;
94     }
95 
96     @Override
toString()97     public String toString() {
98         return "mStates=" + Arrays.toString(mStates);
99     }
100 }
101