summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author TreeHugger Robot <treehugger-gerrit@google.com> 2020-06-15 10:59:15 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2020-06-15 10:59:15 +0000
commit65ddf5fa179a7fe8cd9f751d9186858be4af52cd (patch)
treec1acd1d25ab3d81fbd86330ded93b4de7032191d
parent40bdc176e1b5251c718dc3932c166334dd91b545 (diff)
parent80f4f7c8fd71f508aaea83bd5a02ac1c5505f952 (diff)
Merge "Compare letterbox and bar content frame with the same rotation" into rvc-dev
-rw-r--r--services/core/java/com/android/server/wm/BarController.java11
-rw-r--r--services/core/java/com/android/server/wm/DisplayPolicy.java64
-rw-r--r--services/core/java/com/android/server/wm/StatusBarController.java2
-rw-r--r--services/core/java/com/android/server/wm/WindowToken.java23
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java7
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java67
6 files changed, 129 insertions, 45 deletions
diff --git a/services/core/java/com/android/server/wm/BarController.java b/services/core/java/com/android/server/wm/BarController.java
index 8b14095874e3..26e0790a7604 100644
--- a/services/core/java/com/android/server/wm/BarController.java
+++ b/services/core/java/com/android/server/wm/BarController.java
@@ -59,6 +59,7 @@ public class BarController {
private final int mTransparentFlag;
private final int mStatusBarManagerId;
private final int mTranslucentWmFlag;
+ private final int mWindowType;
protected final Handler mHandler;
private final Object mServiceAquireLock = new Object();
private StatusBarManagerInternal mStatusBarInternal;
@@ -77,13 +78,14 @@ public class BarController {
private OnBarVisibilityChangedListener mVisibilityChangeListener;
BarController(String tag, int displayId, int transientFlag, int unhideFlag, int translucentFlag,
- int statusBarManagerId, int translucentWmFlag, int transparentFlag) {
+ int statusBarManagerId, int windowType, int translucentWmFlag, int transparentFlag) {
mTag = "BarController." + tag;
mDisplayId = displayId;
mTransientFlag = transientFlag;
mUnhideFlag = unhideFlag;
mTranslucentFlag = translucentFlag;
mStatusBarManagerId = statusBarManagerId;
+ mWindowType = windowType;
mTranslucentWmFlag = translucentWmFlag;
mTransparentFlag = transparentFlag;
mHandler = new BarHandler();
@@ -168,7 +170,12 @@ public class BarController {
}
boolean isTransparentAllowed(WindowState win) {
- return win == null || win.letterboxNotIntersectsOrFullyContains(mContentFrame);
+ if (win == null) {
+ return true;
+ }
+ final Rect rotatedContentFrame = win.mToken.getFixedRotationBarContentFrame(mWindowType);
+ final Rect contentFrame = rotatedContentFrame != null ? rotatedContentFrame : mContentFrame;
+ return win.letterboxNotIntersectsOrFullyContains(contentFrame);
}
boolean setBarShowingLw(final boolean show) {
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index cc4a0a255913..3c4a9ad08199 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -151,6 +151,7 @@ import android.util.IntArray;
import android.util.Pair;
import android.util.PrintWriterPrinter;
import android.util.Slog;
+import android.util.SparseArray;
import android.view.DisplayCutout;
import android.view.Gravity;
import android.view.InputChannel;
@@ -199,6 +200,7 @@ import com.android.server.wallpaper.WallpaperManagerInternal;
import com.android.server.wm.utils.InsetUtils;
import java.io.PrintWriter;
+import java.util.function.Consumer;
/**
* The policy that provides the basic behaviors and states of a display to show UI.
@@ -471,6 +473,7 @@ public class DisplayPolicy {
View.NAVIGATION_BAR_UNHIDE,
View.NAVIGATION_BAR_TRANSLUCENT,
StatusBarManager.WINDOW_NAVIGATION_BAR,
+ TYPE_NAVIGATION_BAR,
FLAG_TRANSLUCENT_NAVIGATION,
View.NAVIGATION_BAR_TRANSPARENT);
@@ -1171,6 +1174,11 @@ public class DisplayPolicy {
displayFrames.mDisplayCutoutSafe.top);
}
+ @VisibleForTesting
+ StatusBarController getStatusBarController() {
+ return mStatusBarController;
+ }
+
WindowState getStatusBar() {
return mStatusBar;
}
@@ -1469,13 +1477,16 @@ public class DisplayPolicy {
}
private void simulateLayoutDecorWindow(WindowState win, DisplayFrames displayFrames,
- InsetsState insetsState, WindowFrames simulatedWindowFrames, Runnable layout) {
+ InsetsState insetsState, WindowFrames simulatedWindowFrames,
+ SparseArray<Rect> contentFrames, Consumer<Rect> layout) {
win.setSimulatedWindowFrames(simulatedWindowFrames);
+ final Rect contentFrame = new Rect();
try {
- layout.run();
+ layout.accept(contentFrame);
} finally {
win.setSimulatedWindowFrames(null);
}
+ contentFrames.put(win.mAttrs.type, contentFrame);
mDisplayContent.getInsetsStateController().computeSimulatedState(insetsState, win,
displayFrames, simulatedWindowFrames);
}
@@ -1487,24 +1498,25 @@ public class DisplayPolicy {
* state and some temporal states. In other words, it doesn't change the window frames used to
* show on screen.
*/
- void simulateLayoutDisplay(DisplayFrames displayFrames, InsetsState insetsState, int uiMode) {
+ void simulateLayoutDisplay(DisplayFrames displayFrames, InsetsState insetsState,
+ SparseArray<Rect> barContentFrames) {
displayFrames.onBeginLayout();
updateInsetsStateForDisplayCutout(displayFrames, insetsState);
insetsState.setDisplayFrame(displayFrames.mUnrestricted);
final WindowFrames simulatedWindowFrames = new WindowFrames();
if (mNavigationBar != null) {
- simulateLayoutDecorWindow(
- mNavigationBar, displayFrames, insetsState, simulatedWindowFrames,
- () -> layoutNavigationBar(displayFrames, uiMode, mLastNavVisible,
+ simulateLayoutDecorWindow(mNavigationBar, displayFrames, insetsState,
+ simulatedWindowFrames, barContentFrames,
+ contentFrame -> layoutNavigationBar(displayFrames,
+ mDisplayContent.getConfiguration().uiMode, mLastNavVisible,
mLastNavTranslucent, mLastNavAllowedHidden,
- mLastNotificationShadeForcesShowingNavigation,
- false /* isRealLayout */));
+ mLastNotificationShadeForcesShowingNavigation, contentFrame));
}
if (mStatusBar != null) {
- simulateLayoutDecorWindow(
- mStatusBar, displayFrames, insetsState, simulatedWindowFrames,
- () -> layoutStatusBar(displayFrames, mLastSystemUiFlags,
- false /* isRealLayout */));
+ simulateLayoutDecorWindow(mStatusBar, displayFrames, insetsState,
+ simulatedWindowFrames, barContentFrames,
+ contentFrame -> layoutStatusBar(displayFrames, mLastSystemUiFlags,
+ contentFrame));
}
layoutScreenDecorWindows(displayFrames, simulatedWindowFrames);
postAdjustDisplayFrames(displayFrames);
@@ -1556,9 +1568,10 @@ public class DisplayPolicy {
boolean updateSysUiVisibility = layoutNavigationBar(displayFrames, uiMode, navVisible,
navTranslucent, navAllowedHidden, notificationShadeForcesShowingNavigation,
- true /* isRealLayout */);
+ null /* simulatedContentFrame */);
if (DEBUG_LAYOUT) Slog.i(TAG, "mDock rect:" + displayFrames.mDock);
- updateSysUiVisibility |= layoutStatusBar(displayFrames, sysui, true /* isRealLayout */);
+ updateSysUiVisibility |= layoutStatusBar(displayFrames, sysui,
+ null /* simulatedContentFrame */);
if (updateSysUiVisibility) {
updateSystemUiVisibilityLw();
}
@@ -1730,7 +1743,8 @@ public class DisplayPolicy {
displayFrames.mContent.set(dockFrame);
}
- private boolean layoutStatusBar(DisplayFrames displayFrames, int sysui, boolean isRealLayout) {
+ private boolean layoutStatusBar(DisplayFrames displayFrames, int sysui,
+ Rect simulatedContentFrame) {
// decide where the status bar goes ahead of time
if (mStatusBar == null) {
return false;
@@ -1753,12 +1767,14 @@ public class DisplayPolicy {
displayFrames.mStable.top = Math.max(displayFrames.mStable.top,
displayFrames.mDisplayCutoutSafe.top);
- if (isRealLayout) {
- // Tell the bar controller where the collapsed status bar content is.
- sTmpRect.set(windowFrames.mContentFrame);
- sTmpRect.intersect(displayFrames.mDisplayCutoutSafe);
- sTmpRect.top = windowFrames.mContentFrame.top; // Ignore top display cutout inset
- sTmpRect.bottom = displayFrames.mStable.top; // Use collapsed status bar size
+ // Tell the bar controller where the collapsed status bar content is.
+ sTmpRect.set(windowFrames.mContentFrame);
+ sTmpRect.intersect(displayFrames.mDisplayCutoutSafe);
+ sTmpRect.top = windowFrames.mContentFrame.top; // Ignore top display cutout inset
+ sTmpRect.bottom = displayFrames.mStable.top; // Use collapsed status bar size
+ if (simulatedContentFrame != null) {
+ simulatedContentFrame.set(sTmpRect);
+ } else {
mStatusBarController.setContentFrame(sTmpRect);
}
@@ -1795,7 +1811,7 @@ public class DisplayPolicy {
private boolean layoutNavigationBar(DisplayFrames displayFrames, int uiMode, boolean navVisible,
boolean navTranslucent, boolean navAllowedHidden,
- boolean statusBarForcesShowingNavigation, boolean isRealLayout) {
+ boolean statusBarForcesShowingNavigation, Rect simulatedContentFrame) {
if (mNavigationBar == null) {
return false;
}
@@ -1899,7 +1915,9 @@ public class DisplayPolicy {
navigationFrame /* visibleFrame */, sTmpRect /* decorFrame */,
navigationFrame /* stableFrame */);
mNavigationBar.computeFrame(displayFrames);
- if (isRealLayout) {
+ if (simulatedContentFrame != null) {
+ simulatedContentFrame.set(windowFrames.mContentFrame);
+ } else {
mNavigationBarPosition = navBarPosition;
mNavigationBarController.setContentFrame(windowFrames.mContentFrame);
}
diff --git a/services/core/java/com/android/server/wm/StatusBarController.java b/services/core/java/com/android/server/wm/StatusBarController.java
index cac992a67541..3564e0bce5f5 100644
--- a/services/core/java/com/android/server/wm/StatusBarController.java
+++ b/services/core/java/com/android/server/wm/StatusBarController.java
@@ -17,6 +17,7 @@
package com.android.server.wm;
import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
+import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
import static com.android.server.wm.WindowManagerInternal.AppTransitionListener;
@@ -90,6 +91,7 @@ public class StatusBarController extends BarController {
View.STATUS_BAR_UNHIDE,
View.STATUS_BAR_TRANSLUCENT,
StatusBarManager.WINDOW_STATUS_BAR,
+ TYPE_STATUS_BAR,
FLAG_TRANSLUCENT_STATUS,
View.STATUS_BAR_TRANSPARENT);
}
diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java
index 0d4cea8bc352..86aacf308068 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -48,6 +48,7 @@ import android.os.Debug;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Slog;
+import android.util.SparseArray;
import android.util.proto.ProtoOutputStream;
import android.view.DisplayAdjustments.FixedRotationAdjustments;
import android.view.DisplayInfo;
@@ -124,7 +125,7 @@ class WindowToken extends WindowContainer<WindowState> {
private static class FixedRotationTransformState {
final DisplayInfo mDisplayInfo;
final DisplayFrames mDisplayFrames;
- final InsetsState mInsetsState;
+ final InsetsState mInsetsState = new InsetsState();
final Configuration mRotatedOverrideConfiguration;
final SeamlessRotator mRotator;
/**
@@ -133,14 +134,14 @@ class WindowToken extends WindowContainer<WindowState> {
*/
final ArrayList<WindowToken> mAssociatedTokens = new ArrayList<>(3);
final ArrayList<WindowContainer<?>> mRotatedContainers = new ArrayList<>(3);
+ final SparseArray<Rect> mBarContentFrames = new SparseArray<>();
boolean mIsTransforming = true;
FixedRotationTransformState(DisplayInfo rotatedDisplayInfo,
- DisplayFrames rotatedDisplayFrames, InsetsState rotatedInsetsState,
- Configuration rotatedConfig, int currentRotation) {
+ DisplayFrames rotatedDisplayFrames, Configuration rotatedConfig,
+ int currentRotation) {
mDisplayInfo = rotatedDisplayInfo;
mDisplayFrames = rotatedDisplayFrames;
- mInsetsState = rotatedInsetsState;
mRotatedOverrideConfiguration = rotatedConfig;
// This will use unrotate as rotate, so the new and old rotation are inverted.
mRotator = new SeamlessRotator(rotatedDisplayInfo.rotation, currentRotation,
@@ -516,6 +517,12 @@ class WindowToken extends WindowContainer<WindowState> {
: null;
}
+ Rect getFixedRotationBarContentFrame(int windowType) {
+ return isFixedRotationTransforming()
+ ? mFixedRotationTransformState.mBarContentFrames.get(windowType)
+ : null;
+ }
+
InsetsState getFixedRotationTransformInsetsState() {
return isFixedRotationTransforming() ? mFixedRotationTransformState.mInsetsState : null;
}
@@ -526,12 +533,12 @@ class WindowToken extends WindowContainer<WindowState> {
if (mFixedRotationTransformState != null) {
return;
}
- final InsetsState insetsState = new InsetsState();
- mDisplayContent.getDisplayPolicy().simulateLayoutDisplay(displayFrames, insetsState,
- mDisplayContent.getConfiguration().uiMode);
mFixedRotationTransformState = new FixedRotationTransformState(info, displayFrames,
- insetsState, new Configuration(config), mDisplayContent.getRotation());
+ new Configuration(config), mDisplayContent.getRotation());
mFixedRotationTransformState.mAssociatedTokens.add(this);
+ mDisplayContent.getDisplayPolicy().simulateLayoutDisplay(displayFrames,
+ mFixedRotationTransformState.mInsetsState,
+ mFixedRotationTransformState.mBarContentFrames);
onConfigurationChanged(getParent().getConfiguration());
notifyFixedRotationTransform(true /* enabled */);
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
index 27c4e9ba8641..1922351ac1eb 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
@@ -57,6 +57,7 @@ import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.platform.test.annotations.Presubmit;
import android.util.Pair;
+import android.util.SparseArray;
import android.view.DisplayCutout;
import android.view.DisplayInfo;
import android.view.InsetsState;
@@ -776,15 +777,15 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
}
private void assertSimulateLayoutSameDisplayFrames() {
- final int uiMode = 0;
final String prefix = "";
final InsetsState simulatedInsetsState = new InsetsState();
final DisplayFrames simulatedDisplayFrames = createDisplayFrames();
- mDisplayPolicy.beginLayoutLw(mFrames, uiMode);
+ mDisplayPolicy.beginLayoutLw(mFrames, mDisplayContent.getConfiguration().uiMode);
// Force the display bounds because it is not synced with display frames in policy test.
mDisplayContent.getWindowConfiguration().setBounds(mFrames.mUnrestricted);
mDisplayContent.getInsetsStateController().onPostLayout();
- mDisplayPolicy.simulateLayoutDisplay(simulatedDisplayFrames, simulatedInsetsState, uiMode);
+ mDisplayPolicy.simulateLayoutDisplay(simulatedDisplayFrames, simulatedInsetsState,
+ new SparseArray<>() /* barContentFrames */);
final StringWriter realFramesDump = new StringWriter();
mFrames.dump(prefix, new PrintWriter(realFramesDump));
diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
index 665cf83cd33c..d584d1533807 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -24,6 +24,7 @@ import static android.view.Surface.ROTATION_270;
import static android.view.Surface.ROTATION_90;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.never;
@@ -491,7 +492,10 @@ public class SizeCompatTests extends ActivityTestsBase {
mService.mWindowManager.mIsFixedRotationTransformEnabled = true;
final int dw = 1000;
final int dh = 2500;
- setUpDisplaySizeWithApp(dw, dh);
+ final int notchHeight = 200;
+ setUpApp(new TestDisplayContent.Builder(mService, dw, dh).setNotch(notchHeight).build());
+ addStatusBar(mActivity.mDisplayContent);
+
mActivity.mDisplayContent.prepareAppTransition(WindowManager.TRANSIT_ACTIVITY_OPEN,
false /* alwaysKeepCurrent */);
mActivity.mDisplayContent.mOpeningApps.add(mActivity);
@@ -503,31 +507,76 @@ public class SizeCompatTests extends ActivityTestsBase {
// Display keeps in original orientation.
assertEquals(Configuration.ORIENTATION_PORTRAIT,
mActivity.mDisplayContent.getConfiguration().orientation);
- // Activity bounds should be [350, 0 - 2150, 1000] in landscape. Its width=1000*1.8=1800.
+ // The width should be restricted by the max aspect ratio = 1000 * 1.8 = 1800.
assertEquals((int) (dw * maxAspect), mActivity.getBounds().width());
- // The bounds should be horizontal centered: (2500-1900)/2=350.
- assertEquals((dh - mActivity.getBounds().width()) / 2, mActivity.getBounds().left);
+ // The notch is at the left side of the landscape activity. The bounds should be horizontal
+ // centered in the remaining area [200, 0 - 2500, 1000], so its left should be
+ // 200 + (2300 - 1800) / 2 = 450. The bounds should be [450, 0 - 2250, 1000].
+ assertEquals(notchHeight + (dh - notchHeight - mActivity.getBounds().width()) / 2,
+ mActivity.getBounds().left);
// The letterbox needs a main window to layout.
- addWindowToActivity(mActivity);
+ final WindowState w = addWindowToActivity(mActivity);
// Compute the frames of the window and invoke {@link ActivityRecord#layoutLetterbox}.
mActivity.mRootWindowContainer.performSurfacePlacement();
- // The letterbox insets should be [350, 0 - 350, 0].
+ // The letterbox insets should be [450, 0 - 250, 0].
assertEquals(new Rect(mActivity.getBounds().left, 0, dh - mActivity.getBounds().right, 0),
mActivity.getLetterboxInsets());
+
+ final StatusBarController statusBarController =
+ mActivity.mDisplayContent.getDisplayPolicy().getStatusBarController();
+ // The activity doesn't fill the display, so the letterbox of the rotated activity is
+ // overlapped with the rotated content frame of status bar. Hence the status bar shouldn't
+ // be transparent.
+ assertFalse(statusBarController.isTransparentAllowed(w));
+
+ // Make the activity fill the display.
+ prepareUnresizable(10 /* maxAspect */, SCREEN_ORIENTATION_LANDSCAPE);
+ w.mWinAnimator.mDrawState = WindowStateAnimator.HAS_DRAWN;
+ // Refresh the letterbox.
+ mActivity.mRootWindowContainer.performSurfacePlacement();
+
+ // The letterbox should only cover the notch area, so status bar can be transparent.
+ assertEquals(new Rect(notchHeight, 0, 0, 0), mActivity.getLetterboxInsets());
+ assertTrue(statusBarController.isTransparentAllowed(w));
}
- private WindowState addWindowToActivity(ActivityRecord activity) {
+ private static WindowState addWindowToActivity(ActivityRecord activity) {
final WindowManager.LayoutParams params = new WindowManager.LayoutParams();
params.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
final WindowTestUtils.TestWindowState w = new WindowTestUtils.TestWindowState(
- mService.mWindowManager, mock(Session.class), new TestIWindow(), params, mActivity);
+ activity.mWmService, mock(Session.class), new TestIWindow(), params, activity);
WindowTestsBase.makeWindowVisible(w);
w.mWinAnimator.mDrawState = WindowStateAnimator.HAS_DRAWN;
- mActivity.addWindow(w);
+ activity.addWindow(w);
return w;
}
+ private static void addStatusBar(DisplayContent displayContent) {
+ final DisplayPolicy displayPolicy = displayContent.getDisplayPolicy();
+ doReturn(true).when(displayPolicy).hasStatusBar();
+ displayPolicy.onConfigurationChanged();
+
+ final WindowTestUtils.TestWindowToken token = WindowTestUtils.createTestWindowToken(
+ WindowManager.LayoutParams.TYPE_STATUS_BAR, displayContent);
+ final WindowManager.LayoutParams attrs =
+ new WindowManager.LayoutParams(WindowManager.LayoutParams.TYPE_STATUS_BAR);
+ attrs.gravity = android.view.Gravity.TOP;
+ attrs.layoutInDisplayCutoutMode =
+ WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+ attrs.setFitInsetsTypes(0 /* types */);
+ final WindowTestUtils.TestWindowState statusBar = new WindowTestUtils.TestWindowState(
+ displayContent.mWmService, mock(Session.class), new TestIWindow(), attrs, token);
+ token.addWindow(statusBar);
+ statusBar.setRequestedSize(displayContent.mBaseDisplayWidth,
+ displayContent.getDisplayUiContext().getResources().getDimensionPixelSize(
+ com.android.internal.R.dimen.status_bar_height));
+
+ displayPolicy.addWindowLw(statusBar, attrs);
+ displayPolicy.beginLayoutLw(displayContent.mDisplayFrames,
+ displayContent.getConfiguration().uiMode);
+ }
+
/**
* Setup {@link #mActivity} as a size-compat-mode-able activity with fixed aspect and/or
* orientation.