diff options
| author | 2020-09-24 11:33:23 +0000 | |
|---|---|---|
| committer | 2020-09-24 11:33:23 +0000 | |
| commit | 7b7f225e2196a6c8e93b1f65dd8448c5f12f9165 (patch) | |
| tree | 20f00480ce85044fe54d0f2f1521df22dbbd1c44 | |
| parent | cda123e28857009da4ac8fde82ee8c5ca25b0965 (diff) | |
| parent | 000ce66626fe7de4e396b02d21de41d0ca0d5ecf (diff) | |
Merge changes from topic "pip_migration_8"
* changes:
Use consumer to dispatch signal between Launcher & SysUI OPS Pip(8-2/N)
Re-landing Decouple systemui shared componements from PipController(8/N)
29 files changed, 674 insertions, 502 deletions
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java index 067ac9ec7b1e..e5f2ad5b7586 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java @@ -33,7 +33,6 @@ import android.view.WindowManagerGlobal; import com.android.systemui.shared.recents.view.AppTransitionAnimationSpecsFuture; import com.android.systemui.shared.recents.view.RecentsTransition; -import com.android.systemui.shared.system.PinnedStackListenerForwarder.PinnedStackListener; public class WindowManagerWrapper { @@ -75,7 +74,7 @@ public class WindowManagerWrapper { WindowConfiguration.WINDOWING_MODE_FULLSCREEN; public static final int WINDOWING_MODE_MULTI_WINDOW = WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; - public static final int WINDOWING_MODE_PINNED = WindowConfiguration.WINDOWING_MODE_PINNED; + public static final int WINDOWING_MODE_SPLIT_SCREEN_PRIMARY = WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; public static final int WINDOWING_MODE_SPLIT_SCREEN_SECONDARY = @@ -84,13 +83,6 @@ public class WindowManagerWrapper { private static final WindowManagerWrapper sInstance = new WindowManagerWrapper(); - /** - * Forwarder to which we can add multiple pinned stack listeners. Each listener will receive - * updates from the window manager service. - */ - private PinnedStackListenerForwarder mPinnedStackListenerForwarder = - new PinnedStackListenerForwarder(); - public static WindowManagerWrapper getInstance() { return sInstance; } @@ -188,23 +180,6 @@ public class WindowManagerWrapper { } /** - * Adds a pinned stack listener, which will receive updates from the window manager service - * along with any other pinned stack listeners that were added via this method. - */ - public void addPinnedStackListener(PinnedStackListener listener) throws RemoteException { - mPinnedStackListenerForwarder.addListener(listener); - WindowManagerGlobal.getWindowManagerService().registerPinnedStackListener( - DEFAULT_DISPLAY, mPinnedStackListenerForwarder); - } - - /** - * Removes a pinned stack listener. - */ - public void removePinnedStackListener(PinnedStackListener listener) { - mPinnedStackListenerForwarder.removeListener(listener); - } - - /** * Mirrors a specified display. The SurfaceControl returned is the root of the mirrored * hierarchy. * diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java index b6106025a17a..90b1f55ac514 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java @@ -33,7 +33,6 @@ import static android.view.View.INVISIBLE; import static android.view.View.VISIBLE; import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; -import static com.android.systemui.bubbles.BubbleDebugConfig.DEBUG_BUBBLE_CONTROLLER; import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_BUBBLES; import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.systemui.statusbar.StatusBarState.SHADE; @@ -91,7 +90,6 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.PinnedStackListenerForwarder; import com.android.systemui.shared.system.TaskStackChangeListener; -import com.android.systemui.shared.system.WindowManagerWrapper; import com.android.systemui.statusbar.FeatureFlags; import com.android.systemui.statusbar.NotificationLockscreenUserManager; import com.android.systemui.statusbar.NotificationRemoveInterceptor; @@ -115,6 +113,7 @@ import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.ZenModeController; import com.android.systemui.util.FloatingContentCoordinator; +import com.android.systemui.wmshell.WindowManagerShellWrapper; import java.io.FileDescriptor; import java.io.PrintWriter; @@ -366,6 +365,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi INotificationManager notificationManager, @Nullable IStatusBarService statusBarService, WindowManager windowManager, + WindowManagerShellWrapper windowManagerShellWrapper, LauncherApps launcherApps) { dumpManager.registerDumpable(TAG, this); mContext = context; @@ -441,7 +441,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskStackListener); try { - WindowManagerWrapper.getInstance().addPinnedStackListener(new BubblesImeListener()); + windowManagerShellWrapper.addPinnedStackListener(new BubblesImeListener()); } catch (RemoteException e) { e.printStackTrace(); } diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/dagger/BubbleModule.java b/packages/SystemUI/src/com/android/systemui/bubbles/dagger/BubbleModule.java index 9efc3c20f55a..5bf105368997 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/dagger/BubbleModule.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/dagger/BubbleModule.java @@ -40,6 +40,7 @@ import com.android.systemui.statusbar.phone.ShadeController; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.ZenModeController; import com.android.systemui.util.FloatingContentCoordinator; +import com.android.systemui.wmshell.WindowManagerShellWrapper; import dagger.Module; import dagger.Provides; @@ -73,6 +74,7 @@ public interface BubbleModule { INotificationManager notifManager, IStatusBarService statusBarService, WindowManager windowManager, + WindowManagerShellWrapper windowManagerShellWrapper, LauncherApps launcherApps) { return new BubbleController( context, @@ -96,6 +98,7 @@ public interface BubbleModule { notifManager, statusBarService, windowManager, + windowManagerShellWrapper, launcherApps); } } diff --git a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java index 38e12a6ed5f8..c90e6b1360df 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java @@ -66,6 +66,7 @@ import com.android.systemui.shared.plugins.PluginManager; import com.android.systemui.shared.plugins.PluginManagerImpl; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.DevicePolicyManagerWrapper; +import com.android.systemui.shared.system.WindowManagerWrapper; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.NotificationRemoteInputManager; import com.android.systemui.statusbar.phone.AutoHideController; @@ -312,6 +313,13 @@ public class DependencyProvider { /** */ @Provides + public WindowManagerWrapper providesWindowManagerWrapper() { + return WindowManagerWrapper.getInstance(); + } + + /** */ + @Provides + @SysUISingleton public SystemActions providesSystemActions(Context context) { return new SystemActions(context); } diff --git a/packages/SystemUI/src/com/android/systemui/pip/Pip.java b/packages/SystemUI/src/com/android/systemui/pip/Pip.java index b068370da9e3..2b115508e525 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/Pip.java +++ b/packages/SystemUI/src/com/android/systemui/pip/Pip.java @@ -16,24 +16,21 @@ package com.android.systemui.pip; -import android.content.res.Configuration; +import android.app.ActivityManager; +import android.content.ComponentName; import android.media.session.MediaController; +import com.android.systemui.pip.phone.PipTouchHandler; import com.android.systemui.pip.tv.PipController; -import com.android.systemui.shared.recents.IPinnedStackAnimationListener; import java.io.PrintWriter; +import java.util.function.Consumer; /** * Interface to engage picture in picture feature. */ public interface Pip { /** - * Called when showing Pip menu. - */ - void showPictureInPictureMenu(); - - /** * Registers {@link com.android.systemui.pip.tv.PipController.Listener} that gets called. * whenever receiving notification on changes in PIP. */ @@ -53,6 +50,14 @@ public interface Pip { } /** + * Dump the current state and information if need. + * + * @param pw The stream to dump information to. + */ + default void dump(PrintWriter pw) { + } + + /** * Expand PIP, it's possible that specific request to activate the window via Alt-tab. */ default void expandPip() { @@ -64,7 +69,11 @@ public interface Pip { * @return The state of defined in PipController. */ default int getPlaybackState() { - return 0; + return -1; + } + + default PipTouchHandler getPipTouchHandler() { + return null; } /** @@ -95,9 +104,61 @@ public interface Pip { } /** - * Called when configuration change invoked. + * Called whenever an Activity is moved to the pinned stack from another stack. + */ + default void onActivityPinned(String packageName) { + } + + /** + * Called whenever an Activity is moved from the pinned stack to another stack + */ + default void onActivityUnpinned(ComponentName topActivity) { + } + + /** + * Called whenever IActivityManager.startActivity is called on an activity that is already + * running, but the task is either brought to the front or a new Intent is delivered to it. + * + * @param task information about the task the activity was relaunched into + * @param clearedTask whether or not the launch activity also cleared the task as a part of + * starting + */ + default void onActivityRestartAttempt(ActivityManager.RunningTaskInfo task, + boolean clearedTask) { + } + + /** + * Called when display size or font size of settings changed + */ + default void onDensityOrFontScaleChanged() { + } + + /** + * Called when overlay package change invoked. */ - void onConfigurationChanged(Configuration newConfig); + default void onOverlayChanged() { + } + + /** + * Registers the session listener for the current user. + */ + default void registerSessionListenerForCurrentUser() { + } + + /** + * Called when SysUI state changed. + * + * @param isSysUiStateValid Is SysUI state valid or not. + * @param flag Current SysUI state. + */ + default void onSystemUiStateChanged(boolean isSysUiStateValid, int flag) { + } + + /** + * Called when task stack changed. + */ + default void onTaskStackChanged() { + } /** * Removes a {@link PipController.Listener} from PipController. @@ -137,6 +198,14 @@ public interface Pip { } /** + * Registers the pinned stack animation listener. + * + * @param callback The callback of pinned stack animation. + */ + default void setPinnedStackAnimationListener(Consumer<Boolean> callback) { + } + + /** * Set the pinned stack with {@link PipAnimationController.AnimationType} * * @param animationType The pre-defined {@link PipAnimationController.AnimationType} @@ -145,12 +214,9 @@ public interface Pip { } /** - * Registers the pinned stack animation listener. - * - * @param listener The listener of pinned stack animation. + * Called when showing Pip menu. */ - default void setPinnedStackAnimationListener(IPinnedStackAnimationListener listener) { - } + void showPictureInPictureMenu(); /** * Suspends resizing operation on the Pip until {@link #resumePipResizing} is called. @@ -159,12 +225,4 @@ public interface Pip { */ default void suspendPipResizing(int reason) { } - - /** - * Dump the current state and information if need. - * - * @param pw The stream to dump information to. - */ - default void dump(PrintWriter pw) { - } } diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipSurfaceTransactionHelper.java b/packages/SystemUI/src/com/android/systemui/pip/PipSurfaceTransactionHelper.java index 3e98169c5b2b..fc724cb539dc 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/PipSurfaceTransactionHelper.java +++ b/packages/SystemUI/src/com/android/systemui/pip/PipSurfaceTransactionHelper.java @@ -24,16 +24,14 @@ import android.graphics.RectF; import android.view.SurfaceControl; import com.android.systemui.dagger.SysUISingleton; -import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.wm.shell.R; /** * Abstracts the common operations on {@link SurfaceControl.Transaction} for PiP transition. */ @SysUISingleton -public class PipSurfaceTransactionHelper implements ConfigurationController.ConfigurationListener { +public class PipSurfaceTransactionHelper { - private final Context mContext; private final boolean mEnableCornerRadius; private int mCornerRadius; @@ -44,17 +42,21 @@ public class PipSurfaceTransactionHelper implements ConfigurationController.Conf private final RectF mTmpDestinationRectF = new RectF(); private final Rect mTmpDestinationRect = new Rect(); - public PipSurfaceTransactionHelper(Context context, ConfigurationController configController) { + public PipSurfaceTransactionHelper(Context context) { final Resources res = context.getResources(); - mContext = context; mEnableCornerRadius = res.getBoolean(R.bool.config_pipEnableRoundCorner); - configController.addCallback(this); } - @Override - public void onDensityOrFontScaleChanged() { - final Resources res = mContext.getResources(); - mCornerRadius = res.getDimensionPixelSize(R.dimen.pip_corner_radius); + /** + * Called when display size or font size of settings changed + * + * @param context the current context + */ + public void onDensityOrFontScaleChanged(Context context) { + if (mEnableCornerRadius) { + final Resources res = context.getResources(); + mCornerRadius = res.getDimensionPixelSize(R.dimen.pip_corner_radius); + } } /** diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java index 6cc0cd879d71..9cf2751df8ee 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java +++ b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java @@ -130,7 +130,6 @@ public class PipTaskOrganizer extends TaskOrganizer implements ShellTaskOrganize } } - private final Context mContext; private final Handler mMainHandler; private final Handler mUpdateHandler; private final PipBoundsHandler mPipBoundsHandler; @@ -249,7 +248,6 @@ public class PipTaskOrganizer extends TaskOrganizer implements ShellTaskOrganize @NonNull DisplayController displayController, @NonNull PipUiEventLogger pipUiEventLogger, @NonNull ShellTaskOrganizer shellTaskOrganizer) { - mContext = context; mMainHandler = new Handler(Looper.getMainLooper()); mUpdateHandler = new Handler(PipUpdateThread.get().getLooper(), mUpdateCallbacks); mPipBoundsHandler = boundsHandler; @@ -565,8 +563,8 @@ public class PipTaskOrganizer extends TaskOrganizer implements ShellTaskOrganize if (Looper.getMainLooper() != Looper.myLooper()) { throw new RuntimeException("PipMenuView needs to be attached on the main thread."); } - - mPipViewHost = new SurfaceControlViewHost(mContext, mContext.getDisplay(), + final Context context = menuView.getContext(); + mPipViewHost = new SurfaceControlViewHost(context, context.getDisplay(), (android.os.Binder) null); mPipMenuSurface = mPipViewHost.getSurfacePackage().getSurfaceControl(); SurfaceControl.Transaction transaction = new SurfaceControl.Transaction(); @@ -659,6 +657,13 @@ public class PipTaskOrganizer extends TaskOrganizer implements ShellTaskOrganize } /** + * Called when display size or font size of settings changed + */ + public void onDensityOrFontScaleChanged(Context context) { + mSurfaceTransactionHelper.onDensityOrFontScaleChanged(context); + } + + /** * TODO(b/152809058): consolidate the display info handling logic in SysUI * * @param destinationBoundsOut the current destination bounds will be populated to this param diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipController.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipController.java index 8a2e9e23343c..625304371d5b 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipController.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipController.java @@ -16,55 +16,37 @@ package com.android.systemui.pip.phone; -import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static com.android.systemui.pip.PipAnimationController.isOutPipDirection; import android.annotation.Nullable; import android.app.ActivityManager; -import android.app.ActivityTaskManager; -import android.app.ActivityTaskManager.RootTaskInfo; -import android.app.IActivityManager; import android.app.RemoteAction; import android.content.ComponentName; import android.content.Context; import android.content.pm.ParceledListSlice; -import android.content.res.Configuration; import android.graphics.Rect; import android.os.Handler; import android.os.RemoteException; import android.os.UserHandle; import android.os.UserManager; import android.util.Log; -import android.util.Pair; import android.view.DisplayInfo; import android.view.IPinnedStackController; import android.window.WindowContainerTransaction; -import com.android.systemui.Dependency; -import com.android.systemui.UiOffloadThread; -import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.dagger.SysUISingleton; -import com.android.systemui.model.SysUiState; import com.android.systemui.pip.Pip; import com.android.systemui.pip.PipBoundsHandler; -import com.android.systemui.pip.PipSurfaceTransactionHelper; import com.android.systemui.pip.PipTaskOrganizer; -import com.android.systemui.pip.PipUiEventLogger; -import com.android.systemui.shared.recents.IPinnedStackAnimationListener; -import com.android.systemui.shared.system.ActivityManagerWrapper; -import com.android.systemui.shared.system.InputConsumerController; -import com.android.systemui.shared.system.PinnedStackListenerForwarder.PinnedStackListener; -import com.android.systemui.shared.system.TaskStackChangeListener; -import com.android.systemui.shared.system.WindowManagerWrapper; -import com.android.systemui.statusbar.policy.ConfigurationController; -import com.android.systemui.util.DeviceConfigProxy; -import com.android.systemui.util.FloatingContentCoordinator; +import com.android.systemui.shared.system.PinnedStackListenerForwarder; +import com.android.systemui.wmshell.WindowManagerShellWrapper; import com.android.wm.shell.common.DisplayChangeController; import com.android.wm.shell.common.DisplayController; import java.io.PrintWriter; +import java.util.function.Consumer; /** * Manages the picture-in-picture (PIP) UI and states for Phones. @@ -74,7 +56,6 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac private static final String TAG = "PipController"; private Context mContext; - private IActivityManager mActivityManager; private Handler mHandler = new Handler(); private final DisplayInfo mTmpDisplayInfo = new DisplayInfo(); @@ -83,13 +64,13 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac protected final Rect mReentryBounds = new Rect(); private DisplayController mDisplayController; - private InputConsumerController mInputConsumerController; private PipAppOpsListener mAppOpsListener; private PipBoundsHandler mPipBoundsHandler; private PipMediaController mMediaController; private PipTouchHandler mTouchHandler; - private PipSurfaceTransactionHelper mPipSurfaceTransactionHelper; - private IPinnedStackAnimationListener mPinnedStackAnimationRecentsListener; + private Consumer<Boolean> mPinnedStackAnimationRecentsCallback; + private WindowManagerShellWrapper mWindowManagerShellWrapper; + private boolean mIsInFixedRotation; protected PipMenuActivityController mMenuController; @@ -156,50 +137,10 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac }; /** - * Handler for system task stack changes. - */ - private final TaskStackChangeListener mTaskStackListener = new TaskStackChangeListener() { - @Override - public void onActivityPinned(String packageName, int userId, int taskId, int stackId) { - mTouchHandler.onActivityPinned(); - mMediaController.onActivityPinned(); - mMenuController.onActivityPinned(); - mAppOpsListener.onActivityPinned(packageName); - - Dependency.get(UiOffloadThread.class).execute(() -> { - WindowManagerWrapper.getInstance().setPipVisibility(true); - }); - } - - @Override - public void onActivityUnpinned() { - final Pair<ComponentName, Integer> topPipActivityInfo = PipUtils.getTopPipActivity( - mContext, mActivityManager); - final ComponentName topActivity = topPipActivityInfo.first; - mMenuController.onActivityUnpinned(); - mTouchHandler.onActivityUnpinned(topActivity); - mAppOpsListener.onActivityUnpinned(); - - Dependency.get(UiOffloadThread.class).execute(() -> { - WindowManagerWrapper.getInstance().setPipVisibility(topActivity != null); - }); - } - - @Override - public void onActivityRestartAttempt(ActivityManager.RunningTaskInfo task, - boolean homeTaskVisible, boolean clearedTask, boolean wasVisible) { - if (task.configuration.windowConfiguration.getWindowingMode() - != WINDOWING_MODE_PINNED) { - return; - } - mTouchHandler.getMotionHelper().expandLeavePip(clearedTask /* skipAnimation */); - } - }; - - /** * Handler for messages from the PIP controller. */ - private class PipControllerPinnedStackListener extends PinnedStackListener { + private class PipControllerPinnedStackListener extends + PinnedStackListenerForwarder.PinnedStackListener { @Override public void onListenerRegistered(IPinnedStackController controller) { mHandler.post(() -> mTouchHandler.setPinnedStackController(controller)); @@ -237,7 +178,10 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac @Override public void onConfigurationChanged() { - mHandler.post(() -> mPipBoundsHandler.onConfigurationChanged(mContext)); + mHandler.post(() -> { + mPipBoundsHandler.onConfigurationChanged(mContext); + mTouchHandler.onConfigurationChanged(); + }); } @Override @@ -249,52 +193,36 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac } } - public ConfigurationController.ConfigurationListener mOverlayChangedListener = - new ConfigurationController.ConfigurationListener() { - @Override - public void onOverlayChanged() { - mHandler.post(() -> { - mPipBoundsHandler.onOverlayChanged(mContext, mContext.getDisplay()); - updateMovementBounds(null /* toBounds */, - false /* fromRotation */, false /* fromImeAdjustment */, - false /* fromShelfAdjustment */, - null /* windowContainerTransaction */); - }); - } - }; - - public PipController(Context context, BroadcastDispatcher broadcastDispatcher, - ConfigurationController configController, - DeviceConfigProxy deviceConfig, + public PipController(Context context, DisplayController displayController, - FloatingContentCoordinator floatingContentCoordinator, - SysUiState sysUiState, + PipAppOpsListener pipAppOpsListener, PipBoundsHandler pipBoundsHandler, - PipSurfaceTransactionHelper pipSurfaceTransactionHelper, + PipMediaController pipMediaController, + PipMenuActivityController pipMenuActivityController, PipTaskOrganizer pipTaskOrganizer, - PipUiEventLogger pipUiEventLogger) { + PipTouchHandler pipTouchHandler, + WindowManagerShellWrapper windowManagerShellWrapper + ) { mContext = context; - mActivityManager = ActivityManager.getService(); if (PipUtils.hasSystemFeature(mContext)) { - initController(context, broadcastDispatcher, configController, deviceConfig, - displayController, floatingContentCoordinator, sysUiState, pipBoundsHandler, - pipSurfaceTransactionHelper, pipTaskOrganizer, pipUiEventLogger); + initController(context, displayController, pipAppOpsListener, pipBoundsHandler, + pipMediaController, pipMenuActivityController, pipTaskOrganizer, + pipTouchHandler, windowManagerShellWrapper); } else { Log.w(TAG, "Device not support PIP feature"); } } - private void initController(Context context, BroadcastDispatcher broadcastDispatcher, - ConfigurationController configController, - DeviceConfigProxy deviceConfig, + private void initController(Context context, DisplayController displayController, - FloatingContentCoordinator floatingContentCoordinator, - SysUiState sysUiState, + PipAppOpsListener pipAppOpsListener, PipBoundsHandler pipBoundsHandler, - PipSurfaceTransactionHelper pipSurfaceTransactionHelper, + PipMediaController pipMediaController, + PipMenuActivityController pipMenuActivityController, PipTaskOrganizer pipTaskOrganizer, - PipUiEventLogger pipUiEventLogger) { + PipTouchHandler pipTouchHandler, + WindowManagerShellWrapper windowManagerShellWrapper) { // Ensure that we are the primary user's SystemUI. final int processUser = UserManager.get(context).getUserHandle(); @@ -302,28 +230,15 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac throw new IllegalStateException("Non-primary Pip component not currently supported."); } - try { - WindowManagerWrapper.getInstance().addPinnedStackListener( - new PipControllerPinnedStackListener()); - } catch (RemoteException e) { - Log.e(TAG, "Failed to register pinned stack listener", e); - } - ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskStackListener); - + mWindowManagerShellWrapper = windowManagerShellWrapper; mDisplayController = displayController; mPipBoundsHandler = pipBoundsHandler; - mPipSurfaceTransactionHelper = pipSurfaceTransactionHelper; mPipTaskOrganizer = pipTaskOrganizer; mPipTaskOrganizer.registerPipTransitionCallback(this); - mInputConsumerController = InputConsumerController.getPipInputConsumer(); - mMediaController = new PipMediaController(context, mActivityManager, broadcastDispatcher); - mMenuController = new PipMenuActivityController(context, - mMediaController, mInputConsumerController, mPipTaskOrganizer); - mTouchHandler = new PipTouchHandler(context, mActivityManager, - mMenuController, mInputConsumerController, mPipBoundsHandler, mPipTaskOrganizer, - floatingContentCoordinator, deviceConfig, sysUiState, pipUiEventLogger); - mAppOpsListener = new PipAppOpsListener(context, mActivityManager, - mTouchHandler.getMotionHelper()); + mMediaController = pipMediaController; + mMenuController = pipMenuActivityController; + mTouchHandler = pipTouchHandler; + mAppOpsListener = pipAppOpsListener; displayController.addDisplayChangingController(mRotationController); displayController.addDisplayWindowListener(mFixedRotationListener); @@ -333,26 +248,69 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac context.getDisplay().getDisplayInfo(displayInfo); mPipBoundsHandler.onDisplayInfoChanged(displayInfo); - configController.addCallback(mOverlayChangedListener); - try { - RootTaskInfo taskInfo = ActivityTaskManager.getService().getRootTaskInfo( - WINDOWING_MODE_PINNED, ACTIVITY_TYPE_UNDEFINED); - if (taskInfo != null) { - // If SystemUI restart, and it already existed a pinned stack, - // register the pip input consumer to ensure touch can send to it. - mInputConsumerController.registerInputConsumer(true /* withSfVsync */); - } - } catch (RemoteException | UnsupportedOperationException e) { - e.printStackTrace(); + mWindowManagerShellWrapper.addPinnedStackListener( + new PipControllerPinnedStackListener()); + } catch (RemoteException e) { + Log.e(TAG, "Failed to register pinned stack listener", e); } } - /** - * Updates the PIP per configuration changed. - */ - public void onConfigurationChanged(Configuration newConfig) { - mTouchHandler.onConfigurationChanged(); + @Override + public void onDensityOrFontScaleChanged() { + mHandler.post(() -> { + mPipTaskOrganizer.onDensityOrFontScaleChanged(mContext); + }); + } + + @Override + public void onActivityPinned(String packageName) { + mHandler.post(() -> { + mTouchHandler.onActivityPinned(); + mMediaController.onActivityPinned(); + mMenuController.onActivityPinned(); + mAppOpsListener.onActivityPinned(packageName); + }); + } + + @Override + public void onActivityUnpinned(ComponentName topActivity) { + mHandler.post(() -> { + mMenuController.onActivityUnpinned(); + mTouchHandler.onActivityUnpinned(topActivity); + mAppOpsListener.onActivityUnpinned(); + }); + } + + @Override + public void onActivityRestartAttempt(ActivityManager.RunningTaskInfo task, + boolean clearedTask) { + if (task.configuration.windowConfiguration.getWindowingMode() + != WINDOWING_MODE_PINNED) { + return; + } + mTouchHandler.getMotionHelper().expandLeavePip(clearedTask /* skipAnimation */); + } + + @Override + public void onOverlayChanged() { + mHandler.post(() -> { + mPipBoundsHandler.onOverlayChanged(mContext, mContext.getDisplay()); + updateMovementBounds(null /* toBounds */, + false /* fromRotation */, false /* fromImeAdjustment */, + false /* fromShelfAdjustment */, + null /* windowContainerTransaction */); + }); + } + + @Override + public void registerSessionListenerForCurrentUser() { + mMediaController.registerSessionListenerForCurrentUser(); + } + + @Override + public void onSystemUiStateChanged(boolean isValidState, int flag) { + mTouchHandler.onSystemUiStateChanged(isValidState); } /** @@ -363,6 +321,11 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac mTouchHandler.getMotionHelper().expandLeavePip(false /* skipAnimation */); } + @Override + public PipTouchHandler getPipTouchHandler() { + return mTouchHandler; + } + /** * Hides the PIP menu. */ @@ -408,8 +371,8 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac } @Override - public void setPinnedStackAnimationListener(IPinnedStackAnimationListener listener) { - mHandler.post(() -> mPinnedStackAnimationRecentsListener = listener); + public void setPinnedStackAnimationListener(Consumer<Boolean> callback) { + mHandler.post(() -> mPinnedStackAnimationRecentsCallback = callback); } @Override @@ -421,12 +384,8 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac } // Disable touches while the animation is running mTouchHandler.setTouchEnabled(false); - if (mPinnedStackAnimationRecentsListener != null) { - try { - mPinnedStackAnimationRecentsListener.onPinnedStackAnimationStarted(); - } catch (RemoteException e) { - Log.e(TAG, "Failed to callback recents", e); - } + if (mPinnedStackAnimationRecentsCallback != null) { + mPinnedStackAnimationRecentsCallback.accept(true); } } @@ -477,7 +436,6 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac public void dump(PrintWriter pw) { final String innerPrefix = " "; pw.println(TAG); - mInputConsumerController.dump(pw, innerPrefix); mMenuController.dump(pw, innerPrefix); mTouchHandler.dump(pw, innerPrefix); mPipBoundsHandler.dump(pw, innerPrefix); diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMediaController.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMediaController.java index 361aafacdf76..a5b5092ead8c 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMediaController.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMediaController.java @@ -26,19 +26,14 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.graphics.drawable.Drawable; import android.graphics.drawable.Icon; import android.media.session.MediaController; import android.media.session.MediaSession; import android.media.session.MediaSessionManager; -import android.media.session.MediaSessionManager.OnActiveSessionsChangedListener; import android.media.session.PlaybackState; import android.os.UserHandle; -import com.android.systemui.Dependency; import com.android.systemui.R; -import com.android.systemui.broadcast.BroadcastDispatcher; -import com.android.systemui.statusbar.policy.UserInfoController; import java.util.ArrayList; import java.util.Collections; @@ -101,17 +96,11 @@ public class PipMediaController { }; private final MediaSessionManager.OnActiveSessionsChangedListener mSessionsChangedListener = - new OnActiveSessionsChangedListener() { - @Override - public void onActiveSessionsChanged(List<MediaController> controllers) { - resolveActiveMediaController(controllers); - } - }; + controllers -> resolveActiveMediaController(controllers); private ArrayList<ActionListener> mListeners = new ArrayList<>(); - public PipMediaController(Context context, IActivityManager activityManager, - BroadcastDispatcher broadcastDispatcher) { + public PipMediaController(Context context, IActivityManager activityManager) { mContext = context; mActivityManager = activityManager; IntentFilter mediaControlFilter = new IntentFilter(); @@ -119,16 +108,12 @@ public class PipMediaController { mediaControlFilter.addAction(ACTION_PAUSE); mediaControlFilter.addAction(ACTION_NEXT); mediaControlFilter.addAction(ACTION_PREV); - broadcastDispatcher.registerReceiver(mPlayPauseActionReceiver, mediaControlFilter); + mContext.registerReceiver(mPlayPauseActionReceiver, mediaControlFilter, + UserHandle.USER_ALL); createMediaActions(); mMediaSessionManager = (MediaSessionManager) context.getSystemService(Context.MEDIA_SESSION_SERVICE); - - // The media session listener needs to be re-registered when switching users - UserInfoController userInfoController = Dependency.get(UserInfoController.class); - userInfoController.addCallback((String name, Drawable picture, String userAccount) -> - registerSessionListenerForCurrentUser()); } /** @@ -220,7 +205,7 @@ public class PipMediaController { /** * Re-registers the session listener for the current user. */ - private void registerSessionListenerForCurrentUser() { + public void registerSessionListenerForCurrentUser() { mMediaSessionManager.removeOnActiveSessionsChangedListener(mSessionsChangedListener); mMediaSessionManager.addOnActiveSessionsChangedListener(mSessionsChangedListener, null, UserHandle.USER_CURRENT, null); diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java index a3913aa9db93..4c86ea3aac0c 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java @@ -34,7 +34,6 @@ import android.view.WindowManager; import com.android.systemui.pip.PipTaskOrganizer; import com.android.systemui.pip.phone.PipMediaController.ActionListener; -import com.android.systemui.shared.system.InputConsumerController; import java.io.PrintWriter; import java.util.ArrayList; @@ -86,7 +85,6 @@ public class PipMenuActivityController { private Context mContext; private PipTaskOrganizer mPipTaskOrganizer; private PipMediaController mMediaController; - private InputConsumerController mInputConsumerController; private ArrayList<Listener> mListeners = new ArrayList<>(); private ParceledListSlice<RemoteAction> mAppActions; @@ -104,12 +102,9 @@ public class PipMenuActivityController { }; public PipMenuActivityController(Context context, - PipMediaController mediaController, InputConsumerController inputConsumerController, - PipTaskOrganizer pipTaskOrganizer - ) { + PipMediaController mediaController, PipTaskOrganizer pipTaskOrganizer) { mContext = context; mMediaController = mediaController; - mInputConsumerController = inputConsumerController; mPipTaskOrganizer = pipTaskOrganizer; } @@ -119,12 +114,10 @@ public class PipMenuActivityController { public void onActivityPinned() { attachPipMenuView(); - mInputConsumerController.registerInputConsumer(true /* withSfVsync */); } public void onActivityUnpinned() { hideMenu(); - mInputConsumerController.unregisterInputConsumer(); mPipTaskOrganizer.detachPipMenuViewHost(); mPipMenuView = null; } diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipResizeGestureHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipResizeGestureHandler.java index 08d9b2ae21b0..f911b4912e7a 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipResizeGestureHandler.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipResizeGestureHandler.java @@ -21,13 +21,6 @@ import static com.android.internal.policy.TaskResizingAlgorithm.CTRL_LEFT; import static com.android.internal.policy.TaskResizingAlgorithm.CTRL_NONE; import static com.android.internal.policy.TaskResizingAlgorithm.CTRL_RIGHT; import static com.android.internal.policy.TaskResizingAlgorithm.CTRL_TOP; -import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BOUNCER_SHOWING; -import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BUBBLES_EXPANDED; -import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_GLOBAL_ACTIONS_SHOWING; -import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED; -import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_QUICK_SETTINGS_EXPANDED; -import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING; -import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED; import android.content.Context; import android.content.res.Resources; @@ -50,11 +43,9 @@ import android.view.ScaleGestureDetector; import android.view.ViewConfiguration; import com.android.internal.policy.TaskResizingAlgorithm; -import com.android.systemui.model.SysUiState; import com.android.systemui.pip.PipBoundsHandler; import com.android.systemui.pip.PipTaskOrganizer; import com.android.systemui.pip.PipUiEventLogger; -import com.android.systemui.util.DeviceConfigProxy; import com.android.wm.shell.R; import java.io.PrintWriter; @@ -71,21 +62,11 @@ public class PipResizeGestureHandler { private static final float PINCH_THRESHOLD = 0.05f; private static final float STARTING_SCALE_FACTOR = 1.0f; - private static final int INVALID_SYSUI_STATE_MASK = - SYSUI_STATE_GLOBAL_ACTIONS_SHOWING - | SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING - | SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED - | SYSUI_STATE_BOUNCER_SHOWING - | SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED - | SYSUI_STATE_BUBBLES_EXPANDED - | SYSUI_STATE_QUICK_SETTINGS_EXPANDED; - private final Context mContext; private final PipBoundsHandler mPipBoundsHandler; private final PipMotionHelper mMotionHelper; private final int mDisplayId; private final Executor mMainExecutor; - private final SysUiState mSysUiState; private final ScaleGestureDetector mScaleGestureDetector; private final Region mTmpRegion = new Region(); @@ -110,6 +91,7 @@ public class PipResizeGestureHandler { private boolean mIsAttached; private boolean mIsEnabled; private boolean mEnablePinchResize; + private boolean mIsSysUiStateValid; private boolean mThresholdCrossed; private boolean mUsingPinchToZoom = false; private float mScaleFactor = STARTING_SCALE_FACTOR; @@ -123,9 +105,8 @@ public class PipResizeGestureHandler { private int mCtrlType; public PipResizeGestureHandler(Context context, PipBoundsHandler pipBoundsHandler, - PipMotionHelper motionHelper, DeviceConfigProxy deviceConfig, - PipTaskOrganizer pipTaskOrganizer, Function<Rect, Rect> movementBoundsSupplier, - Runnable updateMovementBoundsRunnable, SysUiState sysUiState, + PipMotionHelper motionHelper, PipTaskOrganizer pipTaskOrganizer, + Function<Rect, Rect> movementBoundsSupplier, Runnable updateMovementBoundsRunnable, PipUiEventLogger pipUiEventLogger, PipMenuActivityController menuActivityController) { mContext = context; mDisplayId = context.getDisplayId(); @@ -135,7 +116,6 @@ public class PipResizeGestureHandler { mPipTaskOrganizer = pipTaskOrganizer; mMovementBoundsSupplier = movementBoundsSupplier; mUpdateMovementBoundsRunnable = updateMovementBoundsRunnable; - mSysUiState = sysUiState; mPipMenuActivityController = menuActivityController; mPipUiEventLogger = pipUiEventLogger; @@ -202,7 +182,7 @@ public class PipResizeGestureHandler { DeviceConfig.NAMESPACE_SYSTEMUI, PIP_PINCH_RESIZE, /* defaultValue = */ false); - deviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_SYSTEMUI, mMainExecutor, + DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_SYSTEMUI, mMainExecutor, new DeviceConfig.OnPropertiesChangedListener() { @Override public void onPropertiesChanged(DeviceConfig.Properties properties) { @@ -218,6 +198,15 @@ public class PipResizeGestureHandler { reloadResources(); } + /** + * Called when SysUI state changed. + * + * @param isSysUiStateValid Is SysUI valid or not. + */ + public void onSystemUiStateChanged(boolean isSysUiStateValid) { + mIsSysUiStateValid = isSysUiStateValid; + } + private void reloadResources() { final Resources res = mContext.getResources(); mDelta = res.getDimensionPixelSize(R.dimen.pip_resize_edge_size); @@ -401,7 +390,7 @@ public class PipResizeGestureHandler { } private boolean isInValidSysUiState() { - return (mSysUiState.getFlags() & INVALID_SYSUI_STATE_MASK) == 0; + return mIsSysUiStateValid; } private void onDragCornerResize(MotionEvent ev) { diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java index 858683c4e2d4..6e2c046d8fb3 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java @@ -23,7 +23,6 @@ import static com.android.systemui.pip.phone.PipMenuActivityController.MENU_STAT import static com.android.systemui.pip.phone.PipMenuActivityController.MENU_STATE_NONE; import android.annotation.SuppressLint; -import android.app.IActivityManager; import android.content.ComponentName; import android.content.Context; import android.content.res.Resources; @@ -57,13 +56,10 @@ import androidx.dynamicanimation.animation.SpringForce; import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.R; -import com.android.systemui.model.SysUiState; import com.android.systemui.pip.PipAnimationController; import com.android.systemui.pip.PipBoundsHandler; import com.android.systemui.pip.PipTaskOrganizer; import com.android.systemui.pip.PipUiEventLogger; -import com.android.systemui.shared.system.InputConsumerController; -import com.android.systemui.util.DeviceConfigProxy; import com.android.systemui.util.DismissCircleView; import com.android.systemui.util.FloatingContentCoordinator; import com.android.systemui.util.animation.PhysicsAnimator; @@ -92,7 +88,6 @@ public class PipTouchHandler { private final boolean mEnableResize; private final Context mContext; private final WindowManager mWindowManager; - private final IActivityManager mActivityManager; private final PipBoundsHandler mPipBoundsHandler; private final PipUiEventLogger mPipUiEventLogger; @@ -216,18 +211,14 @@ public class PipTouchHandler { } @SuppressLint("InflateParams") - public PipTouchHandler(Context context, IActivityManager activityManager, + public PipTouchHandler(Context context, PipMenuActivityController menuController, - InputConsumerController inputConsumerController, PipBoundsHandler pipBoundsHandler, PipTaskOrganizer pipTaskOrganizer, FloatingContentCoordinator floatingContentCoordinator, - DeviceConfigProxy deviceConfig, - SysUiState sysUiState, PipUiEventLogger pipUiEventLogger) { // Initialize the Pip input consumer mContext = context; - mActivityManager = activityManager; mAccessibilityManager = context.getSystemService(AccessibilityManager.class); mPipBoundsHandler = pipBoundsHandler; mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); @@ -238,22 +229,18 @@ public class PipTouchHandler { mPipBoundsHandler.getSnapAlgorithm(), floatingContentCoordinator); mPipResizeGestureHandler = new PipResizeGestureHandler(context, pipBoundsHandler, mMotionHelper, - deviceConfig, pipTaskOrganizer, this::getMovementBounds, - this::updateMovementBounds, sysUiState, pipUiEventLogger, menuController); + pipTaskOrganizer, this::getMovementBounds, + this::updateMovementBounds, pipUiEventLogger, menuController); mTouchState = new PipTouchState(ViewConfiguration.get(context), mHandler, () -> mMenuController.showMenuWithDelay(MENU_STATE_FULL, mMotionHelper.getBounds(), true /* allowMenuTimeout */, willResizeMenu(), shouldShowResizeHandle()), - menuController::hideMenu); + menuController::hideMenu); Resources res = context.getResources(); mEnableDismissDragToEdge = res.getBoolean(R.bool.config_pipEnableDismissDragToEdge); mEnableResize = res.getBoolean(R.bool.config_pipEnableResizeForMenu); reloadResources(); - // Register the listener for input consumer touch events - inputConsumerController.setInputListener(this::handleTouchEvent); - inputConsumerController.setRegistrationListener(this::onRegistrationChanged); - mFloatingContentCoordinator = floatingContentCoordinator; mConnection = new PipAccessibilityInteractionConnection(mContext, mMotionHelper, pipTaskOrganizer, mPipBoundsHandler.getSnapAlgorithm(), @@ -320,15 +307,12 @@ public class PipTouchHandler { DeviceConfig.NAMESPACE_SYSTEMUI, PIP_STASHING, /* defaultValue = */ false); - deviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_SYSTEMUI, + DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_SYSTEMUI, context.getMainExecutor(), - new DeviceConfig.OnPropertiesChangedListener() { - @Override - public void onPropertiesChanged(DeviceConfig.Properties properties) { - if (properties.getKeyset().contains(PIP_STASHING)) { - mEnableStash = properties.getBoolean( - PIP_STASHING, /* defaultValue = */ false); - } + properties -> { + if (properties.getKeyset().contains(PIP_STASHING)) { + mEnableStash = properties.getBoolean( + PIP_STASHING, /* defaultValue = */ false); } }); } @@ -438,6 +422,15 @@ public class PipTouchHandler { mShelfHeight = shelfHeight; } + /** + * Called when SysUI state changed. + * + * @param isSysUiStateValid Is SysUI valid or not. + */ + public void onSystemUiStateChanged(boolean isSysUiStateValid) { + mPipResizeGestureHandler.onSystemUiStateChanged(isSysUiStateValid); + } + public void adjustBoundsForRotation(Rect outBounds, Rect curBounds, Rect insetBounds) { final Rect toMovementBounds = new Rect(); mPipBoundsHandler.getSnapAlgorithm().getMovementBounds(outBounds, insetBounds, @@ -648,7 +641,10 @@ public class PipTouchHandler { } } - private void onRegistrationChanged(boolean isRegistered) { + /** + * TODO Add appropriate description + */ + public void onRegistrationChanged(boolean isRegistered) { mAccessibilityManager.setPictureInPictureActionReplacingConnection(isRegistered ? mConnection : null); if (!isRegistered && mTouchState.isUserInteracting()) { @@ -664,7 +660,10 @@ public class PipTouchHandler { shouldShowResizeHandle()); } - private boolean handleTouchEvent(InputEvent inputEvent) { + /** + * TODO Add appropriate description + */ + public boolean handleTouchEvent(InputEvent inputEvent) { // Skip any non motion events if (!(inputEvent instanceof MotionEvent)) { return true; diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipController.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipController.java index 12a545aa4b02..6ac4e4cbd80d 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipController.java +++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipController.java @@ -20,7 +20,7 @@ import static android.app.ActivityTaskManager.INVALID_STACK_ID; import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; -import android.app.ActivityManager.RunningTaskInfo; +import android.app.ActivityManager; import android.app.ActivityTaskManager; import android.app.ActivityTaskManager.RootTaskInfo; import android.app.IActivityTaskManager; @@ -45,23 +45,16 @@ import android.text.TextUtils; import android.util.Log; import android.view.DisplayInfo; -import com.android.systemui.Dependency; import com.android.systemui.R; -import com.android.systemui.UiOffloadThread; -import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.pip.Pip; import com.android.systemui.pip.PipBoundsHandler; -import com.android.systemui.pip.PipSurfaceTransactionHelper; import com.android.systemui.pip.PipTaskOrganizer; -import com.android.systemui.shared.system.ActivityManagerWrapper; -import com.android.systemui.shared.system.PinnedStackListenerForwarder.PinnedStackListener; -import com.android.systemui.shared.system.TaskStackChangeListener; -import com.android.systemui.shared.system.WindowManagerWrapper; +import com.android.systemui.shared.system.PinnedStackListenerForwarder; +import com.android.systemui.wmshell.WindowManagerShellWrapper; import java.util.ArrayList; import java.util.List; -import java.util.Optional; /** * Manages the picture-in-picture (PIP) UI and states. @@ -113,7 +106,6 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac private Context mContext; private PipBoundsHandler mPipBoundsHandler; private PipTaskOrganizer mPipTaskOrganizer; - private PipSurfaceTransactionHelper mPipSurfaceTransactionHelper; private IActivityTaskManager mActivityTaskManager; private MediaSessionManager mMediaSessionManager; private int mState = STATE_NO_PIP; @@ -133,6 +125,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac private String[] mLastPackagesResourceGranted; private PipNotification mPipNotification; private ParceledListSlice<RemoteAction> mCustomActions; + private WindowManagerShellWrapper mWindowManagerShellWrapper; private int mResizeAnimationDuration; // Used to calculate the movement bounds @@ -143,21 +136,9 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac private boolean mImeVisible; private int mImeHeightAdjustment; - private final PinnedStackListener mPinnedStackListener = new PipControllerPinnedStackListener(); - - private final Runnable mResizePinnedStackRunnable = new Runnable() { - @Override - public void run() { - resizePinnedStack(mResumeResizePinnedStackRunnableState); - } - }; - private final Runnable mClosePipRunnable = new Runnable() { - @Override - public void run() { - closePip(); - } - }; - + private final Runnable mResizePinnedStackRunnable = + () -> resizePinnedStack(mResumeResizePinnedStackRunnableState); + private final Runnable mClosePipRunnable = () -> closePip(); private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { @@ -175,17 +156,23 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac } }; private final MediaSessionManager.OnActiveSessionsChangedListener mActiveMediaSessionListener = - new MediaSessionManager.OnActiveSessionsChangedListener() { - @Override - public void onActiveSessionsChanged(List<MediaController> controllers) { - updateMediaController(controllers); - } - }; + controllers -> updateMediaController(controllers); + private final PinnedStackListenerForwarder.PinnedStackListener mPinnedStackListener = + new PipControllerPinnedStackListener(); + + @Override + public void registerSessionListenerForCurrentUser() { + // TODO Need confirm if TV have to re-registers when switch user + mMediaSessionManager.removeOnActiveSessionsChangedListener(mActiveMediaSessionListener); + mMediaSessionManager.addOnActiveSessionsChangedListener(mActiveMediaSessionListener, null, + UserHandle.USER_CURRENT, null); + } /** * Handler for messages from the PIP controller. */ - private class PipControllerPinnedStackListener extends PinnedStackListener { + private class PipControllerPinnedStackListener extends + PinnedStackListenerForwarder.PinnedStackListener { @Override public void onImeVisibilityChanged(boolean imeVisible, int imeHeight) { mHandler.post(() -> { @@ -227,18 +214,18 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac } } - public PipController(Context context, BroadcastDispatcher broadcastDispatcher, + public PipController(Context context, PipBoundsHandler pipBoundsHandler, - PipSurfaceTransactionHelper pipSurfaceTransactionHelper, - PipTaskOrganizer pipTaskOrganizer) { + PipTaskOrganizer pipTaskOrganizer, + WindowManagerShellWrapper windowManagerShellWrapper + ) { if (mInitialized) { return; } mInitialized = true; mContext = context; - mPipNotification = new PipNotification(context, broadcastDispatcher, - Optional.of(this).get()); + mPipNotification = new PipNotification(context, this); mPipBoundsHandler = pipBoundsHandler; // Ensure that we have the display info in case we get calls to update the bounds before the // listener calls back @@ -248,15 +235,12 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac mResizeAnimationDuration = context.getResources() .getInteger(R.integer.config_pipResizeAnimationDuration); - mPipSurfaceTransactionHelper = pipSurfaceTransactionHelper; mPipTaskOrganizer = pipTaskOrganizer; mPipTaskOrganizer.registerPipTransitionCallback(this); mActivityTaskManager = ActivityTaskManager.getService(); - ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskStackListener); IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(Intent.ACTION_MEDIA_RESOURCE_GRANTED); - broadcastDispatcher.registerReceiver(mBroadcastReceiver, intentFilter, - null /* handler */, UserHandle.ALL); + mContext.registerReceiver(mBroadcastReceiver, intentFilter, UserHandle.USER_ALL); // Initialize the last orientation and apply the current configuration Configuration initialConfig = mContext.getResources().getConfiguration(); @@ -265,10 +249,10 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac mMediaSessionManager = (MediaSessionManager) mContext.getSystemService(Context.MEDIA_SESSION_SERVICE); - + mWindowManagerShellWrapper = windowManagerShellWrapper; try { - WindowManagerWrapper.getInstance().addPinnedStackListener(mPinnedStackListener); - } catch (RemoteException | UnsupportedOperationException e) { + mWindowManagerShellWrapper.addPinnedStackListener(mPinnedStackListener); + } catch (RemoteException e) { Log.e(TAG, "Failed to register pinned stack listener", e); } } @@ -344,7 +328,6 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac mListeners.get(i).onPipActivityClosed(); } mHandler.removeCallbacks(mClosePipRunnable); - updatePipVisibility(false); } /** @@ -358,7 +341,77 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac mListeners.get(i).onMoveToFullscreen(); } resizePinnedStack(STATE_NO_PIP); - updatePipVisibility(false); + } + + @Override + public void onActivityPinned(String packageName) { + if (DEBUG) Log.d(TAG, "onActivityPinned()"); + + RootTaskInfo taskInfo = getPinnedTaskInfo(); + if (taskInfo == null) { + Log.w(TAG, "Cannot find pinned stack"); + return; + } + if (DEBUG) Log.d(TAG, "PINNED_STACK:" + taskInfo); + mPinnedStackId = taskInfo.taskId; + mPipTaskId = taskInfo.childTaskIds[taskInfo.childTaskIds.length - 1]; + mPipComponentName = ComponentName.unflattenFromString( + taskInfo.childTaskNames[taskInfo.childTaskNames.length - 1]); + // Set state to STATE_PIP so we show it when the pinned stack animation ends. + mState = STATE_PIP; + mMediaSessionManager.addOnActiveSessionsChangedListener( + mActiveMediaSessionListener, null); + updateMediaController(mMediaSessionManager.getActiveSessions(null)); + for (int i = mListeners.size() - 1; i >= 0; i--) { + mListeners.get(i).onPipEntered(packageName); + } + } + + @Override + public void onActivityRestartAttempt(ActivityManager.RunningTaskInfo task, + boolean clearedTask) { + if (task.configuration.windowConfiguration.getWindowingMode() + != WINDOWING_MODE_PINNED) { + return; + } + if (DEBUG) Log.d(TAG, "onPinnedActivityRestartAttempt()"); + + // If PIPed activity is launched again by Launcher or intent, make it fullscreen. + movePipToFullscreen(); + } + + @Override + public void onTaskStackChanged() { + if (DEBUG) Log.d(TAG, "onTaskStackChanged()"); + + if (getState() != STATE_NO_PIP) { + boolean hasPip = false; + + RootTaskInfo taskInfo = getPinnedTaskInfo(); + if (taskInfo == null || taskInfo.childTaskIds == null) { + Log.w(TAG, "There is nothing in pinned stack"); + closePipInternal(false); + return; + } + for (int i = taskInfo.childTaskIds.length - 1; i >= 0; --i) { + if (taskInfo.childTaskIds[i] == mPipTaskId) { + // PIP task is still alive. + hasPip = true; + break; + } + } + if (!hasPip) { + // PIP task doesn't exist anymore in PINNED_STACK. + closePipInternal(true); + return; + } + } + if (getState() == STATE_PIP) { + if (mPipBounds != mDefaultPipBounds) { + mPipBounds = mDefaultPipBounds; + resizePinnedStack(STATE_PIP); + } + } } /** @@ -603,80 +656,6 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac return PLAYBACK_STATE_UNAVAILABLE; } - private TaskStackChangeListener mTaskStackListener = new TaskStackChangeListener() { - @Override - public void onTaskStackChanged() { - if (DEBUG) Log.d(TAG, "onTaskStackChanged()"); - - if (getState() != STATE_NO_PIP) { - boolean hasPip = false; - - RootTaskInfo taskInfo = getPinnedTaskInfo(); - if (taskInfo == null || taskInfo.childTaskIds == null) { - Log.w(TAG, "There is nothing in pinned stack"); - closePipInternal(false); - return; - } - for (int i = taskInfo.childTaskIds.length - 1; i >= 0; --i) { - if (taskInfo.childTaskIds[i] == mPipTaskId) { - // PIP task is still alive. - hasPip = true; - break; - } - } - if (!hasPip) { - // PIP task doesn't exist anymore in PINNED_STACK. - closePipInternal(true); - return; - } - } - if (getState() == STATE_PIP) { - if (mPipBounds != mDefaultPipBounds) { - mPipBounds = mDefaultPipBounds; - resizePinnedStack(STATE_PIP); - } - } - } - - @Override - public void onActivityPinned(String packageName, int userId, int taskId, int stackId) { - if (DEBUG) Log.d(TAG, "onActivityPinned()"); - - RootTaskInfo taskInfo = getPinnedTaskInfo(); - if (taskInfo == null) { - Log.w(TAG, "Cannot find pinned stack"); - return; - } - if (DEBUG) Log.d(TAG, "PINNED_STACK:" + taskInfo); - mPinnedStackId = taskInfo.taskId; - mPipTaskId = taskInfo.childTaskIds[taskInfo.childTaskIds.length - 1]; - mPipComponentName = ComponentName.unflattenFromString( - taskInfo.childTaskNames[taskInfo.childTaskNames.length - 1]); - // Set state to STATE_PIP so we show it when the pinned stack animation ends. - mState = STATE_PIP; - mMediaSessionManager.addOnActiveSessionsChangedListener( - mActiveMediaSessionListener, null); - updateMediaController(mMediaSessionManager.getActiveSessions(null)); - for (int i = mListeners.size() - 1; i >= 0; i--) { - mListeners.get(i).onPipEntered(packageName); - } - updatePipVisibility(true); - } - - @Override - public void onActivityRestartAttempt(RunningTaskInfo task, boolean homeTaskVisible, - boolean clearedTask, boolean wasVisible) { - if (task.configuration.windowConfiguration.getWindowingMode() - != WINDOWING_MODE_PINNED) { - return; - } - if (DEBUG) Log.d(TAG, "onPinnedActivityRestartAttempt()"); - - // If PIPed activity is launched again by Launcher or intent, make it fullscreen. - movePipToFullscreen(); - } - }; - @Override public void onPipTransitionStarted(ComponentName activity, int direction, Rect pipBounds) { } @@ -730,12 +709,6 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac void onMediaControllerChanged(); } - private void updatePipVisibility(final boolean visible) { - Dependency.get(UiOffloadThread.class).execute(() -> { - WindowManagerWrapper.getInstance().setPipVisibility(visible); - }); - } - private String getStateDescription() { if (mSuspendPipResizingReason == 0) { return stateToName(mState); diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipControlsViewController.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipControlsViewController.java index 2f4df1fcbe20..8c04a52987c4 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipControlsViewController.java +++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipControlsViewController.java @@ -147,9 +147,10 @@ public class PipControlsViewController { return; } mPipOptional.ifPresent(pip -> { - if (pip.getPlaybackState() == PipController.PLAYBACK_STATE_PAUSED) { + final int playbackState = pip.getPlaybackState(); + if (playbackState == PipController.PLAYBACK_STATE_PAUSED) { mMediaController.getTransportControls().play(); - } else if (pip.getPlaybackState() == PipController.PLAYBACK_STATE_PLAYING) { + } else if (playbackState == PipController.PLAYBACK_STATE_PLAYING) { mMediaController.getTransportControls().pause(); } }); diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipNotification.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipNotification.java index 78569edf009d..0666811db3da 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipNotification.java +++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipNotification.java @@ -32,11 +32,11 @@ import android.graphics.Bitmap; import android.media.MediaMetadata; import android.media.session.MediaController; import android.media.session.PlaybackState; +import android.os.UserHandle; import android.text.TextUtils; import android.util.Log; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; -import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.util.NotificationChannels; import com.android.wm.shell.R; @@ -163,8 +163,7 @@ public class PipNotification { } }; - public PipNotification(Context context, BroadcastDispatcher broadcastDispatcher, - PipController pipController) { + public PipNotification(Context context, PipController pipController) { mPackageManager = context.getPackageManager(); mNotificationManager = (NotificationManager) context.getSystemService( @@ -185,7 +184,7 @@ public class PipNotification { IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(ACTION_MENU); intentFilter.addAction(ACTION_CLOSE); - broadcastDispatcher.registerReceiver(mEventReceiver, intentFilter); + context.registerReceiver(mEventReceiver, intentFilter, UserHandle.USER_ALL); onConfigurationChanged(context); } diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/dagger/TvPipModule.java b/packages/SystemUI/src/com/android/systemui/pip/tv/dagger/TvPipModule.java index e8e392069ea7..f094854308bc 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/tv/dagger/TvPipModule.java +++ b/packages/SystemUI/src/com/android/systemui/pip/tv/dagger/TvPipModule.java @@ -19,7 +19,6 @@ package com.android.systemui.pip.tv.dagger; import android.app.Activity; import android.content.Context; -import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.pip.Pip; import com.android.systemui.pip.PipBoundsHandler; @@ -29,6 +28,7 @@ import com.android.systemui.pip.PipUiEventLogger; import com.android.systemui.pip.tv.PipController; import com.android.systemui.pip.tv.PipMenuActivity; import com.android.systemui.pip.tv.PipNotification; +import com.android.systemui.wmshell.WindowManagerShellWrapper; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.splitscreen.SplitScreen; @@ -56,20 +56,18 @@ public abstract class TvPipModule { @SysUISingleton @Provides static Pip providePipController(Context context, - BroadcastDispatcher broadcastDispatcher, PipBoundsHandler pipBoundsHandler, - PipSurfaceTransactionHelper pipSurfaceTransactionHelper, - PipTaskOrganizer pipTaskOrganizer) { - return new PipController(context, broadcastDispatcher, pipBoundsHandler, - pipSurfaceTransactionHelper, pipTaskOrganizer); + PipTaskOrganizer pipTaskOrganizer, + WindowManagerShellWrapper windowManagerShellWrapper) { + return new PipController(context, pipBoundsHandler, pipTaskOrganizer, + windowManagerShellWrapper); } @SysUISingleton @Provides static PipNotification providePipNotification(Context context, - BroadcastDispatcher broadcastDispatcher, PipController pipController) { - return new PipNotification(context, broadcastDispatcher, pipController); + return new PipNotification(context, pipController); } @SysUISingleton diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java index ed8da7c3d80b..aa435165d3f3 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java +++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java @@ -102,6 +102,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.function.BiConsumer; +import java.util.function.Consumer; import javax.inject.Inject; @@ -142,6 +143,7 @@ public class OverviewProxyService extends CurrentUserTracker implements private Region mActiveNavBarRegion; + private IPinnedStackAnimationListener mIPinnedStackAnimationListener; private IOverviewProxy mOverviewProxy; private int mConnectionBackoffAttempts; private boolean mBound; @@ -158,7 +160,6 @@ public class OverviewProxyService extends CurrentUserTracker implements @VisibleForTesting public ISystemUiProxy mSysUiProxy = new ISystemUiProxy.Stub() { - @Override public void startScreenPinning(int taskId) { if (!verifyCaller("startScreenPinning")) { @@ -438,10 +439,11 @@ public class OverviewProxyService extends CurrentUserTracker implements + mHasPipFeature); return; } + mIPinnedStackAnimationListener = listener; long token = Binder.clearCallingIdentity(); try { mPipOptional.ifPresent( - pip -> pip.setPinnedStackAnimationListener(listener)); + pip -> pip.setPinnedStackAnimationListener(mPinnedStackAnimationCallback)); } finally { Binder.restoreCallingIdentity(token); } @@ -607,6 +609,8 @@ public class OverviewProxyService extends CurrentUserTracker implements private final StatusBarWindowCallback mStatusBarWindowCallback = this::onStatusBarStateChanged; private final BiConsumer<Rect, Rect> mSplitScreenBoundsChangeListener = this::notifySplitScreenBoundsChanged; + private final Consumer<Boolean> mPinnedStackAnimationCallback = + this::notifyPinnedStackAnimationStarted; // This is the death handler for the binder from the launcher service private final IBinder.DeathRecipient mOverviewServiceDeathRcpt @@ -736,6 +740,17 @@ public class OverviewProxyService extends CurrentUserTracker implements } } + private void notifyPinnedStackAnimationStarted(Boolean isAnimationStarted) { + if (mIPinnedStackAnimationListener == null) { + return; + } + try { + mIPinnedStackAnimationListener.onPinnedStackAnimationStarted(); + } catch (RemoteException e) { + Log.e(TAG_OPS, "Failed to call onPinnedStackAnimationStarted()", e); + } + } + private void onStatusBarStateChanged(boolean keyguardShowing, boolean keyguardOccluded, boolean bouncerShowing) { mSysUiState.setFlag(SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING, @@ -766,7 +781,7 @@ public class OverviewProxyService extends CurrentUserTracker implements public void cleanupAfterDeath() { if (mInputFocusTransferStarted) { - mHandler.post(()-> { + mHandler.post(() -> { mStatusBarOptionalLazy.ifPresent(statusBarLazy -> { mInputFocusTransferStarted = false; statusBarLazy.get().onInputFocusTransfer(false, true /* cancel */, diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/TvWMShellModule.java b/packages/SystemUI/src/com/android/systemui/wmshell/TvWMShellModule.java index 524eca389ceb..d6595b2323bf 100644 --- a/packages/SystemUI/src/com/android/systemui/wmshell/TvWMShellModule.java +++ b/packages/SystemUI/src/com/android/systemui/wmshell/TvWMShellModule.java @@ -49,8 +49,6 @@ public class TvWMShellModule { return new DisplayImeController(wmService, displayController, mainHandler, transactionPool); } - @SysUISingleton - @Provides static SplitScreen provideSplitScreen(Context context, DisplayController displayController, SystemWindows systemWindows, DisplayImeController displayImeController, @Main Handler handler, diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java index a3512bec6605..250c59262c4d 100644 --- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java +++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java @@ -16,24 +16,40 @@ package com.android.systemui.wmshell; +import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; +import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON; +import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BOUNCER_SHOWING; +import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BUBBLES_EXPANDED; +import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_GLOBAL_ACTIONS_SHOWING; +import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_ONE_HANDED_ACTIVE; +import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_QUICK_SETTINGS_EXPANDED; +import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING; +import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED; import static com.android.systemui.shared.system.WindowManagerWrapper.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; import android.app.ActivityManager; +import android.app.ActivityTaskManager; +import android.app.ActivityTaskManager.RootTaskInfo; import android.content.ComponentName; import android.content.Context; import android.graphics.Rect; +import android.graphics.drawable.Drawable; import android.inputmethodservice.InputMethodService; import android.os.IBinder; import android.os.ParcelFileDescriptor; +import android.os.RemoteException; +import android.util.Log; +import android.util.Pair; import android.view.KeyEvent; import com.android.internal.annotations.VisibleForTesting; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.KeyguardUpdateMonitorCallback; +import com.android.systemui.Dependency; import com.android.systemui.SystemUI; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.keyguard.ScreenLifecycle; @@ -42,9 +58,12 @@ import com.android.systemui.navigationbar.NavigationModeController; import com.android.systemui.pip.Pip; import com.android.systemui.pip.phone.PipUtils; import com.android.systemui.shared.system.ActivityManagerWrapper; +import com.android.systemui.shared.system.InputConsumerController; import com.android.systemui.shared.system.TaskStackChangeListener; import com.android.systemui.shared.tracing.ProtoTraceable; import com.android.systemui.statusbar.CommandQueue; +import com.android.systemui.statusbar.policy.ConfigurationController; +import com.android.systemui.statusbar.policy.UserInfoController; import com.android.systemui.tracing.ProtoTracer; import com.android.systemui.tracing.nano.SystemUiTraceProto; import com.android.wm.shell.ShellTaskOrganizer; @@ -70,8 +89,20 @@ import javax.inject.Inject; @SysUISingleton public final class WMShell extends SystemUI implements CommandQueue.Callbacks, ProtoTraceable<SystemUiTraceProto> { + private static final String TAG = WMShell.class.getName(); + private static final int INVALID_SYSUI_STATE_MASK = + SYSUI_STATE_GLOBAL_ACTIONS_SHOWING + | SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING + | SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED + | SYSUI_STATE_BOUNCER_SHOWING + | SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED + | SYSUI_STATE_BUBBLES_EXPANDED + | SYSUI_STATE_QUICK_SETTINGS_EXPANDED; + private final CommandQueue mCommandQueue; + private final ConfigurationController mConfigurationController; private final DisplayImeController mDisplayImeController; + private final InputConsumerController mInputConsumerController; private final KeyguardUpdateMonitor mKeyguardUpdateMonitor; private final ActivityManagerWrapper mActivityManagerWrapper; private final NavigationModeController mNavigationModeController; @@ -84,13 +115,15 @@ public final class WMShell extends SystemUI // are non-optional windowing features like FULLSCREEN. private final ShellTaskOrganizer mShellTaskOrganizer; private final ProtoTracer mProtoTracer; - + private boolean mIsSysUiStateValid; private KeyguardUpdateMonitorCallback mSplitScreenKeyguardCallback; private KeyguardUpdateMonitorCallback mPipKeyguardCallback; private KeyguardUpdateMonitorCallback mOneHandedKeyguardCallback; @Inject public WMShell(Context context, CommandQueue commandQueue, + ConfigurationController configurationController, + InputConsumerController inputConsumerController, KeyguardUpdateMonitor keyguardUpdateMonitor, ActivityManagerWrapper activityManagerWrapper, DisplayImeController displayImeController, @@ -104,6 +137,8 @@ public final class WMShell extends SystemUI ProtoTracer protoTracer) { super(context); mCommandQueue = commandQueue; + mConfigurationController = configurationController; + mInputConsumerController = inputConsumerController; mKeyguardUpdateMonitor = keyguardUpdateMonitor; mActivityManagerWrapper = activityManagerWrapper; mDisplayImeController = displayImeController; @@ -141,6 +176,7 @@ public final class WMShell extends SystemUI pip.showPictureInPictureMenu(); } }); + mPipKeyguardCallback = new KeyguardUpdateMonitorCallback() { @Override public void onKeyguardVisibilityChanged(boolean showing) { @@ -150,6 +186,80 @@ public final class WMShell extends SystemUI } }; mKeyguardUpdateMonitor.registerCallback(mPipKeyguardCallback); + + mSysUiState.addCallback(sysUiStateFlag -> { + mIsSysUiStateValid = (sysUiStateFlag & INVALID_SYSUI_STATE_MASK) == 0; + pip.onSystemUiStateChanged(mIsSysUiStateValid, sysUiStateFlag); + }); + + mConfigurationController.addCallback(new ConfigurationController.ConfigurationListener() { + @Override + public void onDensityOrFontScaleChanged() { + pip.onDensityOrFontScaleChanged(); + } + + @Override + public void onOverlayChanged() { + pip.onOverlayChanged(); + } + }); + + // Handle for system task stack changes. + mActivityManagerWrapper.registerTaskStackListener( + new TaskStackChangeListener() { + @Override + public void onTaskStackChanged() { + pip.onTaskStackChanged(); + } + + @Override + public void onActivityPinned(String packageName, int userId, int taskId, + int stackId) { + pip.onActivityPinned(packageName); + mInputConsumerController.registerInputConsumer(true /* withSfVsync */); + } + + @Override + public void onActivityUnpinned() { + final Pair<ComponentName, Integer> topPipActivityInfo = + PipUtils.getTopPipActivity( + mContext, ActivityManager.getService()); + final ComponentName topActivity = topPipActivityInfo.first; + pip.onActivityUnpinned(topActivity); + mInputConsumerController.unregisterInputConsumer(); + } + + @Override + public void onActivityRestartAttempt(ActivityManager.RunningTaskInfo task, + boolean homeTaskVisible, boolean clearedTask, boolean wasVisible) { + pip.onActivityRestartAttempt(task, clearedTask); + } + }); + + try { + RootTaskInfo taskInfo = ActivityTaskManager.getService().getRootTaskInfo( + WINDOWING_MODE_PINNED, ACTIVITY_TYPE_UNDEFINED); + if (taskInfo != null) { + // If SystemUI restart, and it already existed a pinned stack, + // register the pip input consumer to ensure touch can send to it. + mInputConsumerController.registerInputConsumer(true /* withSfVsync */); + } + } catch (RemoteException | UnsupportedOperationException e) { + Log.e(TAG, "Failed to register pinned stack listener", e); + e.printStackTrace(); + } + + // Register the listener for input consumer touch events. Only for Phone + if (pip.getPipTouchHandler() != null) { + mInputConsumerController.setInputListener(pip.getPipTouchHandler()::handleTouchEvent); + mInputConsumerController.setRegistrationListener( + pip.getPipTouchHandler()::onRegistrationChanged); + } + + // The media session listener needs to be re-registered when switching users + UserInfoController userInfoController = Dependency.get(UserInfoController.class); + userInfoController.addCallback((String name, Drawable picture, String userAccount) -> + pip.registerSessionListenerForCurrentUser()); } @VisibleForTesting diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java index 7c129ac92fe3..ae96829379e9 100644 --- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java +++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java @@ -16,6 +16,7 @@ package com.android.systemui.wmshell; +import android.app.IActivityManager; import android.content.Context; import android.content.pm.PackageManager; import android.os.Handler; @@ -28,7 +29,10 @@ import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.pip.Pip; import com.android.systemui.pip.PipSurfaceTransactionHelper; import com.android.systemui.pip.PipUiEventLogger; -import com.android.systemui.statusbar.policy.ConfigurationController; +import com.android.systemui.pip.phone.PipAppOpsListener; +import com.android.systemui.pip.phone.PipMediaController; +import com.android.systemui.pip.phone.PipTouchHandler; +import com.android.systemui.shared.system.InputConsumerController; import com.android.systemui.util.DeviceConfigProxy; import com.android.systemui.util.FloatingContentCoordinator; import com.android.wm.shell.ShellTaskOrganizer; @@ -71,12 +75,33 @@ public abstract class WMShellBaseModule { @SysUISingleton @Provides + static InputConsumerController provideInputConsumerController() { + return InputConsumerController.getPipInputConsumer(); + } + + @SysUISingleton + @Provides static FloatingContentCoordinator provideFloatingContentCoordinator() { return new FloatingContentCoordinator(); } @SysUISingleton @Provides + static PipAppOpsListener providesPipAppOpsListener(Context context, + IActivityManager activityManager, + PipTouchHandler pipTouchHandler) { + return new PipAppOpsListener(context, activityManager, pipTouchHandler.getMotionHelper()); + } + + @SysUISingleton + @Provides + static PipMediaController providesPipMediaController(Context context, + IActivityManager activityManager) { + return new PipMediaController(context, activityManager); + } + + @SysUISingleton + @Provides static PipUiEventLogger providePipUiEventLogger(UiEventLogger uiEventLogger, PackageManager packageManager) { return new PipUiEventLogger(uiEventLogger, packageManager); @@ -84,9 +109,8 @@ public abstract class WMShellBaseModule { @SysUISingleton @Provides - static PipSurfaceTransactionHelper providesPipSurfaceTransactionHelper(Context context, - ConfigurationController configController) { - return new PipSurfaceTransactionHelper(context, configController); + static PipSurfaceTransactionHelper providesPipSurfaceTransactionHelper(Context context) { + return new PipSurfaceTransactionHelper(context); } @SysUISingleton @@ -106,6 +130,12 @@ public abstract class WMShellBaseModule { @SysUISingleton @Provides + static WindowManagerShellWrapper provideWindowManagerShellWrapper() { + return new WindowManagerShellWrapper(); + } + + @SysUISingleton + @Provides static FlingAnimationUtils.Builder provideFlingAnimationUtilsBuilder( DisplayMetrics displayMetrics) { return new FlingAnimationUtils.Builder(displayMetrics); diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java index 16fb2cacc950..6ed836c3b954 100644 --- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java +++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java @@ -20,18 +20,18 @@ import android.content.Context; import android.os.Handler; import android.view.IWindowManager; -import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Main; -import com.android.systemui.model.SysUiState; import com.android.systemui.pip.Pip; import com.android.systemui.pip.PipBoundsHandler; import com.android.systemui.pip.PipSurfaceTransactionHelper; import com.android.systemui.pip.PipTaskOrganizer; import com.android.systemui.pip.PipUiEventLogger; +import com.android.systemui.pip.phone.PipAppOpsListener; import com.android.systemui.pip.phone.PipController; -import com.android.systemui.statusbar.policy.ConfigurationController; -import com.android.systemui.util.DeviceConfigProxy; +import com.android.systemui.pip.phone.PipMediaController; +import com.android.systemui.pip.phone.PipMenuActivityController; +import com.android.systemui.pip.phone.PipTouchHandler; import com.android.systemui.util.FloatingContentCoordinator; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.common.DisplayController; @@ -66,21 +66,17 @@ public class WMShellModule { @SysUISingleton @Provides static Pip providePipController(Context context, - BroadcastDispatcher broadcastDispatcher, - ConfigurationController configController, - DeviceConfigProxy deviceConfig, DisplayController displayController, - FloatingContentCoordinator floatingContentCoordinator, - SysUiState sysUiState, + PipAppOpsListener pipAppOpsListener, PipBoundsHandler pipBoundsHandler, - PipSurfaceTransactionHelper surfaceTransactionHelper, + PipMediaController pipMediaController, + PipMenuActivityController pipMenuActivityController, PipTaskOrganizer pipTaskOrganizer, - PipUiEventLogger pipUiEventLogger) { - return new PipController(context, broadcastDispatcher, configController, deviceConfig, - displayController, floatingContentCoordinator, sysUiState, pipBoundsHandler, - surfaceTransactionHelper, - pipTaskOrganizer, - pipUiEventLogger); + PipTouchHandler pipTouchHandler, + WindowManagerShellWrapper windowManagerShellWrapper) { + return new PipController(context, displayController, + pipAppOpsListener, pipBoundsHandler, pipMediaController, pipMenuActivityController, + pipTaskOrganizer, pipTouchHandler, windowManagerShellWrapper); } @SysUISingleton @@ -101,6 +97,24 @@ public class WMShellModule { @SysUISingleton @Provides + static PipMenuActivityController providesPipMenuActivityController(Context context, + PipMediaController pipMediaController, PipTaskOrganizer pipTaskOrganizer) { + return new PipMenuActivityController(context, pipMediaController, pipTaskOrganizer); + } + + @SysUISingleton + @Provides + static PipTouchHandler providesPipTouchHandler(Context context, + PipMenuActivityController menuActivityController, PipBoundsHandler pipBoundsHandler, + PipTaskOrganizer pipTaskOrganizer, + FloatingContentCoordinator floatingContentCoordinator, + PipUiEventLogger pipUiEventLogger) { + return new PipTouchHandler(context, menuActivityController, pipBoundsHandler, + pipTaskOrganizer, floatingContentCoordinator, pipUiEventLogger); + } + + @SysUISingleton + @Provides static PipTaskOrganizer providesPipTaskOrganizer(Context context, PipBoundsHandler pipBoundsHandler, PipSurfaceTransactionHelper pipSurfaceTransactionHelper, diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WindowManagerShellWrapper.java b/packages/SystemUI/src/com/android/systemui/wmshell/WindowManagerShellWrapper.java new file mode 100644 index 000000000000..178d472cfbee --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/wmshell/WindowManagerShellWrapper.java @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.wmshell; + +import static android.view.Display.DEFAULT_DISPLAY; + +import android.app.WindowConfiguration; +import android.os.RemoteException; +import android.view.WindowManagerGlobal; + +import com.android.systemui.shared.system.PinnedStackListenerForwarder; + +/** + * The singleton wrapper to communicate between WindowManagerService and WMShell features + * (e.g: PIP, SplitScreen, Bubble, OneHandedMode...etc) + */ +public class WindowManagerShellWrapper { + private static final String TAG = WindowManagerShellWrapper.class.getSimpleName(); + + public static final int WINDOWING_MODE_PINNED = WindowConfiguration.WINDOWING_MODE_PINNED; + + /** + * Forwarder to which we can add multiple pinned stack listeners. Each listener will receive + * updates from the window manager service. + */ + private PinnedStackListenerForwarder mPinnedStackListenerForwarder = + new PinnedStackListenerForwarder(); + + /** + * Adds a pinned stack listener, which will receive updates from the window manager service + * along with any other pinned stack listeners that were added via this method. + */ + public void addPinnedStackListener(PinnedStackListenerForwarder.PinnedStackListener listener) + throws + RemoteException { + mPinnedStackListenerForwarder.addListener(listener); + WindowManagerGlobal.getWindowManagerService().registerPinnedStackListener( + DEFAULT_DISPLAY, mPinnedStackListenerForwarder); + } + + /** + * Removes a pinned stack listener. + */ + public void removePinnedStackListener( + PinnedStackListenerForwarder.PinnedStackListener listener) { + mPinnedStackListenerForwarder.removeListener(listener); + } + +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java index f65c2c91c50a..3b8f1bb54d79 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java @@ -92,6 +92,7 @@ import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.statusbar.policy.ZenModeController; import com.android.systemui.util.FloatingContentCoordinator; +import com.android.systemui.wmshell.WindowManagerShellWrapper; import com.google.common.collect.ImmutableList; @@ -191,6 +192,8 @@ public class BubbleControllerTest extends SysuiTestCase { private LauncherApps mLauncherApps; @Mock private LockscreenLockIconController mLockIconController; + @Mock private WindowManagerShellWrapper mWindowManagerShellWrapper; + private BubbleData mBubbleData; private TestableLooper mTestableLooper; @@ -269,6 +272,7 @@ public class BubbleControllerTest extends SysuiTestCase { mock(INotificationManager.class), mStatusBarService, mWindowManager, + mWindowManagerShellWrapper, mLauncherApps); mBubbleController.setExpandListener(mBubbleExpandListener); diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/NewNotifPipelineBubbleControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/NewNotifPipelineBubbleControllerTest.java index dd191e9cd328..cfbd398ec6a4 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/NewNotifPipelineBubbleControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/NewNotifPipelineBubbleControllerTest.java @@ -92,6 +92,7 @@ import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.statusbar.policy.ZenModeController; import com.android.systemui.util.FloatingContentCoordinator; import com.android.systemui.util.InjectionInflationController; +import com.android.systemui.wmshell.WindowManagerShellWrapper; import org.junit.Before; import org.junit.Ignore; @@ -185,6 +186,8 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { private IStatusBarService mStatusBarService; @Mock private LauncherApps mLauncherApps; + @Mock + private WindowManagerShellWrapper mWindowManagerShellWrapper; private BubbleData mBubbleData; @@ -271,6 +274,7 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { mock(INotificationManager.class), mStatusBarService, mWindowManager, + mWindowManagerShellWrapper, mLauncherApps); mBubbleController.addNotifCallback(mNotifCallback); mBubbleController.setExpandListener(mBubbleExpandListener); diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/TestableBubbleController.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/TestableBubbleController.java index 58b27f24a1d4..ec9571a14997 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/TestableBubbleController.java +++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/TestableBubbleController.java @@ -36,6 +36,7 @@ import com.android.systemui.statusbar.phone.ShadeController; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.ZenModeController; import com.android.systemui.util.FloatingContentCoordinator; +import com.android.systemui.wmshell.WindowManagerShellWrapper; /** * Testable BubbleController subclass that immediately synchronizes surfaces. @@ -63,6 +64,7 @@ public class TestableBubbleController extends BubbleController { INotificationManager notificationManager, IStatusBarService statusBarService, WindowManager windowManager, + WindowManagerShellWrapper windowManagerShellWrapper, LauncherApps launcherApps) { super(context, notificationShadeWindowController, statusBarStateController, shadeController, @@ -70,7 +72,7 @@ public class TestableBubbleController extends BubbleController { zenModeController, lockscreenUserManager, groupManager, entryManager, notifPipeline, featureFlags, dumpManager, floatingContentCoordinator, dataRepository, sysUiState, notificationManager, statusBarService, - windowManager, launcherApps); + windowManager, windowManagerShellWrapper, launcherApps); setInflateSynchronously(true); } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/pip/PipAnimationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/pip/PipAnimationControllerTest.java index 6f5cbe21be75..89ca32c1f1a5 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/pip/PipAnimationControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/pip/PipAnimationControllerTest.java @@ -22,7 +22,6 @@ import static com.android.systemui.pip.PipAnimationController.TRANSITION_DIRECTI import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import android.graphics.Matrix; @@ -34,7 +33,6 @@ import android.view.SurfaceControl; import androidx.test.filters.SmallTest; import com.android.systemui.SysuiTestCase; -import com.android.systemui.statusbar.policy.ConfigurationController; import org.junit.Before; import org.junit.Test; @@ -61,7 +59,7 @@ public class PipAnimationControllerTest extends SysuiTestCase { @Before public void setUp() throws Exception { mPipAnimationController = new PipAnimationController( - new PipSurfaceTransactionHelper(mContext, mock(ConfigurationController.class))); + new PipSurfaceTransactionHelper(mContext)); mLeash = new SurfaceControl.Builder() .setContainerLayer() .setName("FakeLeash") diff --git a/packages/SystemUI/tests/src/com/android/systemui/pip/phone/PipControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/pip/phone/PipControllerTest.java index b04349521205..1274621623ea 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/pip/phone/PipControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/pip/phone/PipControllerTest.java @@ -32,16 +32,11 @@ import android.testing.TestableContext; import android.testing.TestableLooper; import com.android.systemui.SysuiTestCase; -import com.android.systemui.broadcast.BroadcastDispatcher; -import com.android.systemui.model.SysUiState; import com.android.systemui.pip.PipBoundsHandler; -import com.android.systemui.pip.PipSurfaceTransactionHelper; import com.android.systemui.pip.PipTaskOrganizer; -import com.android.systemui.pip.PipUiEventLogger; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.statusbar.policy.ConfigurationController; -import com.android.systemui.util.DeviceConfigProxy; -import com.android.systemui.util.FloatingContentCoordinator; +import com.android.systemui.wmshell.WindowManagerShellWrapper; import com.android.wm.shell.common.DisplayController; import org.junit.Before; @@ -61,17 +56,16 @@ public class PipControllerTest extends SysuiTestCase { private TestableContext mSpiedContext; @Mock private ActivityManagerWrapper mMockActivityManagerWrapper; - @Mock private BroadcastDispatcher mMockBroadcastDispatcher; @Mock private ConfigurationController mMockConfigurationController; - @Mock private DeviceConfigProxy mMockDeviceConfigProxy; @Mock private DisplayController mMockdDisplayController; - @Mock private FloatingContentCoordinator mMockFloatingContentCoordinator; @Mock private PackageManager mPackageManager; + @Mock private PipMenuActivityController mMockPipMenuActivityController; + @Mock private PipAppOpsListener mMockPipAppOpsListener; @Mock private PipBoundsHandler mMockPipBoundsHandler; - @Mock private PipSurfaceTransactionHelper mMockPipSurfaceTransactionHelper; + @Mock private PipMediaController mMockPipMediaController; @Mock private PipTaskOrganizer mMockPipTaskOrganizer; - @Mock private PipUiEventLogger mPipUiEventLogger; - @Mock private SysUiState mMockSysUiState; + @Mock private PipTouchHandler mMockPipTouchHandler; + @Mock private WindowManagerShellWrapper mMockWindowManagerShellWrapper; @Before public void setUp() throws RemoteException { @@ -82,10 +76,10 @@ public class PipControllerTest extends SysuiTestCase { when(mPackageManager.hasSystemFeature(FEATURE_PICTURE_IN_PICTURE)).thenReturn(false); when(mSpiedContext.getPackageManager()).thenReturn(mPackageManager); - mPipController = new PipController(mSpiedContext, mMockBroadcastDispatcher, - mMockConfigurationController, mMockDeviceConfigProxy, mMockdDisplayController, - mMockFloatingContentCoordinator, mMockSysUiState, mMockPipBoundsHandler, - mMockPipSurfaceTransactionHelper, mMockPipTaskOrganizer, mPipUiEventLogger); + mPipController = new PipController(mSpiedContext, mMockdDisplayController, + mMockPipAppOpsListener, + mMockPipBoundsHandler, mMockPipMediaController, mMockPipMenuActivityController, + mMockPipTaskOrganizer, mMockPipTouchHandler, mMockWindowManagerShellWrapper); } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/pip/phone/PipTouchHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/pip/phone/PipTouchHandlerTest.java index c8d4aca90519..ad83ebbc76fd 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/pip/phone/PipTouchHandlerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/pip/phone/PipTouchHandlerTest.java @@ -22,7 +22,6 @@ import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; -import android.app.IActivityManager; import android.graphics.Point; import android.graphics.Rect; import android.testing.AndroidTestingRunner; @@ -33,13 +32,10 @@ import androidx.test.filters.SmallTest; import com.android.systemui.R; import com.android.systemui.SysuiTestCase; -import com.android.systemui.model.SysUiState; import com.android.systemui.pip.PipBoundsHandler; import com.android.systemui.pip.PipSnapAlgorithm; import com.android.systemui.pip.PipTaskOrganizer; import com.android.systemui.pip.PipUiEventLogger; -import com.android.systemui.shared.system.InputConsumerController; -import com.android.systemui.util.DeviceConfigProxy; import com.android.systemui.util.FloatingContentCoordinator; import org.junit.Before; @@ -63,27 +59,15 @@ public class PipTouchHandlerTest extends SysuiTestCase { private PipTouchHandler mPipTouchHandler; @Mock - private IActivityManager mActivityManager; - - @Mock private PipMenuActivityController mPipMenuActivityController; @Mock - private InputConsumerController mInputConsumerController; - - @Mock private PipTaskOrganizer mPipTaskOrganizer; @Mock private FloatingContentCoordinator mFloatingContentCoordinator; @Mock - private DeviceConfigProxy mDeviceConfigProxy; - - @Mock - private SysUiState mSysUiState; - - @Mock private PipUiEventLogger mPipUiEventLogger; private PipBoundsHandler mPipBoundsHandler; @@ -105,9 +89,8 @@ public class PipTouchHandlerTest extends SysuiTestCase { mPipBoundsHandler = new PipBoundsHandler(mContext); mPipSnapAlgorithm = mPipBoundsHandler.getSnapAlgorithm(); mPipSnapAlgorithm = new PipSnapAlgorithm(mContext); - mPipTouchHandler = new PipTouchHandler(mContext, mActivityManager, - mPipMenuActivityController, mInputConsumerController, mPipBoundsHandler, - mPipTaskOrganizer, mFloatingContentCoordinator, mDeviceConfigProxy, mSysUiState, + mPipTouchHandler = new PipTouchHandler(mContext, mPipMenuActivityController, + mPipBoundsHandler, mPipTaskOrganizer, mFloatingContentCoordinator, mPipUiEventLogger); mMotionHelper = Mockito.spy(mPipTouchHandler.getMotionHelper()); mPipResizeGestureHandler = Mockito.spy(mPipTouchHandler.getPipResizeGestureHandler()); diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java index 280423fca202..0b7595000e3b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java @@ -37,9 +37,12 @@ import com.android.systemui.keyguard.ScreenLifecycle; import com.android.systemui.model.SysUiState; import com.android.systemui.navigationbar.NavigationModeController; import com.android.systemui.pip.Pip; +import com.android.systemui.pip.phone.PipTouchHandler; import com.android.systemui.shared.system.ActivityManagerWrapper; +import com.android.systemui.shared.system.InputConsumerController; import com.android.systemui.shared.system.TaskStackChangeListener; import com.android.systemui.statusbar.CommandQueue; +import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.tracing.ProtoTracer; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.common.DisplayImeController; @@ -59,9 +62,11 @@ import java.util.Optional; @SmallTest @RunWith(AndroidJUnit4.class) public class WMShellTest extends SysuiTestCase { - + InputConsumerController mInputConsumerController; WMShell mWMShell; + @Mock CommandQueue mCommandQueue; + @Mock ConfigurationController mConfigurationController; @Mock KeyguardUpdateMonitor mKeyguardUpdateMonitor; @Mock ActivityManagerWrapper mActivityManagerWrapper; @Mock DisplayImeController mDisplayImeController; @@ -69,6 +74,7 @@ public class WMShellTest extends SysuiTestCase { @Mock ScreenLifecycle mScreenLifecycle; @Mock SysUiState mSysUiState; @Mock Pip mPip; + @Mock PipTouchHandler mPipTouchHandler; @Mock SplitScreen mSplitScreen; @Mock OneHanded mOneHanded; @Mock ShellTaskOrganizer mTaskOrganizer; @@ -78,10 +84,16 @@ public class WMShellTest extends SysuiTestCase { @Before public void setUp() { MockitoAnnotations.initMocks(this); - mWMShell = new WMShell(mContext, mCommandQueue, mKeyguardUpdateMonitor, - mActivityManagerWrapper, mDisplayImeController, mNavigationModeController, - mScreenLifecycle, mSysUiState, Optional.of(mPip), Optional.of(mSplitScreen), - Optional.of(mOneHanded), mTaskOrganizer, mProtoTracer); + mInputConsumerController = InputConsumerController.getPipInputConsumer(); + + mWMShell = new WMShell(mContext, mCommandQueue, mConfigurationController, + mInputConsumerController, mKeyguardUpdateMonitor, mActivityManagerWrapper, + mDisplayImeController, mNavigationModeController, mScreenLifecycle, mSysUiState, + Optional.of(mPip), Optional.of(mSplitScreen), Optional.of(mOneHanded), + mTaskOrganizer, mProtoTracer); + + when(mPip.getPipTouchHandler()).thenReturn(mPipTouchHandler); + } @Test @@ -103,9 +115,8 @@ public class WMShellTest extends SysuiTestCase { TestableContext spiedContext = spy(mContext); when(mMockPackageManager.hasSystemFeature(FEATURE_PICTURE_IN_PICTURE)).thenReturn(false); when(spiedContext.getPackageManager()).thenReturn(mMockPackageManager); - final WMShell nonPipWMShell = new WMShell(spiedContext, mCommandQueue, - mKeyguardUpdateMonitor, + mConfigurationController, mInputConsumerController, mKeyguardUpdateMonitor, mActivityManagerWrapper, mDisplayImeController, mNavigationModeController, mScreenLifecycle, mSysUiState, Optional.of(mPip), Optional.of(mSplitScreen), Optional.of(mOneHanded), mTaskOrganizer, mProtoTracer); |