From 017d51dccd139e2ca8794940849d4ca0de9b3dd5 Mon Sep 17 00:00:00 2001 From: Tiger Huang Date: Wed, 27 May 2020 17:58:17 +0800 Subject: [PATCH] Let position of system bars can be restored by swipe In the new insets world, apps can move system bars while keeping them visible, which can make the user difficult to access the bars. This CL lets the user can restore the position of system bars by swipe. This CL also removes some unnecessary logic and refactors some methods. Fix: 152194798 Test: Manual test with NewInsetsMainActivity Change-Id: I81c8a41ca88a403d291186d61ec597c6bc5d3d84 --- core/java/android/view/InsetsState.java | 29 +++++++------- .../com/android/server/wm/DisplayPolicy.java | 40 +++++++++++-------- .../com/android/server/wm/InsetsPolicy.java | 24 ++++------- 3 files changed, 46 insertions(+), 47 deletions(-) diff --git a/core/java/android/view/InsetsState.java b/core/java/android/view/InsetsState.java index 3822ee59b4aad..a75efeeaaa8d3 100644 --- a/core/java/android/view/InsetsState.java +++ b/core/java/android/view/InsetsState.java @@ -319,6 +319,19 @@ public class InsetsState implements Parcelable { return mSources.get(type); } + /** + * Returns the source visibility or the default visibility if the source doesn't exist. This is + * useful if when treating this object as a request. + * + * @param type The {@link InternalInsetsType} to query. + * @return {@code true} if the source is visible or the type is default visible and the source + * doesn't exist. + */ + public boolean getSourceOrDefaultVisibility(@InternalInsetsType int type) { + final InsetsSource source = mSources.get(type); + return source != null ? source.isVisible() : getDefaultVisibility(type); + } + public void setDisplayFrame(Rect frame) { mDisplayFrame.set(frame); } @@ -350,20 +363,6 @@ public class InsetsState implements Parcelable { } } - /** - * A shortcut for setting the visibility of the source. - * - * @param type The {@link InternalInsetsType} of the source to set the visibility - * @param referenceState The {@link InsetsState} for reference - */ - public void setSourceVisible(@InternalInsetsType int type, InsetsState referenceState) { - InsetsSource source = mSources.get(type); - InsetsSource referenceSource = referenceState.mSources.get(type); - if (source != null && referenceSource != null) { - source.setVisible(referenceSource.isVisible()); - } - } - public void set(InsetsState other) { set(other, false /* copySources */); } @@ -452,7 +451,7 @@ public class InsetsState implements Parcelable { } } - public static boolean getDefaultVisibility(@InsetsType int type) { + public static boolean getDefaultVisibility(@InternalInsetsType int type) { return type != ITYPE_IME; } diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index e244b5551d191..cc4a0a2559137 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -1579,10 +1579,9 @@ public class DisplayPolicy { navControlTarget instanceof WindowState ? (WindowState) navControlTarget : null; final InsetsState requestedState = navControllingWin != null ? navControllingWin.getRequestedInsetsState() : null; - final InsetsSource navSource = requestedState != null - ? requestedState.peekSource(ITYPE_NAVIGATION_BAR) : null; - final boolean navVisible = navSource != null - ? navSource.isVisible() : InsetsState.getDefaultVisibility(ITYPE_NAVIGATION_BAR); + final boolean navVisible = requestedState != null + ? requestedState.getSourceOrDefaultVisibility(ITYPE_NAVIGATION_BAR) + : InsetsState.getDefaultVisibility(ITYPE_NAVIGATION_BAR); final boolean showBarsByTouch = navControllingWin != null && navControllingWin.mAttrs.insetsFlags.behavior == BEHAVIOR_SHOW_BARS_BY_TOUCH; // When the navigation bar isn't visible, we put up a fake input window to catch all @@ -2372,12 +2371,13 @@ public class DisplayPolicy { final boolean requestedFullscreen = (fl & FLAG_FULLSCREEN) != 0 || (requestedSysUiFl & View.SYSTEM_UI_FLAG_FULLSCREEN) != 0 || (ViewRootImpl.sNewInsetsMode == NEW_INSETS_MODE_FULL - && !win.getRequestedInsetsState().getSource(ITYPE_STATUS_BAR).isVisible()); + && !win.getRequestedInsetsState().getSourceOrDefaultVisibility( + ITYPE_STATUS_BAR)); final boolean requestedHideNavigation = (requestedSysUiFl & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) != 0 || (ViewRootImpl.sNewInsetsMode == NEW_INSETS_MODE_FULL - && !win.getRequestedInsetsState().getSource(ITYPE_NAVIGATION_BAR) - .isVisible()); + && !win.getRequestedInsetsState().getSourceOrDefaultVisibility( + ITYPE_NAVIGATION_BAR)); // TYPE_BASE_APPLICATION windows are never considered floating here because they don't get // cropped / shifted to the displayFrame in WindowState. @@ -3187,24 +3187,32 @@ public class DisplayPolicy { return; } if (ViewRootImpl.sNewInsetsMode == NEW_INSETS_MODE_FULL) { - if (swipeTarget == mNavigationBar - && !getInsetsPolicy().isHidden(ITYPE_NAVIGATION_BAR)) { - // Don't show status bar when swiping on already visible navigation bar - return; - } final InsetsSourceProvider provider = swipeTarget.getControllableInsetProvider(); final InsetsControlTarget controlTarget = provider != null ? provider.getControlTarget() : null; - // No transient mode on lockscreen (in notification shade window). if (controlTarget == null || controlTarget == getNotificationShade()) { + // No transient mode on lockscreen (in notification shade window). return; } + + if (swipeTarget == mNavigationBar + && !getInsetsPolicy().isHidden(ITYPE_NAVIGATION_BAR)) { + // 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. + controlTarget.showInsets(Type.navigationBars(), false); + return; + } + + int insetsTypesToShow = Type.systemBars(); + if (controlTarget.canShowTransient()) { - mDisplayContent.getInsetsPolicy().showTransient(IntArray.wrap( + insetsTypesToShow &= ~mDisplayContent.getInsetsPolicy().showTransient(IntArray.wrap( new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR})); - } else { - controlTarget.showInsets(Type.systemBars(), false); + } + if (insetsTypesToShow != 0) { + controlTarget.showInsets(insetsTypesToShow, false); } } else { boolean sb = mStatusBarController.checkShowTransientBarLw(); diff --git a/services/core/java/com/android/server/wm/InsetsPolicy.java b/services/core/java/com/android/server/wm/InsetsPolicy.java index 035f2015fe918..be6e4b76e8ed5 100644 --- a/services/core/java/com/android/server/wm/InsetsPolicy.java +++ b/services/core/java/com/android/server/wm/InsetsPolicy.java @@ -42,6 +42,7 @@ 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; @@ -127,14 +128,16 @@ class InsetsPolicy { return provider != null && provider.hasWindow() && !provider.getSource().isVisible(); } - void showTransient(IntArray types) { + @InsetsType int showTransient(IntArray types) { + @InsetsType int showingTransientTypes = 0; boolean changed = false; for (int i = types.size() - 1; i >= 0; i--) { final int type = types.get(i); - if (mShowingTransientTypes.indexOf(type) != -1) { + if (!isHidden(type)) { continue; } - if (!isHidden(type)) { + showingTransientTypes |= InsetsState.toPublicType(type); + if (mShowingTransientTypes.indexOf(type) != -1) { continue; } mShowingTransientTypes.add(type); @@ -161,6 +164,7 @@ class InsetsPolicy { } }); } + return showingTransientTypes; } void hideTransient() { @@ -192,18 +196,6 @@ class InsetsPolicy { state = new InsetsState(state); state.setSourceVisible(mShowingTransientTypes.get(i), false); } - if (mFocusedWin != null && getStatusControlTarget(mFocusedWin) == mDummyControlTarget) { - if (state == originalState) { - state = new InsetsState(state); - } - state.setSourceVisible(ITYPE_STATUS_BAR, mFocusedWin.getRequestedInsetsState()); - } - if (mFocusedWin != null && getNavControlTarget(mFocusedWin) == mDummyControlTarget) { - if (state == originalState) { - state = new InsetsState(state); - } - state.setSourceVisible(ITYPE_NAVIGATION_BAR, mFocusedWin.getRequestedInsetsState()); - } return state; } @@ -373,7 +365,7 @@ class InsetsPolicy { final WindowState controllingWin = controlTarget instanceof WindowState ? (WindowState) controlTarget : null; setVisible(controllingWin == null - || controllingWin.getRequestedInsetsState().getSource(type).isVisible()); + || controllingWin.getRequestedInsetsState().getSourceOrDefaultVisibility(type)); } private void setVisible(boolean visible) {