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.animation.AnimationHandler;
20 import android.content.Context;
21 import android.content.pm.LauncherApps;
22 import android.os.Handler;
23 import android.view.WindowManager;
24 
25 import com.android.internal.logging.UiEventLogger;
26 import com.android.internal.statusbar.IStatusBarService;
27 import com.android.launcher3.icons.IconProvider;
28 import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
29 import com.android.wm.shell.ShellTaskOrganizer;
30 import com.android.wm.shell.WindowManagerShellWrapper;
31 import com.android.wm.shell.apppairs.AppPairsController;
32 import com.android.wm.shell.bubbles.BubbleController;
33 import com.android.wm.shell.common.DisplayController;
34 import com.android.wm.shell.common.DisplayImeController;
35 import com.android.wm.shell.common.DisplayInsetsController;
36 import com.android.wm.shell.common.DisplayLayout;
37 import com.android.wm.shell.common.FloatingContentCoordinator;
38 import com.android.wm.shell.common.ShellExecutor;
39 import com.android.wm.shell.common.SyncTransactionQueue;
40 import com.android.wm.shell.common.SystemWindows;
41 import com.android.wm.shell.common.TaskStackListenerImpl;
42 import com.android.wm.shell.common.TransactionPool;
43 import com.android.wm.shell.common.annotations.ChoreographerSfVsync;
44 import com.android.wm.shell.common.annotations.ShellMainThread;
45 import com.android.wm.shell.freeform.FreeformTaskListener;
46 import com.android.wm.shell.fullscreen.FullscreenUnfoldController;
47 import com.android.wm.shell.legacysplitscreen.LegacySplitScreenController;
48 import com.android.wm.shell.onehanded.OneHandedController;
49 import com.android.wm.shell.pip.Pip;
50 import com.android.wm.shell.pip.PipAnimationController;
51 import com.android.wm.shell.pip.PipBoundsAlgorithm;
52 import com.android.wm.shell.pip.PipBoundsState;
53 import com.android.wm.shell.pip.PipMediaController;
54 import com.android.wm.shell.pip.PipSnapAlgorithm;
55 import com.android.wm.shell.pip.PipSurfaceTransactionHelper;
56 import com.android.wm.shell.pip.PipTaskOrganizer;
57 import com.android.wm.shell.pip.PipTransition;
58 import com.android.wm.shell.pip.PipTransitionController;
59 import com.android.wm.shell.pip.PipTransitionState;
60 import com.android.wm.shell.pip.PipUiEventLogger;
61 import com.android.wm.shell.pip.phone.PhonePipMenuController;
62 import com.android.wm.shell.pip.phone.PipAppOpsListener;
63 import com.android.wm.shell.pip.phone.PipController;
64 import com.android.wm.shell.pip.phone.PipMotionHelper;
65 import com.android.wm.shell.pip.phone.PipTouchHandler;
66 import com.android.wm.shell.recents.RecentTasksController;
67 import com.android.wm.shell.splitscreen.SplitScreenController;
68 import com.android.wm.shell.splitscreen.StageTaskUnfoldController;
69 import com.android.wm.shell.transition.Transitions;
70 import com.android.wm.shell.unfold.ShellUnfoldProgressProvider;
71 import com.android.wm.shell.unfold.UnfoldBackgroundController;
72 
73 import java.util.Optional;
74 
75 import javax.inject.Provider;
76 
77 import dagger.Lazy;
78 import dagger.Module;
79 import dagger.Provides;
80 
81 /**
82  * Provides dependencies from {@link com.android.wm.shell}, these dependencies are only
83  * accessible from components within the WM subcomponent (can be explicitly exposed to the
84  * SysUIComponent, see {@link WMComponent}).
85  *
86  * This module only defines Shell dependencies for handheld SystemUI implementation.  Common
87  * dependencies should go into {@link WMShellBaseModule}.
88  */
89 @Module(includes = WMShellBaseModule.class)
90 public class WMShellModule {
91 
92     //
93     // Bubbles
94     //
95 
96     // Note: Handler needed for LauncherApps.register
97     @WMSingleton
98     @Provides
provideBubbleController(Context context, FloatingContentCoordinator floatingContentCoordinator, IStatusBarService statusBarService, WindowManager windowManager, WindowManagerShellWrapper windowManagerShellWrapper, LauncherApps launcherApps, TaskStackListenerImpl taskStackListener, UiEventLogger uiEventLogger, ShellTaskOrganizer organizer, DisplayController displayController, @ShellMainThread ShellExecutor mainExecutor, @ShellMainThread Handler mainHandler, SyncTransactionQueue syncQueue)99     static BubbleController provideBubbleController(Context context,
100             FloatingContentCoordinator floatingContentCoordinator,
101             IStatusBarService statusBarService,
102             WindowManager windowManager,
103             WindowManagerShellWrapper windowManagerShellWrapper,
104             LauncherApps launcherApps,
105             TaskStackListenerImpl taskStackListener,
106             UiEventLogger uiEventLogger,
107             ShellTaskOrganizer organizer,
108             DisplayController displayController,
109             @ShellMainThread ShellExecutor mainExecutor,
110             @ShellMainThread Handler mainHandler,
111             SyncTransactionQueue syncQueue) {
112         return BubbleController.create(context, null /* synchronizer */,
113                 floatingContentCoordinator, statusBarService, windowManager,
114                 windowManagerShellWrapper, launcherApps, taskStackListener,
115                 uiEventLogger, organizer, displayController, mainExecutor, mainHandler, syncQueue);
116     }
117 
118     //
119     // Freeform
120     //
121 
122     @WMSingleton
123     @Provides
124     @DynamicOverride
provideFreeformTaskListener( SyncTransactionQueue syncQueue)125     static FreeformTaskListener provideFreeformTaskListener(
126             SyncTransactionQueue syncQueue) {
127         return new FreeformTaskListener(syncQueue);
128     }
129 
130     //
131     // One handed mode
132     //
133 
134 
135     // Needs the shell main handler for ContentObserver callbacks
136     @WMSingleton
137     @Provides
138     @DynamicOverride
provideOneHandedController(Context context, WindowManager windowManager, DisplayController displayController, DisplayLayout displayLayout, TaskStackListenerImpl taskStackListener, UiEventLogger uiEventLogger, @ShellMainThread ShellExecutor mainExecutor, @ShellMainThread Handler mainHandler)139     static OneHandedController provideOneHandedController(Context context,
140             WindowManager windowManager, DisplayController displayController,
141             DisplayLayout displayLayout, TaskStackListenerImpl taskStackListener,
142             UiEventLogger uiEventLogger,
143             @ShellMainThread ShellExecutor mainExecutor,
144             @ShellMainThread Handler mainHandler) {
145         return OneHandedController.create(context, windowManager,
146                 displayController, displayLayout, taskStackListener, uiEventLogger, mainExecutor,
147                 mainHandler);
148     }
149 
150     //
151     // Splitscreen
152     //
153 
154     @WMSingleton
155     @Provides
156     @DynamicOverride
provideSplitScreenController( ShellTaskOrganizer shellTaskOrganizer, SyncTransactionQueue syncQueue, Context context, RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer, @ShellMainThread ShellExecutor mainExecutor, DisplayImeController displayImeController, DisplayInsetsController displayInsetsController, Transitions transitions, TransactionPool transactionPool, IconProvider iconProvider, Optional<RecentTasksController> recentTasks, Provider<Optional<StageTaskUnfoldController>> stageTaskUnfoldControllerProvider)157     static SplitScreenController provideSplitScreenController(
158             ShellTaskOrganizer shellTaskOrganizer,
159             SyncTransactionQueue syncQueue, Context context,
160             RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
161             @ShellMainThread ShellExecutor mainExecutor,
162             DisplayImeController displayImeController,
163             DisplayInsetsController displayInsetsController, Transitions transitions,
164             TransactionPool transactionPool, IconProvider iconProvider,
165             Optional<RecentTasksController> recentTasks,
166             Provider<Optional<StageTaskUnfoldController>> stageTaskUnfoldControllerProvider) {
167         return new SplitScreenController(shellTaskOrganizer, syncQueue, context,
168                 rootTaskDisplayAreaOrganizer, mainExecutor, displayImeController,
169                 displayInsetsController, transitions, transactionPool, iconProvider,
170                 recentTasks, stageTaskUnfoldControllerProvider);
171     }
172 
173     @WMSingleton
174     @Provides
provideLegacySplitScreen(Context context, DisplayController displayController, SystemWindows systemWindows, DisplayImeController displayImeController, TransactionPool transactionPool, ShellTaskOrganizer shellTaskOrganizer, SyncTransactionQueue syncQueue, TaskStackListenerImpl taskStackListener, Transitions transitions, @ShellMainThread ShellExecutor mainExecutor, @ChoreographerSfVsync AnimationHandler sfVsyncAnimationHandler)175     static LegacySplitScreenController provideLegacySplitScreen(Context context,
176             DisplayController displayController, SystemWindows systemWindows,
177             DisplayImeController displayImeController, TransactionPool transactionPool,
178             ShellTaskOrganizer shellTaskOrganizer, SyncTransactionQueue syncQueue,
179             TaskStackListenerImpl taskStackListener, Transitions transitions,
180             @ShellMainThread ShellExecutor mainExecutor,
181             @ChoreographerSfVsync AnimationHandler sfVsyncAnimationHandler) {
182         return new LegacySplitScreenController(context, displayController, systemWindows,
183                 displayImeController, transactionPool, shellTaskOrganizer, syncQueue,
184                 taskStackListener, transitions, mainExecutor, sfVsyncAnimationHandler);
185     }
186 
187     @WMSingleton
188     @Provides
provideAppPairs(ShellTaskOrganizer shellTaskOrganizer, SyncTransactionQueue syncQueue, DisplayController displayController, @ShellMainThread ShellExecutor mainExecutor, DisplayImeController displayImeController, DisplayInsetsController displayInsetsController)189     static AppPairsController provideAppPairs(ShellTaskOrganizer shellTaskOrganizer,
190             SyncTransactionQueue syncQueue, DisplayController displayController,
191             @ShellMainThread ShellExecutor mainExecutor,
192             DisplayImeController displayImeController,
193             DisplayInsetsController displayInsetsController) {
194         return new AppPairsController(shellTaskOrganizer, syncQueue, displayController,
195                 mainExecutor, displayImeController, displayInsetsController);
196     }
197 
198     //
199     // Pip
200     //
201 
202     @WMSingleton
203     @Provides
providePip(Context context, DisplayController displayController, PipAppOpsListener pipAppOpsListener, PipBoundsAlgorithm pipBoundsAlgorithm, PipBoundsState pipBoundsState, PipMediaController pipMediaController, PhonePipMenuController phonePipMenuController, PipTaskOrganizer pipTaskOrganizer, PipTouchHandler pipTouchHandler, PipTransitionController pipTransitionController, WindowManagerShellWrapper windowManagerShellWrapper, TaskStackListenerImpl taskStackListener, Optional<OneHandedController> oneHandedController, @ShellMainThread ShellExecutor mainExecutor)204     static Optional<Pip> providePip(Context context, DisplayController displayController,
205             PipAppOpsListener pipAppOpsListener, PipBoundsAlgorithm pipBoundsAlgorithm,
206             PipBoundsState pipBoundsState, PipMediaController pipMediaController,
207             PhonePipMenuController phonePipMenuController, PipTaskOrganizer pipTaskOrganizer,
208             PipTouchHandler pipTouchHandler, PipTransitionController pipTransitionController,
209             WindowManagerShellWrapper windowManagerShellWrapper,
210             TaskStackListenerImpl taskStackListener,
211             Optional<OneHandedController> oneHandedController,
212             @ShellMainThread ShellExecutor mainExecutor) {
213         return Optional.ofNullable(PipController.create(context, displayController,
214                 pipAppOpsListener, pipBoundsAlgorithm, pipBoundsState, pipMediaController,
215                 phonePipMenuController, pipTaskOrganizer, pipTouchHandler, pipTransitionController,
216                 windowManagerShellWrapper, taskStackListener, oneHandedController, mainExecutor));
217     }
218 
219     @WMSingleton
220     @Provides
providePipBoundsState(Context context)221     static PipBoundsState providePipBoundsState(Context context) {
222         return new PipBoundsState(context);
223     }
224 
225     @WMSingleton
226     @Provides
providePipSnapAlgorithm()227     static PipSnapAlgorithm providePipSnapAlgorithm() {
228         return new PipSnapAlgorithm();
229     }
230 
231     @WMSingleton
232     @Provides
providesPipBoundsAlgorithm(Context context, PipBoundsState pipBoundsState, PipSnapAlgorithm pipSnapAlgorithm)233     static PipBoundsAlgorithm providesPipBoundsAlgorithm(Context context,
234             PipBoundsState pipBoundsState, PipSnapAlgorithm pipSnapAlgorithm) {
235         return new PipBoundsAlgorithm(context, pipBoundsState, pipSnapAlgorithm);
236     }
237 
238     // Handler is used by Icon.loadDrawableAsync
239     @WMSingleton
240     @Provides
providesPipPhoneMenuController(Context context, PipBoundsState pipBoundsState, PipMediaController pipMediaController, SystemWindows systemWindows, Optional<SplitScreenController> splitScreenOptional, @ShellMainThread ShellExecutor mainExecutor, @ShellMainThread Handler mainHandler)241     static PhonePipMenuController providesPipPhoneMenuController(Context context,
242             PipBoundsState pipBoundsState, PipMediaController pipMediaController,
243             SystemWindows systemWindows,
244             Optional<SplitScreenController> splitScreenOptional,
245             @ShellMainThread ShellExecutor mainExecutor,
246             @ShellMainThread Handler mainHandler) {
247         return new PhonePipMenuController(context, pipBoundsState, pipMediaController,
248                 systemWindows, splitScreenOptional, mainExecutor, mainHandler);
249     }
250 
251     @WMSingleton
252     @Provides
providePipTouchHandler(Context context, PhonePipMenuController menuPhoneController, PipBoundsAlgorithm pipBoundsAlgorithm, PipBoundsState pipBoundsState, PipTaskOrganizer pipTaskOrganizer, PipMotionHelper pipMotionHelper, FloatingContentCoordinator floatingContentCoordinator, PipUiEventLogger pipUiEventLogger, @ShellMainThread ShellExecutor mainExecutor)253     static PipTouchHandler providePipTouchHandler(Context context,
254             PhonePipMenuController menuPhoneController, PipBoundsAlgorithm pipBoundsAlgorithm,
255             PipBoundsState pipBoundsState,
256             PipTaskOrganizer pipTaskOrganizer,
257             PipMotionHelper pipMotionHelper,
258             FloatingContentCoordinator floatingContentCoordinator,
259             PipUiEventLogger pipUiEventLogger,
260             @ShellMainThread ShellExecutor mainExecutor) {
261         return new PipTouchHandler(context, menuPhoneController, pipBoundsAlgorithm,
262                 pipBoundsState, pipTaskOrganizer, pipMotionHelper,
263                 floatingContentCoordinator, pipUiEventLogger, mainExecutor);
264     }
265 
266     @WMSingleton
267     @Provides
providePipTransitionState()268     static PipTransitionState providePipTransitionState() {
269         return new PipTransitionState();
270     }
271 
272     @WMSingleton
273     @Provides
providePipTaskOrganizer(Context context, SyncTransactionQueue syncTransactionQueue, PipTransitionState pipTransitionState, PipBoundsState pipBoundsState, PipBoundsAlgorithm pipBoundsAlgorithm, PhonePipMenuController menuPhoneController, PipAnimationController pipAnimationController, PipSurfaceTransactionHelper pipSurfaceTransactionHelper, PipTransitionController pipTransitionController, Optional<LegacySplitScreenController> splitScreenOptional, Optional<SplitScreenController> newSplitScreenOptional, DisplayController displayController, PipUiEventLogger pipUiEventLogger, ShellTaskOrganizer shellTaskOrganizer, @ShellMainThread ShellExecutor mainExecutor)274     static PipTaskOrganizer providePipTaskOrganizer(Context context,
275             SyncTransactionQueue syncTransactionQueue,
276             PipTransitionState pipTransitionState,
277             PipBoundsState pipBoundsState,
278             PipBoundsAlgorithm pipBoundsAlgorithm,
279             PhonePipMenuController menuPhoneController,
280             PipAnimationController pipAnimationController,
281             PipSurfaceTransactionHelper pipSurfaceTransactionHelper,
282             PipTransitionController pipTransitionController,
283             Optional<LegacySplitScreenController> splitScreenOptional,
284             Optional<SplitScreenController> newSplitScreenOptional,
285             DisplayController displayController,
286             PipUiEventLogger pipUiEventLogger, ShellTaskOrganizer shellTaskOrganizer,
287             @ShellMainThread ShellExecutor mainExecutor) {
288         return new PipTaskOrganizer(context,
289                 syncTransactionQueue, pipTransitionState, pipBoundsState, pipBoundsAlgorithm,
290                 menuPhoneController, pipAnimationController, pipSurfaceTransactionHelper,
291                 pipTransitionController, splitScreenOptional, newSplitScreenOptional,
292                 displayController, pipUiEventLogger, shellTaskOrganizer, mainExecutor);
293     }
294 
295     @WMSingleton
296     @Provides
providePipAnimationController(PipSurfaceTransactionHelper pipSurfaceTransactionHelper)297     static PipAnimationController providePipAnimationController(PipSurfaceTransactionHelper
298             pipSurfaceTransactionHelper) {
299         return new PipAnimationController(pipSurfaceTransactionHelper);
300     }
301 
302     @WMSingleton
303     @Provides
providePipTransitionController(Context context, Transitions transitions, ShellTaskOrganizer shellTaskOrganizer, PipAnimationController pipAnimationController, PipBoundsAlgorithm pipBoundsAlgorithm, PipBoundsState pipBoundsState, PipTransitionState pipTransitionState, PhonePipMenuController pipMenuController)304     static PipTransitionController providePipTransitionController(Context context,
305             Transitions transitions, ShellTaskOrganizer shellTaskOrganizer,
306             PipAnimationController pipAnimationController, PipBoundsAlgorithm pipBoundsAlgorithm,
307             PipBoundsState pipBoundsState, PipTransitionState pipTransitionState,
308             PhonePipMenuController pipMenuController) {
309         return new PipTransition(context, pipBoundsState, pipTransitionState, pipMenuController,
310                 pipBoundsAlgorithm, pipAnimationController, transitions, shellTaskOrganizer);
311     }
312 
313     @WMSingleton
314     @Provides
providePipMotionHelper(Context context, PipBoundsState pipBoundsState, PipTaskOrganizer pipTaskOrganizer, PhonePipMenuController menuController, PipSnapAlgorithm pipSnapAlgorithm, PipTransitionController pipTransitionController, FloatingContentCoordinator floatingContentCoordinator)315     static PipMotionHelper providePipMotionHelper(Context context,
316             PipBoundsState pipBoundsState, PipTaskOrganizer pipTaskOrganizer,
317             PhonePipMenuController menuController, PipSnapAlgorithm pipSnapAlgorithm,
318             PipTransitionController pipTransitionController,
319             FloatingContentCoordinator floatingContentCoordinator) {
320         return new PipMotionHelper(context, pipBoundsState, pipTaskOrganizer,
321                 menuController, pipSnapAlgorithm, pipTransitionController,
322                 floatingContentCoordinator);
323     }
324 
325     //
326     // Unfold transition
327     //
328 
329     @WMSingleton
330     @Provides
331     @DynamicOverride
provideFullscreenUnfoldController( Context context, Optional<ShellUnfoldProgressProvider> progressProvider, Lazy<UnfoldBackgroundController> unfoldBackgroundController, DisplayInsetsController displayInsetsController, @ShellMainThread ShellExecutor mainExecutor )332     static FullscreenUnfoldController provideFullscreenUnfoldController(
333             Context context,
334             Optional<ShellUnfoldProgressProvider> progressProvider,
335             Lazy<UnfoldBackgroundController> unfoldBackgroundController,
336             DisplayInsetsController displayInsetsController,
337             @ShellMainThread ShellExecutor mainExecutor
338     ) {
339         return new FullscreenUnfoldController(context, mainExecutor,
340                 unfoldBackgroundController.get(), progressProvider.get(),
341                 displayInsetsController);
342     }
343 
344     @Provides
provideStageTaskUnfoldController( Optional<ShellUnfoldProgressProvider> progressProvider, Context context, TransactionPool transactionPool, Lazy<UnfoldBackgroundController> unfoldBackgroundController, DisplayInsetsController displayInsetsController, @ShellMainThread ShellExecutor mainExecutor )345     static Optional<StageTaskUnfoldController> provideStageTaskUnfoldController(
346             Optional<ShellUnfoldProgressProvider> progressProvider,
347             Context context,
348             TransactionPool transactionPool,
349             Lazy<UnfoldBackgroundController> unfoldBackgroundController,
350             DisplayInsetsController displayInsetsController,
351             @ShellMainThread ShellExecutor mainExecutor
352     ) {
353         return progressProvider.map(shellUnfoldTransitionProgressProvider ->
354                 new StageTaskUnfoldController(
355                         context,
356                         transactionPool,
357                         shellUnfoldTransitionProgressProvider,
358                         displayInsetsController,
359                         unfoldBackgroundController.get(),
360                         mainExecutor
361                 ));
362     }
363 
364     @WMSingleton
365     @Provides
provideUnfoldBackgroundController( RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer, Context context )366     static UnfoldBackgroundController provideUnfoldBackgroundController(
367             RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
368             Context context
369     ) {
370         return new UnfoldBackgroundController(
371                 context,
372                 rootTaskDisplayAreaOrganizer
373         );
374     }
375 }
376