Merge "[wm]: Make the navigation bar in translucent mode when overlapping with freeform"
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index cf87203..61ba69f 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -284,6 +284,8 @@
/** See {@link #getNavigationBarFrameHeight} */
private int[] mNavigationBarFrameHeightForRotationDefault = new int[4];
+ private boolean mIsFreeformWindowOverlappingWithNavBar;
+
/** Cached value of {@link ScreenShapeHelper#getWindowOutsetBottomPx} */
@Px private int mWindowOutsetBottom;
@@ -2379,6 +2381,7 @@
mAllowLockscreenWhenOn = false;
mShowingDream = false;
mWindowSleepTokenNeeded = false;
+ mIsFreeformWindowOverlappingWithNavBar = false;
}
/**
@@ -2478,6 +2481,13 @@
}
}
+ // Check if the freeform window overlaps with the navigation bar area.
+ final WindowState navBarWin = hasNavigationBar() ? mNavigationBar : null;
+ if (!mIsFreeformWindowOverlappingWithNavBar && win.inFreeformWindowingMode()
+ && isOverlappingWithNavBar(win, navBarWin)) {
+ mIsFreeformWindowOverlappingWithNavBar = true;
+ }
+
// Also keep track of any windows that are dimming but not necessarily fullscreen in the
// docked stack.
if (mTopDockedOpaqueOrDimmingWindowState == null && affectsSystemUi && win.isDimming()
@@ -3458,7 +3468,11 @@
}
} else if (mNavBarOpacityMode == NAV_BAR_OPAQUE_WHEN_FREEFORM_OR_DOCKED) {
if (dockedStackVisible || freeformStackVisible || isDockedDividerResizing) {
- visibility = setNavBarOpaqueFlag(visibility);
+ if (mIsFreeformWindowOverlappingWithNavBar) {
+ visibility = setNavBarTranslucentFlag(visibility);
+ } else {
+ visibility = setNavBarOpaqueFlag(visibility);
+ }
} else if (fullscreenDrawsBackground) {
visibility = setNavBarTransparentFlag(visibility);
}
@@ -3747,4 +3761,14 @@
wm.removeView(mPointerLocationView);
mPointerLocationView = null;
}
+
+ @VisibleForTesting
+ static boolean isOverlappingWithNavBar(WindowState targetWindow, WindowState navBarWindow) {
+ if (navBarWindow == null || !navBarWindow.isVisibleLw()
+ || targetWindow.mAppToken == null || !targetWindow.isVisibleLw()) {
+ return false;
+ }
+
+ return Rect.intersects(targetWindow.getFrameLw(), navBarWindow.getFrameLw());
+ }
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
index 1684f97..6a3c81a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
@@ -32,6 +32,7 @@
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
+import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
@@ -49,10 +50,12 @@
import static org.mockito.Mockito.when;
import android.graphics.PixelFormat;
+import android.graphics.Rect;
import android.platform.test.annotations.Presubmit;
import android.view.Surface;
import android.view.WindowManager;
+import androidx.test.filters.FlakyTest;
import androidx.test.filters.SmallTest;
import org.junit.Test;
@@ -273,4 +276,37 @@
win.mHasSurface = true;
return win;
}
+
+ @Test
+ @FlakyTest(bugId = 131005232)
+ public void testOverlappingWithNavBar() {
+ final WindowState targetWin = createApplicationWindow();
+ final WindowFrames winFrame = targetWin.getWindowFrames();
+ winFrame.mFrame.set(new Rect(100, 100, 200, 200));
+
+ final WindowState navigationBar = createNavigationBarWindow();
+
+ navigationBar.getFrameLw().set(new Rect(100, 200, 200, 300));
+
+ assertFalse("Freeform is overlapping with navigation bar",
+ DisplayPolicy.isOverlappingWithNavBar(targetWin, navigationBar));
+
+ winFrame.mFrame.set(new Rect(100, 101, 200, 201));
+ assertTrue("Freeform should be overlapping with navigation bar (bottom)",
+ DisplayPolicy.isOverlappingWithNavBar(targetWin, navigationBar));
+
+ winFrame.mFrame.set(new Rect(99, 200, 199, 300));
+ assertTrue("Freeform should be overlapping with navigation bar (right)",
+ DisplayPolicy.isOverlappingWithNavBar(targetWin, navigationBar));
+
+ winFrame.mFrame.set(new Rect(199, 200, 299, 300));
+ assertTrue("Freeform should be overlapping with navigation bar (left)",
+ DisplayPolicy.isOverlappingWithNavBar(targetWin, navigationBar));
+ }
+
+ private WindowState createNavigationBarWindow() {
+ final WindowState win = createWindow(null, TYPE_NAVIGATION_BAR, "NavigationBar");
+ win.mHasSurface = true;
+ return win;
+ }
}