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 17 package com.android.wm.shell.dagger; 18 19 import static com.android.wm.shell.onehanded.OneHandedController.SUPPORT_ONE_HANDED_MODE; 20 21 import android.app.ActivityTaskManager; 22 import android.content.Context; 23 import android.content.pm.PackageManager; 24 import android.os.Handler; 25 import android.os.SystemProperties; 26 import android.view.IWindowManager; 27 import android.view.accessibility.AccessibilityManager; 28 29 import com.android.internal.logging.UiEventLogger; 30 import com.android.launcher3.icons.IconProvider; 31 import com.android.wm.shell.ProtoLogController; 32 import com.android.wm.shell.R; 33 import com.android.wm.shell.RootDisplayAreaOrganizer; 34 import com.android.wm.shell.RootTaskDisplayAreaOrganizer; 35 import com.android.wm.shell.ShellTaskOrganizer; 36 import com.android.wm.shell.WindowManagerShellWrapper; 37 import com.android.wm.shell.activityembedding.ActivityEmbeddingController; 38 import com.android.wm.shell.back.BackAnimation; 39 import com.android.wm.shell.back.BackAnimationBackground; 40 import com.android.wm.shell.back.BackAnimationController; 41 import com.android.wm.shell.bubbles.BubbleController; 42 import com.android.wm.shell.bubbles.Bubbles; 43 import com.android.wm.shell.common.DevicePostureController; 44 import com.android.wm.shell.common.DisplayController; 45 import com.android.wm.shell.common.DisplayImeController; 46 import com.android.wm.shell.common.DisplayInsetsController; 47 import com.android.wm.shell.common.DisplayLayout; 48 import com.android.wm.shell.common.DockStateReader; 49 import com.android.wm.shell.common.FloatingContentCoordinator; 50 import com.android.wm.shell.common.LaunchAdjacentController; 51 import com.android.wm.shell.common.ShellExecutor; 52 import com.android.wm.shell.common.SyncTransactionQueue; 53 import com.android.wm.shell.common.SystemWindows; 54 import com.android.wm.shell.common.TabletopModeController; 55 import com.android.wm.shell.common.TaskStackListenerImpl; 56 import com.android.wm.shell.common.TransactionPool; 57 import com.android.wm.shell.common.annotations.ShellAnimationThread; 58 import com.android.wm.shell.common.annotations.ShellBackgroundThread; 59 import com.android.wm.shell.common.annotations.ShellMainThread; 60 import com.android.wm.shell.common.annotations.ShellSplashscreenThread; 61 import com.android.wm.shell.common.pip.PhonePipKeepClearAlgorithm; 62 import com.android.wm.shell.common.pip.PhoneSizeSpecSource; 63 import com.android.wm.shell.common.pip.PipBoundsAlgorithm; 64 import com.android.wm.shell.common.pip.PipBoundsState; 65 import com.android.wm.shell.common.pip.PipDisplayLayoutState; 66 import com.android.wm.shell.common.pip.PipMediaController; 67 import com.android.wm.shell.common.pip.PipSnapAlgorithm; 68 import com.android.wm.shell.common.pip.PipUiEventLogger; 69 import com.android.wm.shell.common.pip.SizeSpecSource; 70 import com.android.wm.shell.compatui.CompatUIConfiguration; 71 import com.android.wm.shell.compatui.CompatUIController; 72 import com.android.wm.shell.compatui.CompatUIShellCommandHandler; 73 import com.android.wm.shell.desktopmode.DesktopMode; 74 import com.android.wm.shell.desktopmode.DesktopModeController; 75 import com.android.wm.shell.desktopmode.DesktopModeStatus; 76 import com.android.wm.shell.desktopmode.DesktopModeTaskRepository; 77 import com.android.wm.shell.desktopmode.DesktopTasksController; 78 import com.android.wm.shell.displayareahelper.DisplayAreaHelper; 79 import com.android.wm.shell.displayareahelper.DisplayAreaHelperController; 80 import com.android.wm.shell.draganddrop.DragAndDropController; 81 import com.android.wm.shell.freeform.FreeformComponents; 82 import com.android.wm.shell.fullscreen.FullscreenTaskListener; 83 import com.android.wm.shell.hidedisplaycutout.HideDisplayCutoutController; 84 import com.android.wm.shell.keyguard.KeyguardTransitionHandler; 85 import com.android.wm.shell.keyguard.KeyguardTransitions; 86 import com.android.wm.shell.onehanded.OneHanded; 87 import com.android.wm.shell.onehanded.OneHandedController; 88 import com.android.wm.shell.recents.RecentTasks; 89 import com.android.wm.shell.recents.RecentTasksController; 90 import com.android.wm.shell.recents.RecentsTransitionHandler; 91 import com.android.wm.shell.splitscreen.SplitScreen; 92 import com.android.wm.shell.splitscreen.SplitScreenController; 93 import com.android.wm.shell.startingsurface.StartingSurface; 94 import com.android.wm.shell.startingsurface.StartingWindowController; 95 import com.android.wm.shell.startingsurface.StartingWindowTypeAlgorithm; 96 import com.android.wm.shell.startingsurface.phone.PhoneStartingWindowTypeAlgorithm; 97 import com.android.wm.shell.sysui.ShellCommandHandler; 98 import com.android.wm.shell.sysui.ShellController; 99 import com.android.wm.shell.sysui.ShellInit; 100 import com.android.wm.shell.sysui.ShellInterface; 101 import com.android.wm.shell.taskview.TaskViewFactory; 102 import com.android.wm.shell.taskview.TaskViewFactoryController; 103 import com.android.wm.shell.taskview.TaskViewTransitions; 104 import com.android.wm.shell.transition.ShellTransitions; 105 import com.android.wm.shell.transition.Transitions; 106 import com.android.wm.shell.unfold.ShellUnfoldProgressProvider; 107 import com.android.wm.shell.unfold.UnfoldAnimationController; 108 import com.android.wm.shell.unfold.UnfoldTransitionHandler; 109 import com.android.wm.shell.windowdecor.WindowDecorViewModel; 110 111 import dagger.BindsOptionalOf; 112 import dagger.Lazy; 113 import dagger.Module; 114 import dagger.Provides; 115 116 import java.util.Optional; 117 118 /** 119 * Provides basic dependencies from {@link com.android.wm.shell}, these dependencies are only 120 * accessible from components within the WM subcomponent (can be explicitly exposed to the 121 * SysUIComponent, see {@link WMComponent}). 122 * 123 * This module only defines *common* dependencies across various SystemUI implementations, 124 * dependencies that are device/form factor SystemUI implementation specific should go into their 125 * respective modules (ie. {@link WMShellModule} for handheld, {@link TvWMShellModule} for tv, etc.) 126 */ 127 @Module(includes = WMShellConcurrencyModule.class) 128 public abstract class WMShellBaseModule { 129 130 // 131 // Internal common - Components used internally by multiple shell features 132 // 133 134 @WMSingleton 135 @Provides provideFloatingContentCoordinator()136 static FloatingContentCoordinator provideFloatingContentCoordinator() { 137 return new FloatingContentCoordinator(); 138 } 139 140 @WMSingleton 141 @Provides provideDisplayController(Context context, IWindowManager wmService, ShellInit shellInit, @ShellMainThread ShellExecutor mainExecutor)142 static DisplayController provideDisplayController(Context context, 143 IWindowManager wmService, 144 ShellInit shellInit, 145 @ShellMainThread ShellExecutor mainExecutor) { 146 return new DisplayController(context, wmService, shellInit, mainExecutor); 147 } 148 149 @WMSingleton 150 @Provides provideDisplayInsetsController(IWindowManager wmService, ShellInit shellInit, DisplayController displayController, @ShellMainThread ShellExecutor mainExecutor)151 static DisplayInsetsController provideDisplayInsetsController(IWindowManager wmService, 152 ShellInit shellInit, 153 DisplayController displayController, 154 @ShellMainThread ShellExecutor mainExecutor) { 155 return new DisplayInsetsController(wmService, shellInit, displayController, 156 mainExecutor); 157 } 158 159 @WMSingleton 160 @Provides provideDisplayImeController( IWindowManager wmService, ShellInit shellInit, DisplayController displayController, DisplayInsetsController displayInsetsController, TransactionPool transactionPool, @ShellMainThread ShellExecutor mainExecutor )161 static DisplayImeController provideDisplayImeController( 162 IWindowManager wmService, 163 ShellInit shellInit, 164 DisplayController displayController, 165 DisplayInsetsController displayInsetsController, 166 TransactionPool transactionPool, 167 @ShellMainThread ShellExecutor mainExecutor 168 ) { 169 return new DisplayImeController(wmService, shellInit, displayController, 170 displayInsetsController, transactionPool, mainExecutor); 171 } 172 173 @WMSingleton 174 @Provides provideDisplayLayout()175 static DisplayLayout provideDisplayLayout() { 176 return new DisplayLayout(); 177 } 178 179 @WMSingleton 180 @Provides provideDevicePostureController( Context context, ShellInit shellInit, @ShellMainThread ShellExecutor mainExecutor )181 static DevicePostureController provideDevicePostureController( 182 Context context, 183 ShellInit shellInit, 184 @ShellMainThread ShellExecutor mainExecutor 185 ) { 186 return new DevicePostureController(context, shellInit, mainExecutor); 187 } 188 189 @WMSingleton 190 @Provides provideTabletopModeController( Context context, ShellInit shellInit, DevicePostureController postureController, DisplayController displayController, @ShellMainThread ShellExecutor mainExecutor)191 static TabletopModeController provideTabletopModeController( 192 Context context, 193 ShellInit shellInit, 194 DevicePostureController postureController, 195 DisplayController displayController, 196 @ShellMainThread ShellExecutor mainExecutor) { 197 return new TabletopModeController( 198 context, shellInit, postureController, displayController, mainExecutor); 199 } 200 201 @WMSingleton 202 @Provides provideDragAndDropController(Context context, ShellInit shellInit, ShellController shellController, ShellCommandHandler shellCommandHandler, DisplayController displayController, UiEventLogger uiEventLogger, IconProvider iconProvider, @ShellMainThread ShellExecutor mainExecutor)203 static Optional<DragAndDropController> provideDragAndDropController(Context context, 204 ShellInit shellInit, 205 ShellController shellController, 206 ShellCommandHandler shellCommandHandler, 207 DisplayController displayController, 208 UiEventLogger uiEventLogger, 209 IconProvider iconProvider, 210 @ShellMainThread ShellExecutor mainExecutor) { 211 return Optional.ofNullable(DragAndDropController.create(context, shellInit, shellController, 212 shellCommandHandler, displayController, uiEventLogger, iconProvider, mainExecutor)); 213 } 214 215 @WMSingleton 216 @Provides provideShellTaskOrganizer( Context context, ShellInit shellInit, ShellCommandHandler shellCommandHandler, CompatUIController compatUI, Optional<UnfoldAnimationController> unfoldAnimationController, Optional<RecentTasksController> recentTasksOptional, @ShellMainThread ShellExecutor mainExecutor )217 static ShellTaskOrganizer provideShellTaskOrganizer( 218 Context context, 219 ShellInit shellInit, 220 ShellCommandHandler shellCommandHandler, 221 CompatUIController compatUI, 222 Optional<UnfoldAnimationController> unfoldAnimationController, 223 Optional<RecentTasksController> recentTasksOptional, 224 @ShellMainThread ShellExecutor mainExecutor 225 ) { 226 if (!context.getResources().getBoolean(R.bool.config_registerShellTaskOrganizerOnInit)) { 227 // TODO(b/238217847): Force override shell init if registration is disabled 228 shellInit = new ShellInit(mainExecutor); 229 } 230 return new ShellTaskOrganizer(shellInit, shellCommandHandler, compatUI, 231 unfoldAnimationController, recentTasksOptional, mainExecutor); 232 } 233 234 @WMSingleton 235 @Provides provideCompatUIController(Context context, ShellInit shellInit, ShellController shellController, DisplayController displayController, DisplayInsetsController displayInsetsController, DisplayImeController imeController, SyncTransactionQueue syncQueue, @ShellMainThread ShellExecutor mainExecutor, Lazy<Transitions> transitionsLazy, DockStateReader dockStateReader, CompatUIConfiguration compatUIConfiguration, CompatUIShellCommandHandler compatUIShellCommandHandler, AccessibilityManager accessibilityManager)236 static CompatUIController provideCompatUIController(Context context, 237 ShellInit shellInit, 238 ShellController shellController, 239 DisplayController displayController, DisplayInsetsController displayInsetsController, 240 DisplayImeController imeController, SyncTransactionQueue syncQueue, 241 @ShellMainThread ShellExecutor mainExecutor, Lazy<Transitions> transitionsLazy, 242 DockStateReader dockStateReader, CompatUIConfiguration compatUIConfiguration, 243 CompatUIShellCommandHandler compatUIShellCommandHandler, 244 AccessibilityManager accessibilityManager) { 245 return new CompatUIController(context, shellInit, shellController, displayController, 246 displayInsetsController, imeController, syncQueue, mainExecutor, transitionsLazy, 247 dockStateReader, compatUIConfiguration, compatUIShellCommandHandler, 248 accessibilityManager); 249 } 250 251 @WMSingleton 252 @Provides provideSyncTransactionQueue(TransactionPool pool, @ShellMainThread ShellExecutor mainExecutor)253 static SyncTransactionQueue provideSyncTransactionQueue(TransactionPool pool, 254 @ShellMainThread ShellExecutor mainExecutor) { 255 return new SyncTransactionQueue(pool, mainExecutor); 256 } 257 258 @WMSingleton 259 @Provides provideSystemWindows(DisplayController displayController, IWindowManager wmService)260 static SystemWindows provideSystemWindows(DisplayController displayController, 261 IWindowManager wmService) { 262 return new SystemWindows(displayController, wmService); 263 } 264 265 @WMSingleton 266 @Provides provideIconProvider(Context context)267 static IconProvider provideIconProvider(Context context) { 268 return new IconProvider(context); 269 } 270 271 // We currently dedupe multiple messages, so we use the shell main handler directly 272 @WMSingleton 273 @Provides providerTaskStackListenerImpl( @hellMainThread Handler mainHandler)274 static TaskStackListenerImpl providerTaskStackListenerImpl( 275 @ShellMainThread Handler mainHandler) { 276 return new TaskStackListenerImpl(mainHandler); 277 } 278 279 @WMSingleton 280 @Provides provideTransactionPool()281 static TransactionPool provideTransactionPool() { 282 return new TransactionPool(); 283 } 284 285 @WMSingleton 286 @Provides provideWindowManagerShellWrapper( @hellMainThread ShellExecutor mainExecutor)287 static WindowManagerShellWrapper provideWindowManagerShellWrapper( 288 @ShellMainThread ShellExecutor mainExecutor) { 289 return new WindowManagerShellWrapper(mainExecutor); 290 } 291 292 @WMSingleton 293 @Provides provideLaunchAdjacentController( SyncTransactionQueue syncQueue)294 static LaunchAdjacentController provideLaunchAdjacentController( 295 SyncTransactionQueue syncQueue) { 296 return new LaunchAdjacentController(syncQueue); 297 } 298 299 // 300 // Back animation 301 // 302 303 @WMSingleton 304 @Provides provideBackAnimation( Optional<BackAnimationController> backAnimationController)305 static Optional<BackAnimation> provideBackAnimation( 306 Optional<BackAnimationController> backAnimationController) { 307 return backAnimationController.map(BackAnimationController::getBackAnimationImpl); 308 } 309 310 @WMSingleton 311 @Provides provideBackAnimationBackground( RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer)312 static BackAnimationBackground provideBackAnimationBackground( 313 RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer) { 314 return new BackAnimationBackground(rootTaskDisplayAreaOrganizer); 315 } 316 317 @WMSingleton 318 @Provides provideBackAnimationController( Context context, ShellInit shellInit, ShellController shellController, @ShellMainThread ShellExecutor shellExecutor, @ShellBackgroundThread Handler backgroundHandler, BackAnimationBackground backAnimationBackground )319 static Optional<BackAnimationController> provideBackAnimationController( 320 Context context, 321 ShellInit shellInit, 322 ShellController shellController, 323 @ShellMainThread ShellExecutor shellExecutor, 324 @ShellBackgroundThread Handler backgroundHandler, 325 BackAnimationBackground backAnimationBackground 326 ) { 327 if (BackAnimationController.IS_ENABLED) { 328 return Optional.of( 329 new BackAnimationController(shellInit, shellController, shellExecutor, 330 backgroundHandler, context, backAnimationBackground)); 331 } 332 return Optional.empty(); 333 } 334 335 // 336 // PiP (optional feature) 337 // 338 339 @WMSingleton 340 @Provides providePipUiEventLogger(UiEventLogger uiEventLogger, PackageManager packageManager)341 static PipUiEventLogger providePipUiEventLogger(UiEventLogger uiEventLogger, 342 PackageManager packageManager) { 343 return new PipUiEventLogger(uiEventLogger, packageManager); 344 } 345 346 @WMSingleton 347 @Provides providePipMediaController(Context context, @ShellMainThread Handler mainHandler)348 static PipMediaController providePipMediaController(Context context, 349 @ShellMainThread Handler mainHandler) { 350 return new PipMediaController(context, mainHandler); 351 } 352 353 @WMSingleton 354 @Provides provideSizeSpecSource(Context context, PipDisplayLayoutState pipDisplayLayoutState)355 static SizeSpecSource provideSizeSpecSource(Context context, 356 PipDisplayLayoutState pipDisplayLayoutState) { 357 return new PhoneSizeSpecSource(context, pipDisplayLayoutState); 358 } 359 360 @WMSingleton 361 @Provides providePipBoundsState(Context context, SizeSpecSource sizeSpecSource, PipDisplayLayoutState pipDisplayLayoutState)362 static PipBoundsState providePipBoundsState(Context context, 363 SizeSpecSource sizeSpecSource, PipDisplayLayoutState pipDisplayLayoutState) { 364 return new PipBoundsState(context, sizeSpecSource, pipDisplayLayoutState); 365 } 366 367 368 @WMSingleton 369 @Provides providePipSnapAlgorithm()370 static PipSnapAlgorithm providePipSnapAlgorithm() { 371 return new PipSnapAlgorithm(); 372 } 373 374 @WMSingleton 375 @Provides providePhonePipKeepClearAlgorithm(Context context)376 static PhonePipKeepClearAlgorithm providePhonePipKeepClearAlgorithm(Context context) { 377 return new PhonePipKeepClearAlgorithm(context); 378 } 379 380 @WMSingleton 381 @Provides providesPipBoundsAlgorithm(Context context, PipBoundsState pipBoundsState, PipSnapAlgorithm pipSnapAlgorithm, PhonePipKeepClearAlgorithm pipKeepClearAlgorithm, PipDisplayLayoutState pipDisplayLayoutState, SizeSpecSource sizeSpecSource)382 static PipBoundsAlgorithm providesPipBoundsAlgorithm(Context context, 383 PipBoundsState pipBoundsState, PipSnapAlgorithm pipSnapAlgorithm, 384 PhonePipKeepClearAlgorithm pipKeepClearAlgorithm, 385 PipDisplayLayoutState pipDisplayLayoutState, SizeSpecSource sizeSpecSource) { 386 return new PipBoundsAlgorithm(context, pipBoundsState, pipSnapAlgorithm, 387 pipKeepClearAlgorithm, pipDisplayLayoutState, sizeSpecSource); 388 } 389 390 // 391 // Bubbles (optional feature) 392 // 393 394 @WMSingleton 395 @Provides provideBubbles(Optional<BubbleController> bubbleController)396 static Optional<Bubbles> provideBubbles(Optional<BubbleController> bubbleController) { 397 return bubbleController.map((controller) -> controller.asBubbles()); 398 } 399 400 @BindsOptionalOf optionalBubblesController()401 abstract BubbleController optionalBubblesController(); 402 403 // 404 // Fullscreen 405 // 406 407 // Workaround for dynamic overriding with a default implementation, see {@link DynamicOverride} 408 @BindsOptionalOf 409 @DynamicOverride optionalFullscreenTaskListener()410 abstract FullscreenTaskListener optionalFullscreenTaskListener(); 411 412 @WMSingleton 413 @Provides provideFullscreenTaskListener( @ynamicOverride Optional<FullscreenTaskListener> fullscreenTaskListener, ShellInit shellInit, ShellTaskOrganizer shellTaskOrganizer, SyncTransactionQueue syncQueue, Optional<RecentTasksController> recentTasksOptional, Optional<WindowDecorViewModel> windowDecorViewModelOptional)414 static FullscreenTaskListener provideFullscreenTaskListener( 415 @DynamicOverride Optional<FullscreenTaskListener> fullscreenTaskListener, 416 ShellInit shellInit, 417 ShellTaskOrganizer shellTaskOrganizer, 418 SyncTransactionQueue syncQueue, 419 Optional<RecentTasksController> recentTasksOptional, 420 Optional<WindowDecorViewModel> windowDecorViewModelOptional) { 421 if (fullscreenTaskListener.isPresent()) { 422 return fullscreenTaskListener.get(); 423 } else { 424 return new FullscreenTaskListener(shellInit, shellTaskOrganizer, syncQueue, 425 recentTasksOptional, windowDecorViewModelOptional); 426 } 427 } 428 429 // 430 // Window Decoration 431 // 432 433 @BindsOptionalOf optionalWindowDecorViewModel()434 abstract WindowDecorViewModel optionalWindowDecorViewModel(); 435 436 // 437 // Unfold transition 438 // 439 440 @BindsOptionalOf optionalShellUnfoldProgressProvider()441 abstract ShellUnfoldProgressProvider optionalShellUnfoldProgressProvider(); 442 443 // Workaround for dynamic overriding with a default implementation, see {@link DynamicOverride} 444 @BindsOptionalOf 445 @DynamicOverride optionalUnfoldController()446 abstract UnfoldAnimationController optionalUnfoldController(); 447 448 @WMSingleton 449 @Provides provideUnfoldController( @ynamicOverride Lazy<Optional<UnfoldAnimationController>> fullscreenUnfoldController, Optional<ShellUnfoldProgressProvider> progressProvider)450 static Optional<UnfoldAnimationController> provideUnfoldController( 451 @DynamicOverride Lazy<Optional<UnfoldAnimationController>> 452 fullscreenUnfoldController, 453 Optional<ShellUnfoldProgressProvider> progressProvider) { 454 if (progressProvider.isPresent() 455 && progressProvider.get() != ShellUnfoldProgressProvider.NO_PROVIDER) { 456 return fullscreenUnfoldController.get(); 457 } 458 return Optional.empty(); 459 } 460 461 @BindsOptionalOf 462 @DynamicOverride optionalUnfoldTransitionHandler()463 abstract UnfoldTransitionHandler optionalUnfoldTransitionHandler(); 464 465 @WMSingleton 466 @Provides provideUnfoldTransitionHandler( Optional<ShellUnfoldProgressProvider> progressProvider, @DynamicOverride Lazy<Optional<UnfoldTransitionHandler>> handler)467 static Optional<UnfoldTransitionHandler> provideUnfoldTransitionHandler( 468 Optional<ShellUnfoldProgressProvider> progressProvider, 469 @DynamicOverride Lazy<Optional<UnfoldTransitionHandler>> handler) { 470 if (progressProvider.isPresent() 471 && progressProvider.get() != ShellUnfoldProgressProvider.NO_PROVIDER) { 472 return handler.get(); 473 } 474 return Optional.empty(); 475 } 476 477 // 478 // Freeform (optional feature) 479 // 480 481 // Workaround for dynamic overriding with a default implementation, see {@link DynamicOverride} 482 @BindsOptionalOf 483 @DynamicOverride optionalFreeformComponents()484 abstract FreeformComponents optionalFreeformComponents(); 485 486 @WMSingleton 487 @Provides provideFreeformComponents( @ynamicOverride Optional<FreeformComponents> freeformComponents, Context context)488 static Optional<FreeformComponents> provideFreeformComponents( 489 @DynamicOverride Optional<FreeformComponents> freeformComponents, 490 Context context) { 491 if (FreeformComponents.isFreeformEnabled(context)) { 492 return freeformComponents; 493 } 494 return Optional.empty(); 495 } 496 497 // 498 // Hide display cutout 499 // 500 501 @WMSingleton 502 @Provides provideHideDisplayCutoutController(Context context, ShellInit shellInit, ShellCommandHandler shellCommandHandler, ShellController shellController, DisplayController displayController, @ShellMainThread ShellExecutor mainExecutor)503 static Optional<HideDisplayCutoutController> provideHideDisplayCutoutController(Context context, 504 ShellInit shellInit, 505 ShellCommandHandler shellCommandHandler, 506 ShellController shellController, 507 DisplayController displayController, 508 @ShellMainThread ShellExecutor mainExecutor) { 509 return Optional.ofNullable( 510 HideDisplayCutoutController.create(context, shellInit, shellCommandHandler, 511 shellController, displayController, mainExecutor)); 512 } 513 514 // 515 // One handed mode (optional feature) 516 // 517 518 @WMSingleton 519 @Provides provideOneHanded(Optional<OneHandedController> oneHandedController)520 static Optional<OneHanded> provideOneHanded(Optional<OneHandedController> oneHandedController) { 521 return oneHandedController.map((controller) -> controller.asOneHanded()); 522 } 523 524 // Workaround for dynamic overriding with a default implementation, see {@link DynamicOverride} 525 @BindsOptionalOf 526 @DynamicOverride optionalOneHandedController()527 abstract OneHandedController optionalOneHandedController(); 528 529 @WMSingleton 530 @Provides providesOneHandedController( @ynamicOverride Optional<OneHandedController> oneHandedController)531 static Optional<OneHandedController> providesOneHandedController( 532 @DynamicOverride Optional<OneHandedController> oneHandedController) { 533 if (SystemProperties.getBoolean(SUPPORT_ONE_HANDED_MODE, false)) { 534 return oneHandedController; 535 } 536 return Optional.empty(); 537 } 538 539 // 540 // Recent tasks 541 // 542 543 @WMSingleton 544 @Provides provideRecentTasks( Optional<RecentTasksController> recentTasksController)545 static Optional<RecentTasks> provideRecentTasks( 546 Optional<RecentTasksController> recentTasksController) { 547 return recentTasksController.map((controller) -> controller.asRecentTasks()); 548 } 549 550 @WMSingleton 551 @Provides provideRecentTasksController( Context context, ShellInit shellInit, ShellController shellController, ShellCommandHandler shellCommandHandler, TaskStackListenerImpl taskStackListener, ActivityTaskManager activityTaskManager, Optional<DesktopModeTaskRepository> desktopModeTaskRepository, @ShellMainThread ShellExecutor mainExecutor )552 static Optional<RecentTasksController> provideRecentTasksController( 553 Context context, 554 ShellInit shellInit, 555 ShellController shellController, 556 ShellCommandHandler shellCommandHandler, 557 TaskStackListenerImpl taskStackListener, 558 ActivityTaskManager activityTaskManager, 559 Optional<DesktopModeTaskRepository> desktopModeTaskRepository, 560 @ShellMainThread ShellExecutor mainExecutor 561 ) { 562 return Optional.ofNullable( 563 RecentTasksController.create(context, shellInit, shellController, 564 shellCommandHandler, taskStackListener, activityTaskManager, 565 desktopModeTaskRepository, mainExecutor)); 566 } 567 568 @BindsOptionalOf optionalRecentsTransitionHandler()569 abstract RecentsTransitionHandler optionalRecentsTransitionHandler(); 570 571 // 572 // Shell transitions 573 // 574 575 @WMSingleton 576 @Provides provideRemoteTransitions(Transitions transitions)577 static ShellTransitions provideRemoteTransitions(Transitions transitions) { 578 return transitions.asRemoteTransitions(); 579 } 580 581 @WMSingleton 582 @Provides provideTransitions(Context context, ShellInit shellInit, ShellController shellController, ShellTaskOrganizer organizer, TransactionPool pool, DisplayController displayController, @ShellMainThread ShellExecutor mainExecutor, @ShellMainThread Handler mainHandler, @ShellAnimationThread ShellExecutor animExecutor, ShellCommandHandler shellCommandHandler, RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer)583 static Transitions provideTransitions(Context context, 584 ShellInit shellInit, 585 ShellController shellController, 586 ShellTaskOrganizer organizer, 587 TransactionPool pool, 588 DisplayController displayController, 589 @ShellMainThread ShellExecutor mainExecutor, 590 @ShellMainThread Handler mainHandler, 591 @ShellAnimationThread ShellExecutor animExecutor, 592 ShellCommandHandler shellCommandHandler, 593 RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer) { 594 if (!context.getResources().getBoolean(R.bool.config_registerShellTransitionsOnInit)) { 595 // TODO(b/238217847): Force override shell init if registration is disabled 596 shellInit = new ShellInit(mainExecutor); 597 } 598 return new Transitions(context, shellInit, shellController, organizer, pool, 599 displayController, mainExecutor, mainHandler, animExecutor, shellCommandHandler, 600 rootTaskDisplayAreaOrganizer); 601 } 602 603 @WMSingleton 604 @Provides provideTaskViewTransitions(Transitions transitions)605 static TaskViewTransitions provideTaskViewTransitions(Transitions transitions) { 606 return new TaskViewTransitions(transitions); 607 } 608 609 // 610 // Keyguard transitions (optional feature) 611 // 612 613 @WMSingleton 614 @Provides provideKeyguardTransitionHandler( ShellInit shellInit, Transitions transitions, @ShellMainThread Handler mainHandler, @ShellMainThread ShellExecutor mainExecutor)615 static KeyguardTransitionHandler provideKeyguardTransitionHandler( 616 ShellInit shellInit, 617 Transitions transitions, 618 @ShellMainThread Handler mainHandler, 619 @ShellMainThread ShellExecutor mainExecutor) { 620 return new KeyguardTransitionHandler( 621 shellInit, transitions, mainHandler, mainExecutor); 622 } 623 624 @WMSingleton 625 @Provides provideKeyguardTransitions( KeyguardTransitionHandler handler)626 static KeyguardTransitions provideKeyguardTransitions( 627 KeyguardTransitionHandler handler) { 628 return handler.asKeyguardTransitions(); 629 } 630 631 // 632 // Display areas 633 // 634 635 @WMSingleton 636 @Provides provideRootTaskDisplayAreaOrganizer( @hellMainThread ShellExecutor mainExecutor, Context context)637 static RootTaskDisplayAreaOrganizer provideRootTaskDisplayAreaOrganizer( 638 @ShellMainThread ShellExecutor mainExecutor, Context context) { 639 return new RootTaskDisplayAreaOrganizer(mainExecutor, context); 640 } 641 642 @WMSingleton 643 @Provides provideRootDisplayAreaOrganizer( @hellMainThread ShellExecutor mainExecutor)644 static RootDisplayAreaOrganizer provideRootDisplayAreaOrganizer( 645 @ShellMainThread ShellExecutor mainExecutor) { 646 return new RootDisplayAreaOrganizer(mainExecutor); 647 } 648 649 @WMSingleton 650 @Provides provideDisplayAreaHelper( @hellMainThread ShellExecutor mainExecutor, RootDisplayAreaOrganizer rootDisplayAreaOrganizer)651 static Optional<DisplayAreaHelper> provideDisplayAreaHelper( 652 @ShellMainThread ShellExecutor mainExecutor, 653 RootDisplayAreaOrganizer rootDisplayAreaOrganizer) { 654 return Optional.of(new DisplayAreaHelperController(mainExecutor, 655 rootDisplayAreaOrganizer)); 656 } 657 658 // 659 // Splitscreen (optional feature) 660 // 661 662 @WMSingleton 663 @Provides provideSplitScreen( Optional<SplitScreenController> splitScreenController)664 static Optional<SplitScreen> provideSplitScreen( 665 Optional<SplitScreenController> splitScreenController) { 666 return splitScreenController.map((controller) -> controller.asSplitScreen()); 667 } 668 669 // Workaround for dynamic overriding with a default implementation, see {@link DynamicOverride} 670 @BindsOptionalOf 671 @DynamicOverride optionalSplitScreenController()672 abstract SplitScreenController optionalSplitScreenController(); 673 674 @WMSingleton 675 @Provides providesSplitScreenController( @ynamicOverride Optional<SplitScreenController> splitscreenController, Context context)676 static Optional<SplitScreenController> providesSplitScreenController( 677 @DynamicOverride Optional<SplitScreenController> splitscreenController, 678 Context context) { 679 if (ActivityTaskManager.supportsSplitScreenMultiWindow(context)) { 680 return splitscreenController; 681 } 682 return Optional.empty(); 683 } 684 685 // 686 // Starting window 687 // 688 689 @WMSingleton 690 @Provides provideStartingSurface( StartingWindowController startingWindowController)691 static Optional<StartingSurface> provideStartingSurface( 692 StartingWindowController startingWindowController) { 693 return Optional.of(startingWindowController.asStartingSurface()); 694 } 695 696 @WMSingleton 697 @Provides provideStartingWindowController( Context context, ShellInit shellInit, ShellController shellController, ShellTaskOrganizer shellTaskOrganizer, @ShellSplashscreenThread ShellExecutor splashScreenExecutor, StartingWindowTypeAlgorithm startingWindowTypeAlgorithm, IconProvider iconProvider, TransactionPool pool)698 static StartingWindowController provideStartingWindowController( 699 Context context, 700 ShellInit shellInit, 701 ShellController shellController, 702 ShellTaskOrganizer shellTaskOrganizer, 703 @ShellSplashscreenThread ShellExecutor splashScreenExecutor, 704 StartingWindowTypeAlgorithm startingWindowTypeAlgorithm, IconProvider iconProvider, 705 TransactionPool pool) { 706 return new StartingWindowController(context, shellInit, shellController, shellTaskOrganizer, 707 splashScreenExecutor, startingWindowTypeAlgorithm, iconProvider, pool); 708 } 709 710 // Workaround for dynamic overriding with a default implementation, see {@link DynamicOverride} 711 @BindsOptionalOf 712 @DynamicOverride optionalStartingWindowTypeAlgorithm()713 abstract StartingWindowTypeAlgorithm optionalStartingWindowTypeAlgorithm(); 714 715 @WMSingleton 716 @Provides provideStartingWindowTypeAlgorithm( @ynamicOverride Optional<StartingWindowTypeAlgorithm> startingWindowTypeAlgorithm )717 static StartingWindowTypeAlgorithm provideStartingWindowTypeAlgorithm( 718 @DynamicOverride Optional<StartingWindowTypeAlgorithm> startingWindowTypeAlgorithm 719 ) { 720 if (startingWindowTypeAlgorithm.isPresent()) { 721 return startingWindowTypeAlgorithm.get(); 722 } 723 // Default to phone starting window type 724 return new PhoneStartingWindowTypeAlgorithm(); 725 } 726 727 // 728 // Task view factory 729 // 730 731 @WMSingleton 732 @Provides provideTaskViewFactory( TaskViewFactoryController taskViewFactoryController)733 static Optional<TaskViewFactory> provideTaskViewFactory( 734 TaskViewFactoryController taskViewFactoryController) { 735 return Optional.of(taskViewFactoryController.asTaskViewFactory()); 736 } 737 738 @WMSingleton 739 @Provides provideTaskViewFactoryController( ShellTaskOrganizer shellTaskOrganizer, @ShellMainThread ShellExecutor mainExecutor, SyncTransactionQueue syncQueue, TaskViewTransitions taskViewTransitions)740 static TaskViewFactoryController provideTaskViewFactoryController( 741 ShellTaskOrganizer shellTaskOrganizer, 742 @ShellMainThread ShellExecutor mainExecutor, 743 SyncTransactionQueue syncQueue, 744 TaskViewTransitions taskViewTransitions) { 745 return new TaskViewFactoryController(shellTaskOrganizer, mainExecutor, syncQueue, 746 taskViewTransitions); 747 } 748 749 750 // 751 // ActivityEmbedding 752 // 753 754 @WMSingleton 755 @Provides provideActivityEmbeddingController( Context context, ShellInit shellInit, Transitions transitions)756 static Optional<ActivityEmbeddingController> provideActivityEmbeddingController( 757 Context context, 758 ShellInit shellInit, 759 Transitions transitions) { 760 return Optional.ofNullable( 761 ActivityEmbeddingController.create(context, shellInit, transitions)); 762 } 763 764 // 765 // SysUI -> Shell interface 766 // 767 768 @WMSingleton 769 @Provides provideShellSysuiCallbacks( @hellCreateTrigger Object createTrigger, ShellController shellController)770 static ShellInterface provideShellSysuiCallbacks( 771 @ShellCreateTrigger Object createTrigger, 772 ShellController shellController) { 773 return shellController.asShell(); 774 } 775 776 @WMSingleton 777 @Provides provideShellController(Context context, ShellInit shellInit, ShellCommandHandler shellCommandHandler, @ShellMainThread ShellExecutor mainExecutor)778 static ShellController provideShellController(Context context, 779 ShellInit shellInit, 780 ShellCommandHandler shellCommandHandler, 781 @ShellMainThread ShellExecutor mainExecutor) { 782 return new ShellController(context, shellInit, shellCommandHandler, mainExecutor); 783 } 784 785 // 786 // Desktop mode (optional feature) 787 // 788 789 @WMSingleton 790 @Provides provideDesktopMode( Optional<DesktopModeController> desktopModeController, Optional<DesktopTasksController> desktopTasksController)791 static Optional<DesktopMode> provideDesktopMode( 792 Optional<DesktopModeController> desktopModeController, 793 Optional<DesktopTasksController> desktopTasksController) { 794 if (DesktopModeStatus.isProto2Enabled()) { 795 return desktopTasksController.map(DesktopTasksController::asDesktopMode); 796 } 797 return desktopModeController.map(DesktopModeController::asDesktopMode); 798 } 799 800 @BindsOptionalOf 801 @DynamicOverride optionalDesktopModeController()802 abstract DesktopModeController optionalDesktopModeController(); 803 804 @WMSingleton 805 @Provides provideDesktopModeController( @ynamicOverride Optional<Lazy<DesktopModeController>> desktopModeController)806 static Optional<DesktopModeController> provideDesktopModeController( 807 @DynamicOverride Optional<Lazy<DesktopModeController>> desktopModeController) { 808 // Use optional-of-lazy for the dependency that this provider relies on. 809 // Lazy ensures that this provider will not be the cause the dependency is created 810 // when it will not be returned due to the condition below. 811 if (DesktopModeStatus.isProto1Enabled()) { 812 return desktopModeController.map(Lazy::get); 813 } 814 return Optional.empty(); 815 } 816 817 @BindsOptionalOf 818 @DynamicOverride optionalDesktopTasksController()819 abstract DesktopTasksController optionalDesktopTasksController(); 820 821 @WMSingleton 822 @Provides providesDesktopTasksController( @ynamicOverride Optional<Lazy<DesktopTasksController>> desktopTasksController)823 static Optional<DesktopTasksController> providesDesktopTasksController( 824 @DynamicOverride Optional<Lazy<DesktopTasksController>> desktopTasksController) { 825 // Use optional-of-lazy for the dependency that this provider relies on. 826 // Lazy ensures that this provider will not be the cause the dependency is created 827 // when it will not be returned due to the condition below. 828 if (DesktopModeStatus.isProto2Enabled()) { 829 return desktopTasksController.map(Lazy::get); 830 } 831 return Optional.empty(); 832 } 833 834 @BindsOptionalOf 835 @DynamicOverride optionalDesktopModeTaskRepository()836 abstract DesktopModeTaskRepository optionalDesktopModeTaskRepository(); 837 838 @WMSingleton 839 @Provides provideDesktopTaskRepository( @ynamicOverride Optional<Lazy<DesktopModeTaskRepository>> desktopModeTaskRepository)840 static Optional<DesktopModeTaskRepository> provideDesktopTaskRepository( 841 @DynamicOverride Optional<Lazy<DesktopModeTaskRepository>> desktopModeTaskRepository) { 842 // Use optional-of-lazy for the dependency that this provider relies on. 843 // Lazy ensures that this provider will not be the cause the dependency is created 844 // when it will not be returned due to the condition below. 845 if (DesktopModeStatus.isAnyEnabled()) { 846 return desktopModeTaskRepository.map(Lazy::get); 847 } 848 return Optional.empty(); 849 } 850 851 // 852 // Misc 853 // 854 855 // Workaround for dynamic overriding with a default implementation, see {@link DynamicOverride} 856 @BindsOptionalOf 857 @ShellCreateTriggerOverride provideIndependentShellComponentsToCreateOverride()858 abstract Object provideIndependentShellComponentsToCreateOverride(); 859 860 // TODO: Temporarily move dependencies to this instead of ShellInit since that is needed to add 861 // the callback. We will be moving to a different explicit startup mechanism in a follow- up CL. 862 @WMSingleton 863 @ShellCreateTrigger 864 @Provides provideIndependentShellComponentsToCreate( DisplayController displayController, DisplayImeController displayImeController, DisplayInsetsController displayInsetsController, Optional<DragAndDropController> dragAndDropControllerOptional, ShellTaskOrganizer shellTaskOrganizer, Optional<BubbleController> bubblesOptional, Optional<SplitScreenController> splitScreenOptional, FullscreenTaskListener fullscreenTaskListener, Optional<UnfoldAnimationController> unfoldAnimationController, Optional<UnfoldTransitionHandler> unfoldTransitionHandler, Optional<FreeformComponents> freeformComponents, Optional<RecentTasksController> recentTasksOptional, Optional<RecentsTransitionHandler> recentsTransitionHandlerOptional, Optional<OneHandedController> oneHandedControllerOptional, Optional<HideDisplayCutoutController> hideDisplayCutoutControllerOptional, Optional<ActivityEmbeddingController> activityEmbeddingOptional, Transitions transitions, StartingWindowController startingWindow, ProtoLogController protoLogController, @ShellCreateTriggerOverride Optional<Object> overriddenCreateTrigger)865 static Object provideIndependentShellComponentsToCreate( 866 DisplayController displayController, 867 DisplayImeController displayImeController, 868 DisplayInsetsController displayInsetsController, 869 Optional<DragAndDropController> dragAndDropControllerOptional, 870 ShellTaskOrganizer shellTaskOrganizer, 871 Optional<BubbleController> bubblesOptional, 872 Optional<SplitScreenController> splitScreenOptional, 873 FullscreenTaskListener fullscreenTaskListener, 874 Optional<UnfoldAnimationController> unfoldAnimationController, 875 Optional<UnfoldTransitionHandler> unfoldTransitionHandler, 876 Optional<FreeformComponents> freeformComponents, 877 Optional<RecentTasksController> recentTasksOptional, 878 Optional<RecentsTransitionHandler> recentsTransitionHandlerOptional, 879 Optional<OneHandedController> oneHandedControllerOptional, 880 Optional<HideDisplayCutoutController> hideDisplayCutoutControllerOptional, 881 Optional<ActivityEmbeddingController> activityEmbeddingOptional, 882 Transitions transitions, 883 StartingWindowController startingWindow, 884 ProtoLogController protoLogController, 885 @ShellCreateTriggerOverride Optional<Object> overriddenCreateTrigger) { 886 return new Object(); 887 } 888 889 @WMSingleton 890 @Provides provideShellInit(@hellMainThread ShellExecutor mainExecutor)891 static ShellInit provideShellInit(@ShellMainThread ShellExecutor mainExecutor) { 892 return new ShellInit(mainExecutor); 893 } 894 895 @WMSingleton 896 @Provides provideShellCommandHandler()897 static ShellCommandHandler provideShellCommandHandler() { 898 return new ShellCommandHandler(); 899 } 900 901 @WMSingleton 902 @Provides provideProtoLogController( ShellInit shellInit, ShellCommandHandler shellCommandHandler)903 static ProtoLogController provideProtoLogController( 904 ShellInit shellInit, 905 ShellCommandHandler shellCommandHandler) { 906 return new ProtoLogController(shellInit, shellCommandHandler); 907 } 908 } 909