• 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 android.content.pm.ActivityInfo.Config;
19 
20 import androidx.annotation.NonNull;
21 import androidx.annotation.Nullable;
22 import androidx.annotation.VisibleForTesting;
23 
24 import com.android.launcher3.anim.AnimatedFloat;
25 import com.android.launcher3.taskbar.allapps.TaskbarAllAppsController;
26 import com.android.launcher3.taskbar.bubbles.BubbleControllers;
27 import com.android.launcher3.taskbar.overlay.TaskbarOverlayController;
28 import com.android.systemui.shared.rotation.RotationButtonController;
29 
30 import java.io.PrintWriter;
31 import java.util.ArrayList;
32 import java.util.List;
33 import java.util.Optional;
34 
35 /**
36  * Hosts various taskbar controllers to facilitate passing between one another.
37  */
38 public class TaskbarControllers {
39 
40     public final TaskbarActivityContext taskbarActivityContext;
41 
42     public final TaskbarDragController taskbarDragController;
43     public final TaskbarNavButtonController navButtonController;
44     public final NavbarButtonsViewController navbarButtonsViewController;
45     public final RotationButtonController rotationButtonController;
46     public final TaskbarDragLayerController taskbarDragLayerController;
47     public final TaskbarScrimViewController taskbarScrimViewController;
48     public final TaskbarViewController taskbarViewController;
49     public final TaskbarUnfoldAnimationController taskbarUnfoldAnimationController;
50     public final TaskbarKeyguardController taskbarKeyguardController;
51     public final StashedHandleViewController stashedHandleViewController;
52     public final TaskbarStashController taskbarStashController;
53     public final TaskbarAutohideSuspendController taskbarAutohideSuspendController;
54     public final TaskbarPopupController taskbarPopupController;
55     public final TaskbarForceVisibleImmersiveController taskbarForceVisibleImmersiveController;
56     public final TaskbarAllAppsController taskbarAllAppsController;
57     public final TaskbarInsetsController taskbarInsetsController;
58     public final VoiceInteractionWindowController voiceInteractionWindowController;
59     public final TaskbarRecentAppsController taskbarRecentAppsController;
60     public final TaskbarTranslationController taskbarTranslationController;
61     public final TaskbarSpringOnStashController taskbarSpringOnStashController;
62     public final TaskbarOverlayController taskbarOverlayController;
63     public final TaskbarEduTooltipController taskbarEduTooltipController;
64     public final KeyboardQuickSwitchController keyboardQuickSwitchController;
65     public final TaskbarDividerPopupController taskbarPinningController;
66     public final Optional<BubbleControllers> bubbleControllers;
67 
68     @Nullable private LoggableTaskbarController[] mControllersToLog = null;
69     @Nullable private BackgroundRendererController[] mBackgroundRendererControllers = null;
70 
71     /** Do not store this controller, as it may change at runtime. */
72     @NonNull public TaskbarUIController uiController = TaskbarUIController.DEFAULT;
73 
74     private boolean mAreAllControllersInitialized;
75     private final List<Runnable> mPostInitCallbacks = new ArrayList<>();
76 
77     @Nullable private TaskbarSharedState mSharedState = null;
78 
79     // Roundness property for round corner above taskbar .
80     private final AnimatedFloat mCornerRoundness = new AnimatedFloat(this::updateCornerRoundness);
81 
82     /**
83      * Want to add a new controller? Don't forget to:
84      *   * Call init
85      *   * Call onDestroy
86      *   * Add to mControllersToLog
87      *   * Add tests by adding this controller to TaskbarBaseTestCase.kt and extending that class
88      */
TaskbarControllers(TaskbarActivityContext taskbarActivityContext, TaskbarDragController taskbarDragController, TaskbarNavButtonController navButtonController, NavbarButtonsViewController navbarButtonsViewController, RotationButtonController rotationButtonController, TaskbarDragLayerController taskbarDragLayerController, TaskbarViewController taskbarViewController, TaskbarScrimViewController taskbarScrimViewController, TaskbarUnfoldAnimationController taskbarUnfoldAnimationController, TaskbarKeyguardController taskbarKeyguardController, StashedHandleViewController stashedHandleViewController, TaskbarStashController taskbarStashController, TaskbarAutohideSuspendController taskbarAutoHideSuspendController, TaskbarPopupController taskbarPopupController, TaskbarForceVisibleImmersiveController taskbarForceVisibleImmersiveController, TaskbarOverlayController taskbarOverlayController, TaskbarAllAppsController taskbarAllAppsController, TaskbarInsetsController taskbarInsetsController, VoiceInteractionWindowController voiceInteractionWindowController, TaskbarTranslationController taskbarTranslationController, TaskbarSpringOnStashController taskbarSpringOnStashController, TaskbarRecentAppsController taskbarRecentAppsController, TaskbarEduTooltipController taskbarEduTooltipController, KeyboardQuickSwitchController keyboardQuickSwitchController, TaskbarDividerPopupController taskbarPinningController, Optional<BubbleControllers> bubbleControllers)89     public TaskbarControllers(TaskbarActivityContext taskbarActivityContext,
90             TaskbarDragController taskbarDragController,
91             TaskbarNavButtonController navButtonController,
92             NavbarButtonsViewController navbarButtonsViewController,
93             RotationButtonController rotationButtonController,
94             TaskbarDragLayerController taskbarDragLayerController,
95             TaskbarViewController taskbarViewController,
96             TaskbarScrimViewController taskbarScrimViewController,
97             TaskbarUnfoldAnimationController taskbarUnfoldAnimationController,
98             TaskbarKeyguardController taskbarKeyguardController,
99             StashedHandleViewController stashedHandleViewController,
100             TaskbarStashController taskbarStashController,
101             TaskbarAutohideSuspendController taskbarAutoHideSuspendController,
102             TaskbarPopupController taskbarPopupController,
103             TaskbarForceVisibleImmersiveController taskbarForceVisibleImmersiveController,
104             TaskbarOverlayController taskbarOverlayController,
105             TaskbarAllAppsController taskbarAllAppsController,
106             TaskbarInsetsController taskbarInsetsController,
107             VoiceInteractionWindowController voiceInteractionWindowController,
108             TaskbarTranslationController taskbarTranslationController,
109             TaskbarSpringOnStashController taskbarSpringOnStashController,
110             TaskbarRecentAppsController taskbarRecentAppsController,
111             TaskbarEduTooltipController taskbarEduTooltipController,
112             KeyboardQuickSwitchController keyboardQuickSwitchController,
113             TaskbarDividerPopupController taskbarPinningController,
114             Optional<BubbleControllers> bubbleControllers) {
115         this.taskbarActivityContext = taskbarActivityContext;
116         this.taskbarDragController = taskbarDragController;
117         this.navButtonController = navButtonController;
118         this.navbarButtonsViewController = navbarButtonsViewController;
119         this.rotationButtonController = rotationButtonController;
120         this.taskbarDragLayerController = taskbarDragLayerController;
121         this.taskbarViewController = taskbarViewController;
122         this.taskbarScrimViewController = taskbarScrimViewController;
123         this.taskbarUnfoldAnimationController = taskbarUnfoldAnimationController;
124         this.taskbarKeyguardController = taskbarKeyguardController;
125         this.stashedHandleViewController = stashedHandleViewController;
126         this.taskbarStashController = taskbarStashController;
127         this.taskbarAutohideSuspendController = taskbarAutoHideSuspendController;
128         this.taskbarPopupController = taskbarPopupController;
129         this.taskbarForceVisibleImmersiveController = taskbarForceVisibleImmersiveController;
130         this.taskbarOverlayController = taskbarOverlayController;
131         this.taskbarAllAppsController = taskbarAllAppsController;
132         this.taskbarInsetsController = taskbarInsetsController;
133         this.voiceInteractionWindowController = voiceInteractionWindowController;
134         this.taskbarTranslationController = taskbarTranslationController;
135         this.taskbarSpringOnStashController = taskbarSpringOnStashController;
136         this.taskbarRecentAppsController = taskbarRecentAppsController;
137         this.taskbarEduTooltipController = taskbarEduTooltipController;
138         this.keyboardQuickSwitchController = keyboardQuickSwitchController;
139         this.taskbarPinningController = taskbarPinningController;
140         this.bubbleControllers = bubbleControllers;
141     }
142 
143     /**
144      * Initializes all controllers. Note that controllers can now reference each other through this
145      * TaskbarControllers instance, but should be careful to only access things that were created
146      * in constructors for now, as some controllers may still be waiting for init().
147      */
init(@onNull TaskbarSharedState sharedState)148     public void init(@NonNull TaskbarSharedState sharedState) {
149         mAreAllControllersInitialized = false;
150         mSharedState = sharedState;
151 
152         taskbarDragController.init(this);
153         navbarButtonsViewController.init(this);
154         rotationButtonController.init();
155         taskbarDragLayerController.init(this);
156         taskbarViewController.init(this);
157         taskbarScrimViewController.init(this);
158         taskbarUnfoldAnimationController.init(this);
159         taskbarKeyguardController.init(navbarButtonsViewController);
160         taskbarSpringOnStashController.init(this);
161         stashedHandleViewController.init(this);
162         taskbarStashController.init(this, sharedState.setupUIVisible, mSharedState);
163         taskbarPopupController.init(this);
164         taskbarForceVisibleImmersiveController.init(this);
165         taskbarOverlayController.init(this);
166         taskbarAllAppsController.init(this, sharedState.allAppsVisible);
167         navButtonController.init(this);
168         taskbarInsetsController.init(this);
169         voiceInteractionWindowController.init(this);
170         taskbarRecentAppsController.init(this);
171         taskbarTranslationController.init(this);
172         taskbarEduTooltipController.init(this);
173         keyboardQuickSwitchController.init(this);
174         taskbarPinningController.init(this);
175         bubbleControllers.ifPresent(controllers -> controllers.init(this));
176 
177         mControllersToLog = new LoggableTaskbarController[] {
178                 taskbarDragController, navButtonController, navbarButtonsViewController,
179                 taskbarDragLayerController, taskbarScrimViewController, taskbarViewController,
180                 taskbarUnfoldAnimationController, taskbarKeyguardController,
181                 stashedHandleViewController, taskbarStashController,
182                 taskbarAutohideSuspendController, taskbarPopupController, taskbarInsetsController,
183                 voiceInteractionWindowController, taskbarTranslationController,
184                 taskbarEduTooltipController, keyboardQuickSwitchController, taskbarPinningController
185         };
186         mBackgroundRendererControllers = new BackgroundRendererController[] {
187                 taskbarDragLayerController, taskbarScrimViewController,
188                 voiceInteractionWindowController
189         };
190         mCornerRoundness.updateValue(TaskbarBackgroundRenderer.DEFAULT_ROUNDNESS);
191 
192         mAreAllControllersInitialized = true;
193         for (Runnable postInitCallback : mPostInitCallbacks) {
194             postInitCallback.run();
195         }
196         mPostInitCallbacks.clear();
197     }
198 
199     /**
200      * Sets the ui controller.
201      */
setUiController(@onNull TaskbarUIController newUiController)202     public void setUiController(@NonNull TaskbarUIController newUiController) {
203         uiController.onDestroy();
204         uiController = newUiController;
205         uiController.init(this);
206         uiController.updateStateForSysuiFlags(mSharedState.sysuiStateFlags);
207 
208         // Notify that the ui controller has changed
209         navbarButtonsViewController.onUiControllerChanged();
210     }
211 
212     @Nullable
getSharedState()213     public TaskbarSharedState getSharedState() {
214         // This should only be null if called before init() and after destroy().
215         return mSharedState;
216     }
217 
onConfigurationChanged(@onfig int configChanges)218     public void onConfigurationChanged(@Config int configChanges) {
219         navbarButtonsViewController.onConfigurationChanged(configChanges);
220         taskbarDragLayerController.onConfigurationChanged();
221         keyboardQuickSwitchController.onConfigurationChanged(configChanges);
222     }
223 
224     /**
225      * Cleans up all controllers.
226      */
onDestroy()227     public void onDestroy() {
228         mAreAllControllersInitialized = false;
229         mSharedState = null;
230 
231         navbarButtonsViewController.onDestroy();
232         uiController.onDestroy();
233         rotationButtonController.onDestroy();
234         taskbarDragLayerController.onDestroy();
235         taskbarUnfoldAnimationController.onDestroy();
236         taskbarViewController.onDestroy();
237         stashedHandleViewController.onDestroy();
238         taskbarAutohideSuspendController.onDestroy();
239         taskbarPopupController.onDestroy();
240         taskbarForceVisibleImmersiveController.onDestroy();
241         taskbarOverlayController.onDestroy();
242         taskbarAllAppsController.onDestroy();
243         navButtonController.onDestroy();
244         taskbarInsetsController.onDestroy();
245         voiceInteractionWindowController.onDestroy();
246         taskbarRecentAppsController.onDestroy();
247         keyboardQuickSwitchController.onDestroy();
248         taskbarStashController.onDestroy();
249         bubbleControllers.ifPresent(controllers -> controllers.onDestroy());
250 
251         mControllersToLog = null;
252         mBackgroundRendererControllers = null;
253     }
254 
255     /**
256      * If all controllers are already initialized, runs the given callback immediately. Otherwise,
257      * queues it to run after calling init() on all controllers. This should likely be used in any
258      * case where one controller is telling another controller to do something inside init().
259      */
runAfterInit(Runnable callback)260     public void runAfterInit(Runnable callback) {
261         if (mAreAllControllersInitialized) {
262             callback.run();
263         } else {
264             mPostInitCallbacks.add(callback);
265         }
266     }
267 
dumpLogs(String prefix, PrintWriter pw)268     protected void dumpLogs(String prefix, PrintWriter pw) {
269         pw.println(prefix + "TaskbarControllers:");
270 
271         if (mControllersToLog == null) {
272             pw.println(String.format(
273                     "%s\t%s", prefix, "All taskbar controllers have already been destroyed."));
274             return;
275         }
276 
277         pw.println(String.format(
278                 "%s\tmAreAllControllersInitialized=%b", prefix, mAreAllControllersInitialized));
279         for (LoggableTaskbarController controller : mControllersToLog) {
280             controller.dumpLogs(prefix + "\t", pw);
281         }
282         uiController.dumpLogs(prefix + "\t", pw);
283         rotationButtonController.dumpLogs(prefix + "\t", pw);
284     }
285 
286     /**
287      * Returns a float property that animates roundness of the round corner above Taskbar.
288      */
getTaskbarCornerRoundness()289     public AnimatedFloat getTaskbarCornerRoundness() {
290         return mCornerRoundness;
291     }
292 
updateCornerRoundness()293     private void updateCornerRoundness() {
294         if (mBackgroundRendererControllers == null) {
295             return;
296         }
297 
298         for (BackgroundRendererController controller : mBackgroundRendererControllers) {
299             controller.setCornerRoundness(mCornerRoundness.value);
300         }
301     }
302 
303     @VisibleForTesting
getTaskbarActivityContext()304     TaskbarActivityContext getTaskbarActivityContext() {
305         // Used to mock
306         return taskbarActivityContext;
307     }
308 
309     protected interface LoggableTaskbarController {
dumpLogs(String prefix, PrintWriter pw)310         void dumpLogs(String prefix, PrintWriter pw);
311     }
312 
313     protected interface BackgroundRendererController {
314         /**
315          * Sets the roundness of the round corner above Taskbar.
316          * @param cornerRoundness 0 has no round corner, 1 has complete round corner.
317          */
setCornerRoundness(float cornerRoundness)318         void setCornerRoundness(float cornerRoundness);
319     }
320 }
321