diff options
15 files changed, 341 insertions, 354 deletions
diff --git a/libs/WindowManager/Shell/Android.bp b/libs/WindowManager/Shell/Android.bp index 1b5dc8bdbcaa..3f03302de474 100644 --- a/libs/WindowManager/Shell/Android.bp +++ b/libs/WindowManager/Shell/Android.bp @@ -38,6 +38,14 @@ filegroup { path: "src", } +filegroup { + name: "wm_shell-aidls", + srcs: [ + "src/**/*.aidl", + ], + path: "src", +} + // TODO(b/168581922) protologtool do not support kotlin(*.kt) filegroup { name: "wm_shell-sources-kt", @@ -98,7 +106,7 @@ android_library { ":wm_shell_protolog_src", // TODO(b/168581922) protologtool do not support kotlin(*.kt) ":wm_shell-sources-kt", - "src/**/I*.aidl", + ":wm_shell-aidls", ], resource_dirs: [ "res", diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellCommandHandlerImpl.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellCommandHandlerImpl.java index eaed24d6195a..d451f4a0661b 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellCommandHandlerImpl.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellCommandHandlerImpl.java @@ -47,21 +47,7 @@ public final class ShellCommandHandlerImpl { private final ShellExecutor mMainExecutor; private final HandlerImpl mImpl = new HandlerImpl(); - public static ShellCommandHandler create( - ShellTaskOrganizer shellTaskOrganizer, - Optional<LegacySplitScreenController> legacySplitScreenOptional, - Optional<SplitScreenController> splitScreenOptional, - Optional<Pip> pipOptional, - Optional<OneHandedController> oneHandedOptional, - Optional<HideDisplayCutoutController> hideDisplayCutout, - Optional<AppPairsController> appPairsOptional, - ShellExecutor mainExecutor) { - return new ShellCommandHandlerImpl(shellTaskOrganizer, legacySplitScreenOptional, - splitScreenOptional, pipOptional, oneHandedOptional, hideDisplayCutout, - appPairsOptional, mainExecutor).mImpl; - } - - private ShellCommandHandlerImpl( + public ShellCommandHandlerImpl( ShellTaskOrganizer shellTaskOrganizer, Optional<LegacySplitScreenController> legacySplitScreenOptional, Optional<SplitScreenController> splitScreenOptional, @@ -80,6 +66,10 @@ public final class ShellCommandHandlerImpl { mMainExecutor = mainExecutor; } + public ShellCommandHandler asShellCommandHandler() { + return mImpl; + } + /** Dumps WM Shell internal state. */ private void dump(PrintWriter pw) { mShellTaskOrganizer.dump(pw, ""); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellInitImpl.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellInitImpl.java index 85bd24c1c2bf..9abda68fbfd7 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellInitImpl.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellInitImpl.java @@ -51,31 +51,7 @@ public class ShellInitImpl { private final InitImpl mImpl = new InitImpl(); - public static ShellInit create(DisplayImeController displayImeController, - DragAndDropController dragAndDropController, - ShellTaskOrganizer shellTaskOrganizer, - Optional<LegacySplitScreenController> legacySplitScreenOptional, - Optional<SplitScreenController> splitScreenOptional, - Optional<AppPairsController> appPairsOptional, - Optional<StartingSurface> startingSurfaceOptional, - Optional<PipTouchHandler> pipTouchHandlerOptional, - FullscreenTaskListener fullscreenTaskListener, - Transitions transitions, - ShellExecutor mainExecutor) { - return new ShellInitImpl(displayImeController, - dragAndDropController, - shellTaskOrganizer, - legacySplitScreenOptional, - splitScreenOptional, - appPairsOptional, - startingSurfaceOptional, - pipTouchHandlerOptional, - fullscreenTaskListener, - transitions, - mainExecutor).mImpl; - } - - private ShellInitImpl(DisplayImeController displayImeController, + public ShellInitImpl(DisplayImeController displayImeController, DragAndDropController dragAndDropController, ShellTaskOrganizer shellTaskOrganizer, Optional<LegacySplitScreenController> legacySplitScreenOptional, @@ -99,6 +75,10 @@ public class ShellInitImpl { mStartingSurfaceOptional = startingSurfaceOptional; } + public ShellInit asShellInit() { + return mImpl; + } + private void init() { // Start listening for display changes mDisplayImeController.startMonitorDisplays(); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/ExecutorUtils.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/ExecutorUtils.java new file mode 100644 index 000000000000..b29058b1f204 --- /dev/null +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/ExecutorUtils.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2021 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.wm.shell.common; + +import android.Manifest; +import android.util.Slog; + +import java.util.function.Consumer; + +/** + * Helpers for working with executors + */ +public class ExecutorUtils { + + /** + * Checks that the caller has the MANAGE_ACTIVITY_TASKS permission and executes the given + * callback. + */ + public static <T> void executeRemoteCallWithTaskPermission(RemoteCallable<T> controllerInstance, + String log, Consumer<T> callback) { + executeRemoteCallWithTaskPermission(controllerInstance, log, callback, + false /* blocking */); + } + + /** + * Checks that the caller has the MANAGE_ACTIVITY_TASKS permission and executes the given + * callback. + */ + public static <T> void executeRemoteCallWithTaskPermission(RemoteCallable<T> controllerInstance, + String log, Consumer<T> callback, boolean blocking) { + if (controllerInstance == null) return; + + final RemoteCallable<T> controller = controllerInstance; + controllerInstance.getContext().enforceCallingPermission( + Manifest.permission.MANAGE_ACTIVITY_TASKS, log); + if (blocking) { + try { + controllerInstance.getRemoteCallExecutor().executeBlocking(() -> { + callback.accept((T) controller); + }); + } catch (InterruptedException e) { + Slog.e("ExecutorUtils", "Remote call failed", e); + } + } else { + controllerInstance.getRemoteCallExecutor().execute(() -> { + callback.accept((T) controller); + }); + } + } +} diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/RemoteCallable.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/RemoteCallable.java new file mode 100644 index 000000000000..30f535ba940c --- /dev/null +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/RemoteCallable.java @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2021 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.wm.shell.common; + +import android.content.Context; + +/** + * An interface for controllers that can receive remote calls. + */ +public interface RemoteCallable<T> { + /** + * Returns a context used for permission checking. + */ + Context getContext(); + + /** + * Returns the executor to post the handler callback to. + */ + ShellExecutor getRemoteCallExecutor(); +}
\ No newline at end of file diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/IPip.aidl b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/IPip.aidl new file mode 100644 index 000000000000..a6ffa6e44584 --- /dev/null +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/IPip.aidl @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2021 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.wm.shell.pip; + +import android.app.PictureInPictureParams; +import android.content.ComponentName; +import android.content.pm.ActivityInfo; +import android.graphics.Rect; + +import com.android.wm.shell.pip.IPipAnimationListener; + +/** + * Interface that is exposed to remote callers to manipulate the Pip feature. + */ +interface IPip { + + /** + * Notifies that Activity is about to be swiped to home with entering PiP transition and + * queries the destination bounds for PiP depends on Launcher's rotation and shelf height. + * + * @param componentName ComponentName represents the Activity + * @param activityInfo ActivityInfo tied to the Activity + * @param pictureInPictureParams PictureInPictureParams tied to the Activity + * @param launcherRotation Launcher rotation to calculate the PiP destination bounds + * @param shelfHeight Shelf height of launcher to calculate the PiP destination bounds + * @return destination bounds the PiP window should land into + */ + Rect startSwipePipToHome(in ComponentName componentName, in ActivityInfo activityInfo, + in PictureInPictureParams pictureInPictureParams, + int launcherRotation, int shelfHeight) = 1; + + /** + * Notifies the swiping Activity to PiP onto home transition is finished + * + * @param componentName ComponentName represents the Activity + * @param destinationBounds the destination bounds the PiP window lands into + */ + oneway void stopSwipePipToHome(in ComponentName componentName, in Rect destinationBounds) = 2; + + /** + * Sets listener to get pinned stack animation callbacks. + */ + oneway void setPinnedStackAnimationListener(IPipAnimationListener listener) = 3; + + /** + * Sets the shelf height and visibility. + */ + oneway void setShelfHeight(boolean visible, int shelfHeight) = 4; +} diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/IPinnedStackAnimationListener.aidl b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/IPipAnimationListener.aidl index 97aa512ea7df..2569b780c1bb 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/IPinnedStackAnimationListener.aidl +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/IPipAnimationListener.aidl @@ -14,15 +14,14 @@ * limitations under the License. */ -package com.android.systemui.shared.recents; +package com.android.wm.shell.pip; /** - * Listener interface that Launcher attaches to SystemUI to get - * pinned stack animation callbacks. + * Listener interface that Launcher attaches to SystemUI to get Pip animation callbacks. */ -oneway interface IPinnedStackAnimationListener { +oneway interface IPipAnimationListener { /** - * Notifies the pinned stack animation is started. + * Notifies the listener that the Pip animation is started. */ - void onPinnedStackAnimationStarted(); + void onPipAnimationStarted(); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java index d14c3e3c0dd4..6d4773bdeb1f 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java @@ -16,15 +16,10 @@ package com.android.wm.shell.pip; -import android.annotation.Nullable; -import android.app.PictureInPictureParams; -import android.content.ComponentName; -import android.content.pm.ActivityInfo; import android.content.res.Configuration; import android.graphics.Rect; import com.android.wm.shell.common.annotations.ExternalThread; -import com.android.wm.shell.pip.phone.PipTouchHandler; import java.io.PrintWriter; import java.util.function.Consumer; @@ -34,6 +29,14 @@ import java.util.function.Consumer; */ @ExternalThread public interface Pip { + + /** + * Returns a binder that can be passed to an external process to manipulate PIP. + */ + default IPip createExternalInterface() { + return null; + } + /** * Expand PIP, it's possible that specific request to activate the window via Alt-tab. */ @@ -109,30 +112,6 @@ public interface Pip { default void showPictureInPictureMenu() {} /** - * Called by Launcher when swiping an auto-pip enabled Activity to home starts - * @param componentName {@link ComponentName} represents the Activity entering PiP - * @param activityInfo {@link ActivityInfo} tied to the Activity - * @param pictureInPictureParams {@link PictureInPictureParams} tied to the Activity - * @param launcherRotation Rotation Launcher is in - * @param shelfHeight Shelf height when landing PiP window onto Launcher - * @return Destination bounds of PiP window based on the parameters passed in - */ - default Rect startSwipePipToHome(ComponentName componentName, ActivityInfo activityInfo, - PictureInPictureParams pictureInPictureParams, - int launcherRotation, int shelfHeight) { - return null; - } - - /** - * Called by Launcher when swiping an auto-pip enable Activity to home finishes - * @param componentName {@link ComponentName} represents the Activity entering PiP - * @param destinationBounds Destination bounds of PiP window - */ - default void stopSwipePipToHome(ComponentName componentName, Rect destinationBounds) { - return; - } - - /** * Called by NavigationBar in order to listen in for PiP bounds change. This is mostly used * for times where the PiP bounds could conflict with SystemUI elements, such as a stashed * PiP and the Back-from-Edge gesture. diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java index 9a584c67f97c..501b90ea6828 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java @@ -21,8 +21,10 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE; import static android.view.WindowManager.INPUT_CONSUMER_PIP; +import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission; import static com.android.wm.shell.pip.PipAnimationController.isOutPipDirection; +import android.Manifest; import android.app.ActivityManager; import android.app.ActivityTaskManager; import android.app.PictureInPictureParams; @@ -33,6 +35,7 @@ import android.content.pm.ActivityInfo; import android.content.pm.ParceledListSlice; import android.content.res.Configuration; import android.graphics.Rect; +import android.os.IBinder; import android.os.RemoteException; import android.os.UserHandle; import android.os.UserManager; @@ -44,6 +47,7 @@ import android.view.DisplayInfo; import android.view.WindowManagerGlobal; import android.window.WindowContainerTransaction; +import androidx.annotation.BinderThread; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -51,9 +55,13 @@ import com.android.wm.shell.WindowManagerShellWrapper; import com.android.wm.shell.common.DisplayChangeController; import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.DisplayLayout; +import com.android.wm.shell.common.ExecutorUtils; +import com.android.wm.shell.common.RemoteCallable; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.TaskStackListenerCallback; import com.android.wm.shell.common.TaskStackListenerImpl; +import com.android.wm.shell.pip.IPip; +import com.android.wm.shell.pip.IPipAnimationListener; import com.android.wm.shell.pip.PinnedStackListenerForwarder; import com.android.wm.shell.pip.Pip; import com.android.wm.shell.pip.PipBoundsAlgorithm; @@ -71,7 +79,8 @@ import java.util.function.Consumer; /** * Manages the picture-in-picture (PIP) UI and states for Phones. */ -public class PipController implements PipTransitionController.PipTransitionCallback { +public class PipController implements PipTransitionController.PipTransitionCallback, + RemoteCallable<PipController> { private static final String TAG = "PipController"; private Context mContext; @@ -85,12 +94,12 @@ public class PipController implements PipTransitionController.PipTransitionCallb private PipBoundsState mPipBoundsState; private PipTouchHandler mTouchHandler; private PipTransitionController mPipTransitionController; - protected final PipImpl mImpl = new PipImpl(); + protected final PipImpl mImpl; private final Rect mTmpInsetBounds = new Rect(); private boolean mIsInFixedRotation; - private Consumer<Boolean> mPinnedStackAnimationRecentsCallback; + private IPipAnimationListener mPinnedStackAnimationRecentsCallback; protected PhonePipMenuController mMenuController; protected PipTaskOrganizer mPipTaskOrganizer; @@ -264,6 +273,7 @@ public class PipController implements PipTransitionController.PipTransitionCallb } mContext = context; + mImpl = new PipImpl(); mWindowManagerShellWrapper = windowManagerShellWrapper; mDisplayController = displayController; mPipBoundsAlgorithm = pipBoundsAlgorithm; @@ -366,6 +376,16 @@ public class PipController implements PipTransitionController.PipTransitionCallb }); } + @Override + public Context getContext() { + return mContext; + } + + @Override + public ShellExecutor getRemoteCallExecutor() { + return mMainExecutor; + } + private void onConfigurationChanged(Configuration newConfig) { mPipBoundsAlgorithm.onConfigurationChanged(mContext); mTouchHandler.onConfigurationChanged(); @@ -474,7 +494,7 @@ public class PipController implements PipTransitionController.PipTransitionCallb mPipTaskOrganizer.setOneShotAnimationType(animationType); } - private void setPinnedStackAnimationListener(Consumer<Boolean> callback) { + private void setPinnedStackAnimationListener(IPipAnimationListener callback) { mPinnedStackAnimationRecentsCallback = callback; } @@ -512,7 +532,11 @@ public class PipController implements PipTransitionController.PipTransitionCallb // Disable touches while the animation is running mTouchHandler.setTouchEnabled(false); if (mPinnedStackAnimationRecentsCallback != null) { - mPinnedStackAnimationRecentsCallback.accept(true); + try { + mPinnedStackAnimationRecentsCallback.onPipAnimationStarted(); + } catch (RemoteException e) { + Log.e(TAG, "Failed to call onPinnedStackAnimationStarted()", e); + } } } @@ -638,7 +662,21 @@ public class PipController implements PipTransitionController.PipTransitionCallb mPipInputConsumer.dump(pw, innerPrefix); } + /** + * The interface for calls from outside the Shell, within the host process. + */ private class PipImpl implements Pip { + private IPipImpl mIPip; + + @Override + public IPip createExternalInterface() { + if (mIPip != null) { + mIPip.invalidate(); + } + mIPip = new IPipImpl(PipController.this); + return mIPip; + } + @Override public void hidePipMenu(Runnable onStartCallback, Runnable onEndCallback) { mMainExecutor.execute(() -> { @@ -696,13 +734,6 @@ public class PipController implements PipTransitionController.PipTransitionCallb } @Override - public void setPinnedStackAnimationListener(Consumer<Boolean> callback) { - mMainExecutor.execute(() -> { - PipController.this.setPinnedStackAnimationListener(callback); - }); - } - - @Override public void setPinnedStackAnimationType(int animationType) { mMainExecutor.execute(() -> { PipController.this.setPinnedStackAnimationType(animationType); @@ -724,37 +755,99 @@ public class PipController implements PipTransitionController.PipTransitionCallb } @Override - public Rect startSwipePipToHome(ComponentName componentName, ActivityInfo activityInfo, - PictureInPictureParams pictureInPictureParams, int launcherRotation, - int shelfHeight) { - Rect[] result = new Rect[1]; + public void dump(PrintWriter pw) { try { mMainExecutor.executeBlocking(() -> { - result[0] = PipController.this.startSwipePipToHome(componentName, activityInfo, - pictureInPictureParams, launcherRotation, shelfHeight); + PipController.this.dump(pw); }); } catch (InterruptedException e) { - Slog.e(TAG, "Failed to start swipe pip to home"); + Slog.e(TAG, "Failed to dump PipController in 2s"); } + } + } + + /** + * The interface for calls from outside the host process. + */ + @BinderThread + private static class IPipImpl extends IPip.Stub { + private PipController mController; + private IPipAnimationListener mListener; + private final IBinder.DeathRecipient mListenerDeathRecipient = + new IBinder.DeathRecipient() { + @Override + @BinderThread + public void binderDied() { + final PipController controller = mController; + controller.getRemoteCallExecutor().execute(() -> { + mListener = null; + controller.setPinnedStackAnimationListener(null); + }); + } + }; + + IPipImpl(PipController controller) { + mController = controller; + } + + /** + * Invalidates this instance, preventing future calls from updating the controller. + */ + void invalidate() { + mController = null; + } + + @Override + public Rect startSwipePipToHome(ComponentName componentName, ActivityInfo activityInfo, + PictureInPictureParams pictureInPictureParams, int launcherRotation, + int shelfHeight) { + Rect[] result = new Rect[1]; + executeRemoteCallWithTaskPermission(mController, "startSwipePipToHome", + (controller) -> { + result[0] = controller.startSwipePipToHome(componentName, activityInfo, + pictureInPictureParams, launcherRotation, shelfHeight); + }, true /* blocking */); return result[0]; } @Override public void stopSwipePipToHome(ComponentName componentName, Rect destinationBounds) { - mMainExecutor.execute(() -> { - PipController.this.stopSwipePipToHome(componentName, destinationBounds); - }); + executeRemoteCallWithTaskPermission(mController, "stopSwipePipToHome", + (controller) -> { + controller.stopSwipePipToHome(componentName, destinationBounds); + }); } @Override - public void dump(PrintWriter pw) { - try { - mMainExecutor.executeBlocking(() -> { - PipController.this.dump(pw); - }); - } catch (InterruptedException e) { - Slog.e(TAG, "Failed to dump PipController in 2s"); - } + public void setShelfHeight(boolean visible, int height) { + executeRemoteCallWithTaskPermission(mController, "setShelfHeight", + (controller) -> { + controller.setShelfHeight(visible, height); + }); + } + + @Override + public void setPinnedStackAnimationListener(IPipAnimationListener listener) { + executeRemoteCallWithTaskPermission(mController, "setPinnedStackAnimationListener", + (controller) -> { + if (mListener != null) { + // Reset the old death recipient + mListener.asBinder().unlinkToDeath(mListenerDeathRecipient, + 0 /* flags */); + } + if (listener != null) { + // Register the death recipient for the new listener to clear the listener + try { + listener.asBinder().linkToDeath(mListenerDeathRecipient, + 0 /* flags */); + } catch (RemoteException e) { + Slog.e(TAG, "Failed to link to death"); + return; + } + } + mListener = listener; + controller.setPinnedStackAnimationListener(listener); + }); } } } diff --git a/packages/SystemUI/shared/Android.bp b/packages/SystemUI/shared/Android.bp index 09e9675a3277..f98a959346d3 100644 --- a/packages/SystemUI/shared/Android.bp +++ b/packages/SystemUI/shared/Android.bp @@ -41,6 +41,7 @@ android_library { srcs: [ "src/**/*.java", "src/**/I*.aidl", + ":wm_shell-aidls", ], static_libs: [ diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl index 49e86f55bb9e..7cb8f86a9a94 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl @@ -17,10 +17,7 @@ package com.android.systemui.shared.recents; import android.app.PendingIntent; -import android.app.PictureInPictureParams; -import android.content.ComponentName; import android.content.Intent; -import android.content.pm.ActivityInfo; import android.graphics.Bitmap; import android.graphics.Insets; import android.graphics.Rect; @@ -28,7 +25,6 @@ import android.os.Bundle; import android.os.UserHandle; import android.view.MotionEvent; -import com.android.systemui.shared.recents.IPinnedStackAnimationListener; import com.android.systemui.shared.recents.ISplitScreenListener; import com.android.systemui.shared.recents.IStartingWindowListener; import com.android.systemui.shared.recents.model.Task; @@ -41,13 +37,6 @@ import com.android.systemui.shared.system.RemoteTransitionCompat; interface ISystemUiProxy { /** - * Proxies SurfaceControl.screenshotToBuffer(). - * @Removed - * GraphicBufferCompat screenshot(in Rect sourceCrop, int width, int height, int minLayer, - * int maxLayer, boolean useIdentityTransform, int rotation) = 0; - */ - - /** * Begins screen pinning on the provided {@param taskId}. */ void startScreenPinning(int taskId) = 1; @@ -121,11 +110,6 @@ interface ISystemUiProxy { void stopScreenPinning() = 17; /** - * Sets the shelf height and visibility. - */ - void setShelfHeight(boolean visible, int shelfHeight) = 20; - - /** * Handle the provided image as if it was a screenshot. * * Deprecated, use handleImageBundleAsScreenshot with image bundle and UserTask @@ -145,11 +129,6 @@ interface ISystemUiProxy { void notifySwipeToHomeFinished() = 23; /** - * Sets listener to get pinned stack animation callbacks. - */ - void setPinnedStackAnimationListener(IPinnedStackAnimationListener listener) = 24; - - /** * Notifies that quickstep will switch to a new task * @param rotation indicates which Surface.Rotation the gesture was started in */ @@ -177,29 +156,6 @@ interface ISystemUiProxy { void expandNotificationPanel() = 29; /** - * Notifies that Activity is about to be swiped to home with entering PiP transition and - * queries the destination bounds for PiP depends on Launcher's rotation and shelf height. - * - * @param componentName ComponentName represents the Activity - * @param activityInfo ActivityInfo tied to the Activity - * @param pictureInPictureParams PictureInPictureParams tied to the Activity - * @param launcherRotation Launcher rotation to calculate the PiP destination bounds - * @param shelfHeight Shelf height of launcher to calculate the PiP destination bounds - * @return destination bounds the PiP window should land into - */ - Rect startSwipePipToHome(in ComponentName componentName, in ActivityInfo activityInfo, - in PictureInPictureParams pictureInPictureParams, - int launcherRotation, int shelfHeight) = 30; - - /** - * Notifies the swiping Activity to PiP onto home transition is finished - * - * @param componentName ComponentName represents the Activity - * @param destinationBounds the destination bounds the PiP window lands into - */ - void stopSwipePipToHome(in ComponentName componentName, in Rect destinationBounds) = 31; - - /** * Registers a RemoteTransitionCompat that will handle transitions. This parameter bundles an * IRemoteTransition and a filter that must pass for it. */ diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java index 937c1df10315..55a6d34d6572 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java @@ -41,6 +41,8 @@ public class QuickStepContract { public static final String KEY_EXTRA_INPUT_MONITOR = "extra_input_monitor"; public static final String KEY_EXTRA_WINDOW_CORNER_RADIUS = "extra_window_corner_radius"; public static final String KEY_EXTRA_SUPPORTS_WINDOW_CORNERS = "extra_supports_window_corners"; + // See IPip.aidl + public static final String KEY_EXTRA_SHELL_PIP = "extra_shell_pip"; public static final String NAV_BAR_MODE_2BUTTON_OVERLAY = WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON_OVERLAY; diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java index a87bfd83916a..3cc481b95b39 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java +++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java @@ -25,6 +25,7 @@ import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON; import static com.android.internal.accessibility.common.ShortcutConstants.CHOOSER_PACKAGE_NAME; import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_INPUT_MONITOR; +import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SHELL_PIP; import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SUPPORTS_WINDOW_CORNERS; import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SYSUI_PROXY; import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_WINDOW_CORNER_RADIUS; @@ -83,7 +84,6 @@ import com.android.systemui.navigationbar.NavigationModeController; import com.android.systemui.recents.OverviewProxyService.OverviewProxyListener; import com.android.systemui.settings.CurrentUserTracker; import com.android.systemui.shared.recents.IOverviewProxy; -import com.android.systemui.shared.recents.IPinnedStackAnimationListener; import com.android.systemui.shared.recents.ISplitScreenListener; import com.android.systemui.shared.recents.IStartingWindowListener; import com.android.systemui.shared.recents.ISystemUiProxy; @@ -156,7 +156,6 @@ public class OverviewProxyService extends CurrentUserTracker implements private Region mActiveNavBarRegion; - private IPinnedStackAnimationListener mIPinnedStackAnimationListener; private IOverviewProxy mOverviewProxy; private int mConnectionBackoffAttempts; private boolean mBound; @@ -388,20 +387,6 @@ public class OverviewProxyService extends CurrentUserTracker implements } @Override - public void setShelfHeight(boolean visible, int shelfHeight) { - if (!verifyCaller("setShelfHeight")) { - return; - } - final long token = Binder.clearCallingIdentity(); - try { - mPipOptional.ifPresent( - pip -> pip.setShelfHeight(visible, shelfHeight)); - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override public void handleImageAsScreenshot(Bitmap screenImage, Rect locationInScreen, Insets visibleInsets, int taskId) { // Deprecated @@ -429,21 +414,6 @@ public class OverviewProxyService extends CurrentUserTracker implements } @Override - public void setPinnedStackAnimationListener(IPinnedStackAnimationListener listener) { - if (!verifyCaller("setPinnedStackAnimationListener")) { - return; - } - mIPinnedStackAnimationListener = listener; - final long token = Binder.clearCallingIdentity(); - try { - mPipOptional.ifPresent( - pip -> pip.setPinnedStackAnimationListener(mPinnedStackAnimationCallback)); - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override public void setStartingWindowListener(IStartingWindowListener listener) { if (!verifyCaller("setStartingWindowListener")) { return; @@ -526,38 +496,6 @@ public class OverviewProxyService extends CurrentUserTracker implements } @Override - public Rect startSwipePipToHome(ComponentName componentName, ActivityInfo activityInfo, - PictureInPictureParams pictureInPictureParams, - int launcherRotation, int shelfHeight) { - if (!verifyCaller("startSwipePipToHome")) { - return null; - } - final long binderToken = Binder.clearCallingIdentity(); - try { - return mPipOptional.map(pip -> - pip.startSwipePipToHome(componentName, activityInfo, - pictureInPictureParams, launcherRotation, shelfHeight)) - .orElse(null); - } finally { - Binder.restoreCallingIdentity(binderToken); - } - } - - @Override - public void stopSwipePipToHome(ComponentName componentName, Rect destinationBounds) { - if (!verifyCaller("stopSwipePipToHome")) { - return; - } - final long binderToken = Binder.clearCallingIdentity(); - try { - mPipOptional.ifPresent(pip -> pip.stopSwipePipToHome( - componentName, destinationBounds)); - } finally { - Binder.restoreCallingIdentity(binderToken); - } - } - - @Override public void registerRemoteTransition(RemoteTransitionCompat remoteTransition) { if (!verifyCaller("registerRemoteTransition")) return; final long binderToken = Binder.clearCallingIdentity(); @@ -762,6 +700,10 @@ public class OverviewProxyService extends CurrentUserTracker implements params.putBinder(KEY_EXTRA_SYSUI_PROXY, mSysUiProxy.asBinder()); params.putFloat(KEY_EXTRA_WINDOW_CORNER_RADIUS, mWindowCornerRadius); params.putBoolean(KEY_EXTRA_SUPPORTS_WINDOW_CORNERS, mSupportsRoundedCornersOnWindows); + + mPipOptional.ifPresent((pip) -> params.putBinder(KEY_EXTRA_SHELL_PIP, + pip.createExternalInterface().asBinder())); + try { mOverviewProxy.onInitialize(params); } catch (RemoteException e) { @@ -801,8 +743,6 @@ 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; private final BiConsumer<Integer, Integer> mStartingWindowListener = this::notifyTaskLaunching; @@ -966,17 +906,6 @@ 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 notifyTaskLaunching(int taskId, int supportedType) { if (mIStartingWindowListener == null) { return; diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java index 1b6c61237e29..c3ecb5c1f08b 100644 --- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java +++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java @@ -509,7 +509,13 @@ public abstract class WMShellBaseModule { @WMSingleton @Provides - static ShellInit provideShellInit(DisplayImeController displayImeController, + static ShellInit provideShellInit(ShellInitImpl impl) { + return impl.asShellInit(); + } + + @WMSingleton + @Provides + static ShellInitImpl provideShellInitImpl(DisplayImeController displayImeController, DragAndDropController dragAndDropController, ShellTaskOrganizer shellTaskOrganizer, Optional<LegacySplitScreenController> legacySplitScreenOptional, @@ -520,7 +526,7 @@ public abstract class WMShellBaseModule { FullscreenTaskListener fullscreenTaskListener, Transitions transitions, @ShellMainThread ShellExecutor mainExecutor) { - return ShellInitImpl.create(displayImeController, + return new ShellInitImpl(displayImeController, dragAndDropController, shellTaskOrganizer, legacySplitScreenOptional, @@ -539,7 +545,13 @@ public abstract class WMShellBaseModule { */ @WMSingleton @Provides - static Optional<ShellCommandHandler> provideShellCommandHandler( + static Optional<ShellCommandHandler> provideShellCommandHandler(ShellCommandHandlerImpl impl) { + return Optional.of(impl.asShellCommandHandler()); + } + + @WMSingleton + @Provides + static ShellCommandHandlerImpl provideShellCommandHandlerImpl( ShellTaskOrganizer shellTaskOrganizer, Optional<LegacySplitScreenController> legacySplitScreenOptional, Optional<SplitScreenController> splitScreenOptional, @@ -548,8 +560,8 @@ public abstract class WMShellBaseModule { Optional<HideDisplayCutoutController> hideDisplayCutout, Optional<AppPairsController> appPairsOptional, @ShellMainThread ShellExecutor mainExecutor) { - return Optional.of(ShellCommandHandlerImpl.create(shellTaskOrganizer, + return new ShellCommandHandlerImpl(shellTaskOrganizer, legacySplitScreenOptional, splitScreenOptional, pipOptional, oneHandedOptional, - hideDisplayCutout, appPairsOptional, mainExecutor)); + hideDisplayCutout, appPairsOptional, mainExecutor); } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/recents/OverviewProxyServiceTest.java b/packages/SystemUI/tests/src/com/android/systemui/recents/OverviewProxyServiceTest.java deleted file mode 100644 index 25104b8b1d20..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/recents/OverviewProxyServiceTest.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * 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.recents; - -import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.content.pm.PackageManager; -import android.os.RemoteException; -import android.test.suitebuilder.annotation.SmallTest; -import android.testing.AndroidTestingRunner; -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.navigationbar.NavigationBarController; -import com.android.systemui.navigationbar.NavigationModeController; -import com.android.systemui.shared.recents.IPinnedStackAnimationListener; -import com.android.systemui.statusbar.CommandQueue; -import com.android.systemui.statusbar.NotificationShadeWindowController; -import com.android.systemui.statusbar.phone.StatusBar; -import com.android.wm.shell.legacysplitscreen.LegacySplitScreen; -import com.android.wm.shell.pip.Pip; -import com.android.wm.shell.splitscreen.SplitScreen; -import com.android.wm.shell.startingsurface.StartingSurface; -import com.android.wm.shell.transition.RemoteTransitions; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import java.util.Optional; - -import dagger.Lazy; - -/** - * Unit tests for {@link com.android.systemui.recents.OverviewProxyService} - */ -@SmallTest -@RunWith(AndroidTestingRunner.class) -@TestableLooper.RunWithLooper -public class OverviewProxyServiceTest extends SysuiTestCase { - private OverviewProxyService mSpiedOverviewProxyService; - private TestableContext mSpiedContext; - - @Mock private BroadcastDispatcher mMockBroadcastDispatcher; - @Mock private CommandQueue mMockCommandQueue; - @Mock private Lazy<NavigationBarController> mMockNavBarControllerLazy; - @Mock private IPinnedStackAnimationListener mMockPinnedStackAnimationListener; - @Mock private NavigationModeController mMockNavModeController; - @Mock private NotificationShadeWindowController mMockStatusBarWinController; - @Mock private Optional<Pip> mMockPipOptional; - @Mock private Optional<LegacySplitScreen> mMockLegacySplitScreenOptional; - @Mock private Optional<SplitScreen> mMockSplitScreenOptional; - @Mock private Optional<Lazy<StatusBar>> mMockStatusBarOptionalLazy; - @Mock private Optional<com.android.wm.shell.onehanded.OneHanded> mMockOneHandedOptional; - @Mock private PackageManager mPackageManager; - @Mock private SysUiState mMockSysUiState; - @Mock private RemoteTransitions mMockTransitions; - @Mock private Optional<StartingSurface> mStartingSurface; - - @Before - public void setUp() throws RemoteException { - MockitoAnnotations.initMocks(this); - - mSpiedContext = spy(mContext); - - when(mPackageManager.hasSystemFeature(FEATURE_PICTURE_IN_PICTURE)).thenReturn(false); - when(mSpiedContext.getPackageManager()).thenReturn(mPackageManager); - - mSpiedOverviewProxyService = spy(new OverviewProxyService(mSpiedContext, mMockCommandQueue, - mMockNavBarControllerLazy, mMockNavModeController, mMockStatusBarWinController, - mMockSysUiState, mMockPipOptional, mMockLegacySplitScreenOptional, - mMockSplitScreenOptional, mMockStatusBarOptionalLazy, mMockOneHandedOptional, - mMockBroadcastDispatcher, mMockTransitions, mStartingSurface)); - } - - @Test - public void testNonPipDevice_shouldNotNotifySwipeToHomeFinished() throws RemoteException { - mSpiedOverviewProxyService.mSysUiProxy.notifySwipeToHomeFinished(); - - verify(mMockPipOptional, never()).ifPresent(any()); - } - - @Test - public void testNonPipDevice_shouldNotSetPinnedStackAnimationListener() throws RemoteException { - mSpiedOverviewProxyService.mSysUiProxy.setPinnedStackAnimationListener( - mMockPinnedStackAnimationListener); - - verify(mMockPipOptional, never()).ifPresent(any()); - } - - @Test - public void testNonPipDevice_shouldNotSetShelfHeight() throws RemoteException { - mSpiedOverviewProxyService.mSysUiProxy.setShelfHeight(true /* visible */, - 100 /* shelfHeight */); - - verify(mMockPipOptional, never()).ifPresent(any()); - } -} |