1 /* 2 * Copyright (C) 2023 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.pip; 18 19 import android.annotation.NonNull; 20 import android.content.Context; 21 import android.os.Handler; 22 import android.window.DesktopModeFlags; 23 24 import com.android.internal.jank.InteractionJankMonitor; 25 import com.android.wm.shell.RootTaskDisplayAreaOrganizer; 26 import com.android.wm.shell.ShellTaskOrganizer; 27 import com.android.wm.shell.common.DisplayController; 28 import com.android.wm.shell.common.DisplayInsetsController; 29 import com.android.wm.shell.common.FloatingContentCoordinator; 30 import com.android.wm.shell.common.ShellExecutor; 31 import com.android.wm.shell.common.SystemWindows; 32 import com.android.wm.shell.common.TaskStackListenerImpl; 33 import com.android.wm.shell.common.pip.PipAppOpsListener; 34 import com.android.wm.shell.common.pip.PipBoundsAlgorithm; 35 import com.android.wm.shell.common.pip.PipBoundsState; 36 import com.android.wm.shell.common.pip.PipDesktopState; 37 import com.android.wm.shell.common.pip.PipDisplayLayoutState; 38 import com.android.wm.shell.common.pip.PipMediaController; 39 import com.android.wm.shell.common.pip.PipPerfHintController; 40 import com.android.wm.shell.common.pip.PipSnapAlgorithm; 41 import com.android.wm.shell.common.pip.PipUiEventLogger; 42 import com.android.wm.shell.common.pip.PipUtils; 43 import com.android.wm.shell.common.pip.SizeSpecSource; 44 import com.android.wm.shell.dagger.WMShellBaseModule; 45 import com.android.wm.shell.dagger.WMSingleton; 46 import com.android.wm.shell.desktopmode.DesktopPipTransitionController; 47 import com.android.wm.shell.desktopmode.DesktopTasksController; 48 import com.android.wm.shell.desktopmode.DesktopUserRepositories; 49 import com.android.wm.shell.desktopmode.DragToDesktopTransitionHandler; 50 import com.android.wm.shell.pip2.phone.PhonePipMenuController; 51 import com.android.wm.shell.pip2.phone.PipController; 52 import com.android.wm.shell.pip2.phone.PipInteractionHandler; 53 import com.android.wm.shell.pip2.phone.PipMotionHelper; 54 import com.android.wm.shell.pip2.phone.PipScheduler; 55 import com.android.wm.shell.pip2.phone.PipTaskListener; 56 import com.android.wm.shell.pip2.phone.PipTouchHandler; 57 import com.android.wm.shell.pip2.phone.PipTransition; 58 import com.android.wm.shell.pip2.phone.PipTransitionState; 59 import com.android.wm.shell.pip2.phone.PipUiStateChangeController; 60 import com.android.wm.shell.shared.annotations.ShellMainThread; 61 import com.android.wm.shell.shared.desktopmode.DesktopModeStatus; 62 import com.android.wm.shell.splitscreen.SplitScreenController; 63 import com.android.wm.shell.sysui.ShellCommandHandler; 64 import com.android.wm.shell.sysui.ShellController; 65 import com.android.wm.shell.sysui.ShellInit; 66 import com.android.wm.shell.transition.Transitions; 67 68 import dagger.BindsOptionalOf; 69 import dagger.Module; 70 import dagger.Provides; 71 72 import java.util.Optional; 73 74 /** 75 * Provides dependencies from {@link com.android.wm.shell.pip2}, this implementation is meant to be 76 * the successor of its sibling {@link Pip1Module}. 77 */ 78 @Module(includes = WMShellBaseModule.class) 79 public abstract class Pip2Module { 80 @WMSingleton 81 @Provides providePipTransition(Context context, @NonNull ShellInit shellInit, @NonNull ShellTaskOrganizer shellTaskOrganizer, @NonNull Transitions transitions, PipBoundsState pipBoundsState, PipBoundsAlgorithm pipBoundsAlgorithm, Optional<PipController> pipController, PipTouchHandler pipTouchHandler, PipTaskListener pipTaskListener, @NonNull PipScheduler pipScheduler, @NonNull PipTransitionState pipStackListenerController, @NonNull PipDisplayLayoutState pipDisplayLayoutState, @NonNull PipUiStateChangeController pipUiStateChangeController, DisplayController displayController, Optional<SplitScreenController> splitScreenControllerOptional, PipDesktopState pipDesktopState, Optional<DesktopPipTransitionController> desktopPipTransitionController, PipInteractionHandler pipInteractionHandler)82 static PipTransition providePipTransition(Context context, 83 @NonNull ShellInit shellInit, 84 @NonNull ShellTaskOrganizer shellTaskOrganizer, 85 @NonNull Transitions transitions, 86 PipBoundsState pipBoundsState, 87 PipBoundsAlgorithm pipBoundsAlgorithm, 88 Optional<PipController> pipController, 89 PipTouchHandler pipTouchHandler, 90 PipTaskListener pipTaskListener, 91 @NonNull PipScheduler pipScheduler, 92 @NonNull PipTransitionState pipStackListenerController, 93 @NonNull PipDisplayLayoutState pipDisplayLayoutState, 94 @NonNull PipUiStateChangeController pipUiStateChangeController, 95 DisplayController displayController, 96 Optional<SplitScreenController> splitScreenControllerOptional, 97 PipDesktopState pipDesktopState, 98 Optional<DesktopPipTransitionController> desktopPipTransitionController, 99 PipInteractionHandler pipInteractionHandler) { 100 return new PipTransition(context, shellInit, shellTaskOrganizer, transitions, 101 pipBoundsState, null, pipBoundsAlgorithm, pipTaskListener, 102 pipScheduler, pipStackListenerController, pipDisplayLayoutState, 103 pipUiStateChangeController, displayController, splitScreenControllerOptional, 104 pipDesktopState, desktopPipTransitionController, pipInteractionHandler); 105 } 106 107 @WMSingleton 108 @Provides providePip2(Optional<PipController> pipController)109 static Optional<PipController.PipImpl> providePip2(Optional<PipController> pipController) { 110 if (pipController.isEmpty()) { 111 return Optional.empty(); 112 } else { 113 return Optional.ofNullable(pipController.get().getPipImpl()); 114 } 115 } 116 117 @WMSingleton 118 @Provides providePipController(Context context, ShellInit shellInit, ShellCommandHandler shellCommandHandler, ShellController shellController, DisplayController displayController, DisplayInsetsController displayInsetsController, PipBoundsState pipBoundsState, PipBoundsAlgorithm pipBoundsAlgorithm, PipDisplayLayoutState pipDisplayLayoutState, PipScheduler pipScheduler, TaskStackListenerImpl taskStackListener, ShellTaskOrganizer shellTaskOrganizer, PipTransitionState pipTransitionState, PipTouchHandler pipTouchHandler, PipAppOpsListener pipAppOpsListener, PhonePipMenuController pipMenuController, PipUiEventLogger pipUiEventLogger, @ShellMainThread ShellExecutor mainExecutor)119 static Optional<PipController> providePipController(Context context, 120 ShellInit shellInit, 121 ShellCommandHandler shellCommandHandler, 122 ShellController shellController, 123 DisplayController displayController, 124 DisplayInsetsController displayInsetsController, 125 PipBoundsState pipBoundsState, 126 PipBoundsAlgorithm pipBoundsAlgorithm, 127 PipDisplayLayoutState pipDisplayLayoutState, 128 PipScheduler pipScheduler, 129 TaskStackListenerImpl taskStackListener, 130 ShellTaskOrganizer shellTaskOrganizer, 131 PipTransitionState pipTransitionState, 132 PipTouchHandler pipTouchHandler, 133 PipAppOpsListener pipAppOpsListener, 134 PhonePipMenuController pipMenuController, 135 PipUiEventLogger pipUiEventLogger, 136 @ShellMainThread ShellExecutor mainExecutor) { 137 if (!PipUtils.isPip2ExperimentEnabled()) { 138 return Optional.empty(); 139 } else { 140 return Optional.ofNullable(PipController.create( 141 context, shellInit, shellCommandHandler, shellController, displayController, 142 displayInsetsController, pipBoundsState, pipBoundsAlgorithm, 143 pipDisplayLayoutState, pipScheduler, taskStackListener, shellTaskOrganizer, 144 pipTransitionState, pipTouchHandler, pipAppOpsListener, pipMenuController, 145 pipUiEventLogger, mainExecutor)); 146 } 147 } 148 149 @WMSingleton 150 @Provides providePipScheduler(Context context, PipBoundsState pipBoundsState, @ShellMainThread ShellExecutor mainExecutor, PipTransitionState pipTransitionState, Optional<SplitScreenController> splitScreenControllerOptional, PipDesktopState pipDesktopState)151 static PipScheduler providePipScheduler(Context context, 152 PipBoundsState pipBoundsState, 153 @ShellMainThread ShellExecutor mainExecutor, 154 PipTransitionState pipTransitionState, 155 Optional<SplitScreenController> splitScreenControllerOptional, 156 PipDesktopState pipDesktopState) { 157 return new PipScheduler(context, pipBoundsState, mainExecutor, pipTransitionState, 158 splitScreenControllerOptional, pipDesktopState); 159 } 160 161 @WMSingleton 162 @Provides providePipPhoneMenuController(Context context, PipBoundsState pipBoundsState, PipMediaController pipMediaController, SystemWindows systemWindows, PipUiEventLogger pipUiEventLogger, PipTaskListener pipTaskListener, @NonNull PipTransitionState pipTransitionState, @NonNull PipDisplayLayoutState pipDisplayLayoutState, @ShellMainThread ShellExecutor mainExecutor, @ShellMainThread Handler mainHandler)163 static PhonePipMenuController providePipPhoneMenuController(Context context, 164 PipBoundsState pipBoundsState, PipMediaController pipMediaController, 165 SystemWindows systemWindows, 166 PipUiEventLogger pipUiEventLogger, 167 PipTaskListener pipTaskListener, 168 @NonNull PipTransitionState pipTransitionState, 169 @NonNull PipDisplayLayoutState pipDisplayLayoutState, 170 @ShellMainThread ShellExecutor mainExecutor, 171 @ShellMainThread Handler mainHandler) { 172 return new PhonePipMenuController(context, pipBoundsState, pipMediaController, 173 systemWindows, pipUiEventLogger, pipTaskListener, pipTransitionState, 174 pipDisplayLayoutState, mainExecutor, mainHandler); 175 } 176 177 178 @WMSingleton 179 @Provides providePipTouchHandler(Context context, ShellInit shellInit, ShellCommandHandler shellCommandHandler, PhonePipMenuController menuPhoneController, PipBoundsAlgorithm pipBoundsAlgorithm, @NonNull PipBoundsState pipBoundsState, @NonNull PipTransitionState pipTransitionState, @NonNull PipScheduler pipScheduler, @NonNull SizeSpecSource sizeSpecSource, @NonNull PipDisplayLayoutState pipDisplayLayoutState, PipDesktopState pipDesktopState, DisplayController displayController, PipMotionHelper pipMotionHelper, FloatingContentCoordinator floatingContentCoordinator, PipUiEventLogger pipUiEventLogger, @ShellMainThread ShellExecutor mainExecutor, Optional<PipPerfHintController> pipPerfHintControllerOptional)180 static PipTouchHandler providePipTouchHandler(Context context, 181 ShellInit shellInit, 182 ShellCommandHandler shellCommandHandler, 183 PhonePipMenuController menuPhoneController, 184 PipBoundsAlgorithm pipBoundsAlgorithm, 185 @NonNull PipBoundsState pipBoundsState, 186 @NonNull PipTransitionState pipTransitionState, 187 @NonNull PipScheduler pipScheduler, 188 @NonNull SizeSpecSource sizeSpecSource, 189 @NonNull PipDisplayLayoutState pipDisplayLayoutState, 190 PipDesktopState pipDesktopState, 191 DisplayController displayController, 192 PipMotionHelper pipMotionHelper, 193 FloatingContentCoordinator floatingContentCoordinator, 194 PipUiEventLogger pipUiEventLogger, 195 @ShellMainThread ShellExecutor mainExecutor, 196 Optional<PipPerfHintController> pipPerfHintControllerOptional) { 197 return new PipTouchHandler(context, shellInit, shellCommandHandler, menuPhoneController, 198 pipBoundsAlgorithm, pipBoundsState, pipTransitionState, pipScheduler, 199 sizeSpecSource, pipDisplayLayoutState, pipDesktopState, displayController, 200 pipMotionHelper, floatingContentCoordinator, pipUiEventLogger, mainExecutor, 201 pipPerfHintControllerOptional); 202 } 203 204 @WMSingleton 205 @Provides providePipMotionHelper(Context context, PipBoundsState pipBoundsState, PhonePipMenuController menuController, PipSnapAlgorithm pipSnapAlgorithm, FloatingContentCoordinator floatingContentCoordinator, PipScheduler pipScheduler, Optional<PipPerfHintController> pipPerfHintControllerOptional, PipTransitionState pipTransitionState, PipUiEventLogger pipUiEventLogger)206 static PipMotionHelper providePipMotionHelper(Context context, 207 PipBoundsState pipBoundsState, PhonePipMenuController menuController, 208 PipSnapAlgorithm pipSnapAlgorithm, 209 FloatingContentCoordinator floatingContentCoordinator, 210 PipScheduler pipScheduler, 211 Optional<PipPerfHintController> pipPerfHintControllerOptional, 212 PipTransitionState pipTransitionState, 213 PipUiEventLogger pipUiEventLogger) { 214 return new PipMotionHelper(context, pipBoundsState, menuController, pipSnapAlgorithm, 215 floatingContentCoordinator, pipScheduler, pipPerfHintControllerOptional, 216 pipTransitionState, pipUiEventLogger); 217 } 218 219 @WMSingleton 220 @Provides providePipTransitionState(@hellMainThread Handler handler, PipDesktopState pipDesktopState)221 static PipTransitionState providePipTransitionState(@ShellMainThread Handler handler, 222 PipDesktopState pipDesktopState) { 223 return new PipTransitionState(handler, pipDesktopState); 224 } 225 226 @WMSingleton 227 @Provides providePipUiStateChangeController( PipTransitionState pipTransitionState)228 static PipUiStateChangeController providePipUiStateChangeController( 229 PipTransitionState pipTransitionState) { 230 return new PipUiStateChangeController(pipTransitionState); 231 } 232 233 @WMSingleton 234 @Provides providePipTaskListener(Context context, ShellTaskOrganizer shellTaskOrganizer, PipTransitionState pipTransitionState, PipScheduler pipScheduler, PipBoundsState pipBoundsState, PipBoundsAlgorithm pipBoundsAlgorithm, @ShellMainThread ShellExecutor mainExecutor)235 static PipTaskListener providePipTaskListener(Context context, 236 ShellTaskOrganizer shellTaskOrganizer, 237 PipTransitionState pipTransitionState, 238 PipScheduler pipScheduler, 239 PipBoundsState pipBoundsState, 240 PipBoundsAlgorithm pipBoundsAlgorithm, 241 @ShellMainThread ShellExecutor mainExecutor) { 242 return new PipTaskListener(context, shellTaskOrganizer, pipTransitionState, 243 pipScheduler, pipBoundsState, pipBoundsAlgorithm, mainExecutor); 244 } 245 246 @WMSingleton 247 @Provides providePipDesktopState( PipDisplayLayoutState pipDisplayLayoutState, Optional<DesktopUserRepositories> desktopUserRepositoriesOptional, Optional<DragToDesktopTransitionHandler> dragToDesktopTransitionHandlerOptional, RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer )248 static PipDesktopState providePipDesktopState( 249 PipDisplayLayoutState pipDisplayLayoutState, 250 Optional<DesktopUserRepositories> desktopUserRepositoriesOptional, 251 Optional<DragToDesktopTransitionHandler> dragToDesktopTransitionHandlerOptional, 252 RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer 253 ) { 254 return new PipDesktopState(pipDisplayLayoutState, desktopUserRepositoriesOptional, 255 dragToDesktopTransitionHandlerOptional, rootTaskDisplayAreaOrganizer); 256 } 257 258 @WMSingleton 259 @Provides provideDesktopPipTransitionController( Context context, Optional<DesktopTasksController> desktopTasksControllerOptional, Optional<DesktopUserRepositories> desktopUserRepositoriesOptional, PipDesktopState pipDesktopState )260 static Optional<DesktopPipTransitionController> provideDesktopPipTransitionController( 261 Context context, Optional<DesktopTasksController> desktopTasksControllerOptional, 262 Optional<DesktopUserRepositories> desktopUserRepositoriesOptional, 263 PipDesktopState pipDesktopState 264 ) { 265 if (DesktopModeStatus.canEnterDesktopMode(context) 266 && DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PIP.isTrue()) { 267 return Optional.of( 268 new DesktopPipTransitionController(desktopTasksControllerOptional.get(), 269 desktopUserRepositoriesOptional.get(), pipDesktopState)); 270 } 271 return Optional.empty(); 272 } 273 274 @BindsOptionalOf optionalDragToDesktopTransitionHandler()275 abstract DragToDesktopTransitionHandler optionalDragToDesktopTransitionHandler(); 276 277 @WMSingleton 278 @Provides providePipInteractionHandler( Context context, @ShellMainThread Handler mainHandler )279 static PipInteractionHandler providePipInteractionHandler( 280 Context context, 281 @ShellMainThread Handler mainHandler 282 ) { 283 return new PipInteractionHandler(context, mainHandler, 284 InteractionJankMonitor.getInstance()); 285 } 286 } 287