summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/wm/InsetsPolicy.java80
-rw-r--r--services/core/java/com/android/server/wm/Session.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java45
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java4
4 files changed, 103 insertions, 28 deletions
diff --git a/services/core/java/com/android/server/wm/InsetsPolicy.java b/services/core/java/com/android/server/wm/InsetsPolicy.java
index 03f025b1f0f4..d0d7f493b969 100644
--- a/services/core/java/com/android/server/wm/InsetsPolicy.java
+++ b/services/core/java/com/android/server/wm/InsetsPolicy.java
@@ -75,6 +75,18 @@ class InsetsPolicy {
/** Used to show system bars permanently. This will affect the layout. */
private final InsetsControlTarget mPermanentControlTarget;
+ /**
+ * Used to override the visibility of {@link Type#statusBars()} when dispatching insets to
+ * clients.
+ */
+ private InsetsControlTarget mFakeStatusControlTarget;
+
+ /**
+ * Used to override the visibility of {@link Type#navigationBars()} when dispatching insets to
+ * clients.
+ */
+ private InsetsControlTarget mFakeNavControlTarget;
+
private WindowState mFocusedWin;
private final BarWindow mStatusBar = new BarWindow(StatusBarManager.WINDOW_STATUS_BAR);
private final BarWindow mNavBar = new BarWindow(StatusBarManager.WINDOW_NAVIGATION_BAR);
@@ -101,25 +113,25 @@ class InsetsPolicy {
abortTransient();
}
mFocusedWin = focusedWin;
+ final WindowState notificationShade = mPolicy.getNotificationShade();
+ final WindowState topApp = mPolicy.getTopFullscreenOpaqueWindow();
final InsetsControlTarget statusControlTarget =
getStatusControlTarget(focusedWin, false /* fake */);
+ mFakeStatusControlTarget = statusControlTarget == mTransientControlTarget
+ ? getStatusControlTarget(focusedWin, true /* fake */)
+ : statusControlTarget == notificationShade
+ ? getStatusControlTarget(topApp, true /* fake */)
+ : null;
final InsetsControlTarget navControlTarget =
getNavControlTarget(focusedWin, false /* fake */);
- final WindowState notificationShade = mPolicy.getNotificationShade();
- final WindowState topApp = mPolicy.getTopFullscreenOpaqueWindow();
+ mFakeNavControlTarget = navControlTarget == mTransientControlTarget
+ ? getNavControlTarget(focusedWin, true /* fake */)
+ : navControlTarget == notificationShade
+ ? getNavControlTarget(topApp, true /* fake */)
+ : null;
mStateController.onBarControlTargetChanged(
- statusControlTarget,
- statusControlTarget == mTransientControlTarget
- ? getStatusControlTarget(focusedWin, true /* fake */)
- : statusControlTarget == notificationShade
- ? getStatusControlTarget(topApp, true /* fake */)
- : null,
- navControlTarget,
- navControlTarget == mTransientControlTarget
- ? getNavControlTarget(focusedWin, true /* fake */)
- : navControlTarget == notificationShade
- ? getNavControlTarget(topApp, true /* fake */)
- : null);
+ statusControlTarget, mFakeStatusControlTarget,
+ navControlTarget, mFakeNavControlTarget);
mStatusBar.updateVisibility(statusControlTarget, Type.statusBars());
mNavBar.updateVisibility(navControlTarget, Type.navigationBars());
}
@@ -204,7 +216,7 @@ class InsetsPolicy {
boolean includesTransient) {
InsetsState state;
if (!includesTransient) {
- state = adjustVisibilityForTransientTypes(originalState);
+ state = adjustVisibilityForFakeControllingSources(originalState);
} else {
state = originalState;
}
@@ -319,21 +331,37 @@ class InsetsPolicy {
return state;
}
- private InsetsState adjustVisibilityForTransientTypes(InsetsState originalState) {
+ private InsetsState adjustVisibilityForFakeControllingSources(InsetsState originalState) {
+ if (mFakeStatusControlTarget == null && mFakeNavControlTarget == null) {
+ return originalState;
+ }
InsetsState state = originalState;
for (int i = state.sourceSize() - 1; i >= 0; i--) {
final InsetsSource source = state.sourceAt(i);
- if (isTransient(source.getType()) && source.isVisible()) {
- if (state == originalState) {
- // The source will be modified, create a non-deep copy to store the new one.
- state = new InsetsState(originalState);
- }
- // Replace the source with a copy in invisible state.
- final InsetsSource outSource = new InsetsSource(source);
- outSource.setVisible(false);
- state.addSource(outSource);
- }
+ state = adjustVisibilityForFakeControllingSource(state, Type.statusBars(), source,
+ mFakeStatusControlTarget);
+ state = adjustVisibilityForFakeControllingSource(state, Type.navigationBars(), source,
+ mFakeNavControlTarget);
+ }
+ return state;
+ }
+
+ private static InsetsState adjustVisibilityForFakeControllingSource(InsetsState originalState,
+ @InsetsType int type, InsetsSource source, InsetsControlTarget target) {
+ if (source.getType() != type || target == null) {
+ return originalState;
}
+ final boolean isRequestedVisible = target.isRequestedVisible(type);
+ if (source.isVisible() == isRequestedVisible) {
+ return originalState;
+ }
+ // The source will be modified, create a non-deep copy to store the new one.
+ final InsetsState state = new InsetsState(originalState);
+
+ // Replace the source with a copy with the overridden visibility.
+ final InsetsSource outSource = new InsetsSource(source);
+ outSource.setVisible(isRequestedVisible);
+ state.addSource(outSource);
return state;
}
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index d9881c7c46c5..2bc701000398 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -108,7 +108,7 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
private final ArraySet<WindowSurfaceController> mAlertWindowSurfaces = new ArraySet<>();
private final DragDropController mDragDropController;
final boolean mCanAddInternalSystemWindow;
- final boolean mCanForceShowingInsets;
+ boolean mCanForceShowingInsets;
private final boolean mCanStartTasksFromRecents;
final boolean mCanCreateSystemApplicationOverlay;
diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java
index 411712e6b577..ffa1ed926766 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java
@@ -327,6 +327,7 @@ public class InsetsPolicyTest extends WindowTestsBase {
addNavigationBar().getControllableInsetProvider().getSource();
statusBarSource.setVisible(false);
navBarSource.setVisible(false);
+ mAppWindow.setRequestedVisibleTypes(0, navigationBars() | statusBars());
mAppWindow.mAboveInsetsState.addSource(navBarSource);
mAppWindow.mAboveInsetsState.addSource(statusBarSource);
final InsetsPolicy policy = mDisplayContent.getInsetsPolicy();
@@ -387,6 +388,50 @@ public class InsetsPolicyTest extends WindowTestsBase {
assertFalse(policy.isTransient(navigationBars()));
}
+ @Test
+ public void testFakeControlTarget_overrideVisibilityReceivedByWindows() {
+ final WindowState statusBar = addStatusBar();
+ final InsetsSourceProvider statusBarProvider = statusBar.getControllableInsetProvider();
+ statusBar.mSession.mCanForceShowingInsets = true;
+ statusBar.setHasSurface(true);
+ statusBarProvider.setServerVisible(true);
+
+ final InsetsSource statusBarSource = statusBarProvider.getSource();
+ final int statusBarId = statusBarSource.getId();
+ assertTrue(statusBarSource.isVisible());
+
+ final WindowState app1 = addWindow(TYPE_APPLICATION, "app1");
+ app1.mAboveInsetsState.addSource(statusBarSource);
+ assertTrue(app1.getInsetsState().peekSource(statusBarId).isVisible());
+
+ final WindowState app2 = addWindow(TYPE_APPLICATION, "app2");
+ app2.mAboveInsetsState.addSource(statusBarSource);
+ assertTrue(app2.getInsetsState().peekSource(statusBarId).isVisible());
+
+ app2.setRequestedVisibleTypes(0, navigationBars() | statusBars());
+ mDisplayContent.getInsetsPolicy().updateBarControlTarget(app2);
+ waitUntilWindowAnimatorIdle();
+
+ // app2 is the real control target now. It can override the visibility of all sources that
+ // it controls.
+ assertFalse(statusBarSource.isVisible());
+ assertFalse(app1.getInsetsState().peekSource(statusBarId).isVisible());
+ assertFalse(app2.getInsetsState().peekSource(statusBarId).isVisible());
+
+ statusBar.mAttrs.forciblyShownTypes = statusBars();
+ mDisplayContent.getDisplayPolicy().applyPostLayoutPolicyLw(
+ statusBar, statusBar.mAttrs, null, null);
+ mDisplayContent.getInsetsPolicy().updateBarControlTarget(app2);
+ waitUntilWindowAnimatorIdle();
+
+ // app2 is the fake control target now. It can only override the visibility of sources
+ // received by windows, but not the raw source.
+ assertTrue(statusBarSource.isVisible());
+ assertFalse(app1.getInsetsState().peekSource(statusBarId).isVisible());
+ assertFalse(app2.getInsetsState().peekSource(statusBarId).isVisible());
+
+ }
+
private WindowState addNavigationBar() {
final Binder owner = new Binder();
final WindowState win = createWindow(null, TYPE_NAVIGATION_BAR, "navBar");
diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
index 114796d17ef1..2085d6140f68 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
@@ -367,9 +367,11 @@ public class InsetsStateControllerTest extends WindowTestsBase {
doReturn(rotatedState).when(app.mToken).getFixedRotationTransformInsetsState();
assertTrue(rotatedState.isSourceOrDefaultVisible(ID_STATUS_BAR, statusBars()));
- provider.getSource().setVisible(false);
+ app.setRequestedVisibleTypes(0, statusBars());
+ mDisplayContent.getInsetsPolicy().updateBarControlTarget(app);
mDisplayContent.getInsetsPolicy().showTransient(statusBars(),
true /* isGestureOnSystemBar */);
+ waitUntilWindowAnimatorIdle();
assertTrue(mDisplayContent.getInsetsPolicy().isTransient(statusBars()));
assertFalse(app.getInsetsState().isSourceOrDefaultVisible(ID_STATUS_BAR, statusBars()));