Merge "Fix wrong divider position after rotation" into udc-dev
This commit is contained in:
@@ -63,8 +63,10 @@ import com.android.internal.policy.DockedDividerUtils;
|
||||
import com.android.wm.shell.R;
|
||||
import com.android.wm.shell.ShellTaskOrganizer;
|
||||
import com.android.wm.shell.animation.Interpolators;
|
||||
import com.android.wm.shell.common.DisplayController;
|
||||
import com.android.wm.shell.common.DisplayImeController;
|
||||
import com.android.wm.shell.common.DisplayInsetsController;
|
||||
import com.android.wm.shell.common.DisplayLayout;
|
||||
import com.android.wm.shell.common.InteractionJankMonitorUtils;
|
||||
import com.android.wm.shell.common.split.SplitScreenConstants.SplitPosition;
|
||||
|
||||
@@ -104,6 +106,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
|
||||
private final Rect mWinBounds2 = new Rect();
|
||||
private final SplitLayoutHandler mSplitLayoutHandler;
|
||||
private final SplitWindowManager mSplitWindowManager;
|
||||
private final DisplayController mDisplayController;
|
||||
private final DisplayImeController mDisplayImeController;
|
||||
private final ImePositionProcessor mImePositionProcessor;
|
||||
private final ResizingEffectPolicy mSurfaceEffectPolicy;
|
||||
@@ -128,13 +131,14 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
|
||||
public SplitLayout(String windowName, Context context, Configuration configuration,
|
||||
SplitLayoutHandler splitLayoutHandler,
|
||||
SplitWindowManager.ParentContainerCallbacks parentContainerCallbacks,
|
||||
DisplayImeController displayImeController, ShellTaskOrganizer taskOrganizer,
|
||||
int parallaxType) {
|
||||
DisplayController displayController, DisplayImeController displayImeController,
|
||||
ShellTaskOrganizer taskOrganizer, int parallaxType) {
|
||||
mContext = context.createConfigurationContext(configuration);
|
||||
mOrientation = configuration.orientation;
|
||||
mRotation = configuration.windowConfiguration.getRotation();
|
||||
mDensity = configuration.densityDpi;
|
||||
mSplitLayoutHandler = splitLayoutHandler;
|
||||
mDisplayController = displayController;
|
||||
mDisplayImeController = displayImeController;
|
||||
mSplitWindowManager = new SplitWindowManager(windowName, mContext, configuration,
|
||||
parentContainerCallbacks);
|
||||
@@ -145,7 +149,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
|
||||
updateDividerConfig(mContext);
|
||||
|
||||
mRootBounds.set(configuration.windowConfiguration.getBounds());
|
||||
mDividerSnapAlgorithm = getSnapAlgorithm(mContext, mRootBounds, null);
|
||||
mDividerSnapAlgorithm = getSnapAlgorithm(mContext, mRootBounds);
|
||||
resetDividerPosition();
|
||||
|
||||
mDimNonImeSide = mContext.getResources().getBoolean(R.bool.config_dimNonImeAttachedSide);
|
||||
@@ -314,7 +318,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
|
||||
mRotation = rotation;
|
||||
mDensity = density;
|
||||
mUiMode = uiMode;
|
||||
mDividerSnapAlgorithm = getSnapAlgorithm(mContext, mRootBounds, null);
|
||||
mDividerSnapAlgorithm = getSnapAlgorithm(mContext, mRootBounds);
|
||||
updateDividerConfig(mContext);
|
||||
initDividerPosition(mTempRect);
|
||||
updateInvisibleRect();
|
||||
@@ -324,7 +328,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
|
||||
|
||||
/** Rotate the layout to specific rotation and calculate new bounds. The stable insets value
|
||||
* should be calculated by display layout. */
|
||||
public void rotateTo(int newRotation, Rect stableInsets) {
|
||||
public void rotateTo(int newRotation) {
|
||||
final int rotationDelta = (newRotation - mRotation + 4) % 4;
|
||||
final boolean changeOrient = (rotationDelta % 2) != 0;
|
||||
|
||||
@@ -337,7 +341,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
|
||||
// We only need new bounds here, other configuration should be update later.
|
||||
mTempRect.set(mRootBounds);
|
||||
mRootBounds.set(tmpRect);
|
||||
mDividerSnapAlgorithm = getSnapAlgorithm(mContext, mRootBounds, stableInsets);
|
||||
mDividerSnapAlgorithm = getSnapAlgorithm(mContext, mRootBounds);
|
||||
initDividerPosition(mTempRect);
|
||||
}
|
||||
|
||||
@@ -548,10 +552,9 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
|
||||
return mDividerSnapAlgorithm.calculateSnapTarget(position, velocity, hardDismiss);
|
||||
}
|
||||
|
||||
private DividerSnapAlgorithm getSnapAlgorithm(Context context, Rect rootBounds,
|
||||
@Nullable Rect stableInsets) {
|
||||
private DividerSnapAlgorithm getSnapAlgorithm(Context context, Rect rootBounds) {
|
||||
final boolean isLandscape = isLandscape(rootBounds);
|
||||
final Rect insets = stableInsets != null ? stableInsets : getDisplayInsets(context);
|
||||
final Rect insets = getDisplayStableInsets(context);
|
||||
|
||||
// Make split axis insets value same as the larger one to avoid bounds1 and bounds2
|
||||
// have difference for avoiding size-compat mode when switching unresizable apps in
|
||||
@@ -634,7 +637,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
|
||||
public void splitSwitching(SurfaceControl.Transaction t, SurfaceControl leash1,
|
||||
SurfaceControl leash2, Consumer<Rect> finishCallback) {
|
||||
final boolean isLandscape = isLandscape();
|
||||
final Rect insets = getDisplayInsets(mContext);
|
||||
final Rect insets = getDisplayStableInsets(mContext);
|
||||
insets.set(isLandscape ? insets.left : 0, isLandscape ? 0 : insets.top,
|
||||
isLandscape ? insets.right : 0, isLandscape ? 0 : insets.bottom);
|
||||
|
||||
@@ -705,13 +708,17 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
|
||||
return animator;
|
||||
}
|
||||
|
||||
private static Rect getDisplayInsets(Context context) {
|
||||
return context.getSystemService(WindowManager.class)
|
||||
.getMaximumWindowMetrics()
|
||||
.getWindowInsets()
|
||||
.getInsetsIgnoringVisibility(WindowInsets.Type.systemBars()
|
||||
| WindowInsets.Type.displayCutout())
|
||||
.toRect();
|
||||
private Rect getDisplayStableInsets(Context context) {
|
||||
final DisplayLayout displayLayout =
|
||||
mDisplayController.getDisplayLayout(context.getDisplayId());
|
||||
return displayLayout != null
|
||||
? displayLayout.stableInsets()
|
||||
: context.getSystemService(WindowManager.class)
|
||||
.getMaximumWindowMetrics()
|
||||
.getWindowInsets()
|
||||
.getInsetsIgnoringVisibility(WindowInsets.Type.systemBars()
|
||||
| WindowInsets.Type.displayCutout())
|
||||
.toRect();
|
||||
}
|
||||
|
||||
private static boolean isLandscape(Rect bounds) {
|
||||
@@ -784,7 +791,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
|
||||
|
||||
private int getSmallestWidthDp(Rect bounds) {
|
||||
mTempRect.set(bounds);
|
||||
mTempRect.inset(getDisplayInsets(mContext));
|
||||
mTempRect.inset(getDisplayStableInsets(mContext));
|
||||
final int minWidth = Math.min(mTempRect.width(), mTempRect.height());
|
||||
final float density = mContext.getResources().getDisplayMetrics().density;
|
||||
return (int) (minWidth / density);
|
||||
|
||||
@@ -122,7 +122,6 @@ import com.android.wm.shell.ShellTaskOrganizer;
|
||||
import com.android.wm.shell.common.DisplayController;
|
||||
import com.android.wm.shell.common.DisplayImeController;
|
||||
import com.android.wm.shell.common.DisplayInsetsController;
|
||||
import com.android.wm.shell.common.DisplayLayout;
|
||||
import com.android.wm.shell.common.ScreenshotUtils;
|
||||
import com.android.wm.shell.common.ShellExecutor;
|
||||
import com.android.wm.shell.common.SyncTransactionQueue;
|
||||
@@ -171,7 +170,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
private final StageListenerImpl mMainStageListener = new StageListenerImpl();
|
||||
private final SideStage mSideStage;
|
||||
private final StageListenerImpl mSideStageListener = new StageListenerImpl();
|
||||
private final DisplayLayout mDisplayLayout;
|
||||
@SplitPosition
|
||||
private int mSideStagePosition = SPLIT_POSITION_BOTTOM_OR_RIGHT;
|
||||
|
||||
@@ -311,7 +309,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
mSplitTransitions = new SplitScreenTransitions(transactionPool, transitions,
|
||||
this::onTransitionAnimationComplete, this);
|
||||
mDisplayController.addDisplayWindowListener(this);
|
||||
mDisplayLayout = new DisplayLayout(displayController.getDisplayLayout(displayId));
|
||||
transitions.addHandler(this);
|
||||
mSplitUnsupportedToast = Toast.makeText(mContext,
|
||||
R.string.dock_non_resizeble_failed_to_dock_text, Toast.LENGTH_SHORT);
|
||||
@@ -345,7 +342,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
mMainExecutor = mainExecutor;
|
||||
mRecentTasks = recentTasks;
|
||||
mDisplayController.addDisplayWindowListener(this);
|
||||
mDisplayLayout = new DisplayLayout();
|
||||
transitions.addHandler(this);
|
||||
mSplitUnsupportedToast = Toast.makeText(mContext,
|
||||
R.string.dock_non_resizeble_failed_to_dock_text, Toast.LENGTH_SHORT);
|
||||
@@ -1689,7 +1685,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
if (mSplitLayout == null) {
|
||||
mSplitLayout = new SplitLayout(TAG + "SplitDivider", mContext,
|
||||
mRootTaskInfo.configuration, this, mParentContainerCallbacks,
|
||||
mDisplayImeController, mTaskOrganizer,
|
||||
mDisplayController, mDisplayImeController, mTaskOrganizer,
|
||||
PARALLAX_ALIGN_CENTER /* parallaxType */);
|
||||
mDisplayInsetsController.addInsetsChangedListener(mDisplayId, mSplitLayout);
|
||||
}
|
||||
@@ -2153,8 +2149,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
if (displayId != DEFAULT_DISPLAY) {
|
||||
return;
|
||||
}
|
||||
mDisplayLayout.set(mDisplayController.getDisplayLayout(displayId));
|
||||
|
||||
if (mSplitLayout != null && mSplitLayout.isDensityChanged(newConfig.densityDpi)
|
||||
&& mMainStage.isActive()
|
||||
&& mSplitLayout.updateConfiguration(newConfig)
|
||||
@@ -2171,10 +2165,9 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
|
||||
private void onDisplayChange(int displayId, int fromRotation, int toRotation,
|
||||
@Nullable DisplayAreaInfo newDisplayAreaInfo, WindowContainerTransaction wct) {
|
||||
if (!mMainStage.isActive()) return;
|
||||
if (displayId != DEFAULT_DISPLAY || !mMainStage.isActive()) return;
|
||||
|
||||
mDisplayLayout.rotateTo(mContext.getResources(), toRotation);
|
||||
mSplitLayout.rotateTo(toRotation, mDisplayLayout.stableInsets());
|
||||
mSplitLayout.rotateTo(toRotation);
|
||||
if (newDisplayAreaInfo != null) {
|
||||
mSplitLayout.updateConfiguration(newDisplayAreaInfo.configuration);
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
@@ -41,6 +42,7 @@ 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.DisplayController;
|
||||
import com.android.wm.shell.common.DisplayImeController;
|
||||
|
||||
import org.junit.Before;
|
||||
@@ -57,6 +59,7 @@ import org.mockito.MockitoAnnotations;
|
||||
public class SplitLayoutTests extends ShellTestCase {
|
||||
@Mock SplitLayout.SplitLayoutHandler mSplitLayoutHandler;
|
||||
@Mock SplitWindowManager.ParentContainerCallbacks mCallbacks;
|
||||
@Mock DisplayController mDisplayController;
|
||||
@Mock DisplayImeController mDisplayImeController;
|
||||
@Mock ShellTaskOrganizer mTaskOrganizer;
|
||||
@Mock WindowContainerTransaction mWct;
|
||||
@@ -72,6 +75,7 @@ public class SplitLayoutTests extends ShellTestCase {
|
||||
getConfiguration(),
|
||||
mSplitLayoutHandler,
|
||||
mCallbacks,
|
||||
mDisplayController,
|
||||
mDisplayImeController,
|
||||
mTaskOrganizer,
|
||||
SplitLayout.PARALLAX_NONE));
|
||||
@@ -100,6 +104,10 @@ public class SplitLayoutTests extends ShellTestCase {
|
||||
// Verify updateConfiguration returns true if the density changed.
|
||||
config.densityDpi = 123;
|
||||
assertThat(mSplitLayout.updateConfiguration(config)).isTrue();
|
||||
|
||||
// Verify updateConfiguration checks the current DisplayLayout
|
||||
verify(mDisplayController, times(5)) // init * 1 + updateConfiguration * 4
|
||||
.getDisplayLayout(anyInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -168,6 +176,14 @@ public class SplitLayoutTests extends ShellTestCase {
|
||||
verify(mWct).setSmallestScreenWidthDp(eq(task2.token), anyInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRoateTo_checksDisplayLayout() {
|
||||
mSplitLayout.rotateTo(90);
|
||||
|
||||
verify(mDisplayController, times(2)) // init * 1 + rotateTo * 1
|
||||
.getDisplayLayout(anyInt());
|
||||
}
|
||||
|
||||
private void waitDividerFlingFinished() {
|
||||
verify(mSplitLayout).flingDividePosition(anyInt(), anyInt(), anyInt(),
|
||||
mRunnableCaptor.capture());
|
||||
|
||||
Reference in New Issue
Block a user