summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISplitScreenListener.aidl25
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl48
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java145
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/recents/OverviewProxyServiceTest.java8
4 files changed, 216 insertions, 10 deletions
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISplitScreenListener.aidl b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISplitScreenListener.aidl
new file mode 100644
index 000000000000..e5ced3ec3dc2
--- /dev/null
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISplitScreenListener.aidl
@@ -0,0 +1,25 @@
+/*
+ * 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.systemui.shared.recents;
+
+/**
+ * Listener interface that Launcher attaches to SystemUI to get split-screen callbacks.
+ */
+oneway interface ISplitScreenListener {
+ void onStagePositionChanged(int stage, int position);
+ void onTaskStageChanged(int taskId, int stage);
+} \ No newline at end of file
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 388eeb6cd706..e38cf237d36b 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
@@ -16,6 +16,7 @@
package com.android.systemui.shared.recents;
+import android.app.PendingIntent;
import android.app.PictureInPictureParams;
import android.content.ComponentName;
import android.content.pm.ActivityInfo;
@@ -23,9 +24,11 @@ import android.graphics.Bitmap;
import android.graphics.Insets;
import android.graphics.Rect;
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.model.Task;
import com.android.systemui.shared.system.RemoteTransitionCompat;
@@ -202,4 +205,49 @@ interface ISystemUiProxy {
/** Unegisters a RemoteTransitionCompat that will handle transitions. */
void unregisterRemoteTransition(in RemoteTransitionCompat remoteTransition) = 33;
+
+// SplitScreen APIs...copied from SplitScreen.java
+ /**
+ * Stage position isn't specified normally meaning to use what ever it is currently set to.
+ */
+ //int STAGE_POSITION_UNDEFINED = -1;
+ /**
+ * Specifies that a stage is positioned at the top half of the screen if
+ * in portrait mode or at the left half of the screen if in landscape mode.
+ */
+ //int STAGE_POSITION_TOP_OR_LEFT = 0;
+ /**
+ * Specifies that a stage is positioned at the bottom half of the screen if
+ * in portrait mode or at the right half of the screen if in landscape mode.
+ */
+ //int STAGE_POSITION_BOTTOM_OR_RIGHT = 1;
+
+ /**
+ * Stage type isn't specified normally meaning to use what ever the default is.
+ * E.g. exit split-screen and launch the app in fullscreen.
+ */
+ //int STAGE_TYPE_UNDEFINED = -1;
+ /**
+ * The main stage type.
+ * @see MainStage
+ */
+ //int STAGE_TYPE_MAIN = 0;
+ /**
+ * The side stage type.
+ * @see SideStage
+ */
+ //int STAGE_TYPE_SIDE = 1;
+
+ void registerSplitScreenListener(in ISplitScreenListener listener) = 34;
+ void unregisterSplitScreenListener(in ISplitScreenListener listener) = 35;
+
+ /** Hides the side-stage if it is currently visible. */
+ void setSideStageVisibility(in boolean visible) = 36;
+ /** Removes the split-screen stages. */
+ void exitSplitScreen() = 37;
+ void startTask(in int taskId, in int stage, in int position, in Bundle options) = 38;
+ void startShortcut(in String packageName, in String shortcutId, in int stage, in int position,
+ in Bundle options, in UserHandle user) = 39;
+ void startIntent(
+ in PendingIntent intent, in int stage, in int position, in Bundle options) = 40;
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
index 760ebadf1b99..a9f76f61c537 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
@@ -35,6 +35,7 @@ import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_T
import android.annotation.FloatRange;
import android.app.ActivityTaskManager;
+import android.app.PendingIntent;
import android.app.PictureInPictureParams;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
@@ -83,6 +84,7 @@ 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.ISystemUiProxy;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.system.ActivityManagerWrapper;
@@ -98,6 +100,7 @@ import com.android.wm.shell.legacysplitscreen.LegacySplitScreen;
import com.android.wm.shell.onehanded.OneHanded;
import com.android.wm.shell.pip.Pip;
import com.android.wm.shell.pip.PipAnimationController;
+import com.android.wm.shell.splitscreen.SplitScreen;
import com.android.wm.shell.transition.Transitions;
import java.io.FileDescriptor;
@@ -133,7 +136,8 @@ public class OverviewProxyService extends CurrentUserTracker implements
private final Context mContext;
private final Optional<Pip> mPipOptional;
private final Optional<Lazy<StatusBar>> mStatusBarOptionalLazy;
- private final Optional<LegacySplitScreen> mSplitScreenOptional;
+ private final Optional<LegacySplitScreen> mLegacySplitScreenOptional;
+ private final Optional<SplitScreen> mSplitScreenOptional;
private SysUiState mSysUiState;
private final Handler mHandler;
private final Lazy<NavigationBarController> mNavBarControllerLazy;
@@ -263,7 +267,7 @@ public class OverviewProxyService extends CurrentUserTracker implements
}
final long token = Binder.clearCallingIdentity();
try {
- return mSplitScreenOptional.map(splitScreen ->
+ return mLegacySplitScreenOptional.map(splitScreen ->
splitScreen.getDividerView().getNonMinimizedSplitScreenSecondaryBounds())
.orElse(null);
} finally {
@@ -401,7 +405,7 @@ public class OverviewProxyService extends CurrentUserTracker implements
@Override
public void setSplitScreenMinimized(boolean minimized) {
- mSplitScreenOptional.ifPresent(
+ mLegacySplitScreenOptional.ifPresent(
splitScreen -> splitScreen.setMinimized(minimized));
}
@@ -559,6 +563,105 @@ public class OverviewProxyService extends CurrentUserTracker implements
}
}
+ @Override
+ public void registerSplitScreenListener(ISplitScreenListener listener) {
+ if (!verifyCaller("registerSplitScreenListener")) {
+ return;
+ }
+ mISplitScreenListener = listener;
+ final long token = Binder.clearCallingIdentity();
+ try {
+ mSplitScreenOptional.ifPresent(
+ s -> s.registerSplitScreenListener(mSplitScreenListener));
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
+ @Override
+ public void unregisterSplitScreenListener(ISplitScreenListener listener) {
+ if (!verifyCaller("unregisterSplitScreenListener")) {
+ return;
+ }
+ mISplitScreenListener = null;
+ final long token = Binder.clearCallingIdentity();
+ try {
+ mSplitScreenOptional.ifPresent(
+ s -> s.unregisterSplitScreenListener(mSplitScreenListener));
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
+ @Override
+ public void setSideStageVisibility(boolean visible) {
+ if (!verifyCaller("setSideStageVisibility")) {
+ return;
+ }
+ final long token = Binder.clearCallingIdentity();
+ try {
+ mSplitScreenOptional.ifPresent(s -> s.setSideStageVisibility(visible));
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
+ @Override
+ public void exitSplitScreen() {
+ if (!verifyCaller("exitSplitScreen")) {
+ return;
+ }
+ final long token = Binder.clearCallingIdentity();
+ try {
+ mSplitScreenOptional.ifPresent(s -> s.exitSplitScreen());
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
+ @Override
+ public void startTask(int taskId, int stage, int position, Bundle options) {
+ if (!verifyCaller("startTask")) {
+ return;
+ }
+ final long token = Binder.clearCallingIdentity();
+ try {
+ mSplitScreenOptional.ifPresent(
+ s -> s.startTask(taskId, stage, position, options));
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
+ @Override
+ public void startShortcut(String packageName, String shortcutId, int stage, int position,
+ Bundle options, UserHandle user) {
+ if (!verifyCaller("startShortcut")) {
+ return;
+ }
+ final long token = Binder.clearCallingIdentity();
+ try {
+ mSplitScreenOptional.ifPresent(s ->
+ s.startShortcut(packageName, shortcutId, stage, position, options, user));
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
+ @Override
+ public void startIntent(PendingIntent intent, int stage, int position, Bundle options) {
+ if (!verifyCaller("startIntent")) {
+ return;
+ }
+ final long token = Binder.clearCallingIdentity();
+ try {
+ mSplitScreenOptional.ifPresent(s ->
+ s.startIntent(intent, stage, position, options));
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
private boolean verifyCaller(String reason) {
final int callerId = Binder.getCallingUserHandle().getIdentifier();
if (callerId != mCurrentBoundedUserId) {
@@ -658,6 +761,32 @@ public class OverviewProxyService extends CurrentUserTracker implements
private final IBinder.DeathRecipient mOverviewServiceDeathRcpt
= this::cleanupAfterDeath;
+ private ISplitScreenListener mISplitScreenListener;
+ private final SplitScreen.SplitScreenListener mSplitScreenListener =
+ new SplitScreen.SplitScreenListener() {
+ @Override
+ public void onStagePositionChanged(int stage, int position) {
+ try {
+ if (mISplitScreenListener != null) {
+ mISplitScreenListener.onStagePositionChanged(stage, position);
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG_OPS, "onStagePositionChanged", e);
+ }
+ }
+
+ @Override
+ public void onTaskStageChanged(int taskId, int stage) {
+ try {
+ if (mISplitScreenListener != null) {
+ mISplitScreenListener.onTaskStageChanged(taskId, stage);
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG_OPS, "onTaskStageChanged", e);
+ }
+ }
+ };
+
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
@Inject
public OverviewProxyService(Context context, CommandQueue commandQueue,
@@ -665,7 +794,8 @@ public class OverviewProxyService extends CurrentUserTracker implements
NavigationModeController navModeController,
NotificationShadeWindowController statusBarWinController, SysUiState sysUiState,
Optional<Pip> pipOptional,
- Optional<LegacySplitScreen> splitScreenOptional,
+ Optional<LegacySplitScreen> legacySplitScreenOptional,
+ Optional<SplitScreen> splitScreenOptional,
Optional<Lazy<StatusBar>> statusBarOptionalLazy,
Optional<OneHanded> oneHandedOptional,
BroadcastDispatcher broadcastDispatcher,
@@ -718,9 +848,10 @@ public class OverviewProxyService extends CurrentUserTracker implements
});
mCommandQueue = commandQueue;
- splitScreenOptional.ifPresent(splitScreen ->
- splitScreen.registerBoundsChangeListener(mSplitScreenBoundsChangeListener));
mSplitScreenOptional = splitScreenOptional;
+ legacySplitScreenOptional.ifPresent(splitScreen ->
+ splitScreen.registerBoundsChangeListener(mSplitScreenBoundsChangeListener));
+ mLegacySplitScreenOptional = legacySplitScreenOptional;
// Listen for user setup
startTracking();
@@ -835,7 +966,7 @@ public class OverviewProxyService extends CurrentUserTracker implements
startConnectionToCurrentUser();
// Clean up the minimized state if launcher dies
- mSplitScreenOptional.ifPresent(
+ mLegacySplitScreenOptional.ifPresent(
splitScreen -> splitScreen.setMinimized(false));
// Clean up any registered remote transitions
diff --git a/packages/SystemUI/tests/src/com/android/systemui/recents/OverviewProxyServiceTest.java b/packages/SystemUI/tests/src/com/android/systemui/recents/OverviewProxyServiceTest.java
index b63274ba246a..451c78fd1202 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/recents/OverviewProxyServiceTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/recents/OverviewProxyServiceTest.java
@@ -42,6 +42,7 @@ 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.transition.Transitions;
import org.junit.Before;
@@ -71,7 +72,8 @@ public class OverviewProxyServiceTest extends SysuiTestCase {
@Mock private NavigationModeController mMockNavModeController;
@Mock private NotificationShadeWindowController mMockStatusBarWinController;
@Mock private Optional<Pip> mMockPipOptional;
- @Mock private Optional<LegacySplitScreen> mMockSplitScreenOptional;
+ @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;
@@ -89,8 +91,8 @@ public class OverviewProxyServiceTest extends SysuiTestCase {
mSpiedOverviewProxyService = spy(new OverviewProxyService(mSpiedContext, mMockCommandQueue,
mMockNavBarControllerLazy, mMockNavModeController, mMockStatusBarWinController,
- mMockSysUiState, mMockPipOptional, mMockSplitScreenOptional,
- mMockStatusBarOptionalLazy, mMockOneHandedOptional,
+ mMockSysUiState, mMockPipOptional, mMockLegacySplitScreenOptional,
+ mMockSplitScreenOptional, mMockStatusBarOptionalLazy, mMockOneHandedOptional,
mMockBroadcastDispatcher, mMockTransitions));
}