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