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