Fixed issue with not sending stage position change

Also, added API to specify if split-screen should exit on hide.

Bug: 179176511
Test: presubmits
Change-Id: Iad2884554d16d922906386cb2887bcf35d6327e8
This commit is contained in:
Wale Ogunwale
2021-02-08 14:51:40 -08:00
parent 1afc2cdb46
commit 31e48a2df8
5 changed files with 50 additions and 5 deletions

View File

@@ -106,6 +106,8 @@ public interface SplitScreen extends DragAndDropPolicy.Starter {
/** Removes the split-screen stages. */
void exitSplitScreen();
/** @param exitSplitScreenOnHide if to exit split-screen if both stages are not visible. */
void exitSplitScreenOnHide(boolean exitSplitScreenOnHide);
/** Gets the stage bounds. */
void getStageBounds(Rect outTopOrLeftBounds, Rect outBottomOrRightBounds);

View File

@@ -126,6 +126,10 @@ public class SplitScreenController implements DragAndDropPolicy.Starter {
mStageCoordinator.exitSplitScreen();
}
public void exitSplitScreenOnHide(boolean exitSplitScreenOnHide) {
mStageCoordinator.exitSplitScreenOnHide(exitSplitScreenOnHide);
}
public void getStageBounds(Rect outTopOrLeftBounds, Rect outBottomOrRightBounds) {
mStageCoordinator.getStageBounds(outTopOrLeftBounds, outBottomOrRightBounds);
}
@@ -291,6 +295,13 @@ public class SplitScreenController implements DragAndDropPolicy.Starter {
});
}
@Override
public void exitSplitScreenOnHide(boolean exitSplitScreenOnHide) {
mMainExecutor.execute(() -> {
SplitScreenController.this.exitSplitScreenOnHide(exitSplitScreenOnHide);
});
}
@Override
public void getStageBounds(Rect outTopOrLeftBounds, Rect outBottomOrRightBounds) {
try {

View File

@@ -79,6 +79,7 @@ class StageCoordinator implements SplitLayout.LayoutChangeListener,
private DisplayAreaInfo mDisplayAreaInfo;
private final Context mContext;
private final List<SplitScreen.SplitScreenListener> mListeners = new ArrayList<>();
private boolean mExitSplitScreenOnHide = true;
StageCoordinator(Context context, int displayId, SyncTransactionQueue syncQueue,
RootTaskDisplayAreaOrganizer rootTDAOrganizer, ShellTaskOrganizer taskOrganizer) {
@@ -113,7 +114,7 @@ class StageCoordinator implements SplitLayout.LayoutChangeListener,
boolean moveToSideStage(ActivityManager.RunningTaskInfo task,
@SplitScreen.StagePosition int sideStagePosition) {
final WindowContainerTransaction wct = new WindowContainerTransaction();
mSideStagePosition = sideStagePosition;
setSideStagePosition(sideStagePosition);
mMainStage.activate(getMainStageBounds(), wct);
mSideStage.addTask(task, getSideStageBounds(), wct);
mTaskOrganizer.applyTransaction(wct);
@@ -144,10 +145,14 @@ class StageCoordinator implements SplitLayout.LayoutChangeListener,
}
void setSideStagePosition(@SplitScreen.StagePosition int sideStagePosition) {
if (mSideStagePosition == sideStagePosition) return;
mSideStagePosition = sideStagePosition;
if (mSideStageListener.mVisible) {
onStageVisibilityChanged(mSideStageListener);
}
sendOnStagePositionChanged();
}
void setSideStageVisibility(boolean visible) {
@@ -162,6 +167,10 @@ class StageCoordinator implements SplitLayout.LayoutChangeListener,
exitSplitScreen(null /* childrenToTop */);
}
void exitSplitScreenOnHide(boolean exitSplitScreenOnHide) {
mExitSplitScreenOnHide = exitSplitScreenOnHide;
}
private void exitSplitScreen(StageTaskListener childrenToTop) {
final WindowContainerTransaction wct = new WindowContainerTransaction();
mSideStage.removeAllTasks(wct, childrenToTop == mSideStage);
@@ -202,6 +211,14 @@ class StageCoordinator implements SplitLayout.LayoutChangeListener,
mListeners.remove(listener);
}
private void sendOnStagePositionChanged() {
for (int i = mListeners.size() - 1; i >= 0; --i) {
final SplitScreen.SplitScreenListener l = mListeners.get(i);
l.onStagePositionChanged(STAGE_TYPE_MAIN, getMainStagePosition());
l.onStagePositionChanged(STAGE_TYPE_SIDE, getSideStagePosition());
}
}
private void onStageChildTaskStatusChanged(
StageListenerImpl stageListener, int taskId, boolean present) {
@@ -251,7 +268,7 @@ class StageCoordinator implements SplitLayout.LayoutChangeListener,
}
}
if (!mainStageVisible && !sideStageVisible) {
if (mExitSplitScreenOnHide && !mainStageVisible && !sideStageVisible) {
// Exit split-screen if both stage are not visible.
// TODO: This is only a temporary request from UX and is likely to be removed soon...
exitSplitScreen();

View File

@@ -245,9 +245,11 @@ interface ISystemUiProxy {
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;
/** @param exitSplitScreenOnHide if to exit split-screen if both stages are not visible. */
void exitSplitScreenOnHide(boolean exitSplitScreenOnHide) = 38;
void startTask(in int taskId, in int stage, in int position, in Bundle options) = 39;
void startShortcut(in String packageName, in String shortcutId, in int stage, in int position,
in Bundle options, in UserHandle user) = 39;
in Bundle options, in UserHandle user) = 40;
void startIntent(
in PendingIntent intent, in int stage, in int position, in Bundle options) = 40;
in PendingIntent intent, in int stage, in int position, in Bundle options) = 41;
}

View File

@@ -619,6 +619,19 @@ public class OverviewProxyService extends CurrentUserTracker implements
}
}
@Override
public void exitSplitScreenOnHide(boolean exitSplitScreenOnHide) {
if (!verifyCaller("exitSplitScreenOnHide")) {
return;
}
final long token = Binder.clearCallingIdentity();
try {
mSplitScreenOptional.ifPresent(s -> s.exitSplitScreenOnHide(exitSplitScreenOnHide));
} finally {
Binder.restoreCallingIdentity(token);
}
}
@Override
public void startTask(int taskId, int stage, int position, Bundle options) {
if (!verifyCaller("startTask")) {