Merge "Update the split screen APIs used by the launcher" into sc-dev
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -495,8 +495,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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
void onTaskStageChanged(int taskId, int stage, boolean visible);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user