• 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 android.provider.Settings.Secure.COMPAT_UI_EDUCATION_SHOWING;
20 
21 import static com.android.wm.shell.compatui.CompatUIStatusManager.COMPAT_UI_EDUCATION_HIDDEN;
22 import static com.android.wm.shell.onehanded.OneHandedController.SUPPORT_ONE_HANDED_MODE;
23 
24 import android.annotation.NonNull;
25 import android.app.ActivityTaskManager;
26 import android.content.Context;
27 import android.content.pm.PackageManager;
28 import android.hardware.display.DisplayManager;
29 import android.os.Handler;
30 import android.os.SystemProperties;
31 import android.provider.Settings;
32 import android.view.IWindowManager;
33 import android.view.accessibility.AccessibilityManager;
34 import android.window.DesktopModeFlags;
35 import android.window.SystemPerformanceHinter;
36 
37 import com.android.internal.logging.UiEventLogger;
38 import com.android.launcher3.icons.IconProvider;
39 import com.android.window.flags.Flags;
40 import com.android.wm.shell.ProtoLogController;
41 import com.android.wm.shell.R;
42 import com.android.wm.shell.RootDisplayAreaOrganizer;
43 import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
44 import com.android.wm.shell.ShellTaskOrganizer;
45 import com.android.wm.shell.WindowManagerShellWrapper;
46 import com.android.wm.shell.activityembedding.ActivityEmbeddingController;
47 import com.android.wm.shell.appzoomout.AppZoomOut;
48 import com.android.wm.shell.appzoomout.AppZoomOutController;
49 import com.android.wm.shell.back.BackAnimation;
50 import com.android.wm.shell.back.BackAnimationBackground;
51 import com.android.wm.shell.back.BackAnimationController;
52 import com.android.wm.shell.back.ShellBackAnimationRegistry;
53 import com.android.wm.shell.bubbles.BubbleController;
54 import com.android.wm.shell.bubbles.Bubbles;
55 import com.android.wm.shell.common.DevicePostureController;
56 import com.android.wm.shell.common.DisplayController;
57 import com.android.wm.shell.common.DisplayImeController;
58 import com.android.wm.shell.common.DisplayInsetsController;
59 import com.android.wm.shell.common.DisplayLayout;
60 import com.android.wm.shell.common.DockStateReader;
61 import com.android.wm.shell.common.FloatingContentCoordinator;
62 import com.android.wm.shell.common.LaunchAdjacentController;
63 import com.android.wm.shell.common.MultiInstanceHelper;
64 import com.android.wm.shell.common.ShellExecutor;
65 import com.android.wm.shell.common.SyncTransactionQueue;
66 import com.android.wm.shell.common.SystemWindows;
67 import com.android.wm.shell.common.TabletopModeController;
68 import com.android.wm.shell.common.TaskStackListenerImpl;
69 import com.android.wm.shell.common.pip.PhonePipKeepClearAlgorithm;
70 import com.android.wm.shell.common.pip.PhoneSizeSpecSource;
71 import com.android.wm.shell.common.pip.PipAppOpsListener;
72 import com.android.wm.shell.common.pip.PipBoundsAlgorithm;
73 import com.android.wm.shell.common.pip.PipBoundsState;
74 import com.android.wm.shell.common.pip.PipDisplayLayoutState;
75 import com.android.wm.shell.common.pip.PipMediaController;
76 import com.android.wm.shell.common.pip.PipPerfHintController;
77 import com.android.wm.shell.common.pip.PipSnapAlgorithm;
78 import com.android.wm.shell.common.pip.PipUiEventLogger;
79 import com.android.wm.shell.common.pip.SizeSpecSource;
80 import com.android.wm.shell.common.split.SplitState;
81 import com.android.wm.shell.compatui.CompatUIConfiguration;
82 import com.android.wm.shell.compatui.CompatUIController;
83 import com.android.wm.shell.compatui.CompatUIShellCommandHandler;
84 import com.android.wm.shell.compatui.CompatUIStatusManager;
85 import com.android.wm.shell.compatui.api.CompatUIComponentFactory;
86 import com.android.wm.shell.compatui.api.CompatUIComponentIdGenerator;
87 import com.android.wm.shell.compatui.api.CompatUIHandler;
88 import com.android.wm.shell.compatui.api.CompatUIRepository;
89 import com.android.wm.shell.compatui.api.CompatUIState;
90 import com.android.wm.shell.compatui.components.RestartButtonSpecKt;
91 import com.android.wm.shell.compatui.impl.DefaultCompatUIComponentFactory;
92 import com.android.wm.shell.compatui.impl.DefaultCompatUIHandler;
93 import com.android.wm.shell.compatui.impl.DefaultCompatUIRepository;
94 import com.android.wm.shell.compatui.impl.DefaultComponentIdGenerator;
95 import com.android.wm.shell.desktopmode.DesktopMode;
96 import com.android.wm.shell.desktopmode.DesktopTasksController;
97 import com.android.wm.shell.desktopmode.DesktopUserRepositories;
98 import com.android.wm.shell.desktopmode.common.DefaultHomePackageSupplier;
99 import com.android.wm.shell.desktopmode.desktopwallpaperactivity.DesktopWallpaperActivityTokenProvider;
100 import com.android.wm.shell.displayareahelper.DisplayAreaHelper;
101 import com.android.wm.shell.displayareahelper.DisplayAreaHelperController;
102 import com.android.wm.shell.freeform.FreeformComponents;
103 import com.android.wm.shell.fullscreen.FullscreenTaskListener;
104 import com.android.wm.shell.hidedisplaycutout.HideDisplayCutoutController;
105 import com.android.wm.shell.keyguard.KeyguardTransitionHandler;
106 import com.android.wm.shell.keyguard.KeyguardTransitions;
107 import com.android.wm.shell.onehanded.OneHanded;
108 import com.android.wm.shell.onehanded.OneHandedController;
109 import com.android.wm.shell.performance.PerfHintController;
110 import com.android.wm.shell.recents.RecentTasks;
111 import com.android.wm.shell.recents.RecentTasksController;
112 import com.android.wm.shell.recents.RecentsTransitionHandler;
113 import com.android.wm.shell.recents.TaskStackTransitionObserver;
114 import com.android.wm.shell.shared.ShellTransitions;
115 import com.android.wm.shell.shared.TransactionPool;
116 import com.android.wm.shell.shared.annotations.ShellAnimationThread;
117 import com.android.wm.shell.shared.annotations.ShellMainThread;
118 import com.android.wm.shell.shared.annotations.ShellSplashscreenThread;
119 import com.android.wm.shell.shared.desktopmode.DesktopModeCompatPolicy;
120 import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
121 import com.android.wm.shell.splitscreen.SplitScreen;
122 import com.android.wm.shell.splitscreen.SplitScreenController;
123 import com.android.wm.shell.startingsurface.StartingSurface;
124 import com.android.wm.shell.startingsurface.StartingWindowController;
125 import com.android.wm.shell.startingsurface.StartingWindowTypeAlgorithm;
126 import com.android.wm.shell.startingsurface.phone.PhoneStartingWindowTypeAlgorithm;
127 import com.android.wm.shell.sysui.ShellCommandHandler;
128 import com.android.wm.shell.sysui.ShellController;
129 import com.android.wm.shell.sysui.ShellInit;
130 import com.android.wm.shell.sysui.ShellInterface;
131 import com.android.wm.shell.taskview.TaskViewFactory;
132 import com.android.wm.shell.taskview.TaskViewFactoryController;
133 import com.android.wm.shell.taskview.TaskViewRepository;
134 import com.android.wm.shell.taskview.TaskViewTransitions;
135 import com.android.wm.shell.transition.FocusTransitionObserver;
136 import com.android.wm.shell.transition.HomeTransitionObserver;
137 import com.android.wm.shell.transition.MixedTransitionHandler;
138 import com.android.wm.shell.transition.Transitions;
139 import com.android.wm.shell.unfold.ShellUnfoldProgressProvider;
140 import com.android.wm.shell.unfold.UnfoldAnimationController;
141 import com.android.wm.shell.unfold.UnfoldTransitionHandler;
142 import com.android.wm.shell.windowdecor.WindowDecorViewModel;
143 
144 import dagger.BindsOptionalOf;
145 import dagger.Lazy;
146 import dagger.Module;
147 import dagger.Provides;
148 
149 import java.util.Optional;
150 
151 /**
152  * Provides basic dependencies from {@link com.android.wm.shell}, these dependencies are only
153  * accessible from components within the WM subcomponent (can be explicitly exposed to the
154  * SysUIComponent, see {@link com.android.systemui.dagger.WMComponent}).
155  *
156  * <p>This module only defines *common* dependencies across various SystemUI implementations,
157  * dependencies that are device/form factor SystemUI implementation specific should go into their
158  * respective modules (ie. {@link WMShellModule} for handheld, {@link TvWMShellModule} for tv, etc.)
159  */
160 @Module(
161         includes = {
162                 WMShellConcurrencyModule.class,
163                 WMShellCoroutinesModule.class
164         })
165 public abstract class WMShellBaseModule {
166 
167     //
168     // Internal common - Components used internally by multiple shell features
169     //
170 
171     @WMSingleton
172     @Provides
provideFloatingContentCoordinator()173     static FloatingContentCoordinator provideFloatingContentCoordinator() {
174         return new FloatingContentCoordinator();
175     }
176 
177     @WMSingleton
178     @Provides
provideDisplayController(Context context, IWindowManager wmService, ShellInit shellInit, @ShellMainThread ShellExecutor mainExecutor, DisplayManager displayManager)179     static DisplayController provideDisplayController(Context context,
180             IWindowManager wmService,
181             ShellInit shellInit,
182             @ShellMainThread ShellExecutor mainExecutor,
183             DisplayManager displayManager) {
184         return new DisplayController(context, wmService, shellInit, mainExecutor, displayManager);
185     }
186 
187     @WMSingleton
188     @Provides
provideDisplayInsetsController(IWindowManager wmService, ShellInit shellInit, DisplayController displayController, @ShellMainThread ShellExecutor mainExecutor)189     static DisplayInsetsController provideDisplayInsetsController(IWindowManager wmService,
190             ShellInit shellInit,
191             DisplayController displayController,
192             @ShellMainThread ShellExecutor mainExecutor) {
193         return new DisplayInsetsController(wmService, shellInit, displayController,
194                 mainExecutor);
195     }
196 
197     @WMSingleton
198     @Provides
provideDisplayImeController( IWindowManager wmService, ShellInit shellInit, DisplayController displayController, DisplayInsetsController displayInsetsController, TransactionPool transactionPool, @ShellMainThread ShellExecutor mainExecutor )199     static DisplayImeController provideDisplayImeController(
200             IWindowManager wmService,
201             ShellInit shellInit,
202             DisplayController displayController,
203             DisplayInsetsController displayInsetsController,
204             TransactionPool transactionPool,
205             @ShellMainThread ShellExecutor mainExecutor
206     ) {
207         return new DisplayImeController(wmService, shellInit, displayController,
208                 displayInsetsController, transactionPool, mainExecutor);
209     }
210 
211     @WMSingleton
212     @Provides
provideDisplayLayout()213     static DisplayLayout provideDisplayLayout() {
214         return new DisplayLayout();
215     }
216 
217     @WMSingleton
218     @Provides
provideDevicePostureController( Context context, ShellInit shellInit, @ShellMainThread ShellExecutor mainExecutor )219     static DevicePostureController provideDevicePostureController(
220             Context context,
221             ShellInit shellInit,
222             @ShellMainThread ShellExecutor mainExecutor
223     ) {
224         return new DevicePostureController(context, shellInit, mainExecutor);
225     }
226 
227     @WMSingleton
228     @Provides
provideTabletopModeController( Context context, ShellInit shellInit, DevicePostureController postureController, DisplayController displayController, @ShellMainThread ShellExecutor mainExecutor)229     static TabletopModeController provideTabletopModeController(
230             Context context,
231             ShellInit shellInit,
232             DevicePostureController postureController,
233             DisplayController displayController,
234             @ShellMainThread ShellExecutor mainExecutor) {
235         return new TabletopModeController(
236                 context, shellInit, postureController, displayController, mainExecutor);
237     }
238 
239     @WMSingleton
240     @Provides
provideShellTaskOrganizer( Context context, ShellInit shellInit, ShellCommandHandler shellCommandHandler, Optional<CompatUIHandler> compatUI, Optional<UnfoldAnimationController> unfoldAnimationController, Optional<RecentTasksController> recentTasksOptional, @ShellMainThread ShellExecutor mainExecutor)241     static ShellTaskOrganizer provideShellTaskOrganizer(
242             Context context,
243             ShellInit shellInit,
244             ShellCommandHandler shellCommandHandler,
245             Optional<CompatUIHandler> compatUI,
246             Optional<UnfoldAnimationController> unfoldAnimationController,
247             Optional<RecentTasksController> recentTasksOptional,
248             @ShellMainThread ShellExecutor mainExecutor) {
249         if (!context.getResources().getBoolean(R.bool.config_registerShellTaskOrganizerOnInit)) {
250             // TODO(b/238217847): Force override shell init if registration is disabled
251             shellInit = new ShellInit(mainExecutor);
252         }
253         return new ShellTaskOrganizer(
254                 shellInit,
255                 shellCommandHandler,
256                 compatUI.orElse(null),
257                 unfoldAnimationController,
258                 recentTasksOptional,
259                 mainExecutor);
260     }
261 
262     @WMSingleton
263     @Provides
provideDesktopModeCompatPolicy( Context context, ShellInit shellInit, @ShellMainThread Handler mainHandler)264     static DesktopModeCompatPolicy provideDesktopModeCompatPolicy(
265             Context context,
266             ShellInit shellInit,
267             @ShellMainThread Handler mainHandler) {
268         final DesktopModeCompatPolicy policy = new DesktopModeCompatPolicy(context);
269         policy.setDefaultHomePackageSupplier(new DefaultHomePackageSupplier(
270                 context, shellInit, mainHandler));
271         return policy;
272     }
273 
274     @WMSingleton
275     @Provides
provideCompatUIController( Context context, ShellInit shellInit, ShellController shellController, DisplayController displayController, DisplayInsetsController displayInsetsController, DisplayImeController imeController, SyncTransactionQueue syncQueue, @ShellMainThread ShellExecutor mainExecutor, Lazy<Transitions> transitionsLazy, Lazy<DockStateReader> dockStateReader, Lazy<CompatUIConfiguration> compatUIConfiguration, Lazy<CompatUIShellCommandHandler> compatUIShellCommandHandler, Lazy<AccessibilityManager> accessibilityManager, CompatUIRepository compatUIRepository, Optional<DesktopUserRepositories> desktopUserRepositories, @NonNull CompatUIState compatUIState, @NonNull CompatUIComponentIdGenerator componentIdGenerator, @NonNull CompatUIComponentFactory compatUIComponentFactory, CompatUIStatusManager compatUIStatusManager)276     static Optional<CompatUIHandler> provideCompatUIController(
277             Context context,
278             ShellInit shellInit,
279             ShellController shellController,
280             DisplayController displayController,
281             DisplayInsetsController displayInsetsController,
282             DisplayImeController imeController,
283             SyncTransactionQueue syncQueue,
284             @ShellMainThread ShellExecutor mainExecutor,
285             Lazy<Transitions> transitionsLazy,
286             Lazy<DockStateReader> dockStateReader,
287             Lazy<CompatUIConfiguration> compatUIConfiguration,
288             Lazy<CompatUIShellCommandHandler> compatUIShellCommandHandler,
289             Lazy<AccessibilityManager> accessibilityManager,
290             CompatUIRepository compatUIRepository,
291             Optional<DesktopUserRepositories> desktopUserRepositories,
292             @NonNull CompatUIState compatUIState,
293             @NonNull CompatUIComponentIdGenerator componentIdGenerator,
294             @NonNull CompatUIComponentFactory compatUIComponentFactory,
295             CompatUIStatusManager compatUIStatusManager) {
296         if (!context.getResources().getBoolean(R.bool.config_enableCompatUIController)) {
297             return Optional.empty();
298         }
299         if (Flags.appCompatUiFramework()) {
300             return Optional.of(
301                     new DefaultCompatUIHandler(compatUIRepository, compatUIState,
302                             componentIdGenerator, compatUIComponentFactory, mainExecutor));
303         }
304         return Optional.of(
305                 new CompatUIController(
306                         context,
307                         shellInit,
308                         shellController,
309                         displayController,
310                         displayInsetsController,
311                         imeController,
312                         syncQueue,
313                         mainExecutor,
314                         transitionsLazy,
315                         dockStateReader.get(),
316                         compatUIConfiguration.get(),
317                         compatUIShellCommandHandler.get(),
318                         accessibilityManager.get(),
319                         compatUIStatusManager,
320                         desktopUserRepositories));
321     }
322 
323     @WMSingleton
324     @Provides
provideCompatUIStatusManager(@onNull Context context)325     static CompatUIStatusManager provideCompatUIStatusManager(@NonNull Context context) {
326         if (DesktopModeFlags.ENABLE_DESKTOP_COMPAT_UI_VISIBILITY_STATUS.isTrue()) {
327             return new CompatUIStatusManager(
328                     newState -> Settings.Secure.putInt(context.getContentResolver(),
329                             COMPAT_UI_EDUCATION_SHOWING, newState),
330                     () -> Settings.Secure.getInt(context.getContentResolver(),
331                             COMPAT_UI_EDUCATION_SHOWING, COMPAT_UI_EDUCATION_HIDDEN));
332         } else {
333             return new CompatUIStatusManager();
334         }
335     }
336 
337     @WMSingleton
338     @Provides
provideCompatUIState()339     static CompatUIState provideCompatUIState() {
340         return new CompatUIState();
341     }
342 
343     @WMSingleton
344     @Provides
provideCompatUIComponentFactory( @onNull Context context, @NonNull SyncTransactionQueue syncQueue, @NonNull DisplayController displayController)345     static CompatUIComponentFactory provideCompatUIComponentFactory(
346             @NonNull Context context,
347             @NonNull SyncTransactionQueue syncQueue,
348             @NonNull DisplayController displayController) {
349         return new DefaultCompatUIComponentFactory(context, syncQueue, displayController);
350     }
351 
352     @WMSingleton
353     @Provides
provideCompatUIComponentIdGenerator()354     static CompatUIComponentIdGenerator provideCompatUIComponentIdGenerator() {
355         return new DefaultComponentIdGenerator();
356     }
357 
358     @WMSingleton
359     @Provides
provideCompatUIRepository()360     static CompatUIRepository provideCompatUIRepository() {
361         // TODO(b/360288344) Integrate Dagger Multibinding
362         final CompatUIRepository repository = new DefaultCompatUIRepository();
363         repository.addSpec(RestartButtonSpecKt.getRestartButtonSpec());
364         return repository;
365     }
366 
367     @WMSingleton
368     @Provides
provideSyncTransactionQueue(TransactionPool pool, @ShellMainThread ShellExecutor mainExecutor)369     static SyncTransactionQueue provideSyncTransactionQueue(TransactionPool pool,
370             @ShellMainThread ShellExecutor mainExecutor) {
371         return new SyncTransactionQueue(pool, mainExecutor);
372     }
373 
374     @WMSingleton
375     @Provides
provideSystemWindows(DisplayController displayController, IWindowManager wmService)376     static SystemWindows provideSystemWindows(DisplayController displayController,
377             IWindowManager wmService) {
378         return new SystemWindows(displayController, wmService);
379     }
380 
381     @WMSingleton
382     @Provides
provideIconProvider(Context context)383     static IconProvider provideIconProvider(Context context) {
384         return new IconProvider(context);
385     }
386 
387     // We currently dedupe multiple messages, so we use the shell main handler directly
388     @WMSingleton
389     @Provides
providerTaskStackListenerImpl( @hellMainThread Handler mainHandler)390     static TaskStackListenerImpl providerTaskStackListenerImpl(
391             @ShellMainThread Handler mainHandler) {
392         return new TaskStackListenerImpl(mainHandler);
393     }
394 
395     @WMSingleton
396     @Provides
provideTransactionPool()397     static TransactionPool provideTransactionPool() {
398         return new TransactionPool();
399     }
400 
401     @WMSingleton
402     @Provides
provideWindowManagerShellWrapper( @hellMainThread ShellExecutor mainExecutor)403     static WindowManagerShellWrapper provideWindowManagerShellWrapper(
404             @ShellMainThread ShellExecutor mainExecutor) {
405         return new WindowManagerShellWrapper(mainExecutor);
406     }
407 
408     @WMSingleton
409     @Provides
provideLaunchAdjacentController( SyncTransactionQueue syncQueue)410     static LaunchAdjacentController provideLaunchAdjacentController(
411             SyncTransactionQueue syncQueue) {
412         return new LaunchAdjacentController(syncQueue);
413     }
414 
415     @WMSingleton
416     @Provides
provideSystemPerformanceHinter(Context context, ShellInit shellInit, ShellCommandHandler shellCommandHandler, RootTaskDisplayAreaOrganizer rootTdaOrganizer)417     static Optional<SystemPerformanceHinter> provideSystemPerformanceHinter(Context context,
418             ShellInit shellInit,
419             ShellCommandHandler shellCommandHandler,
420             RootTaskDisplayAreaOrganizer rootTdaOrganizer) {
421         final PerfHintController perfHintController =
422                 new PerfHintController(context, shellInit, shellCommandHandler, rootTdaOrganizer);
423         return Optional.of(perfHintController.getHinter());
424     }
425 
426     @WMSingleton
427     @Provides
provideMultiInstanceHelper( Context context, ShellInit shellInit, ShellCommandHandler shellCommandHandler )428     static MultiInstanceHelper provideMultiInstanceHelper(
429             Context context,
430             ShellInit shellInit,
431             ShellCommandHandler shellCommandHandler
432     ) {
433         return new MultiInstanceHelper(context, context.getPackageManager(),
434                 shellInit, shellCommandHandler, Flags.supportsMultiInstanceSystemUi());
435     }
436 
437     //
438     // Back animation
439     //
440 
441     @WMSingleton
442     @Provides
provideBackAnimation( Optional<BackAnimationController> backAnimationController)443     static Optional<BackAnimation> provideBackAnimation(
444             Optional<BackAnimationController> backAnimationController) {
445         return backAnimationController.map(BackAnimationController::getBackAnimationImpl);
446     }
447 
448     @WMSingleton
449     @Provides
provideBackAnimationBackground( RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer)450     static BackAnimationBackground provideBackAnimationBackground(
451             RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer) {
452         return new BackAnimationBackground(rootTaskDisplayAreaOrganizer);
453     }
454 
455     @WMSingleton
456     @Provides
provideBackAnimationController( Context context, ShellInit shellInit, ShellController shellController, @ShellMainThread ShellExecutor shellExecutor, BackAnimationBackground backAnimationBackground, Optional<ShellBackAnimationRegistry> shellBackAnimationRegistry, ShellCommandHandler shellCommandHandler, Transitions transitions, @ShellMainThread Handler handler )457     static Optional<BackAnimationController> provideBackAnimationController(
458             Context context,
459             ShellInit shellInit,
460             ShellController shellController,
461             @ShellMainThread ShellExecutor shellExecutor,
462             BackAnimationBackground backAnimationBackground,
463             Optional<ShellBackAnimationRegistry> shellBackAnimationRegistry,
464             ShellCommandHandler shellCommandHandler,
465             Transitions transitions,
466             @ShellMainThread Handler handler
467     ) {
468             return shellBackAnimationRegistry.map(
469                     (animations) ->
470                             new BackAnimationController(
471                                     shellInit,
472                                     shellController,
473                                     shellExecutor,
474                                     context,
475                                     backAnimationBackground,
476                                     animations,
477                                     shellCommandHandler,
478                                     transitions,
479                                     handler));
480     }
481 
482     @BindsOptionalOf
optionalBackAnimationRegistry()483     abstract ShellBackAnimationRegistry optionalBackAnimationRegistry();
484 
485     //
486     // PiP (optional feature)
487     //
488 
489     @WMSingleton
490     @Provides
providePipUiEventLogger(UiEventLogger uiEventLogger, PackageManager packageManager)491     static PipUiEventLogger providePipUiEventLogger(UiEventLogger uiEventLogger,
492             PackageManager packageManager) {
493         return new PipUiEventLogger(uiEventLogger, packageManager);
494     }
495 
496     @WMSingleton
497     @Provides
providePipMediaController(Context context, @ShellMainThread Handler mainHandler)498     static PipMediaController providePipMediaController(Context context,
499             @ShellMainThread Handler mainHandler) {
500         return new PipMediaController(context, mainHandler);
501     }
502 
503     @WMSingleton
504     @Provides
provideSizeSpecSource(Context context, PipDisplayLayoutState pipDisplayLayoutState)505     static SizeSpecSource provideSizeSpecSource(Context context,
506             PipDisplayLayoutState pipDisplayLayoutState) {
507         return new PhoneSizeSpecSource(context, pipDisplayLayoutState);
508     }
509 
510     @WMSingleton
511     @Provides
providePipPerfHintController( PipDisplayLayoutState pipDisplayLayoutState, @ShellMainThread ShellExecutor mainExecutor, Optional<SystemPerformanceHinter> systemPerformanceHinterOptional)512     static Optional<PipPerfHintController> providePipPerfHintController(
513             PipDisplayLayoutState pipDisplayLayoutState,
514             @ShellMainThread ShellExecutor mainExecutor,
515             Optional<SystemPerformanceHinter> systemPerformanceHinterOptional) {
516         if (systemPerformanceHinterOptional.isPresent()) {
517             return Optional.of(new PipPerfHintController(pipDisplayLayoutState, mainExecutor,
518                     systemPerformanceHinterOptional.get()));
519         } else {
520             return Optional.empty();
521         }
522     }
523 
524     @WMSingleton
525     @Provides
providePipBoundsState(Context context, SizeSpecSource sizeSpecSource, PipDisplayLayoutState pipDisplayLayoutState)526     static PipBoundsState providePipBoundsState(Context context,
527             SizeSpecSource sizeSpecSource, PipDisplayLayoutState pipDisplayLayoutState) {
528         return new PipBoundsState(context, sizeSpecSource, pipDisplayLayoutState);
529     }
530 
531 
532     @WMSingleton
533     @Provides
providePipSnapAlgorithm()534     static PipSnapAlgorithm providePipSnapAlgorithm() {
535         return new PipSnapAlgorithm();
536     }
537 
538     @WMSingleton
539     @Provides
providePhonePipKeepClearAlgorithm(Context context)540     static PhonePipKeepClearAlgorithm providePhonePipKeepClearAlgorithm(Context context) {
541         return new PhonePipKeepClearAlgorithm(context);
542     }
543 
544     @WMSingleton
545     @Provides
providesPipBoundsAlgorithm(Context context, PipBoundsState pipBoundsState, PipSnapAlgorithm pipSnapAlgorithm, PhonePipKeepClearAlgorithm pipKeepClearAlgorithm, PipDisplayLayoutState pipDisplayLayoutState, SizeSpecSource sizeSpecSource)546     static PipBoundsAlgorithm providesPipBoundsAlgorithm(Context context,
547             PipBoundsState pipBoundsState, PipSnapAlgorithm pipSnapAlgorithm,
548             PhonePipKeepClearAlgorithm pipKeepClearAlgorithm,
549             PipDisplayLayoutState pipDisplayLayoutState, SizeSpecSource sizeSpecSource) {
550         return new PipBoundsAlgorithm(context, pipBoundsState, pipSnapAlgorithm,
551                 pipKeepClearAlgorithm, pipDisplayLayoutState, sizeSpecSource);
552     }
553 
554     @WMSingleton
555     @Provides
providePipAppOpsListener(Context context, @ShellMainThread ShellExecutor mainExecutor)556     static PipAppOpsListener providePipAppOpsListener(Context context,
557             @ShellMainThread ShellExecutor mainExecutor) {
558         return new PipAppOpsListener(context, mainExecutor);
559     }
560 
561     //
562     // Bubbles (optional feature)
563     //
564 
565     @WMSingleton
566     @Provides
provideBubbles(Optional<BubbleController> bubbleController)567     static Optional<Bubbles> provideBubbles(Optional<BubbleController> bubbleController) {
568         return bubbleController.map((controller) -> controller.asBubbles());
569     }
570 
571     @BindsOptionalOf
optionalBubblesController()572     abstract BubbleController optionalBubblesController();
573 
574     //
575     // Fullscreen
576     //
577 
578     // Workaround for dynamic overriding with a default implementation, see {@link DynamicOverride}
579     @BindsOptionalOf
580     @DynamicOverride
optionalFullscreenTaskListener()581     abstract FullscreenTaskListener optionalFullscreenTaskListener();
582 
583     @WMSingleton
584     @Provides
provideFullscreenTaskListener( @ynamicOverride Optional<FullscreenTaskListener> fullscreenTaskListener, ShellInit shellInit, ShellTaskOrganizer shellTaskOrganizer, SyncTransactionQueue syncQueue, Optional<RecentTasksController> recentTasksOptional, Optional<WindowDecorViewModel> windowDecorViewModelOptional, Optional<DesktopWallpaperActivityTokenProvider> desktopWallpaperActivityTokenProviderOptional)585     static FullscreenTaskListener provideFullscreenTaskListener(
586             @DynamicOverride Optional<FullscreenTaskListener> fullscreenTaskListener,
587             ShellInit shellInit,
588             ShellTaskOrganizer shellTaskOrganizer,
589             SyncTransactionQueue syncQueue,
590             Optional<RecentTasksController> recentTasksOptional,
591             Optional<WindowDecorViewModel> windowDecorViewModelOptional,
592             Optional<DesktopWallpaperActivityTokenProvider>
593                     desktopWallpaperActivityTokenProviderOptional) {
594         if (fullscreenTaskListener.isPresent()) {
595             return fullscreenTaskListener.get();
596         } else {
597             return new FullscreenTaskListener(shellInit, shellTaskOrganizer, syncQueue,
598                     recentTasksOptional, windowDecorViewModelOptional,
599                     desktopWallpaperActivityTokenProviderOptional);
600         }
601     }
602 
603     //
604     // Window Decoration
605     //
606 
607     @BindsOptionalOf
optionalWindowDecorViewModel()608     abstract WindowDecorViewModel optionalWindowDecorViewModel();
609 
610     //
611     // Unfold transition
612     //
613 
614     @BindsOptionalOf
optionalShellUnfoldProgressProvider()615     abstract ShellUnfoldProgressProvider optionalShellUnfoldProgressProvider();
616 
617     // Workaround for dynamic overriding with a default implementation, see {@link DynamicOverride}
618     @BindsOptionalOf
619     @DynamicOverride
optionalUnfoldController()620     abstract UnfoldAnimationController optionalUnfoldController();
621 
622     @WMSingleton
623     @Provides
provideUnfoldController( @ynamicOverride Lazy<Optional<UnfoldAnimationController>> fullscreenUnfoldController, Optional<ShellUnfoldProgressProvider> progressProvider)624     static Optional<UnfoldAnimationController> provideUnfoldController(
625             @DynamicOverride Lazy<Optional<UnfoldAnimationController>>
626                     fullscreenUnfoldController,
627             Optional<ShellUnfoldProgressProvider> progressProvider) {
628         if (progressProvider.isPresent()
629                 && progressProvider.get() != ShellUnfoldProgressProvider.NO_PROVIDER) {
630             return fullscreenUnfoldController.get();
631         }
632         return Optional.empty();
633     }
634 
635     @BindsOptionalOf
636     @DynamicOverride
optionalUnfoldTransitionHandler()637     abstract UnfoldTransitionHandler optionalUnfoldTransitionHandler();
638 
639     @WMSingleton
640     @Provides
provideUnfoldTransitionHandler( Optional<ShellUnfoldProgressProvider> progressProvider, @DynamicOverride Lazy<Optional<UnfoldTransitionHandler>> handler)641     static Optional<UnfoldTransitionHandler> provideUnfoldTransitionHandler(
642             Optional<ShellUnfoldProgressProvider> progressProvider,
643             @DynamicOverride Lazy<Optional<UnfoldTransitionHandler>> handler) {
644         if (progressProvider.isPresent()
645                 && progressProvider.get() != ShellUnfoldProgressProvider.NO_PROVIDER) {
646             return handler.get();
647         }
648         return Optional.empty();
649     }
650 
651     //
652     // Freeform (optional feature)
653     //
654 
655     // Workaround for dynamic overriding with a default implementation, see {@link DynamicOverride}
656     @BindsOptionalOf
657     @DynamicOverride
optionalFreeformComponents()658     abstract FreeformComponents optionalFreeformComponents();
659 
660     @WMSingleton
661     @Provides
provideFreeformComponents( @ynamicOverride Optional<FreeformComponents> freeformComponents, Context context)662     static Optional<FreeformComponents> provideFreeformComponents(
663             @DynamicOverride Optional<FreeformComponents> freeformComponents,
664             Context context) {
665         if (FreeformComponents.requiresFreeformComponents(context)) {
666             return freeformComponents;
667         }
668         return Optional.empty();
669     }
670 
671     //
672     // Hide display cutout
673     //
674 
675     @WMSingleton
676     @Provides
provideHideDisplayCutoutController(Context context, ShellInit shellInit, ShellCommandHandler shellCommandHandler, ShellController shellController, DisplayController displayController, @ShellMainThread ShellExecutor mainExecutor)677     static Optional<HideDisplayCutoutController> provideHideDisplayCutoutController(Context context,
678             ShellInit shellInit,
679             ShellCommandHandler shellCommandHandler,
680             ShellController shellController,
681             DisplayController displayController,
682             @ShellMainThread ShellExecutor mainExecutor) {
683         return Optional.ofNullable(
684                 HideDisplayCutoutController.create(context, shellInit, shellCommandHandler,
685                         shellController, displayController, mainExecutor));
686     }
687 
688     //
689     // One handed mode (optional feature)
690     //
691 
692     @WMSingleton
693     @Provides
provideOneHanded(Optional<OneHandedController> oneHandedController)694     static Optional<OneHanded> provideOneHanded(Optional<OneHandedController> oneHandedController) {
695         return oneHandedController.map((controller) -> controller.asOneHanded());
696     }
697 
698     // Workaround for dynamic overriding with a default implementation, see {@link DynamicOverride}
699     @BindsOptionalOf
700     @DynamicOverride
optionalOneHandedController()701     abstract OneHandedController optionalOneHandedController();
702 
703     @WMSingleton
704     @Provides
providesOneHandedController( @ynamicOverride Optional<OneHandedController> oneHandedController)705     static Optional<OneHandedController> providesOneHandedController(
706             @DynamicOverride Optional<OneHandedController> oneHandedController) {
707         if (SystemProperties.getBoolean(SUPPORT_ONE_HANDED_MODE, false)) {
708             return oneHandedController;
709         }
710         return Optional.empty();
711     }
712 
713     //
714     // Recent tasks
715     //
716 
717     @WMSingleton
718     @Provides
provideRecentTasks( Optional<RecentTasksController> recentTasksController)719     static Optional<RecentTasks> provideRecentTasks(
720             Optional<RecentTasksController> recentTasksController) {
721         return recentTasksController.map((controller) -> controller.asRecentTasks());
722     }
723 
724     @WMSingleton
725     @Provides
provideRecentTasksController( Context context, ShellInit shellInit, ShellController shellController, ShellCommandHandler shellCommandHandler, TaskStackListenerImpl taskStackListener, ActivityTaskManager activityTaskManager, Optional<DesktopUserRepositories> desktopUserRepositories, TaskStackTransitionObserver taskStackTransitionObserver, @ShellMainThread ShellExecutor mainExecutor )726     static Optional<RecentTasksController> provideRecentTasksController(
727             Context context,
728             ShellInit shellInit,
729             ShellController shellController,
730             ShellCommandHandler shellCommandHandler,
731             TaskStackListenerImpl taskStackListener,
732             ActivityTaskManager activityTaskManager,
733             Optional<DesktopUserRepositories> desktopUserRepositories,
734             TaskStackTransitionObserver taskStackTransitionObserver,
735             @ShellMainThread ShellExecutor mainExecutor
736     ) {
737         return Optional.ofNullable(
738                 RecentTasksController.create(context, shellInit, shellController,
739                         shellCommandHandler, taskStackListener, activityTaskManager,
740                         desktopUserRepositories, taskStackTransitionObserver, mainExecutor));
741     }
742 
743     @BindsOptionalOf
optionalRecentsTransitionHandler()744     abstract RecentsTransitionHandler optionalRecentsTransitionHandler();
745 
746     //
747     // Shell transitions
748     //
749 
750     @WMSingleton
751     @Provides
provideRemoteTransitions(Transitions transitions)752     static ShellTransitions provideRemoteTransitions(Transitions transitions) {
753         return transitions.asRemoteTransitions();
754     }
755 
756     @WMSingleton
757     @Provides
provideTransitions(Context context, ShellInit shellInit, ShellCommandHandler shellCommandHandler, ShellController shellController, ShellTaskOrganizer organizer, TransactionPool pool, DisplayController displayController, DisplayInsetsController displayInsetsController, @ShellMainThread ShellExecutor mainExecutor, @ShellMainThread Handler mainHandler, @ShellAnimationThread ShellExecutor animExecutor, @ShellAnimationThread Handler animHandler, RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer, HomeTransitionObserver homeTransitionObserver, FocusTransitionObserver focusTransitionObserver)758     static Transitions provideTransitions(Context context,
759             ShellInit shellInit,
760             ShellCommandHandler shellCommandHandler,
761             ShellController shellController,
762             ShellTaskOrganizer organizer,
763             TransactionPool pool,
764             DisplayController displayController,
765             DisplayInsetsController displayInsetsController,
766             @ShellMainThread ShellExecutor mainExecutor,
767             @ShellMainThread Handler mainHandler,
768             @ShellAnimationThread ShellExecutor animExecutor,
769             @ShellAnimationThread Handler animHandler,
770             RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
771             HomeTransitionObserver homeTransitionObserver,
772             FocusTransitionObserver focusTransitionObserver) {
773         if (!context.getResources().getBoolean(R.bool.config_registerShellTransitionsOnInit)) {
774             // TODO(b/238217847): Force override shell init if registration is disabled
775             shellInit = new ShellInit(mainExecutor);
776         }
777         return new Transitions(context, shellInit, shellCommandHandler, shellController, organizer,
778                 pool, displayController, displayInsetsController, mainExecutor, mainHandler,
779                 animExecutor, animHandler, rootTaskDisplayAreaOrganizer, homeTransitionObserver,
780                 focusTransitionObserver);
781     }
782 
783     @WMSingleton
784     @Provides
provideHomeTransitionObserver(Context context, @ShellMainThread ShellExecutor mainExecutor, DisplayInsetsController displayInsetsController, ShellInit shellInit)785     static HomeTransitionObserver provideHomeTransitionObserver(Context context,
786             @ShellMainThread ShellExecutor mainExecutor,
787             DisplayInsetsController displayInsetsController,
788             ShellInit shellInit) {
789         return new HomeTransitionObserver(context, mainExecutor, displayInsetsController,
790                 shellInit);
791     }
792 
793     @WMSingleton
794     @Provides
provideFocusTransitionObserver()795     static FocusTransitionObserver provideFocusTransitionObserver() {
796         return new FocusTransitionObserver();
797     }
798 
799     @WMSingleton
800     @Provides
provideTaskViewTransitions(Transitions transitions, TaskViewRepository repository, ShellTaskOrganizer organizer, SyncTransactionQueue syncQueue)801     static TaskViewTransitions provideTaskViewTransitions(Transitions transitions,
802             TaskViewRepository repository, ShellTaskOrganizer organizer,
803             SyncTransactionQueue syncQueue) {
804         return new TaskViewTransitions(transitions, repository, organizer, syncQueue);
805     }
806 
807     @WMSingleton
808     @Provides
provideTaskViewRepository()809     static TaskViewRepository provideTaskViewRepository() {
810         return new TaskViewRepository();
811     }
812 
813     // Workaround for dynamic overriding with a default implementation, see {@link DynamicOverride}
814     @BindsOptionalOf
815     @DynamicOverride
optionalMixedTransitionHandler()816     abstract MixedTransitionHandler optionalMixedTransitionHandler();
817 
818     @WMSingleton
819     @Provides
provideMixedTransitionHandler( @ynamicOverride Optional<MixedTransitionHandler> mixedTransitionHandler )820     static Optional<MixedTransitionHandler> provideMixedTransitionHandler(
821             @DynamicOverride Optional<MixedTransitionHandler> mixedTransitionHandler
822     ) {
823         if (mixedTransitionHandler.isPresent()) {
824             return mixedTransitionHandler;
825         }
826         return Optional.empty();
827     }
828 
829     //
830     // Keyguard transitions (optional feature)
831     //
832 
833     @WMSingleton
834     @Provides
provideKeyguardTransitionHandler( ShellInit shellInit, ShellController shellController, DisplayController displayController, Transitions transitions, TaskStackListenerImpl taskStackListener, @ShellMainThread Handler mainHandler, @ShellMainThread ShellExecutor mainExecutor, FocusTransitionObserver focusTransitionObserver)835     static KeyguardTransitionHandler provideKeyguardTransitionHandler(
836             ShellInit shellInit,
837             ShellController shellController,
838             DisplayController displayController,
839             Transitions transitions,
840             TaskStackListenerImpl taskStackListener,
841             @ShellMainThread Handler mainHandler,
842             @ShellMainThread ShellExecutor mainExecutor,
843             FocusTransitionObserver focusTransitionObserver) {
844         return new KeyguardTransitionHandler(
845                 shellInit, shellController, displayController, transitions, taskStackListener,
846                 mainHandler, mainExecutor, focusTransitionObserver);
847     }
848 
849     @WMSingleton
850     @Provides
provideKeyguardTransitions( KeyguardTransitionHandler handler)851     static KeyguardTransitions provideKeyguardTransitions(
852             KeyguardTransitionHandler handler) {
853         return handler.asKeyguardTransitions();
854     }
855 
856     //
857     // Display areas
858     //
859 
860     @WMSingleton
861     @Provides
provideRootTaskDisplayAreaOrganizer( @hellMainThread ShellExecutor mainExecutor, Context context, ShellInit shellInit)862     static RootTaskDisplayAreaOrganizer provideRootTaskDisplayAreaOrganizer(
863             @ShellMainThread ShellExecutor mainExecutor, Context context, ShellInit shellInit) {
864         return new RootTaskDisplayAreaOrganizer(mainExecutor, context, shellInit);
865     }
866 
867     @WMSingleton
868     @Provides
provideRootDisplayAreaOrganizer( @hellMainThread ShellExecutor mainExecutor, ShellInit shellInit)869     static RootDisplayAreaOrganizer provideRootDisplayAreaOrganizer(
870             @ShellMainThread ShellExecutor mainExecutor, ShellInit shellInit) {
871         return new RootDisplayAreaOrganizer(mainExecutor, shellInit);
872     }
873 
874     @WMSingleton
875     @Provides
provideDisplayAreaHelper( @hellMainThread ShellExecutor mainExecutor, RootDisplayAreaOrganizer rootDisplayAreaOrganizer)876     static Optional<DisplayAreaHelper> provideDisplayAreaHelper(
877             @ShellMainThread ShellExecutor mainExecutor,
878             RootDisplayAreaOrganizer rootDisplayAreaOrganizer) {
879         return Optional.of(new DisplayAreaHelperController(mainExecutor,
880                 rootDisplayAreaOrganizer));
881     }
882 
883     //
884     // Splitscreen (optional feature)
885     //
886 
887     @WMSingleton
888     @Provides
provideSplitScreen( Optional<SplitScreenController> splitScreenController)889     static Optional<SplitScreen> provideSplitScreen(
890             Optional<SplitScreenController> splitScreenController) {
891         return splitScreenController.map((controller) -> controller.asSplitScreen());
892     }
893 
894     // Workaround for dynamic overriding with a default implementation, see {@link DynamicOverride}
895     @BindsOptionalOf
896     @DynamicOverride
optionalSplitScreenController()897     abstract SplitScreenController optionalSplitScreenController();
898 
899     @WMSingleton
900     @Provides
providesSplitScreenController( @ynamicOverride Optional<SplitScreenController> splitscreenController, Context context)901     static Optional<SplitScreenController> providesSplitScreenController(
902             @DynamicOverride Optional<SplitScreenController> splitscreenController,
903             Context context) {
904         if (ActivityTaskManager.supportsSplitScreenMultiWindow(context)) {
905             return splitscreenController;
906         }
907         return Optional.empty();
908     }
909 
910     @WMSingleton
911     @Provides
provideSplitState()912     static SplitState provideSplitState() {
913         return new SplitState();
914     }
915 
916     //
917     // Starting window
918     //
919 
920     @WMSingleton
921     @Provides
provideStartingSurface( StartingWindowController startingWindowController)922     static Optional<StartingSurface> provideStartingSurface(
923             StartingWindowController startingWindowController) {
924         return Optional.of(startingWindowController.asStartingSurface());
925     }
926 
927     @WMSingleton
928     @Provides
provideStartingWindowController( Context context, ShellInit shellInit, ShellController shellController, ShellTaskOrganizer shellTaskOrganizer, @ShellSplashscreenThread ShellExecutor splashScreenExecutor, StartingWindowTypeAlgorithm startingWindowTypeAlgorithm, IconProvider iconProvider, TransactionPool pool)929     static StartingWindowController provideStartingWindowController(
930             Context context,
931             ShellInit shellInit,
932             ShellController shellController,
933             ShellTaskOrganizer shellTaskOrganizer,
934             @ShellSplashscreenThread ShellExecutor splashScreenExecutor,
935             StartingWindowTypeAlgorithm startingWindowTypeAlgorithm, IconProvider iconProvider,
936             TransactionPool pool) {
937         return new StartingWindowController(context, shellInit, shellController, shellTaskOrganizer,
938                 splashScreenExecutor, startingWindowTypeAlgorithm, iconProvider, pool);
939     }
940 
941     // Workaround for dynamic overriding with a default implementation, see {@link DynamicOverride}
942     @BindsOptionalOf
943     @DynamicOverride
optionalStartingWindowTypeAlgorithm()944     abstract StartingWindowTypeAlgorithm optionalStartingWindowTypeAlgorithm();
945 
946     @WMSingleton
947     @Provides
provideStartingWindowTypeAlgorithm( @ynamicOverride Optional<StartingWindowTypeAlgorithm> startingWindowTypeAlgorithm )948     static StartingWindowTypeAlgorithm provideStartingWindowTypeAlgorithm(
949             @DynamicOverride Optional<StartingWindowTypeAlgorithm> startingWindowTypeAlgorithm
950     ) {
951         if (startingWindowTypeAlgorithm.isPresent()) {
952             return startingWindowTypeAlgorithm.get();
953         }
954         // Default to phone starting window type
955         return new PhoneStartingWindowTypeAlgorithm();
956     }
957 
958     //
959     // Task view factory
960     //
961 
962     @WMSingleton
963     @Provides
provideTaskViewFactory( TaskViewFactoryController taskViewFactoryController)964     static Optional<TaskViewFactory> provideTaskViewFactory(
965             TaskViewFactoryController taskViewFactoryController) {
966         return Optional.of(taskViewFactoryController.asTaskViewFactory());
967     }
968 
969     @WMSingleton
970     @Provides
provideTaskViewFactoryController( ShellTaskOrganizer shellTaskOrganizer, @ShellMainThread ShellExecutor mainExecutor, SyncTransactionQueue syncQueue, TaskViewTransitions taskViewTransitions)971     static TaskViewFactoryController provideTaskViewFactoryController(
972             ShellTaskOrganizer shellTaskOrganizer,
973             @ShellMainThread ShellExecutor mainExecutor,
974             SyncTransactionQueue syncQueue,
975             TaskViewTransitions taskViewTransitions) {
976         return new TaskViewFactoryController(shellTaskOrganizer, mainExecutor, syncQueue,
977                 taskViewTransitions);
978     }
979 
980 
981     //
982     // ActivityEmbedding
983     //
984 
985     @WMSingleton
986     @Provides
provideActivityEmbeddingController( Context context, ShellInit shellInit, Transitions transitions)987     static Optional<ActivityEmbeddingController> provideActivityEmbeddingController(
988             Context context,
989             ShellInit shellInit,
990             Transitions transitions) {
991         return Optional.ofNullable(
992                 ActivityEmbeddingController.create(context, shellInit, transitions));
993     }
994 
995     //
996     // SysUI -> Shell interface
997     //
998 
999     @WMSingleton
1000     @Provides
provideShellSysuiCallbacks( @hellCreateTrigger Object createTrigger, ShellController shellController)1001     static ShellInterface provideShellSysuiCallbacks(
1002             @ShellCreateTrigger Object createTrigger,
1003             ShellController shellController) {
1004         return shellController.asShell();
1005     }
1006 
1007     @WMSingleton
1008     @Provides
provideShellController(Context context, ShellInit shellInit, ShellCommandHandler shellCommandHandler, DisplayInsetsController displayInsetsController, @ShellMainThread ShellExecutor mainExecutor)1009     static ShellController provideShellController(Context context,
1010             ShellInit shellInit,
1011             ShellCommandHandler shellCommandHandler,
1012             DisplayInsetsController displayInsetsController,
1013             @ShellMainThread ShellExecutor mainExecutor) {
1014         return new ShellController(context, shellInit, shellCommandHandler,
1015                 displayInsetsController, mainExecutor);
1016     }
1017 
1018     //
1019     // Desktop mode (optional feature)
1020     //
1021 
1022     @WMSingleton
1023     @Provides
provideDesktopMode( Optional<DesktopTasksController> desktopTasksController)1024     static Optional<DesktopMode> provideDesktopMode(
1025             Optional<DesktopTasksController> desktopTasksController) {
1026         return desktopTasksController.map(DesktopTasksController::asDesktopMode);
1027     }
1028 
1029 
1030     @BindsOptionalOf
1031     @DynamicOverride
optionalDesktopTasksController()1032     abstract DesktopTasksController optionalDesktopTasksController();
1033 
1034     @WMSingleton
1035     @Provides
providesDesktopTasksController(Context context, @DynamicOverride Optional<Lazy<DesktopTasksController>> desktopTasksController)1036     static Optional<DesktopTasksController> providesDesktopTasksController(Context context,
1037             @DynamicOverride Optional<Lazy<DesktopTasksController>> desktopTasksController) {
1038         // Use optional-of-lazy for the dependency that this provider relies on.
1039         // Lazy ensures that this provider will not be the cause the dependency is created
1040         // when it will not be returned due to the condition below.
1041         return desktopTasksController.flatMap((lazy) -> {
1042             if (DesktopModeStatus.canEnterDesktopModeOrShowAppHandle(context)) {
1043                 return Optional.of(lazy.get());
1044             }
1045             return Optional.empty();
1046         });
1047     }
1048 
1049     @BindsOptionalOf
1050     @DynamicOverride
1051     abstract DesktopUserRepositories optionalDesktopUserRepositories();
1052 
1053     @WMSingleton
1054     @Provides
1055     static Optional<DesktopUserRepositories> provideDesktopUserRepositories(Context context,
1056             @DynamicOverride Optional<Lazy<DesktopUserRepositories>> desktopUserRepositories) {
1057         // Use optional-of-lazy for the dependency that this provider relies on.
1058         // Lazy ensures that this provider will not be the cause the dependency is created
1059         // when it will not be returned due to the condition below.
1060         return desktopUserRepositories.flatMap((lazy) -> {
1061             if (DesktopModeStatus.canEnterDesktopMode(context)) {
1062                 return Optional.of(lazy.get());
1063             }
1064             return Optional.empty();
1065         });
1066     }
1067 
1068     @BindsOptionalOf
1069     abstract DesktopWallpaperActivityTokenProvider optionalDesktopWallpaperActivityTokenProvider();
1070 
1071     //
1072     // App zoom out (optional feature)
1073     //
1074 
1075     @WMSingleton
1076     @Provides
1077     static Optional<AppZoomOut> provideAppZoomOut(
1078             Optional<AppZoomOutController> appZoomOutController) {
1079         return appZoomOutController.map((controller) -> controller.asAppZoomOut());
1080     }
1081 
1082     @BindsOptionalOf
1083     abstract AppZoomOutController optionalAppZoomOutController();
1084 
1085     //
1086     // Task Stack
1087     //
1088 
1089     @WMSingleton
1090     @Provides
1091     static TaskStackTransitionObserver provideTaskStackTransitionObserver(
1092             ShellInit shellInit,
1093             Lazy<ShellTaskOrganizer> shellTaskOrganizer,
1094             ShellCommandHandler shellCommandHandler,
1095             Lazy<Transitions> transitions
1096     ) {
1097         return new TaskStackTransitionObserver(shellInit, shellTaskOrganizer, shellCommandHandler,
1098                 transitions);
1099     }
1100 
1101     //
1102     // Misc
1103     //
1104 
1105     // Workaround for dynamic overriding with a default implementation, see {@link DynamicOverride}
1106     @BindsOptionalOf
1107     @ShellCreateTriggerOverride
1108     abstract Object provideIndependentShellComponentsToCreateOverride();
1109 
1110     // TODO: Temporarily move dependencies to this instead of ShellInit since that is needed to add
1111     // the callback. We will be moving to a different explicit startup mechanism in a follow- up CL.
1112     @WMSingleton
1113     @ShellCreateTrigger
1114     @Provides
1115     static Object provideIndependentShellComponentsToCreate(
1116             DisplayController displayController,
1117             DisplayImeController displayImeController,
1118             DisplayInsetsController displayInsetsController,
1119             ShellTaskOrganizer shellTaskOrganizer,
1120             Optional<BubbleController> bubblesOptional,
1121             Optional<SplitScreenController> splitScreenOptional,
1122             FullscreenTaskListener fullscreenTaskListener,
1123             Optional<UnfoldAnimationController> unfoldAnimationController,
1124             Optional<UnfoldTransitionHandler> unfoldTransitionHandler,
1125             Optional<FreeformComponents> freeformComponents,
1126             Optional<RecentTasksController> recentTasksOptional,
1127             Optional<RecentsTransitionHandler> recentsTransitionHandlerOptional,
1128             Optional<OneHandedController> oneHandedControllerOptional,
1129             Optional<AppZoomOutController> appZoomOutControllerOptional,
1130             Optional<HideDisplayCutoutController> hideDisplayCutoutControllerOptional,
1131             Optional<ActivityEmbeddingController> activityEmbeddingOptional,
1132             Optional<MixedTransitionHandler> mixedTransitionHandler,
1133             Transitions transitions,
1134             StartingWindowController startingWindow,
1135             ProtoLogController protoLogController,
1136             @ShellCreateTriggerOverride Optional<Object> overriddenCreateTrigger) {
1137         return new Object();
1138     }
1139 
1140     @WMSingleton
1141     @Provides
1142     static ShellInit provideShellInit(@ShellMainThread ShellExecutor mainExecutor) {
1143         return new ShellInit(mainExecutor);
1144     }
1145 
1146     @WMSingleton
1147     @Provides
1148     static ShellCommandHandler provideShellCommandHandler() {
1149         return new ShellCommandHandler();
1150     }
1151 
1152     @WMSingleton
1153     @Provides
1154     static ProtoLogController provideProtoLogController(
1155             ShellInit shellInit,
1156             ShellCommandHandler shellCommandHandler) {
1157         return new ProtoLogController(shellInit, shellCommandHandler);
1158     }
1159 }
1160