Merge "Updating the display bounds when it changes" into sc-dev
This commit is contained in:
@@ -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());
|
||||||
|
|||||||
@@ -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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user