Merge "Let top-fullscreen-app window keep controlling status bar" into rvc-dev
This commit is contained in:
@@ -2756,19 +2756,22 @@ public class DisplayPolicy {
|
||||
* @return Whether the top app should hide the statusbar based on the top fullscreen opaque
|
||||
* window.
|
||||
*/
|
||||
private boolean topAppHidesStatusBar() {
|
||||
boolean topAppHidesStatusBar() {
|
||||
if (mTopFullscreenOpaqueWindowState == null || mForceShowSystemBars) {
|
||||
return false;
|
||||
}
|
||||
final int fl = PolicyControl.getWindowFlags(null,
|
||||
mTopFullscreenOpaqueWindowState.getAttrs());
|
||||
final LayoutParams attrs = mTopFullscreenOpaqueWindowState.getAttrs();
|
||||
final int fl = PolicyControl.getWindowFlags(null, attrs);
|
||||
final int sysui = PolicyControl.getSystemUiVisibility(null, attrs);
|
||||
final InsetsSource request = mTopFullscreenOpaqueWindowState.getRequestedInsetsState()
|
||||
.peekSource(ITYPE_STATUS_BAR);
|
||||
if (WindowManagerDebugConfig.DEBUG) {
|
||||
Slog.d(TAG, "frame: " + mTopFullscreenOpaqueWindowState.getFrameLw());
|
||||
Slog.d(TAG, "attr: " + mTopFullscreenOpaqueWindowState.getAttrs()
|
||||
+ " lp.flags=0x" + Integer.toHexString(fl));
|
||||
Slog.d(TAG, "attr: " + attrs + " request: " + request);
|
||||
}
|
||||
return (fl & LayoutParams.FLAG_FULLSCREEN) != 0
|
||||
|| (mLastSystemUiFlags & View.SYSTEM_UI_FLAG_FULLSCREEN) != 0;
|
||||
|| (sysui & View.SYSTEM_UI_FLAG_FULLSCREEN) != 0
|
||||
|| (request != null && !request.isVisible());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -117,13 +117,8 @@ class InsetsPolicy {
|
||||
if (ViewRootImpl.sNewInsetsMode != ViewRootImpl.NEW_INSETS_MODE_FULL) {
|
||||
return;
|
||||
}
|
||||
mStatusBar.setVisible(focusedWin == null
|
||||
|| focusedWin != getStatusControlTarget(focusedWin)
|
||||
|| focusedWin.getRequestedInsetsState().getSource(ITYPE_STATUS_BAR).isVisible());
|
||||
mNavBar.setVisible(focusedWin == null
|
||||
|| focusedWin != getNavControlTarget(focusedWin)
|
||||
|| focusedWin.getRequestedInsetsState().getSource(ITYPE_NAVIGATION_BAR)
|
||||
.isVisible());
|
||||
mStatusBar.updateVisibility(getStatusControlTarget(focusedWin), ITYPE_STATUS_BAR);
|
||||
mNavBar.updateVisibility(getNavControlTarget(focusedWin), ITYPE_NAVIGATION_BAR);
|
||||
mPolicy.updateHideNavInputEventReceiver();
|
||||
}
|
||||
|
||||
@@ -215,16 +210,7 @@ class InsetsPolicy {
|
||||
void onInsetsModified(WindowState windowState, InsetsState state) {
|
||||
mStateController.onInsetsModified(windowState, state);
|
||||
checkAbortTransient(windowState, state);
|
||||
if (ViewRootImpl.sNewInsetsMode != ViewRootImpl.NEW_INSETS_MODE_FULL) {
|
||||
return;
|
||||
}
|
||||
if (windowState == getStatusControlTarget(mFocusedWin)) {
|
||||
mStatusBar.setVisible(state.getSource(ITYPE_STATUS_BAR).isVisible());
|
||||
}
|
||||
if (windowState == getNavControlTarget(mFocusedWin)) {
|
||||
mNavBar.setVisible(state.getSource(ITYPE_NAVIGATION_BAR).isVisible());
|
||||
}
|
||||
mPolicy.updateHideNavInputEventReceiver();
|
||||
updateBarControlTarget(mFocusedWin);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -248,7 +234,6 @@ class InsetsPolicy {
|
||||
if (abortTypes.size() > 0) {
|
||||
mPolicy.getStatusBarManagerInternal().abortTransient(mDisplayContent.getDisplayId(),
|
||||
abortTypes.toArray());
|
||||
updateBarControlTarget(mFocusedWin);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -289,6 +274,11 @@ class InsetsPolicy {
|
||||
// fake control to the client, so that it can re-show the bar during this scenario.
|
||||
return mDummyControlTarget;
|
||||
}
|
||||
if (mPolicy.topAppHidesStatusBar()) {
|
||||
// Non-fullscreen focused window should not break the state that the top-fullscreen-app
|
||||
// window hides status bar.
|
||||
return mPolicy.getTopFullscreenOpaqueWindow();
|
||||
}
|
||||
return focusedWin;
|
||||
}
|
||||
|
||||
@@ -378,6 +368,14 @@ class InsetsPolicy {
|
||||
mId = id;
|
||||
}
|
||||
|
||||
private void updateVisibility(InsetsControlTarget controlTarget,
|
||||
@InternalInsetsType int type) {
|
||||
final WindowState controllingWin =
|
||||
controlTarget instanceof WindowState ? (WindowState) controlTarget : null;
|
||||
setVisible(controllingWin == null
|
||||
|| controllingWin.getRequestedInsetsState().getSource(type).isVisible());
|
||||
}
|
||||
|
||||
private void setVisible(boolean visible) {
|
||||
final int state = visible ? WINDOW_STATE_SHOWING : WINDOW_STATE_HIDDEN;
|
||||
if (mState != state) {
|
||||
|
||||
@@ -21,6 +21,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
|
||||
import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
|
||||
import static android.view.InsetsState.ITYPE_STATUS_BAR;
|
||||
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
|
||||
import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL;
|
||||
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
|
||||
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR;
|
||||
@@ -182,6 +183,47 @@ public class InsetsPolicyTest extends WindowTestsBase {
|
||||
assertNull(controls);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testControlsForDispatch_topAppHidesStatusBar() {
|
||||
addWindow(TYPE_STATUS_BAR, "statusBar");
|
||||
addWindow(TYPE_NAVIGATION_BAR, "navBar");
|
||||
|
||||
// Add a fullscreen (MATCH_PARENT x MATCH_PARENT) app window which hides status bar.
|
||||
final WindowState fullscreenApp = addWindow(TYPE_APPLICATION, "fullscreenApp");
|
||||
final InsetsState requestedState = new InsetsState();
|
||||
requestedState.getSource(ITYPE_STATUS_BAR).setVisible(false);
|
||||
fullscreenApp.updateRequestedInsetsState(requestedState);
|
||||
|
||||
// Add a non-fullscreen dialog window.
|
||||
final WindowState dialog = addWindow(TYPE_APPLICATION, "dialog");
|
||||
dialog.mAttrs.width = WRAP_CONTENT;
|
||||
dialog.mAttrs.height = WRAP_CONTENT;
|
||||
|
||||
// Let fullscreenApp be mTopFullscreenOpaqueWindowState.
|
||||
final DisplayPolicy displayPolicy = mDisplayContent.getDisplayPolicy();
|
||||
displayPolicy.beginPostLayoutPolicyLw();
|
||||
displayPolicy.applyPostLayoutPolicyLw(dialog, dialog.mAttrs, fullscreenApp, null);
|
||||
displayPolicy.applyPostLayoutPolicyLw(fullscreenApp, fullscreenApp.mAttrs, null, null);
|
||||
displayPolicy.finishPostLayoutPolicyLw();
|
||||
mDisplayContent.getInsetsPolicy().updateBarControlTarget(dialog);
|
||||
|
||||
assertEquals(fullscreenApp, displayPolicy.getTopFullscreenOpaqueWindow());
|
||||
|
||||
// dialog is the focused window, but it can only control navigation bar.
|
||||
final InsetsSourceControl[] dialogControls =
|
||||
mDisplayContent.getInsetsStateController().getControlsForDispatch(dialog);
|
||||
assertNotNull(dialogControls);
|
||||
assertEquals(1, dialogControls.length);
|
||||
assertEquals(ITYPE_NAVIGATION_BAR, dialogControls[0].getType());
|
||||
|
||||
// fullscreenApp is hiding status bar, and it can keep controlling status bar.
|
||||
final InsetsSourceControl[] fullscreenAppControls =
|
||||
mDisplayContent.getInsetsStateController().getControlsForDispatch(fullscreenApp);
|
||||
assertNotNull(fullscreenAppControls);
|
||||
assertEquals(1, fullscreenAppControls.length);
|
||||
assertEquals(ITYPE_STATUS_BAR, fullscreenAppControls[0].getType());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShowTransientBars_bothCanBeTransient_appGetsBothFakeControls() {
|
||||
addNonFocusableWindow(TYPE_STATUS_BAR, "statusBar")
|
||||
|
||||
Reference in New Issue
Block a user