Merge "Update smallestScreenWidthDp when split bounds resized" into tm-dev

This commit is contained in:
Jerry Chang
2022-03-02 04:31:36 +00:00
committed by Android (Google) Code Review
7 changed files with 42 additions and 28 deletions

View File

@@ -502,16 +502,24 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
if (!mBounds1.equals(mWinBounds1) || !task1.token.equals(mWinToken1)) {
wct.setBounds(task1.token, mBounds1);
wct.setSmallestScreenWidthDp(task1.token, getSmallestWidthDp(mBounds1));
mWinBounds1.set(mBounds1);
mWinToken1 = task1.token;
}
if (!mBounds2.equals(mWinBounds2) || !task2.token.equals(mWinToken2)) {
wct.setBounds(task2.token, mBounds2);
wct.setSmallestScreenWidthDp(task2.token, getSmallestWidthDp(mBounds2));
mWinBounds2.set(mBounds2);
mWinToken2 = task2.token;
}
}
private int getSmallestWidthDp(Rect bounds) {
final int minWidth = Math.min(bounds.width(), bounds.height());
final float density = mContext.getResources().getDisplayMetrics().density;
return (int) (minWidth / density);
}
/**
* Shift configuration bounds to prevent client apps get configuration changed or relaunch. And
* restore shifted configuration bounds if it's no longer shifted.

View File

@@ -18,7 +18,6 @@ package com.android.wm.shell.splitscreen;
import android.annotation.Nullable;
import android.content.Context;
import android.graphics.Rect;
import android.view.SurfaceSession;
import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction;
@@ -49,14 +48,13 @@ class MainStage extends StageTaskListener {
return mIsActive;
}
void activate(Rect rootBounds, WindowContainerTransaction wct, boolean includingTopTask) {
void activate(WindowContainerTransaction wct, boolean includingTopTask) {
if (mIsActive) return;
final WindowContainerToken rootToken = mRootTaskInfo.token;
wct.setBounds(rootToken, rootBounds)
// Moving the root task to top after the child tasks were re-parented , or the root
// task cannot be visible and focused.
.reorder(rootToken, true /* onTop */);
// Moving the root task to top after the child tasks were re-parented , or the root
// task cannot be visible and focused.
wct.reorder(rootToken, true /* onTop */);
if (includingTopTask) {
wct.reparentTasks(
null /* currentParent */,

View File

@@ -354,8 +354,8 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
mSplitLayout.setDivideRatio(splitRatio);
// Build a request WCT that will launch both apps such that task 0 is on the main stage
// while task 1 is on the side stage.
mMainStage.activate(getMainStageBounds(), wct, false /* reparent */);
mSideStage.setBounds(getSideStageBounds(), wct);
mMainStage.activate(wct, false /* reparent */);
updateWindowBounds(mSplitLayout, wct);
// Make sure the launch options will put tasks in the corresponding split roots
addActivityOptions(mainOptions, mMainStage);
@@ -470,13 +470,14 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
mSplitLayout.setDivideRatio(splitRatio);
if (mMainStage.isActive()) {
mMainStage.moveToTop(getMainStageBounds(), wct);
mMainStage.moveToTop(wct);
} else {
// Build a request WCT that will launch both apps such that task 0 is on the main stage
// while task 1 is on the side stage.
mMainStage.activate(getMainStageBounds(), wct, false /* reparent */);
mMainStage.activate(wct, false /* reparent */);
}
mSideStage.moveToTop(getSideStageBounds(), wct);
mSideStage.moveToTop(wct);
updateWindowBounds(mSplitLayout, wct);
// Make sure the launch options will put tasks in the corresponding split roots
addActivityOptions(mainOptions, mMainStage);
@@ -774,8 +775,9 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
setSideStagePosition(startPosition, wct);
mSideStage.addTask(taskInfo, wct);
}
mMainStage.activate(getMainStageBounds(), wct, true /* includingTopTask */);
mSideStage.moveToTop(getSideStageBounds(), wct);
mMainStage.activate(wct, true /* includingTopTask */);
mSideStage.moveToTop(wct);
updateWindowBounds(mSplitLayout, wct);
}
void finishEnterSplitScreen(SurfaceControl.Transaction t) {
@@ -997,10 +999,9 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
// Exit to side stage if main stage no longer has children.
exitSplitScreen(mSideStage, EXIT_REASON_APP_FINISHED);
}
} else if (isSideStage) {
} else if (isSideStage && !mMainStage.isActive()) {
final WindowContainerTransaction wct = new WindowContainerTransaction();
mSplitLayout.init();
// Make sure the main stage is active.
prepareEnterSplitScreen(wct);
mSyncQueue.queue(wct);
mSyncQueue.runInSync(t -> {

View File

@@ -53,8 +53,8 @@ import java.io.PrintWriter;
* Base class that handle common task org. related for split-screen stages.
* Note that this class and its sub-class do not directly perform hierarchy operations.
* They only serve to hold a collection of tasks and provide APIs like
* {@link #setBounds(Rect, WindowContainerTransaction)} for the centralized {@link StageCoordinator}
* to perform operations in-sync with other containers.
* {@link #addTask(ActivityManager.RunningTaskInfo, WindowContainerTransaction)} for the centralized
* {@link StageCoordinator} to perform hierarchy operations in-sync with other containers.
*
* @see StageCoordinator
*/
@@ -310,13 +310,9 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener {
wct.reparent(task.token, mRootTaskInfo.token, true /* onTop*/);
}
void moveToTop(Rect rootBounds, WindowContainerTransaction wct) {
void moveToTop(WindowContainerTransaction wct) {
final WindowContainerToken rootToken = mRootTaskInfo.token;
wct.setBounds(rootToken, rootBounds).reorder(rootToken, true /* onTop */);
}
void setBounds(Rect bounds, WindowContainerTransaction wct) {
wct.setBounds(mRootTaskInfo.token, bounds);
wct.reorder(rootToken, true /* onTop */);
}
void reorderChild(int taskId, boolean onTop, WindowContainerTransaction wct) {

View File

@@ -28,8 +28,10 @@ import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import android.app.ActivityManager;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.window.WindowContainerTransaction;
import androidx.test.annotation.UiThreadTest;
import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -38,6 +40,7 @@ import androidx.test.filters.SmallTest;
import com.android.internal.policy.DividerSnapAlgorithm;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.ShellTestCase;
import com.android.wm.shell.TestRunningTaskInfoBuilder;
import com.android.wm.shell.common.DisplayImeController;
import org.junit.Before;
@@ -56,6 +59,7 @@ public class SplitLayoutTests extends ShellTestCase {
@Mock SplitWindowManager.ParentContainerCallbacks mCallbacks;
@Mock DisplayImeController mDisplayImeController;
@Mock ShellTaskOrganizer mTaskOrganizer;
@Mock WindowContainerTransaction mWct;
@Captor ArgumentCaptor<Runnable> mRunnableCaptor;
private SplitLayout mSplitLayout;
@@ -149,6 +153,16 @@ public class SplitLayoutTests extends ShellTestCase {
verify(mSplitLayoutHandler).onSnappedToDismiss(eq(true));
}
@Test
public void testApplyTaskChanges_updatesSmallestScreenWidthDp() {
final ActivityManager.RunningTaskInfo task1 = new TestRunningTaskInfoBuilder().build();
final ActivityManager.RunningTaskInfo task2 = new TestRunningTaskInfoBuilder().build();
mSplitLayout.applyTaskChanges(mWct, task1, task2);
verify(mWct).setSmallestScreenWidthDp(eq(task1.token), anyInt());
verify(mWct).setSmallestScreenWidthDp(eq(task2.token), anyInt());
}
private void waitDividerFlingFinished() {
verify(mSplitLayout).flingDividePosition(anyInt(), anyInt(), mRunnableCaptor.capture());
mRunnableCaptor.getValue().run();

View File

@@ -67,8 +67,7 @@ public class MainStageTests extends ShellTestCase {
@Test
public void testActiveDeactivate() {
mMainStage.activate(mRootTaskInfo.configuration.windowConfiguration.getBounds(), mWct,
true /* reparent */);
mMainStage.activate(mWct, true /* reparent */);
assertThat(mMainStage.isActive()).isTrue();
mMainStage.deactivate(mWct);

View File

@@ -44,7 +44,6 @@ import static org.mockito.Mockito.mock;
import android.annotation.NonNull;
import android.app.ActivityManager;
import android.graphics.Rect;
import android.os.IBinder;
import android.os.RemoteException;
import android.view.SurfaceControl;
@@ -421,8 +420,7 @@ public class SplitTransitionTests extends ShellTestCase {
mock(SurfaceControl.Transaction.class),
mock(SurfaceControl.Transaction.class),
mock(Transitions.TransitionFinishCallback.class));
mMainStage.activate(new Rect(0, 0, 100, 100), new WindowContainerTransaction(),
true /* includingTopTask */);
mMainStage.activate(new WindowContainerTransaction(), true /* includingTopTask */);
}
private boolean containsSplitEnter(@NonNull WindowContainerTransaction wct) {