Merge "Updating the display bounds when it changes" into sc-dev

This commit is contained in:
Shawn Lin
2021-06-28 07:00:09 +00:00
committed by Android (Google) Code Review
2 changed files with 74 additions and 32 deletions

View File

@@ -19,8 +19,8 @@ package com.android.wm.shell.hidedisplaycutout;
import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.DEFAULT_DISPLAY;
import android.content.Context; import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Insets; import android.graphics.Insets;
import android.graphics.Point;
import android.graphics.Rect; import android.graphics.Rect;
import android.util.ArrayMap; import android.util.ArrayMap;
import android.util.Log; import android.util.Log;
@@ -40,13 +40,12 @@ import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting; import androidx.annotation.VisibleForTesting;
import com.android.internal.R; import com.android.internal.R;
import com.android.wm.shell.common.DisplayChangeController;
import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.ShellExecutor;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.util.List; import java.util.List;
import java.util.concurrent.Executor;
/** /**
* Manages the display areas of hide display cutout feature. * Manages the display areas of hide display cutout feature.
@@ -76,19 +75,29 @@ class HideDisplayCutoutOrganizer extends DisplayAreaOrganizer {
@VisibleForTesting @VisibleForTesting
int mRotation; int mRotation;
/** private final DisplayController.OnDisplaysChangedListener mListener =
* Handles rotation based on OnDisplayChangingListener callback. new DisplayController.OnDisplaysChangedListener() {
*/ @Override
private final DisplayChangeController.OnDisplayChangingListener mRotationController = public void onDisplayConfigurationChanged(int displayId, Configuration newConfig) {
(display, fromRotation, toRotation, wct) -> { if (displayId != DEFAULT_DISPLAY) {
mRotation = toRotation; return;
updateBoundsAndOffsets(true /* enable */); }
final SurfaceControl.Transaction t = new SurfaceControl.Transaction(); DisplayLayout displayLayout =
applyAllBoundsAndOffsets(wct, t); mDisplayController.getDisplayLayout(DEFAULT_DISPLAY);
// Only apply t here since the server will do the wct.apply when the method if (displayLayout == null) {
// finishes. return;
t.apply(); }
}; final boolean rotationChanged = mRotation != displayLayout.rotation();
mRotation = displayLayout.rotation();
if (rotationChanged || isDisplayBoundsChanged()) {
updateBoundsAndOffsets(true /* enabled */);
final WindowContainerTransaction wct = new WindowContainerTransaction();
final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
applyAllBoundsAndOffsets(wct, t);
applyTransaction(wct, t);
}
}
};
HideDisplayCutoutOrganizer(Context context, DisplayController displayController, HideDisplayCutoutOrganizer(Context context, DisplayController displayController,
ShellExecutor mainExecutor) { ShellExecutor mainExecutor) {
@@ -154,10 +163,10 @@ class HideDisplayCutoutOrganizer extends DisplayAreaOrganizer {
* Enables hide display cutout. * Enables hide display cutout.
*/ */
void enableHideDisplayCutout() { void enableHideDisplayCutout() {
mDisplayController.addDisplayChangingController(mRotationController); mDisplayController.addDisplayWindowListener(mListener);
final Display display = mDisplayController.getDisplay(DEFAULT_DISPLAY); final DisplayLayout displayLayout = mDisplayController.getDisplayLayout(DEFAULT_DISPLAY);
if (display != null) { if (displayLayout != null) {
mRotation = display.getRotation(); mRotation = displayLayout.rotation();
} }
final List<DisplayAreaAppearedInfo> displayAreaInfos = final List<DisplayAreaAppearedInfo> displayAreaInfos =
registerOrganizer(DisplayAreaOrganizer.FEATURE_HIDE_DISPLAY_CUTOUT); registerOrganizer(DisplayAreaOrganizer.FEATURE_HIDE_DISPLAY_CUTOUT);
@@ -174,7 +183,7 @@ class HideDisplayCutoutOrganizer extends DisplayAreaOrganizer {
*/ */
void disableHideDisplayCutout() { void disableHideDisplayCutout() {
updateBoundsAndOffsets(false /* enabled */); updateBoundsAndOffsets(false /* enabled */);
mDisplayController.removeDisplayChangingController(mRotationController); mDisplayController.removeDisplayWindowListener(mListener);
unregisterOrganizer(); unregisterOrganizer();
} }
@@ -193,23 +202,35 @@ class HideDisplayCutoutOrganizer extends DisplayAreaOrganizer {
@VisibleForTesting @VisibleForTesting
Rect getDisplayBoundsOfNaturalOrientation() { Rect getDisplayBoundsOfNaturalOrientation() {
Point realSize = new Point(0, 0); final DisplayLayout displayLayout = mDisplayController.getDisplayLayout(DEFAULT_DISPLAY);
final Display display = mDisplayController.getDisplay(DEFAULT_DISPLAY); if (displayLayout == null) {
if (display != null) { return new Rect();
display.getRealSize(realSize);
} }
final boolean isDisplaySizeFlipped = isDisplaySizeFlipped(); final boolean isDisplaySizeFlipped = isDisplaySizeFlipped();
return new Rect( return new Rect(
0, 0,
0, 0,
isDisplaySizeFlipped ? realSize.y : realSize.x, isDisplaySizeFlipped ? displayLayout.height() : displayLayout.width(),
isDisplaySizeFlipped ? realSize.x : realSize.y); isDisplaySizeFlipped ? displayLayout.width() : displayLayout.height());
} }
private boolean isDisplaySizeFlipped() { private boolean isDisplaySizeFlipped() {
return mRotation == Surface.ROTATION_90 || mRotation == Surface.ROTATION_270; return mRotation == Surface.ROTATION_90 || mRotation == Surface.ROTATION_270;
} }
private boolean isDisplayBoundsChanged() {
final DisplayLayout displayLayout = mDisplayController.getDisplayLayout(DEFAULT_DISPLAY);
if (displayLayout == null) {
return false;
}
final boolean isDisplaySizeFlipped = isDisplaySizeFlipped();
final int width = isDisplaySizeFlipped ? displayLayout.height() : displayLayout.width();
final int height = isDisplaySizeFlipped ? displayLayout.width() : displayLayout.height();
return mDefaultDisplayBounds.isEmpty()
|| mDefaultDisplayBounds.width() != width
|| mDefaultDisplayBounds.height() != height;
}
/** /**
* Updates bounds and offsets according to current state. * Updates bounds and offsets according to current state.
* *
@@ -237,7 +258,6 @@ class HideDisplayCutoutOrganizer extends DisplayAreaOrganizer {
mCurrentDisplayBounds.right); mCurrentDisplayBounds.right);
} }
mCurrentDisplayBounds.inset(mCurrentCutoutInsets); mCurrentDisplayBounds.inset(mCurrentCutoutInsets);
// Replace the top bound with the max(status bar height, cutout height) if there is // Replace the top bound with the max(status bar height, cutout height) if there is
// cutout on the top side. // cutout on the top side.
mStatusBarHeight = getStatusBarHeight(); mStatusBarHeight = getStatusBarHeight();
@@ -256,7 +276,7 @@ class HideDisplayCutoutOrganizer extends DisplayAreaOrganizer {
} }
private void initDefaultValuesIfNeeded() { private void initDefaultValuesIfNeeded() {
if (!mDefaultDisplayBounds.isEmpty()) { if (!isDisplayBoundsChanged()) {
return; return;
} }
mDefaultDisplayBounds.set(getDisplayBoundsOfNaturalOrientation()); mDefaultDisplayBounds.set(getDisplayBoundsOfNaturalOrientation());

View File

@@ -50,6 +50,7 @@ import androidx.test.filters.SmallTest;
import com.android.internal.R; import com.android.internal.R;
import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.ShellExecutor;
import org.junit.Before; import org.junit.Before;
@@ -82,6 +83,8 @@ public class HideDisplayCutoutOrganizerTest {
@Mock @Mock
private Display mDisplay; private Display mDisplay;
@Mock @Mock
private DisplayLayout mDisplayLayout;
@Mock
private IWindowContainerToken mMockRealToken; private IWindowContainerToken mMockRealToken;
private WindowContainerToken mToken; private WindowContainerToken mToken;
@@ -95,6 +98,7 @@ public class HideDisplayCutoutOrganizerTest {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
when(mMockDisplayController.getDisplay(anyInt())).thenReturn(mDisplay); when(mMockDisplayController.getDisplay(anyInt())).thenReturn(mDisplay);
when(mMockDisplayController.getDisplayLayout(anyInt())).thenReturn(mDisplayLayout);
HideDisplayCutoutOrganizer organizer = new HideDisplayCutoutOrganizer( HideDisplayCutoutOrganizer organizer = new HideDisplayCutoutOrganizer(
mContext, mMockDisplayController, mMockMainExecutor); mContext, mMockDisplayController, mMockMainExecutor);
@@ -152,7 +156,7 @@ public class HideDisplayCutoutOrganizerTest {
.getDisplayCutoutInsetsOfNaturalOrientation(); .getDisplayCutoutInsetsOfNaturalOrientation();
mContext.getOrCreateTestableResources().addOverride( mContext.getOrCreateTestableResources().addOverride(
R.dimen.status_bar_height_portrait, mFakeStatusBarHeightPortrait); R.dimen.status_bar_height_portrait, mFakeStatusBarHeightPortrait);
doReturn(Surface.ROTATION_0).when(mDisplay).getRotation(); doReturn(Surface.ROTATION_0).when(mDisplayLayout).rotation();
mOrganizer.enableHideDisplayCutout(); mOrganizer.enableHideDisplayCutout();
verify(mOrganizer).registerOrganizer(DisplayAreaOrganizer.FEATURE_HIDE_DISPLAY_CUTOUT); verify(mOrganizer).registerOrganizer(DisplayAreaOrganizer.FEATURE_HIDE_DISPLAY_CUTOUT);
@@ -171,7 +175,7 @@ public class HideDisplayCutoutOrganizerTest {
.getDisplayCutoutInsetsOfNaturalOrientation(); .getDisplayCutoutInsetsOfNaturalOrientation();
mContext.getOrCreateTestableResources().addOverride( mContext.getOrCreateTestableResources().addOverride(
R.dimen.status_bar_height_landscape, mFakeStatusBarHeightLandscape); R.dimen.status_bar_height_landscape, mFakeStatusBarHeightLandscape);
doReturn(Surface.ROTATION_90).when(mDisplay).getRotation(); doReturn(Surface.ROTATION_90).when(mDisplayLayout).rotation();
mOrganizer.enableHideDisplayCutout(); mOrganizer.enableHideDisplayCutout();
verify(mOrganizer).registerOrganizer(DisplayAreaOrganizer.FEATURE_HIDE_DISPLAY_CUTOUT); verify(mOrganizer).registerOrganizer(DisplayAreaOrganizer.FEATURE_HIDE_DISPLAY_CUTOUT);
@@ -190,7 +194,7 @@ public class HideDisplayCutoutOrganizerTest {
.getDisplayCutoutInsetsOfNaturalOrientation(); .getDisplayCutoutInsetsOfNaturalOrientation();
mContext.getOrCreateTestableResources().addOverride( mContext.getOrCreateTestableResources().addOverride(
R.dimen.status_bar_height_landscape, mFakeStatusBarHeightLandscape); R.dimen.status_bar_height_landscape, mFakeStatusBarHeightLandscape);
doReturn(Surface.ROTATION_270).when(mDisplay).getRotation(); doReturn(Surface.ROTATION_270).when(mDisplayLayout).rotation();
mOrganizer.enableHideDisplayCutout(); mOrganizer.enableHideDisplayCutout();
verify(mOrganizer).registerOrganizer(DisplayAreaOrganizer.FEATURE_HIDE_DISPLAY_CUTOUT); verify(mOrganizer).registerOrganizer(DisplayAreaOrganizer.FEATURE_HIDE_DISPLAY_CUTOUT);
@@ -219,4 +223,22 @@ public class HideDisplayCutoutOrganizerTest {
assertThat(mOrganizer.mOffsetX).isEqualTo(0); assertThat(mOrganizer.mOffsetX).isEqualTo(0);
assertThat(mOrganizer.mOffsetY).isEqualTo(0); assertThat(mOrganizer.mOffsetY).isEqualTo(0);
} }
@Test
public void testDisplaySizeChange() {
doReturn(100).when(mDisplayLayout).width();
doReturn(200).when(mDisplayLayout).height();
doReturn(mFakeDefaultCutoutInsets).when(mOrganizer)
.getDisplayCutoutInsetsOfNaturalOrientation();
mContext.getOrCreateTestableResources().addOverride(
R.dimen.status_bar_height_portrait, mFakeStatusBarHeightPortrait);
doReturn(Surface.ROTATION_0).when(mDisplayLayout).rotation();
mOrganizer.enableHideDisplayCutout();
assertThat(mOrganizer.mCurrentDisplayBounds).isEqualTo(new Rect(0, 15, 100, 200));
doReturn(200).when(mDisplayLayout).width();
doReturn(400).when(mDisplayLayout).height();
mOrganizer.updateBoundsAndOffsets(true);
assertThat(mOrganizer.mCurrentDisplayBounds).isEqualTo(new Rect(0, 15, 200, 400));
}
} }