1/ Add mechanism to expose shell feature directly (for Pip)
- Also split impl and controller for ShellInit/ShellCommandHandler
(as with ag/13502602)
- Example implementation of exposing a subset of the Pip interface to
Launcher directly. This has the benefit of reducing unnecessary code
in SysUI just to pipe calls to the Shell.
The controller implements the binder interface which is collected
and exposed to Launcher when it binds to the overview service
and Launcher can call through the binders directly.
Note: this requires the shared lib to also build with the Shell
interfaces so changes to the Shell aidls will still require updating
the shared lib (until the shared lib prebuilt can removed).
Bug: 180074017
Test: atest WMShellUnitTests
Test: Verify Pip calls from Launcher work
Change-Id: Id74114da6a6a73d32c957f84fce5bbe23e87ba01
diff --git a/packages/SystemUI/shared/Android.bp b/packages/SystemUI/shared/Android.bp
index 09e9675a..f98a959 100644
--- a/packages/SystemUI/shared/Android.bp
+++ b/packages/SystemUI/shared/Android.bp
@@ -41,6 +41,7 @@
srcs: [
"src/**/*.java",
"src/**/I*.aidl",
+ ":wm_shell-aidls",
],
static_libs: [
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/IPinnedStackAnimationListener.aidl b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/IPinnedStackAnimationListener.aidl
deleted file mode 100644
index 97aa512..0000000
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/IPinnedStackAnimationListener.aidl
+++ /dev/null
@@ -1,28 +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.shared.recents;
-
-/**
- * Listener interface that Launcher attaches to SystemUI to get
- * pinned stack animation callbacks.
- */
-oneway interface IPinnedStackAnimationListener {
- /**
- * Notifies the pinned stack animation is started.
- */
- void onPinnedStackAnimationStarted();
-}
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 5126284..e89ae38 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.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 @@
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;
@@ -115,11 +104,6 @@
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
@@ -139,11 +123,6 @@
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
*/
@@ -171,29 +150,6 @@
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 937c1df..55a6d34 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 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 8951605..9851ea1 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 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.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 @@
private Region mActiveNavBarRegion;
- private IPinnedStackAnimationListener mIPinnedStackAnimationListener;
private IOverviewProxy mOverviewProxy;
private int mConnectionBackoffAttempts;
private boolean mBound;
@@ -383,20 +382,6 @@
}
@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
@@ -424,21 +409,6 @@
}
@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;
@@ -521,38 +491,6 @@
}
@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();
@@ -757,6 +695,10 @@
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) {
@@ -796,8 +738,6 @@
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;
@@ -961,17 +901,6 @@
}
}
- 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 3f4ec85..01cdb09 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 @@
@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 @@
FullscreenTaskListener fullscreenTaskListener,
Transitions transitions,
@ShellMainThread ShellExecutor mainExecutor) {
- return ShellInitImpl.create(displayImeController,
+ return new ShellInitImpl(displayImeController,
dragAndDropController,
shellTaskOrganizer,
legacySplitScreenOptional,
@@ -539,7 +545,13 @@
*/
@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 @@
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 25104b8..0000000
--- 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());
- }
-}