Merge "Use current fullscreen opaque window as insets control target" into rvc-qpr-dev

This commit is contained in:
TreeHugger Robot
2020-12-01 16:40:30 +00:00
committed by Android (Google) Code Review
5 changed files with 66 additions and 13 deletions

View File

@@ -36,6 +36,7 @@ import android.view.InsetsAnimationControlCallbacks;
import android.view.InsetsAnimationControlImpl;
import android.view.InsetsAnimationControlRunner;
import android.view.InsetsController;
import android.view.InsetsSource;
import android.view.InsetsSourceControl;
import android.view.InsetsState;
import android.view.InsetsState.InternalInsetsType;
@@ -212,11 +213,21 @@ class InsetsPolicy {
* @see InsetsStateController#getInsetsForDispatch
*/
InsetsState getInsetsForDispatch(WindowState target) {
InsetsState originalState = mStateController.getInsetsForDispatch(target);
final InsetsState originalState = mStateController.getInsetsForDispatch(target);
InsetsState state = originalState;
for (int i = mShowingTransientTypes.size() - 1; i >= 0; i--) {
state = new InsetsState(state);
state.setSourceVisible(mShowingTransientTypes.get(i), false);
final int type = mShowingTransientTypes.get(i);
final InsetsSource originalSource = state.peekSource(type);
if (originalSource != null && originalSource.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 source = new InsetsSource(originalSource);
source.setVisible(false);
state.addSource(source);
}
}
return state;
}
@@ -252,11 +263,14 @@ class InsetsPolicy {
}
}
/**
* If the caller is not {@link #updateBarControlTarget}, it should call
* updateBarControlTarget(mFocusedWin) after this invocation.
*/
private void abortTransient() {
mPolicy.getStatusBarManagerInternal().abortTransient(mDisplayContent.getDisplayId(),
mShowingTransientTypes.toArray());
mShowingTransientTypes.clear();
updateBarControlTarget(mFocusedWin);
}
private @Nullable InsetsControlTarget getFakeControlTarget(@Nullable WindowState focused,
@@ -290,7 +304,7 @@ class InsetsPolicy {
// fake control to the client, so that it can re-show the bar during this scenario.
return mDummyControlTarget;
}
if (mPolicy.topAppHidesStatusBar()) {
if (!canBeTopFullscreenOpaqueWindow(focusedWin) && mPolicy.topAppHidesStatusBar()) {
// Non-fullscreen focused window should not break the state that the top-fullscreen-app
// window hides status bar.
return mPolicy.getTopFullscreenOpaqueWindow();
@@ -298,6 +312,16 @@ class InsetsPolicy {
return focusedWin;
}
private static boolean canBeTopFullscreenOpaqueWindow(@Nullable WindowState win) {
// The condition doesn't use WindowState#canAffectSystemUiFlags because the window may
// haven't drawn or committed the visibility.
final boolean nonAttachedAppWindow = win != null
&& win.mAttrs.type >= WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW
&& win.mAttrs.type <= WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
return nonAttachedAppWindow && win.mAttrs.isFullscreen() && !win.isFullyTransparent()
&& !win.inMultiWindowMode();
}
private @Nullable InsetsControlTarget getNavControlTarget(@Nullable WindowState focusedWin,
boolean forceShowsSystemBarsForWindowingMode) {
if (mShowingTransientTypes.indexOf(ITYPE_NAVIGATION_BAR) != -1) {

View File

@@ -480,9 +480,7 @@ class TaskSnapshotController {
final int color = ColorUtils.setAlphaComponent(
task.getTaskDescription().getBackgroundColor(), 255);
final LayoutParams attrs = mainWindow.getAttrs();
final InsetsPolicy insetsPolicy = mainWindow.getDisplayContent().getInsetsPolicy();
final InsetsState insetsState =
new InsetsState(insetsPolicy.getInsetsForDispatch(mainWindow));
final InsetsState insetsState = new InsetsState(mainWindow.getInsetsState());
mergeInsetsSources(insetsState, mainWindow.getRequestedInsetsState());
final Rect systemBarInsets = getSystemBarInsets(mainWindow.getFrameLw(), insetsState);
final SystemBarBackgroundPainter decorPainter = new SystemBarBackgroundPainter(attrs.flags,

View File

@@ -245,11 +245,7 @@ class TaskSnapshotSurface implements StartingSurface {
task.getBounds(taskBounds);
currentOrientation = topFullscreenOpaqueWindow.getConfiguration().orientation;
activityType = activity.getActivityType();
final InsetsPolicy insetsPolicy = topFullscreenOpaqueWindow.getDisplayContent()
.getInsetsPolicy();
insetsState =
new InsetsState(insetsPolicy.getInsetsForDispatch(topFullscreenOpaqueWindow));
insetsState = new InsetsState(topFullscreenOpaqueWindow.getInsetsState());
mergeInsetsSources(insetsState, topFullscreenOpaqueWindow.getRequestedInsetsState());
}
try {

View File

@@ -1525,6 +1525,10 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
return getDisplayContent().getDisplayInfo();
}
/**
* Returns the insets state for the client. Its sources may be the copies with visibility
* modification according to the state of transient bars.
*/
InsetsState getInsetsState() {
return getDisplayContent().getInsetsPolicy().getInsetsForDispatch(this);
}

View File

@@ -38,10 +38,13 @@ import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import android.app.StatusBarManager;
import android.platform.test.annotations.Presubmit;
import android.view.InsetsSourceControl;
import android.view.InsetsState;
@@ -49,6 +52,8 @@ import android.view.test.InsetsModeSession;
import androidx.test.filters.SmallTest;
import com.android.server.statusbar.StatusBarManagerInternal;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
@@ -222,6 +227,23 @@ public class InsetsPolicyTest extends WindowTestsBase {
assertNotNull(fullscreenAppControls);
assertEquals(1, fullscreenAppControls.length);
assertEquals(ITYPE_STATUS_BAR, fullscreenAppControls[0].getType());
// Assume mFocusedWindow is updated but mTopFullscreenOpaqueWindowState hasn't.
final WindowState newFocusedFullscreenApp = addWindow(TYPE_APPLICATION, "newFullscreenApp");
final InsetsState newRequestedState = new InsetsState();
newRequestedState.getSource(ITYPE_STATUS_BAR).setVisible(true);
newFocusedFullscreenApp.updateRequestedInsetsState(newRequestedState);
// Make sure status bar is hidden by previous insets state.
mDisplayContent.getInsetsPolicy().updateBarControlTarget(fullscreenApp);
final StatusBarManagerInternal sbmi =
mDisplayContent.getDisplayPolicy().getStatusBarManagerInternal();
clearInvocations(sbmi);
mDisplayContent.getInsetsPolicy().updateBarControlTarget(newFocusedFullscreenApp);
// The status bar should be shown by newFocusedFullscreenApp even
// mTopFullscreenOpaqueWindowState is still fullscreenApp.
verify(sbmi).setWindowState(mDisplayContent.mDisplayId, StatusBarManager.WINDOW_STATUS_BAR,
StatusBarManager.WINDOW_STATE_SHOWING);
}
@Test
@@ -309,6 +331,15 @@ public class InsetsPolicyTest extends WindowTestsBase {
final InsetsState state = policy.getInsetsForDispatch(mAppWindow);
state.setSourceVisible(ITYPE_STATUS_BAR, true);
state.setSourceVisible(ITYPE_NAVIGATION_BAR, true);
final InsetsState clientState = mAppWindow.getInsetsState();
// The transient bar states for client should be invisible.
assertFalse(clientState.getSource(ITYPE_STATUS_BAR).isVisible());
assertFalse(clientState.getSource(ITYPE_NAVIGATION_BAR).isVisible());
// The original state shouldn't be modified.
assertTrue(state.getSource(ITYPE_STATUS_BAR).isVisible());
assertTrue(state.getSource(ITYPE_NAVIGATION_BAR).isVisible());
policy.onInsetsModified(mAppWindow, state);
waitUntilWindowAnimatorIdle();