• 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 
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