• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 package com.android.launcher3.taskbar;
17 
18 import static android.view.Display.DEFAULT_DISPLAY;
19 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
20 
21 import static com.android.launcher3.util.DisplayController.CHANGE_ACTIVE_SCREEN;
22 import static com.android.launcher3.util.DisplayController.CHANGE_DENSITY;
23 import static com.android.launcher3.util.DisplayController.CHANGE_SUPPORTED_BOUNDS;
24 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SHOWING;
25 
26 import android.content.Context;
27 import android.hardware.display.DisplayManager;
28 import android.inputmethodservice.InputMethodService;
29 import android.view.Display;
30 
31 import androidx.annotation.Nullable;
32 
33 import com.android.launcher3.BaseQuickstepLauncher;
34 import com.android.launcher3.DeviceProfile;
35 import com.android.launcher3.LauncherAppState;
36 import com.android.launcher3.config.FeatureFlags;
37 import com.android.launcher3.util.DisplayController;
38 import com.android.launcher3.util.DisplayController.Info;
39 import com.android.quickstep.SysUINavigationMode;
40 import com.android.quickstep.SysUINavigationMode.Mode;
41 import com.android.quickstep.TouchInteractionService;
42 
43 /**
44  * Class to manager taskbar lifecycle
45  */
46 public class TaskbarManager implements DisplayController.DisplayInfoChangeListener,
47         SysUINavigationMode.NavigationModeChangeListener {
48 
49     private final Context mContext;
50     private final DisplayController mDisplayController;
51     private final SysUINavigationMode mSysUINavigationMode;
52     private final TaskbarNavButtonController mNavButtonController;
53 
54     private TaskbarActivityContext mTaskbarActivityContext;
55     private BaseQuickstepLauncher mLauncher;
56 
57     private static final int CHANGE_FLAGS =
58             CHANGE_ACTIVE_SCREEN | CHANGE_DENSITY | CHANGE_SUPPORTED_BOUNDS;
59 
60     private boolean mUserUnlocked = false;
61 
TaskbarManager(TouchInteractionService service)62     public TaskbarManager(TouchInteractionService service) {
63         mDisplayController = DisplayController.INSTANCE.get(service);
64         mSysUINavigationMode = SysUINavigationMode.INSTANCE.get(service);
65         Display display =
66                 service.getSystemService(DisplayManager.class).getDisplay(DEFAULT_DISPLAY);
67         mContext = service.createWindowContext(display, TYPE_APPLICATION_OVERLAY, null);
68         mNavButtonController = new TaskbarNavButtonController(service);
69 
70         mDisplayController.addChangeListener(this);
71         mSysUINavigationMode.addModeChangeListener(this);
72         recreateTaskbar();
73     }
74 
75     @Override
onNavigationModeChanged(Mode newMode)76     public void onNavigationModeChanged(Mode newMode) {
77         recreateTaskbar();
78     }
79 
80     @Override
onDisplayInfoChanged(Context context, Info info, int flags)81     public void onDisplayInfoChanged(Context context, Info info, int flags) {
82         if ((flags & CHANGE_FLAGS) != 0) {
83             recreateTaskbar();
84         }
85     }
86 
destroyExistingTaskbar()87     private void destroyExistingTaskbar() {
88         if (mTaskbarActivityContext != null) {
89             mTaskbarActivityContext.onDestroy();
90             mTaskbarActivityContext = null;
91         }
92     }
93 
94     /**
95      * Called when the user is unlocked
96      */
onUserUnlocked()97     public void onUserUnlocked() {
98         mUserUnlocked = true;
99         recreateTaskbar();
100     }
101 
102     /**
103      * Sets or clears a launcher to act as taskbar callback
104      */
setLauncher(@ullable BaseQuickstepLauncher launcher)105     public void setLauncher(@Nullable BaseQuickstepLauncher launcher) {
106         mLauncher = launcher;
107         if (mTaskbarActivityContext != null) {
108             mTaskbarActivityContext.setUIController(mLauncher == null
109                     ? TaskbarUIController.DEFAULT
110                     : new LauncherTaskbarUIController(launcher, mTaskbarActivityContext));
111         }
112     }
113 
recreateTaskbar()114     private void recreateTaskbar() {
115         destroyExistingTaskbar();
116         if (!FeatureFlags.ENABLE_TASKBAR.get()) {
117             return;
118         }
119         if (!mUserUnlocked) {
120             return;
121         }
122         DeviceProfile dp = LauncherAppState.getIDP(mContext).getDeviceProfile(mContext);
123         if (!dp.isTaskbarPresent) {
124             return;
125         }
126         mTaskbarActivityContext = new TaskbarActivityContext(
127                 mContext, dp.copy(mContext), mNavButtonController);
128         mTaskbarActivityContext.init();
129         if (mLauncher != null) {
130             mTaskbarActivityContext.setUIController(
131                     new LauncherTaskbarUIController(mLauncher, mTaskbarActivityContext));
132         }
133     }
134 
135     /**
136      * See {@link com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags}
137      * @param systemUiStateFlags The latest SystemUiStateFlags
138      */
onSystemUiFlagsChanged(int systemUiStateFlags)139     public void onSystemUiFlagsChanged(int systemUiStateFlags) {
140         boolean isImeVisible = (systemUiStateFlags & SYSUI_STATE_IME_SHOWING) != 0;
141         if (mTaskbarActivityContext != null) {
142             mTaskbarActivityContext.setImeIsVisible(isImeVisible);
143         }
144     }
145 
146     /**
147      * When in 3 button nav, the above doesn't get called since we prevent sysui nav bar from
148      * instantiating at all, which is what's responsible for sending sysui state flags over.
149      *
150      * @param vis IME visibility flag
151      * @param backDisposition Used to determine back button behavior for software keyboard
152      *                        See BACK_DISPOSITION_* constants in {@link InputMethodService}
153      */
updateImeStatus(int displayId, int vis, int backDisposition, boolean showImeSwitcher)154     public void updateImeStatus(int displayId, int vis, int backDisposition,
155             boolean showImeSwitcher) {
156         if (mTaskbarActivityContext != null) {
157             mTaskbarActivityContext.updateImeStatus(displayId, vis, showImeSwitcher);
158         }
159     }
160 
161     /**
162      * Called when the manager is no longer needed
163      */
destroy()164     public void destroy() {
165         destroyExistingTaskbar();
166         mDisplayController.removeChangeListener(this);
167         mSysUINavigationMode.removeModeChangeListener(this);
168     }
169 }
170