diff options
| author | 2021-03-01 14:47:11 -0800 | |
|---|---|---|
| committer | 2021-03-02 16:40:30 -0800 | |
| commit | 031bb5d8355b3908341dfef623ad06a2c96c1e45 (patch) | |
| tree | 25857d0c7853ae497254bf920a53b4a0a5913dfd | |
| parent | 6d5cc3989be7a7b9a873e21d212d32c4ee5a31fb (diff) | |
Update the split screen APIs used by the launcher
Makes the following changes:
1. Adds a boolean visible parameter to the onTaskChanged method of
SplitScreenListener to allow the launcher to determine which task is
on top of a stage
2. Allows the launcher to specify a fill-in intent when asking to open
a PendingIntent on the main or side stages.
3. Allows the launcher to ask to remove a task from the side stage.
Bug: 179176511
Test: manually tested against the foldable taskbar launcher.
Change-Id: I9fa530f546af58779ccf71d0753d9b6d3479fd0b
9 files changed, 70 insertions, 43 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java index 6f5f2eb5723c..aab2334f8255 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java @@ -234,8 +234,8 @@ public class DragAndDropPolicy { final UserHandle user = intent.getParcelableExtra(EXTRA_USER); mStarter.startShortcut(packageName, id, stage, position, opts, user); } else { - mStarter.startIntent(intent.getParcelableExtra(EXTRA_PENDING_INTENT), stage, position, - opts); + mStarter.startIntent(intent.getParcelableExtra(EXTRA_PENDING_INTENT), + mContext, null, stage, position, opts); } } @@ -295,7 +295,8 @@ public class DragAndDropPolicy { @Nullable Bundle options); void startShortcut(String packageName, String shortcutId, @StageType int stage, @StagePosition int position, @Nullable Bundle options, UserHandle user); - void startIntent(PendingIntent intent, @StageType int stage, @StagePosition int position, + void startIntent(PendingIntent intent, Context context, Intent fillInIntent, + @StageType int stage, @StagePosition int position, @Nullable Bundle options); void enterSplitScreen(int taskId, boolean leftOrTop); void exitSplitScreen(); @@ -336,10 +337,11 @@ public class DragAndDropPolicy { } @Override - public void startIntent(PendingIntent intent, int stage, int position, + public void startIntent(PendingIntent intent, Context context, + @Nullable Intent fillInIntent, int stage, int position, @Nullable Bundle options) { try { - intent.send(null, 0, null, null, null, null, options); + intent.send(mContext, 0, fillInIntent, null, null, null, options); } catch (PendingIntent.CanceledException e) { Slog.e(TAG, "Failed to launch activity", e); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreen.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreen.java index 7ca569349633..25a84bd46484 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreen.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreen.java @@ -19,18 +19,17 @@ package com.android.wm.shell.splitscreen; import android.annotation.IntDef; import android.app.ActivityManager; import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; import android.graphics.Rect; import android.os.Bundle; import android.os.UserHandle; -import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.wm.shell.common.annotations.ExternalThread; import com.android.wm.shell.draganddrop.DragAndDropPolicy; -import java.io.PrintWriter; - /** * Interface to engage split-screen feature. * TODO: Figure out which of these are actually needed outside of the Shell @@ -87,7 +86,7 @@ public interface SplitScreen extends DragAndDropPolicy.Starter { /** Callback interface for listening to changes in a split-screen stage. */ interface SplitScreenListener { void onStagePositionChanged(@StageType int stage, @StagePosition int position); - void onTaskStageChanged(int taskId, @StageType int stage); + void onTaskStageChanged(int taskId, @StageType int stage, boolean visible); } /** @return {@code true} if split-screen is currently visible. */ @@ -118,6 +117,7 @@ public interface SplitScreen extends DragAndDropPolicy.Starter { @StageType int stage, @StagePosition int position, @Nullable Bundle options); void startShortcut(String packageName, String shortcutId, @StageType int stage, @StagePosition int position, @Nullable Bundle options, UserHandle user); - void startIntent(PendingIntent intent, - @StageType int stage, @StagePosition int position, @Nullable Bundle options); + void startIntent(PendingIntent intent, Context context, + @Nullable Intent fillInIntent, @StageType int stage, + @StagePosition int position, @Nullable Bundle options); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java index 11548adaf5d1..bb6f6f259a1e 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java @@ -30,6 +30,7 @@ import android.app.ActivityTaskManager; import android.app.PendingIntent; import android.content.ActivityNotFoundException; import android.content.Context; +import android.content.Intent; import android.content.pm.LauncherApps; import android.graphics.Rect; import android.os.Bundle; @@ -171,12 +172,13 @@ public class SplitScreenController implements DragAndDropPolicy.Starter { } } - public void startIntent(PendingIntent intent, @SplitScreen.StageType int stage, + public void startIntent(PendingIntent intent, Context context, + Intent fillInIntent, @SplitScreen.StageType int stage, @SplitScreen.StagePosition int position, @Nullable Bundle options) { options = resolveStartStage(stage, position, options); try { - intent.send(null, 0, null, null, null, null, options); + intent.send(context, 0, fillInIntent, null, null, null, options); } catch (PendingIntent.CanceledException e) { Slog.e(TAG, "Failed to launch activity", e); } @@ -348,10 +350,11 @@ public class SplitScreenController implements DragAndDropPolicy.Starter { } @Override - public void startIntent(PendingIntent intent, int stage, int position, - @Nullable Bundle options) { + public void startIntent(PendingIntent intent, Context context, Intent fillInIntent, + int stage, int position, @Nullable Bundle options) { mMainExecutor.execute(() -> { - SplitScreenController.this.startIntent(intent, stage, position, options); + SplitScreenController.this.startIntent(intent, context, fillInIntent, stage, + position, options); }); } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java index 22c97515ad76..c7fe5e79562c 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java @@ -225,7 +225,7 @@ class StageCoordinator implements SplitLayout.LayoutChangeListener, } private void onStageChildTaskStatusChanged( - StageListenerImpl stageListener, int taskId, boolean present) { + StageListenerImpl stageListener, int taskId, boolean present, boolean visible) { int stage; if (present) { @@ -236,7 +236,7 @@ class StageCoordinator implements SplitLayout.LayoutChangeListener, } for (int i = mListeners.size() - 1; i >= 0; --i) { - mListeners.get(i).onTaskStageChanged(taskId, stage); + mListeners.get(i).onTaskStageChanged(taskId, stage, visible); } } @@ -494,8 +494,8 @@ class StageCoordinator implements SplitLayout.LayoutChangeListener, } @Override - public void onChildTaskStatusChanged(int taskId, boolean present) { - StageCoordinator.this.onStageChildTaskStatusChanged(this, taskId, present); + public void onChildTaskStatusChanged(int taskId, boolean present, boolean visible) { + StageCoordinator.this.onStageChildTaskStatusChanged(this, taskId, present, visible); } @Override diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java index 10c742b69578..b8cdc4ab4d75 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java @@ -58,7 +58,7 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener { public interface StageListenerCallbacks { void onRootTaskAppeared(); void onStatusChanged(boolean visible, boolean hasChildren); - void onChildTaskStatusChanged(int taskId, boolean present); + void onChildTaskStatusChanged(int taskId, boolean present, boolean visible); void onRootTaskVanished(); } private final StageListenerCallbacks mCallbacks; @@ -88,7 +88,7 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener { mChildrenLeashes.put(taskId, leash); mChildrenTaskInfo.put(taskId, taskInfo); updateChildTaskSurface(taskInfo, leash, true /* firstAppeared */); - mCallbacks.onChildTaskStatusChanged(taskId, true /* present */); + mCallbacks.onChildTaskStatusChanged(taskId, true /* present */, taskInfo.isVisible); } else { throw new IllegalArgumentException(this + "\n Unknown task: " + taskInfo + "\n mRootTaskInfo: " + mRootTaskInfo); @@ -105,6 +105,8 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener { mChildrenTaskInfo.put(taskInfo.taskId, taskInfo); updateChildTaskSurface( taskInfo, mChildrenLeashes.get(taskInfo.taskId), false /* firstAppeared */); + mCallbacks.onChildTaskStatusChanged(taskInfo.taskId, true /* present */, + taskInfo.isVisible); } else { throw new IllegalArgumentException(this + "\n Unknown task: " + taskInfo + "\n mRootTaskInfo: " + mRootTaskInfo); @@ -123,7 +125,7 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener { mChildrenTaskInfo.remove(taskId); mChildrenLeashes.remove(taskId); sendStatusChanged(); - mCallbacks.onChildTaskStatusChanged(taskId, false /* present */); + mCallbacks.onChildTaskStatusChanged(taskId, false /* present */, taskInfo.isVisible); } else { throw new IllegalArgumentException(this + "\n Unknown task: " + taskInfo + "\n mRootTaskInfo: " + mRootTaskInfo); @@ -152,7 +154,9 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener { void onSplitScreenListenerRegistered(SplitScreen.SplitScreenListener listener, @SplitScreen.StageType int stage) { for (int i = mChildrenTaskInfo.size() - 1; i >= 0; --i) { - listener.onTaskStageChanged(mChildrenTaskInfo.keyAt(i), stage); + int taskId = mChildrenTaskInfo.keyAt(i); + listener.onTaskStageChanged(taskId, stage, + mChildrenTaskInfo.get(taskId).isVisible); } } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/draganddrop/DragAndDropPolicyTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/draganddrop/DragAndDropPolicyTest.java index 19ecc49513e5..c1c4c6dd08d7 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/draganddrop/DragAndDropPolicyTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/draganddrop/DragAndDropPolicyTest.java @@ -205,7 +205,7 @@ public class DragAndDropPolicyTest { mPolicy.getTargets(mInsets), TYPE_FULLSCREEN); mPolicy.handleDrop(filterTargetByType(targets, TYPE_FULLSCREEN), mActivityClipData); - verify(mSplitScreenStarter).startIntent(any(), + verify(mSplitScreenStarter).startIntent(any(), any(), any(), eq(STAGE_TYPE_UNDEFINED), eq(STAGE_POSITION_UNDEFINED), any()); } @@ -217,12 +217,12 @@ public class DragAndDropPolicyTest { mPolicy.getTargets(mInsets), TYPE_FULLSCREEN, TYPE_SPLIT_LEFT, TYPE_SPLIT_RIGHT); mPolicy.handleDrop(filterTargetByType(targets, TYPE_FULLSCREEN), mActivityClipData); - verify(mSplitScreenStarter).startIntent(any(), + verify(mSplitScreenStarter).startIntent(any(), any(), any(), eq(STAGE_TYPE_UNDEFINED), eq(STAGE_POSITION_UNDEFINED), any()); reset(mSplitScreenStarter); mPolicy.handleDrop(filterTargetByType(targets, TYPE_SPLIT_RIGHT), mActivityClipData); - verify(mSplitScreenStarter).startIntent(any(), + verify(mSplitScreenStarter).startIntent(any(), any(), any(), eq(STAGE_TYPE_SIDE), eq(STAGE_POSITION_BOTTOM_OR_RIGHT), any()); } @@ -234,12 +234,12 @@ public class DragAndDropPolicyTest { mPolicy.getTargets(mInsets), TYPE_FULLSCREEN, TYPE_SPLIT_TOP, TYPE_SPLIT_BOTTOM); mPolicy.handleDrop(filterTargetByType(targets, TYPE_FULLSCREEN), mActivityClipData); - verify(mSplitScreenStarter).startIntent(any(), + verify(mSplitScreenStarter).startIntent(any(), any(), any(), eq(STAGE_TYPE_UNDEFINED), eq(STAGE_POSITION_UNDEFINED), any()); reset(mSplitScreenStarter); mPolicy.handleDrop(filterTargetByType(targets, TYPE_SPLIT_BOTTOM), mActivityClipData); - verify(mSplitScreenStarter).startIntent(any(), + verify(mSplitScreenStarter).startIntent(any(), any(), any(), eq(STAGE_TYPE_SIDE), eq(STAGE_POSITION_BOTTOM_OR_RIGHT), any()); } @@ -251,7 +251,7 @@ public class DragAndDropPolicyTest { mPolicy.getTargets(mInsets), TYPE_FULLSCREEN, TYPE_SPLIT_LEFT, TYPE_SPLIT_RIGHT); mPolicy.handleDrop(filterTargetByType(targets, TYPE_FULLSCREEN), mActivityClipData); - verify(mSplitScreenStarter).startIntent(any(), + verify(mSplitScreenStarter).startIntent(any(), any(), any(), eq(STAGE_TYPE_UNDEFINED), eq(STAGE_POSITION_UNDEFINED), any()); } @@ -263,7 +263,7 @@ public class DragAndDropPolicyTest { mPolicy.getTargets(mInsets), TYPE_FULLSCREEN, TYPE_SPLIT_LEFT, TYPE_SPLIT_RIGHT); mPolicy.handleDrop(filterTargetByType(targets, TYPE_FULLSCREEN), mActivityClipData); - verify(mSplitScreenStarter).startIntent(any(), + verify(mSplitScreenStarter).startIntent(any(), any(), any(), eq(STAGE_TYPE_UNDEFINED), eq(STAGE_POSITION_UNDEFINED), any()); } @@ -276,13 +276,13 @@ public class DragAndDropPolicyTest { mPolicy.getTargets(mInsets), TYPE_FULLSCREEN, TYPE_SPLIT_LEFT, TYPE_SPLIT_RIGHT); mPolicy.handleDrop(filterTargetByType(targets, TYPE_FULLSCREEN), mActivityClipData); - verify(mSplitScreenStarter).startIntent(any(), + verify(mSplitScreenStarter).startIntent(any(), any(), any(), eq(STAGE_TYPE_UNDEFINED), eq(STAGE_POSITION_UNDEFINED), any()); reset(mSplitScreenStarter); // TODO(b/169894807): Just verify starting for the non-docked task until we have app pairs mPolicy.handleDrop(filterTargetByType(targets, TYPE_SPLIT_RIGHT), mActivityClipData); - verify(mSplitScreenStarter).startIntent(any(), + verify(mSplitScreenStarter).startIntent(any(), any(), any(), eq(STAGE_TYPE_SIDE), eq(STAGE_POSITION_BOTTOM_OR_RIGHT), any()); } @@ -295,13 +295,13 @@ public class DragAndDropPolicyTest { mPolicy.getTargets(mInsets), TYPE_FULLSCREEN, TYPE_SPLIT_TOP, TYPE_SPLIT_BOTTOM); mPolicy.handleDrop(filterTargetByType(targets, TYPE_FULLSCREEN), mActivityClipData); - verify(mSplitScreenStarter).startIntent(any(), + verify(mSplitScreenStarter).startIntent(any(), any(), any(), eq(STAGE_TYPE_UNDEFINED), eq(STAGE_POSITION_UNDEFINED), any()); reset(mSplitScreenStarter); // TODO(b/169894807): Just verify starting for the non-docked task until we have app pairs mPolicy.handleDrop(filterTargetByType(targets, TYPE_SPLIT_BOTTOM), mActivityClipData); - verify(mSplitScreenStarter).startIntent(any(), + verify(mSplitScreenStarter).startIntent(any(), any(), any(), eq(STAGE_TYPE_SIDE), eq(STAGE_POSITION_BOTTOM_OR_RIGHT), any()); } 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 index e5ced3ec3dc2..54242bece2b6 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISplitScreenListener.aidl +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISplitScreenListener.aidl @@ -21,5 +21,5 @@ package com.android.systemui.shared.recents; */ oneway interface ISplitScreenListener { void onStagePositionChanged(int stage, int position); - void onTaskStageChanged(int taskId, int stage); -}
\ No newline at end of file + void onTaskStageChanged(int taskId, int stage, boolean visible); +} 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 5c943f63a9a1..bac4c43ccddc 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 @@ -19,6 +19,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; @@ -34,7 +35,7 @@ import com.android.systemui.shared.system.RemoteTransitionCompat; /** * Temporary callbacks into SystemUI. - * Next id = 30 + * Next id = 43 */ interface ISystemUiProxy { @@ -251,5 +252,7 @@ interface ISystemUiProxy { void startShortcut(in String packageName, in String shortcutId, in int stage, in int position, in Bundle options, in UserHandle user) = 40; void startIntent( - in PendingIntent intent, in int stage, in int position, in Bundle options) = 41; + in PendingIntent intent, in Intent fillInIntent, in int stage, in int position, + in Bundle options) = 41; + void removeFromSideStage(in int taskId) = 42; } diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java index 5b2a7e7ff617..e7d42832878b 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java +++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java @@ -662,14 +662,29 @@ public class OverviewProxyService extends CurrentUserTracker implements } @Override - public void startIntent(PendingIntent intent, int stage, int position, Bundle options) { + public void startIntent(PendingIntent intent, Intent fillInIntent, + 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)); + s.startIntent(intent, mContext, fillInIntent, stage, position, options)); + } finally { + Binder.restoreCallingIdentity(token); + } + } + + @Override + public void removeFromSideStage(int taskId) { + if (!verifyCaller("removeFromSideStage")) { + return; + } + final long token = Binder.clearCallingIdentity(); + try { + mSplitScreenOptional.ifPresent( + s -> s.removeFromSideStage(taskId)); } finally { Binder.restoreCallingIdentity(token); } @@ -789,10 +804,10 @@ public class OverviewProxyService extends CurrentUserTracker implements } @Override - public void onTaskStageChanged(int taskId, int stage) { + public void onTaskStageChanged(int taskId, int stage, boolean visible) { try { if (mISplitScreenListener != null) { - mISplitScreenListener.onTaskStageChanged(taskId, stage); + mISplitScreenListener.onTaskStageChanged(taskId, stage, visible); } } catch (RemoteException e) { Log.e(TAG_OPS, "onTaskStageChanged", e); |