diff options
author | Tiger Huang <tigerhuang@google.com> | 2020-08-07 20:13:55 +0800 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2020-08-20 16:25:17 +0000 |
commit | 0cb4db0f40cc607b2f6ef927ee3a11f8d467bd1d (patch) | |
tree | bb247a5e6780c5b9efc404c0e23ecb01f7eda8ea | |
parent | 3e817cab966035ab9b572e17bc9c2d75da007e99 (diff) | |
download | base-0cb4db0f40cc607b2f6ef927ee3a11f8d467bd1d.tar.gz |
Refine system bar position restoring
The previous logic restores the system bar as long as its insets source
is visible. There can be a timing issue that if the user swipes to show
transient bars while an immersive app just becomes the control target
but the hide-bar info haven't sent to WM yet, WM will re-show the bar
incorrectly.
This CL uses the requested visibility and the behavior to decide if we
should restore the postion and the visibility.
This CL also refines and caches the arguments of showTransient. In this
way, we don't have to create the array every time while invoking that
method.
Fix: 161247175
Test: atest InsetsPolicyTest
Merged-In: Idef314dfe6625399b88b3dacb4c74c7071453497
Change-Id: Idef314dfe6625399b88b3dacb4c74c7071453497
(cherry picked from commit 533682ebb39456df26097753d1f5172bff0e3d5d)
(cherry picked from commit 444e8dc6ce224f87b4d062d697a6db5a62e11183)
6 files changed, 37 insertions, 27 deletions
diff --git a/core/java/android/view/InsetsState.java b/core/java/android/view/InsetsState.java index 6b0b509932a8..593b37af26ad 100644 --- a/core/java/android/view/InsetsState.java +++ b/core/java/android/view/InsetsState.java @@ -60,6 +60,8 @@ import java.util.StringJoiner; */ public class InsetsState implements Parcelable { + public static final InsetsState EMPTY = new InsetsState(); + /** * Internal representation of inset source types. This is different from the public API in * {@link WindowInsets.Type} as one type from the public API might indicate multiple windows diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index 0d467c50aa11..7f827e488af2 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -241,6 +241,9 @@ public class DisplayPolicy { | View.STATUS_BAR_TRANSPARENT | View.NAVIGATION_BAR_TRANSPARENT; + private static final int[] SHOW_TYPES_FOR_SWIPE = {ITYPE_NAVIGATION_BAR, ITYPE_STATUS_BAR}; + private static final int[] SHOW_TYPES_FOR_PANIC = {ITYPE_NAVIGATION_BAR}; + private final WindowManagerService mService; private final Context mContext; private final Context mUiContext; @@ -3215,8 +3218,15 @@ public class DisplayPolicy { return; } + final InsetsState requestedState = controlTarget.getRequestedInsetsState(); + final @InsetsType int restorePositionTypes = + (requestedState.getSourceOrDefaultVisibility(ITYPE_NAVIGATION_BAR) + ? Type.navigationBars() : 0) + | (requestedState.getSourceOrDefaultVisibility(ITYPE_STATUS_BAR) + ? Type.statusBars() : 0); + if (swipeTarget == mNavigationBar - && !getInsetsPolicy().isHidden(ITYPE_NAVIGATION_BAR)) { + && (restorePositionTypes & Type.navigationBars()) != 0) { // Don't show status bar when swiping on already visible navigation bar. // But restore the position of navigation bar if it has been moved by the control // target. @@ -3224,14 +3234,13 @@ public class DisplayPolicy { return; } - int insetsTypesToShow = Type.systemBars(); - if (controlTarget.canShowTransient()) { - insetsTypesToShow &= ~mDisplayContent.getInsetsPolicy().showTransient(IntArray.wrap( - new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR})); - } - if (insetsTypesToShow != 0) { - controlTarget.showInsets(insetsTypesToShow, false); + // Show transient bars if they are hidden; restore position if they are visible. + mDisplayContent.getInsetsPolicy().showTransient(SHOW_TYPES_FOR_SWIPE); + controlTarget.showInsets(restorePositionTypes, false); + } else { + // Restore visibilities and positions of system bars. + controlTarget.showInsets(Type.statusBars() | Type.navigationBars(), false); } } else { boolean sb = mStatusBarController.checkShowTransientBarLw(); @@ -3809,8 +3818,7 @@ public class DisplayPolicy { mPendingPanicGestureUptime = SystemClock.uptimeMillis(); if (!isNavBarEmpty(mLastSystemUiFlags)) { mNavigationBarController.showTransient(); - mDisplayContent.getInsetsPolicy().showTransient(IntArray.wrap( - new int[] {ITYPE_NAVIGATION_BAR})); + mDisplayContent.getInsetsPolicy().showTransient(SHOW_TYPES_FOR_PANIC); } } } diff --git a/services/core/java/com/android/server/wm/InsetsControlTarget.java b/services/core/java/com/android/server/wm/InsetsControlTarget.java index 3ffc26a7a8ad..5e7ed3f80e43 100644 --- a/services/core/java/com/android/server/wm/InsetsControlTarget.java +++ b/services/core/java/com/android/server/wm/InsetsControlTarget.java @@ -17,6 +17,7 @@ package com.android.server.wm; import android.inputmethodservice.InputMethodService; +import android.view.InsetsState; import android.view.WindowInsets.Type.InsetsType; /** @@ -38,6 +39,13 @@ interface InsetsControlTarget { } /** + * @return The requested {@link InsetsState} of this target. + */ + default InsetsState getRequestedInsetsState() { + return InsetsState.EMPTY; + } + + /** * Instructs the control target to show inset sources. * * @param types to specify which types of insets source window should be shown. diff --git a/services/core/java/com/android/server/wm/InsetsPolicy.java b/services/core/java/com/android/server/wm/InsetsPolicy.java index 254356d673e3..a145be0ab83c 100644 --- a/services/core/java/com/android/server/wm/InsetsPolicy.java +++ b/services/core/java/com/android/server/wm/InsetsPolicy.java @@ -42,7 +42,6 @@ import android.view.InsetsState.InternalInsetsType; import android.view.SurfaceControl; import android.view.SyncRtSurfaceTransactionApplier; import android.view.ViewRootImpl; -import android.view.WindowInsets.Type.InsetsType; import android.view.WindowInsetsAnimation; import android.view.WindowInsetsAnimation.Bounds; import android.view.WindowInsetsAnimationControlListener; @@ -133,15 +132,13 @@ class InsetsPolicy { return provider != null && provider.hasWindow() && !provider.getSource().isVisible(); } - @InsetsType int showTransient(IntArray types) { - @InsetsType int showingTransientTypes = 0; + void showTransient(@InternalInsetsType int[] types) { boolean changed = false; - for (int i = types.size() - 1; i >= 0; i--) { - final int type = types.get(i); + for (int i = types.length - 1; i >= 0; i--) { + final @InternalInsetsType int type = types[i]; if (!isHidden(type)) { continue; } - showingTransientTypes |= InsetsState.toPublicType(type); if (mShowingTransientTypes.indexOf(type) != -1) { continue; } @@ -169,7 +166,6 @@ class InsetsPolicy { } }); } - return showingTransientTypes; } void hideTransient() { diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 11db705f4e04..6a2c54e0b292 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -725,7 +725,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP * @return The insets state as requested by the client, i.e. the dispatched insets state * for which the visibilities are overridden with what the client requested. */ - InsetsState getRequestedInsetsState() { + @Override + public InsetsState getRequestedInsetsState() { return mRequestedInsetsState; } 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 c794e1a3b328..da36ba9d3613 100644 --- a/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java @@ -43,7 +43,6 @@ import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.spy; import android.platform.test.annotations.Presubmit; -import android.util.IntArray; import android.view.InsetsSourceControl; import android.view.InsetsState; import android.view.test.InsetsModeSession; @@ -240,8 +239,7 @@ public class InsetsPolicyTest extends WindowTestsBase { }).when(policy).startAnimation(anyBoolean(), any(), any()); policy.updateBarControlTarget(mAppWindow); - policy.showTransient( - IntArray.wrap(new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR})); + policy.showTransient(new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR}); waitUntilWindowAnimatorIdle(); final InsetsSourceControl[] controls = mDisplayContent.getInsetsStateController().getControlsForDispatch(mAppWindow); @@ -268,8 +266,7 @@ public class InsetsPolicyTest extends WindowTestsBase { final InsetsPolicy policy = spy(mDisplayContent.getInsetsPolicy()); doNothing().when(policy).startAnimation(anyBoolean(), any(), any()); policy.updateBarControlTarget(mAppWindow); - policy.showTransient( - IntArray.wrap(new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR})); + policy.showTransient(new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR}); waitUntilWindowAnimatorIdle(); final InsetsSourceControl[] controls = mDisplayContent.getInsetsStateController().getControlsForDispatch(mAppWindow); @@ -297,8 +294,7 @@ public class InsetsPolicyTest extends WindowTestsBase { final InsetsPolicy policy = spy(mDisplayContent.getInsetsPolicy()); doNothing().when(policy).startAnimation(anyBoolean(), any(), any()); policy.updateBarControlTarget(mAppWindow); - policy.showTransient( - IntArray.wrap(new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR})); + policy.showTransient(new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR}); waitUntilWindowAnimatorIdle(); InsetsSourceControl[] controls = mDisplayContent.getInsetsStateController().getControlsForDispatch(mAppWindow); @@ -336,8 +332,7 @@ public class InsetsPolicyTest extends WindowTestsBase { final InsetsPolicy policy = spy(mDisplayContent.getInsetsPolicy()); doNothing().when(policy).startAnimation(anyBoolean(), any(), any()); policy.updateBarControlTarget(app); - policy.showTransient( - IntArray.wrap(new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR})); + policy.showTransient(new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR}); final InsetsSourceControl[] controls = mDisplayContent.getInsetsStateController().getControlsForDispatch(app); policy.updateBarControlTarget(app2); |