Prevent rendering divider bar into wrong orientation
The display area's bounds and orientation changed might be callbacked seperatedly when the device's folded state changed, causing the SplitLayout rendered divider bar into wrong orientation. This makes sure to update divider bar and split layout correspondingly when the orientation, rotation and root bounds chagned. Fix: 189101216 Test: atest WMShellUnitTests Change-Id: Ie5d7132e4122b82d9b5b404a40f97cca3095ce2c
This commit is contained in:
@@ -92,12 +92,16 @@ public final class SplitLayout {
|
||||
private DividerSnapAlgorithm mDividerSnapAlgorithm;
|
||||
private int mDividePosition;
|
||||
private boolean mInitialized = false;
|
||||
private int mOrientation;
|
||||
private int mRotation;
|
||||
|
||||
public SplitLayout(String windowName, Context context, Configuration configuration,
|
||||
SplitLayoutHandler splitLayoutHandler,
|
||||
SplitWindowManager.ParentContainerCallbacks parentContainerCallbacks,
|
||||
DisplayImeController displayImeController, ShellTaskOrganizer taskOrganizer) {
|
||||
mContext = context.createConfigurationContext(configuration);
|
||||
mOrientation = configuration.orientation;
|
||||
mRotation = configuration.windowConfiguration.getRotation();
|
||||
mSplitLayoutHandler = splitLayoutHandler;
|
||||
mDisplayImeController = displayImeController;
|
||||
mSplitWindowManager = new SplitWindowManager(
|
||||
@@ -144,25 +148,37 @@ public final class SplitLayout {
|
||||
|
||||
/** Applies new configuration, returns {@code false} if there's no effect to the layout. */
|
||||
public boolean updateConfiguration(Configuration configuration) {
|
||||
boolean affectsLayout = false;
|
||||
|
||||
// Make sure to render the divider bar with proper resources that matching the screen
|
||||
// orientation.
|
||||
final int orientation = configuration.orientation;
|
||||
if (orientation != mOrientation) {
|
||||
mOrientation = orientation;
|
||||
mContext = mContext.createConfigurationContext(configuration);
|
||||
mSplitWindowManager.setConfiguration(configuration);
|
||||
affectsLayout = true;
|
||||
}
|
||||
|
||||
// Update the split bounds when necessary. Besides root bounds changed, split bounds need to
|
||||
// be updated when the rotation changed to cover the case that users rotated the screen 180
|
||||
// degrees.
|
||||
final int rotation = configuration.windowConfiguration.getRotation();
|
||||
final Rect rootBounds = configuration.windowConfiguration.getBounds();
|
||||
if (mRootBounds.equals(rootBounds)) {
|
||||
return false;
|
||||
if (rotation != mRotation || !mRootBounds.equals(rootBounds)) {
|
||||
mRootBounds.set(rootBounds);
|
||||
mDividerSnapAlgorithm = getSnapAlgorithm(mContext, mRootBounds);
|
||||
resetDividerPosition();
|
||||
affectsLayout = true;
|
||||
}
|
||||
|
||||
mContext = mContext.createConfigurationContext(configuration);
|
||||
mSplitWindowManager.setConfiguration(configuration);
|
||||
mRootBounds.set(rootBounds);
|
||||
mDividerSnapAlgorithm = getSnapAlgorithm(mContext, mRootBounds);
|
||||
resetDividerPosition();
|
||||
|
||||
// Don't inflate divider bar if it is not initialized.
|
||||
if (!mInitialized) {
|
||||
return false;
|
||||
if (mInitialized && affectsLayout) {
|
||||
release();
|
||||
init();
|
||||
return true;
|
||||
}
|
||||
|
||||
release();
|
||||
init();
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Updates recording bounds of divider window and both of the splits. */
|
||||
|
||||
@@ -61,7 +61,7 @@ public class SplitLayoutTests extends ShellTestCase {
|
||||
mSplitLayout = new SplitLayout(
|
||||
"TestSplitLayout",
|
||||
mContext,
|
||||
getConfiguration(false),
|
||||
getConfiguration(),
|
||||
mSplitLayoutHandler,
|
||||
b -> b.setParent(mRootLeash),
|
||||
mDisplayImeController,
|
||||
@@ -71,9 +71,23 @@ public class SplitLayoutTests extends ShellTestCase {
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void testUpdateConfiguration() {
|
||||
final Configuration config = getConfiguration();
|
||||
mSplitLayout.init();
|
||||
assertThat(mSplitLayout.updateConfiguration(getConfiguration(false))).isFalse();
|
||||
assertThat(mSplitLayout.updateConfiguration(getConfiguration(true))).isTrue();
|
||||
|
||||
// Verify it returns true if new config won't affect split layout.
|
||||
assertThat(mSplitLayout.updateConfiguration(config)).isFalse();
|
||||
|
||||
// Verify updateConfiguration returns true if the orientation changed.
|
||||
config.orientation = ORIENTATION_LANDSCAPE;
|
||||
assertThat(mSplitLayout.updateConfiguration(config)).isTrue();
|
||||
|
||||
// Verify updateConfiguration returns true if it rotated.
|
||||
config.windowConfiguration.setRotation(1);
|
||||
assertThat(mSplitLayout.updateConfiguration(config)).isTrue();
|
||||
|
||||
// Verify updateConfiguration returns true if the root bounds changed.
|
||||
config.windowConfiguration.setBounds(new Rect(0, 0, 2160, 1080));
|
||||
assertThat(mSplitLayout.updateConfiguration(config)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -108,12 +122,13 @@ public class SplitLayoutTests extends ShellTestCase {
|
||||
verify(mSplitLayoutHandler).onSnappedToDismiss(eq(true));
|
||||
}
|
||||
|
||||
private static Configuration getConfiguration(boolean isLandscape) {
|
||||
private static Configuration getConfiguration() {
|
||||
final Configuration configuration = new Configuration();
|
||||
configuration.unset();
|
||||
configuration.orientation = isLandscape ? ORIENTATION_LANDSCAPE : ORIENTATION_PORTRAIT;
|
||||
configuration.orientation = ORIENTATION_PORTRAIT;
|
||||
configuration.windowConfiguration.setRotation(0);
|
||||
configuration.windowConfiguration.setBounds(
|
||||
new Rect(0, 0, isLandscape ? 2160 : 1080, isLandscape ? 1080 : 2160));
|
||||
new Rect(0, 0, 1080, 2160));
|
||||
return configuration;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user