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 android.annotation.Nullable;
20 import android.content.Context;
21 import android.content.pm.LauncherApps;
22 import android.os.Handler;
23 import android.os.UserManager;
24 import android.view.Choreographer;
25 import android.view.IWindowManager;
26 import android.view.WindowManager;
27 
28 import com.android.internal.jank.InteractionJankMonitor;
29 import com.android.internal.logging.UiEventLogger;
30 import com.android.internal.statusbar.IStatusBarService;
31 import com.android.launcher3.icons.IconProvider;
32 import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
33 import com.android.wm.shell.ShellTaskOrganizer;
34 import com.android.wm.shell.WindowManagerShellWrapper;
35 import com.android.wm.shell.bubbles.BubbleController;
36 import com.android.wm.shell.bubbles.BubbleData;
37 import com.android.wm.shell.bubbles.BubbleDataRepository;
38 import com.android.wm.shell.bubbles.BubbleLogger;
39 import com.android.wm.shell.bubbles.BubblePositioner;
40 import com.android.wm.shell.bubbles.properties.ProdBubbleProperties;
41 import com.android.wm.shell.bubbles.storage.BubblePersistentRepository;
42 import com.android.wm.shell.common.DisplayController;
43 import com.android.wm.shell.common.DisplayImeController;
44 import com.android.wm.shell.common.DisplayInsetsController;
45 import com.android.wm.shell.common.DisplayLayout;
46 import com.android.wm.shell.common.FloatingContentCoordinator;
47 import com.android.wm.shell.common.LaunchAdjacentController;
48 import com.android.wm.shell.common.ShellExecutor;
49 import com.android.wm.shell.common.SyncTransactionQueue;
50 import com.android.wm.shell.common.TaskStackListenerImpl;
51 import com.android.wm.shell.common.TransactionPool;
52 import com.android.wm.shell.common.annotations.ShellAnimationThread;
53 import com.android.wm.shell.common.annotations.ShellBackgroundThread;
54 import com.android.wm.shell.common.annotations.ShellMainThread;
55 import com.android.wm.shell.dagger.pip.PipModule;
56 import com.android.wm.shell.desktopmode.DesktopModeController;
57 import com.android.wm.shell.desktopmode.DesktopModeStatus;
58 import com.android.wm.shell.desktopmode.DesktopModeTaskRepository;
59 import com.android.wm.shell.desktopmode.DesktopTasksController;
60 import com.android.wm.shell.desktopmode.EnterDesktopTaskTransitionHandler;
61 import com.android.wm.shell.desktopmode.ExitDesktopTaskTransitionHandler;
62 import com.android.wm.shell.desktopmode.ToggleResizeDesktopTaskTransitionHandler;
63 import com.android.wm.shell.draganddrop.DragAndDropController;
64 import com.android.wm.shell.freeform.FreeformComponents;
65 import com.android.wm.shell.freeform.FreeformTaskListener;
66 import com.android.wm.shell.freeform.FreeformTaskTransitionHandler;
67 import com.android.wm.shell.freeform.FreeformTaskTransitionObserver;
68 import com.android.wm.shell.keyguard.KeyguardTransitionHandler;
69 import com.android.wm.shell.onehanded.OneHandedController;
70 import com.android.wm.shell.pip.PipTransitionController;
71 import com.android.wm.shell.recents.RecentTasksController;
72 import com.android.wm.shell.recents.RecentsTransitionHandler;
73 import com.android.wm.shell.splitscreen.SplitScreenController;
74 import com.android.wm.shell.sysui.ShellCommandHandler;
75 import com.android.wm.shell.sysui.ShellController;
76 import com.android.wm.shell.sysui.ShellInit;
77 import com.android.wm.shell.taskview.TaskViewTransitions;
78 import com.android.wm.shell.transition.DefaultMixedHandler;
79 import com.android.wm.shell.transition.Transitions;
80 import com.android.wm.shell.unfold.ShellUnfoldProgressProvider;
81 import com.android.wm.shell.unfold.UnfoldAnimationController;
82 import com.android.wm.shell.unfold.UnfoldBackgroundController;
83 import com.android.wm.shell.unfold.UnfoldTransitionHandler;
84 import com.android.wm.shell.unfold.animation.FullscreenUnfoldTaskAnimator;
85 import com.android.wm.shell.unfold.animation.SplitTaskUnfoldAnimator;
86 import com.android.wm.shell.unfold.animation.UnfoldTaskAnimator;
87 import com.android.wm.shell.unfold.qualifier.UnfoldShellTransition;
88 import com.android.wm.shell.unfold.qualifier.UnfoldTransition;
89 import com.android.wm.shell.windowdecor.CaptionWindowDecorViewModel;
90 import com.android.wm.shell.windowdecor.DesktopModeWindowDecorViewModel;
91 import com.android.wm.shell.windowdecor.WindowDecorViewModel;
92 
93 import dagger.Binds;
94 import dagger.Lazy;
95 import dagger.Module;
96 import dagger.Provides;
97 
98 import java.util.ArrayList;
99 import java.util.List;
100 import java.util.Optional;
101 
102 /**
103  * Provides dependencies from {@link com.android.wm.shell}, these dependencies are only
104  * accessible from components within the WM subcomponent (can be explicitly exposed to the
105  * SysUIComponent, see {@link WMComponent}).
106  *
107  * This module only defines Shell dependencies for handheld SystemUI implementation.  Common
108  * dependencies should go into {@link WMShellBaseModule}.
109  */
110 @Module(includes = {
111         WMShellBaseModule.class,
112         PipModule.class
113 })
114 public abstract class WMShellModule {
115 
116     //
117     // Bubbles
118     //
119 
120     @WMSingleton
121     @Provides
provideBubbleLogger(UiEventLogger uiEventLogger)122     static BubbleLogger provideBubbleLogger(UiEventLogger uiEventLogger) {
123         return new BubbleLogger(uiEventLogger);
124     }
125 
126     @WMSingleton
127     @Provides
provideBubblePositioner(Context context, WindowManager windowManager)128     static BubblePositioner provideBubblePositioner(Context context,
129             WindowManager windowManager) {
130         return new BubblePositioner(context, windowManager);
131     }
132 
133     @WMSingleton
134     @Provides
provideBubbleData(Context context, BubbleLogger logger, BubblePositioner positioner, @ShellMainThread ShellExecutor mainExecutor)135     static BubbleData provideBubbleData(Context context,
136             BubbleLogger logger,
137             BubblePositioner positioner,
138             @ShellMainThread ShellExecutor mainExecutor) {
139         return new BubbleData(context, logger, positioner, mainExecutor);
140     }
141 
142     // Note: Handler needed for LauncherApps.register
143     @WMSingleton
144     @Provides
provideBubbleController(Context context, ShellInit shellInit, ShellCommandHandler shellCommandHandler, ShellController shellController, BubbleData data, FloatingContentCoordinator floatingContentCoordinator, IStatusBarService statusBarService, WindowManager windowManager, WindowManagerShellWrapper windowManagerShellWrapper, UserManager userManager, LauncherApps launcherApps, TaskStackListenerImpl taskStackListener, BubbleLogger logger, ShellTaskOrganizer organizer, BubblePositioner positioner, DisplayController displayController, @DynamicOverride Optional<OneHandedController> oneHandedOptional, Optional<DragAndDropController> dragAndDropController, @ShellMainThread ShellExecutor mainExecutor, @ShellMainThread Handler mainHandler, @ShellBackgroundThread ShellExecutor bgExecutor, TaskViewTransitions taskViewTransitions, SyncTransactionQueue syncQueue, IWindowManager wmService)145     static BubbleController provideBubbleController(Context context,
146             ShellInit shellInit,
147             ShellCommandHandler shellCommandHandler,
148             ShellController shellController,
149             BubbleData data,
150             FloatingContentCoordinator floatingContentCoordinator,
151             IStatusBarService statusBarService,
152             WindowManager windowManager,
153             WindowManagerShellWrapper windowManagerShellWrapper,
154             UserManager userManager,
155             LauncherApps launcherApps,
156             TaskStackListenerImpl taskStackListener,
157             BubbleLogger logger,
158             ShellTaskOrganizer organizer,
159             BubblePositioner positioner,
160             DisplayController displayController,
161             @DynamicOverride Optional<OneHandedController> oneHandedOptional,
162             Optional<DragAndDropController> dragAndDropController,
163             @ShellMainThread ShellExecutor mainExecutor,
164             @ShellMainThread Handler mainHandler,
165             @ShellBackgroundThread ShellExecutor bgExecutor,
166             TaskViewTransitions taskViewTransitions,
167             SyncTransactionQueue syncQueue,
168             IWindowManager wmService) {
169         return new BubbleController(context, shellInit, shellCommandHandler, shellController, data,
170                 null /* synchronizer */, floatingContentCoordinator,
171                 new BubbleDataRepository(launcherApps, mainExecutor,
172                         new BubblePersistentRepository(context)),
173                 statusBarService, windowManager, windowManagerShellWrapper, userManager,
174                 launcherApps, logger, taskStackListener, organizer, positioner, displayController,
175                 oneHandedOptional, dragAndDropController, mainExecutor, mainHandler, bgExecutor,
176                 taskViewTransitions, syncQueue, wmService, ProdBubbleProperties.INSTANCE);
177     }
178 
179     //
180     // Window decoration
181     //
182 
183     @WMSingleton
184     @Provides
provideWindowDecorViewModel( Context context, @ShellMainThread Handler mainHandler, @ShellMainThread Choreographer mainChoreographer, ShellInit shellInit, ShellTaskOrganizer taskOrganizer, DisplayController displayController, ShellController shellController, SyncTransactionQueue syncQueue, Transitions transitions, Optional<DesktopModeController> desktopModeController, Optional<DesktopTasksController> desktopTasksController)185     static WindowDecorViewModel provideWindowDecorViewModel(
186             Context context,
187             @ShellMainThread Handler mainHandler,
188             @ShellMainThread Choreographer mainChoreographer,
189             ShellInit shellInit,
190             ShellTaskOrganizer taskOrganizer,
191             DisplayController displayController,
192             ShellController shellController,
193             SyncTransactionQueue syncQueue,
194             Transitions transitions,
195             Optional<DesktopModeController> desktopModeController,
196             Optional<DesktopTasksController> desktopTasksController) {
197         if (DesktopModeStatus.isAnyEnabled()) {
198             return new DesktopModeWindowDecorViewModel(
199                     context,
200                     mainHandler,
201                     mainChoreographer,
202                     shellInit,
203                     taskOrganizer,
204                     displayController,
205                     shellController,
206                     syncQueue,
207                     transitions,
208                     desktopModeController,
209                     desktopTasksController);
210         }
211         return new CaptionWindowDecorViewModel(
212                 context,
213                 mainHandler,
214                 mainChoreographer,
215                 taskOrganizer,
216                 displayController,
217                 syncQueue);
218     }
219 
220     //
221     // Freeform
222     //
223 
224     @WMSingleton
225     @Provides
226     @DynamicOverride
provideFreeformComponents( FreeformTaskListener taskListener, FreeformTaskTransitionHandler transitionHandler, FreeformTaskTransitionObserver transitionObserver)227     static FreeformComponents provideFreeformComponents(
228             FreeformTaskListener taskListener,
229             FreeformTaskTransitionHandler transitionHandler,
230             FreeformTaskTransitionObserver transitionObserver) {
231         return new FreeformComponents(
232                 taskListener, Optional.of(transitionHandler), Optional.of(transitionObserver));
233     }
234 
235     @WMSingleton
236     @Provides
provideFreeformTaskListener( Context context, ShellInit shellInit, ShellTaskOrganizer shellTaskOrganizer, Optional<DesktopModeTaskRepository> desktopModeTaskRepository, WindowDecorViewModel windowDecorViewModel)237     static FreeformTaskListener provideFreeformTaskListener(
238             Context context,
239             ShellInit shellInit,
240             ShellTaskOrganizer shellTaskOrganizer,
241             Optional<DesktopModeTaskRepository> desktopModeTaskRepository,
242             WindowDecorViewModel windowDecorViewModel) {
243         // TODO(b/238217847): Temporarily add this check here until we can remove the dynamic
244         //                    override for this controller from the base module
245         ShellInit init = FreeformComponents.isFreeformEnabled(context)
246                 ? shellInit
247                 : null;
248         return new FreeformTaskListener(init, shellTaskOrganizer, desktopModeTaskRepository,
249                 windowDecorViewModel);
250     }
251 
252     @WMSingleton
253     @Provides
provideFreeformTaskTransitionHandler( ShellInit shellInit, Transitions transitions, Context context, WindowDecorViewModel windowDecorViewModel, DisplayController displayController, @ShellMainThread ShellExecutor mainExecutor, @ShellAnimationThread ShellExecutor animExecutor)254     static FreeformTaskTransitionHandler provideFreeformTaskTransitionHandler(
255             ShellInit shellInit,
256             Transitions transitions,
257             Context context,
258             WindowDecorViewModel windowDecorViewModel,
259             DisplayController displayController,
260             @ShellMainThread ShellExecutor mainExecutor,
261             @ShellAnimationThread ShellExecutor animExecutor) {
262         return new FreeformTaskTransitionHandler(shellInit, transitions, context,
263                 windowDecorViewModel, displayController, mainExecutor, animExecutor);
264     }
265 
266     @WMSingleton
267     @Provides
provideFreeformTaskTransitionObserver( Context context, ShellInit shellInit, Transitions transitions, WindowDecorViewModel windowDecorViewModel)268     static FreeformTaskTransitionObserver provideFreeformTaskTransitionObserver(
269             Context context,
270             ShellInit shellInit,
271             Transitions transitions,
272             WindowDecorViewModel windowDecorViewModel) {
273         return new FreeformTaskTransitionObserver(
274                 context, shellInit, transitions, windowDecorViewModel);
275     }
276 
277     //
278     // One handed mode
279     //
280 
281 
282     // Needs the shell main handler for ContentObserver callbacks
283     @WMSingleton
284     @Provides
285     @DynamicOverride
provideOneHandedController(Context context, ShellInit shellInit, ShellCommandHandler shellCommandHandler, ShellController shellController, WindowManager windowManager, DisplayController displayController, DisplayLayout displayLayout, TaskStackListenerImpl taskStackListener, UiEventLogger uiEventLogger, InteractionJankMonitor jankMonitor, @ShellMainThread ShellExecutor mainExecutor, @ShellMainThread Handler mainHandler)286     static OneHandedController provideOneHandedController(Context context,
287             ShellInit shellInit,
288             ShellCommandHandler shellCommandHandler,
289             ShellController shellController,
290             WindowManager windowManager,
291             DisplayController displayController,
292             DisplayLayout displayLayout,
293             TaskStackListenerImpl taskStackListener,
294             UiEventLogger uiEventLogger,
295             InteractionJankMonitor jankMonitor,
296             @ShellMainThread ShellExecutor mainExecutor,
297             @ShellMainThread Handler mainHandler) {
298         return OneHandedController.create(context, shellInit, shellCommandHandler, shellController,
299                 windowManager, displayController, displayLayout, taskStackListener, jankMonitor,
300                 uiEventLogger, mainExecutor, mainHandler);
301     }
302 
303     //
304     // Splitscreen
305     //
306 
307     @WMSingleton
308     @Provides
309     @DynamicOverride
provideSplitScreenController( Context context, ShellInit shellInit, ShellCommandHandler shellCommandHandler, ShellController shellController, ShellTaskOrganizer shellTaskOrganizer, SyncTransactionQueue syncQueue, RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer, DisplayController displayController, DisplayImeController displayImeController, DisplayInsetsController displayInsetsController, Optional<DragAndDropController> dragAndDropController, Transitions transitions, TransactionPool transactionPool, IconProvider iconProvider, Optional<RecentTasksController> recentTasks, LaunchAdjacentController launchAdjacentController, Optional<WindowDecorViewModel> windowDecorViewModel, Optional<DesktopTasksController> desktopTasksController, @ShellMainThread ShellExecutor mainExecutor)310     static SplitScreenController provideSplitScreenController(
311             Context context,
312             ShellInit shellInit,
313             ShellCommandHandler shellCommandHandler,
314             ShellController shellController,
315             ShellTaskOrganizer shellTaskOrganizer,
316             SyncTransactionQueue syncQueue,
317             RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
318             DisplayController displayController,
319             DisplayImeController displayImeController,
320             DisplayInsetsController displayInsetsController,
321             Optional<DragAndDropController> dragAndDropController,
322             Transitions transitions,
323             TransactionPool transactionPool,
324             IconProvider iconProvider,
325             Optional<RecentTasksController> recentTasks,
326             LaunchAdjacentController launchAdjacentController,
327             Optional<WindowDecorViewModel> windowDecorViewModel,
328             Optional<DesktopTasksController> desktopTasksController,
329             @ShellMainThread ShellExecutor mainExecutor) {
330         return new SplitScreenController(context, shellInit, shellCommandHandler, shellController,
331                 shellTaskOrganizer, syncQueue, rootTaskDisplayAreaOrganizer, displayController,
332                 displayImeController, displayInsetsController, dragAndDropController, transitions,
333                 transactionPool, iconProvider, recentTasks, launchAdjacentController,
334                 windowDecorViewModel, desktopTasksController, mainExecutor);
335     }
336 
337     //
338     // Transitions
339     //
340 
341     @WMSingleton
342     @Provides
provideDefaultMixedHandler( ShellInit shellInit, Optional<SplitScreenController> splitScreenOptional, @Nullable PipTransitionController pipTransitionController, Optional<RecentsTransitionHandler> recentsTransitionHandler, KeyguardTransitionHandler keyguardTransitionHandler, Optional<DesktopModeController> desktopModeController, Optional<DesktopTasksController> desktopTasksController, Optional<UnfoldTransitionHandler> unfoldHandler, Transitions transitions)343     static DefaultMixedHandler provideDefaultMixedHandler(
344             ShellInit shellInit,
345             Optional<SplitScreenController> splitScreenOptional,
346             @Nullable PipTransitionController pipTransitionController,
347             Optional<RecentsTransitionHandler> recentsTransitionHandler,
348             KeyguardTransitionHandler keyguardTransitionHandler,
349             Optional<DesktopModeController> desktopModeController,
350             Optional<DesktopTasksController> desktopTasksController,
351             Optional<UnfoldTransitionHandler> unfoldHandler,
352             Transitions transitions) {
353         return new DefaultMixedHandler(shellInit, transitions, splitScreenOptional,
354                 pipTransitionController, recentsTransitionHandler,
355                 keyguardTransitionHandler, desktopModeController, desktopTasksController,
356                 unfoldHandler);
357     }
358 
359     @WMSingleton
360     @Provides
provideRecentsTransitionHandler( ShellInit shellInit, Transitions transitions, Optional<RecentTasksController> recentTasksController)361     static RecentsTransitionHandler provideRecentsTransitionHandler(
362             ShellInit shellInit,
363             Transitions transitions,
364             Optional<RecentTasksController> recentTasksController) {
365         return new RecentsTransitionHandler(shellInit, transitions,
366                 recentTasksController.orElse(null));
367     }
368 
369     //
370     // Unfold transition
371     //
372 
373     @WMSingleton
374     @Provides
375     @DynamicOverride
provideUnfoldAnimationController( Optional<ShellUnfoldProgressProvider> progressProvider, TransactionPool transactionPool, @UnfoldTransition SplitTaskUnfoldAnimator splitAnimator, FullscreenUnfoldTaskAnimator fullscreenAnimator, Lazy<Optional<UnfoldTransitionHandler>> unfoldTransitionHandler, ShellInit shellInit, @ShellMainThread ShellExecutor mainExecutor )376     static UnfoldAnimationController provideUnfoldAnimationController(
377             Optional<ShellUnfoldProgressProvider> progressProvider,
378             TransactionPool transactionPool,
379             @UnfoldTransition SplitTaskUnfoldAnimator splitAnimator,
380             FullscreenUnfoldTaskAnimator fullscreenAnimator,
381             Lazy<Optional<UnfoldTransitionHandler>> unfoldTransitionHandler,
382             ShellInit shellInit,
383             @ShellMainThread ShellExecutor mainExecutor
384     ) {
385         final List<UnfoldTaskAnimator> animators = new ArrayList<>();
386         animators.add(splitAnimator);
387         animators.add(fullscreenAnimator);
388 
389         return new UnfoldAnimationController(
390                 shellInit,
391                 transactionPool,
392                 progressProvider.get(),
393                 animators,
394                 unfoldTransitionHandler,
395                 mainExecutor
396         );
397     }
398 
399     @Provides
provideFullscreenUnfoldTaskAnimator( Context context, UnfoldBackgroundController unfoldBackgroundController, ShellController shellController, DisplayInsetsController displayInsetsController )400     static FullscreenUnfoldTaskAnimator provideFullscreenUnfoldTaskAnimator(
401             Context context,
402             UnfoldBackgroundController unfoldBackgroundController,
403             ShellController shellController,
404             DisplayInsetsController displayInsetsController
405     ) {
406         return new FullscreenUnfoldTaskAnimator(context, unfoldBackgroundController,
407                 shellController, displayInsetsController);
408     }
409 
410     @Provides
provideSplitTaskUnfoldAnimatorBase( Context context, UnfoldBackgroundController backgroundController, ShellController shellController, @ShellMainThread ShellExecutor executor, Lazy<Optional<SplitScreenController>> splitScreenOptional, DisplayInsetsController displayInsetsController )411     static SplitTaskUnfoldAnimator provideSplitTaskUnfoldAnimatorBase(
412             Context context,
413             UnfoldBackgroundController backgroundController,
414             ShellController shellController,
415             @ShellMainThread ShellExecutor executor,
416             Lazy<Optional<SplitScreenController>> splitScreenOptional,
417             DisplayInsetsController displayInsetsController
418     ) {
419         // TODO(b/238217847): The lazy reference here causes some dependency issues since it
420         // immediately registers a listener on that controller on init.  We should reference the
421         // controller directly once we refactor ShellTaskOrganizer to not depend on the unfold
422         // animation controller directly.
423         return new SplitTaskUnfoldAnimator(context, executor, splitScreenOptional,
424                 shellController, backgroundController, displayInsetsController);
425     }
426 
427     @WMSingleton
428     @UnfoldShellTransition
429     @Binds
provideShellSplitTaskUnfoldAnimator( SplitTaskUnfoldAnimator splitTaskUnfoldAnimator)430     abstract SplitTaskUnfoldAnimator provideShellSplitTaskUnfoldAnimator(
431             SplitTaskUnfoldAnimator splitTaskUnfoldAnimator);
432 
433     @WMSingleton
434     @UnfoldTransition
435     @Binds
provideSplitTaskUnfoldAnimator( SplitTaskUnfoldAnimator splitTaskUnfoldAnimator)436     abstract SplitTaskUnfoldAnimator provideSplitTaskUnfoldAnimator(
437             SplitTaskUnfoldAnimator splitTaskUnfoldAnimator);
438 
439     @WMSingleton
440     @Provides
441     @DynamicOverride
provideUnfoldTransitionHandler( Optional<ShellUnfoldProgressProvider> progressProvider, FullscreenUnfoldTaskAnimator animator, @UnfoldShellTransition SplitTaskUnfoldAnimator unfoldAnimator, TransactionPool transactionPool, Transitions transitions, @ShellMainThread ShellExecutor executor, ShellInit shellInit)442     static UnfoldTransitionHandler provideUnfoldTransitionHandler(
443             Optional<ShellUnfoldProgressProvider> progressProvider,
444             FullscreenUnfoldTaskAnimator animator,
445             @UnfoldShellTransition SplitTaskUnfoldAnimator unfoldAnimator,
446             TransactionPool transactionPool,
447             Transitions transitions,
448             @ShellMainThread ShellExecutor executor,
449             ShellInit shellInit) {
450         return new UnfoldTransitionHandler(shellInit, progressProvider.get(), animator,
451                 unfoldAnimator, transactionPool, executor, transitions);
452     }
453 
454     @WMSingleton
455     @Provides
provideUnfoldBackgroundController(Context context)456     static UnfoldBackgroundController provideUnfoldBackgroundController(Context context) {
457         return new UnfoldBackgroundController(context);
458     }
459 
460     //
461     // Desktop mode (optional feature)
462     //
463 
464     @WMSingleton
465     @Provides
466     @DynamicOverride
provideDesktopModeController(Context context, ShellInit shellInit, ShellController shellController, ShellTaskOrganizer shellTaskOrganizer, RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer, Transitions transitions, @DynamicOverride DesktopModeTaskRepository desktopModeTaskRepository, @ShellMainThread Handler mainHandler, @ShellMainThread ShellExecutor mainExecutor )467     static DesktopModeController provideDesktopModeController(Context context,
468             ShellInit shellInit,
469             ShellController shellController,
470             ShellTaskOrganizer shellTaskOrganizer,
471             RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
472             Transitions transitions,
473             @DynamicOverride DesktopModeTaskRepository desktopModeTaskRepository,
474             @ShellMainThread Handler mainHandler,
475             @ShellMainThread ShellExecutor mainExecutor
476     ) {
477         return new DesktopModeController(context, shellInit, shellController, shellTaskOrganizer,
478                 rootTaskDisplayAreaOrganizer, transitions, desktopModeTaskRepository, mainHandler,
479                 mainExecutor);
480     }
481 
482     @WMSingleton
483     @Provides
484     @DynamicOverride
provideDesktopTasksController( Context context, ShellInit shellInit, ShellCommandHandler shellCommandHandler, ShellController shellController, DisplayController displayController, ShellTaskOrganizer shellTaskOrganizer, SyncTransactionQueue syncQueue, RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer, Transitions transitions, EnterDesktopTaskTransitionHandler enterDesktopTransitionHandler, ExitDesktopTaskTransitionHandler exitDesktopTransitionHandler, ToggleResizeDesktopTaskTransitionHandler toggleResizeDesktopTaskTransitionHandler, @DynamicOverride DesktopModeTaskRepository desktopModeTaskRepository, LaunchAdjacentController launchAdjacentController, @ShellMainThread ShellExecutor mainExecutor )485     static DesktopTasksController provideDesktopTasksController(
486             Context context,
487             ShellInit shellInit,
488             ShellCommandHandler shellCommandHandler,
489             ShellController shellController,
490             DisplayController displayController,
491             ShellTaskOrganizer shellTaskOrganizer,
492             SyncTransactionQueue syncQueue,
493             RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
494             Transitions transitions,
495             EnterDesktopTaskTransitionHandler enterDesktopTransitionHandler,
496             ExitDesktopTaskTransitionHandler exitDesktopTransitionHandler,
497             ToggleResizeDesktopTaskTransitionHandler toggleResizeDesktopTaskTransitionHandler,
498             @DynamicOverride DesktopModeTaskRepository desktopModeTaskRepository,
499             LaunchAdjacentController launchAdjacentController,
500             @ShellMainThread ShellExecutor mainExecutor
501     ) {
502         return new DesktopTasksController(context, shellInit, shellCommandHandler, shellController,
503                 displayController, shellTaskOrganizer, syncQueue, rootTaskDisplayAreaOrganizer,
504                 transitions, enterDesktopTransitionHandler, exitDesktopTransitionHandler,
505                 toggleResizeDesktopTaskTransitionHandler, desktopModeTaskRepository,
506                 launchAdjacentController, mainExecutor);
507     }
508 
509     @WMSingleton
510     @Provides
provideEnterDesktopModeTaskTransitionHandler( Transitions transitions)511     static EnterDesktopTaskTransitionHandler provideEnterDesktopModeTaskTransitionHandler(
512             Transitions transitions) {
513         return new EnterDesktopTaskTransitionHandler(transitions);
514     }
515 
516     @WMSingleton
517     @Provides
provideToggleResizeDesktopTaskTransitionHandler( Transitions transitions)518     static ToggleResizeDesktopTaskTransitionHandler provideToggleResizeDesktopTaskTransitionHandler(
519             Transitions transitions) {
520         return new ToggleResizeDesktopTaskTransitionHandler(transitions);
521     }
522 
523     @WMSingleton
524     @Provides
provideExitDesktopTaskTransitionHandler( Transitions transitions, Context context )525     static ExitDesktopTaskTransitionHandler provideExitDesktopTaskTransitionHandler(
526             Transitions transitions,
527             Context context
528     ) {
529         return new ExitDesktopTaskTransitionHandler(transitions, context);
530     }
531 
532     @WMSingleton
533     @Provides
534     @DynamicOverride
provideDesktopModeTaskRepository()535     static DesktopModeTaskRepository provideDesktopModeTaskRepository() {
536         return new DesktopModeTaskRepository();
537     }
538 
539     //
540     // Misc
541     //
542 
543     // TODO: Temporarily move dependencies to this instead of ShellInit since that is needed to add
544     // the callback. We will be moving to a different explicit startup mechanism in a follow- up CL.
545     @WMSingleton
546     @ShellCreateTriggerOverride
547     @Provides
provideIndependentShellComponentsToCreate( DefaultMixedHandler defaultMixedHandler, Optional<DesktopModeController> desktopModeController)548     static Object provideIndependentShellComponentsToCreate(
549             DefaultMixedHandler defaultMixedHandler,
550             Optional<DesktopModeController> desktopModeController) {
551         return new Object();
552     }
553 }
554