diff --git a/core/java/android/view/InsetsState.java b/core/java/android/view/InsetsState.java index 397b04e9c023b..17620fa3bb4b7 100644 --- a/core/java/android/view/InsetsState.java +++ b/core/java/android/view/InsetsState.java @@ -357,6 +357,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); } @@ -388,20 +401,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 */); } @@ -490,7 +489,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) {