Merge "Fix flickers when changing control" into rvc-dev am: c322ed2173 am: 162040e358 am: b88c500fea am: 3cb2ddd649
Change-Id: I5a7d6e658add347463be56e4022d31ccc1e30a04
This commit is contained in:
@@ -456,6 +456,11 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
|
||||
return mState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRequestedVisible(int type) {
|
||||
return getSourceConsumer(type).isRequestedVisible();
|
||||
}
|
||||
|
||||
public InsetsState getLastDispatchedState() {
|
||||
return mLastDispachedState;
|
||||
}
|
||||
|
||||
@@ -112,12 +112,12 @@ public class InsetsSourceConsumer {
|
||||
hideTypes[0] |= toPublicType(getType());
|
||||
}
|
||||
} else {
|
||||
// We are gaining control, but don't need to run an animation.
|
||||
// However make sure that the leash visibility is still up to date.
|
||||
if (applyLocalVisibilityOverride()) {
|
||||
mController.notifyVisibilityChanged();
|
||||
}
|
||||
applyHiddenToControl();
|
||||
// We are gaining control, but don't need to run an animation.
|
||||
// However make sure that the leash visibility is still up to date.
|
||||
if (applyLocalVisibilityOverride()) {
|
||||
mController.notifyVisibilityChanged();
|
||||
applyHiddenToControl();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (lastControl != null) {
|
||||
|
||||
@@ -107,6 +107,14 @@ public class PendingInsetsController implements WindowInsetsController {
|
||||
return mDummyState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRequestedVisible(int type) {
|
||||
|
||||
// Method is only used once real insets controller is attached, so no need to traverse
|
||||
// requests here.
|
||||
return InsetsState.getDefaultVisibility(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addOnControllableInsetsChangedListener(
|
||||
OnControllableInsetsChangedListener listener) {
|
||||
|
||||
@@ -22,6 +22,7 @@ import android.annotation.Nullable;
|
||||
import android.graphics.Insets;
|
||||
import android.inputmethodservice.InputMethodService;
|
||||
import android.os.CancellationSignal;
|
||||
import android.view.InsetsState.InternalInsetsType;
|
||||
import android.view.WindowInsets.Type;
|
||||
import android.view.WindowInsets.Type.InsetsType;
|
||||
import android.view.animation.Interpolator;
|
||||
@@ -225,6 +226,13 @@ public interface WindowInsetsController {
|
||||
*/
|
||||
InsetsState getState();
|
||||
|
||||
/**
|
||||
* @return Whether the specified insets source is currently requested to be visible by the
|
||||
* application.
|
||||
* @hide
|
||||
*/
|
||||
boolean isRequestedVisible(@InternalInsetsType int type);
|
||||
|
||||
/**
|
||||
* Adds a {@link OnControllableInsetsChangedListener} to the window insets controller.
|
||||
*
|
||||
|
||||
@@ -120,6 +120,7 @@ import com.android.internal.widget.DecorCaptionView;
|
||||
import com.android.internal.widget.FloatingToolbar;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
/** @hide */
|
||||
public class DecorView extends FrameLayout implements RootViewSurfaceTaker, WindowCallbacks {
|
||||
@@ -1101,7 +1102,6 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
|
||||
int sysUiVisibility = attrs.systemUiVisibility | getWindowSystemUiVisibility();
|
||||
|
||||
final WindowInsetsController controller = getWindowInsetsController();
|
||||
final InsetsState state = controller != null ? controller.getState() : null;
|
||||
|
||||
// IME is an exceptional floating window that requires color view.
|
||||
final boolean isImeWindow =
|
||||
@@ -1151,7 +1151,7 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
|
||||
calculateNavigationBarColor(), mWindow.mNavigationBarDividerColor, navBarSize,
|
||||
navBarToRightEdge || navBarToLeftEdge, navBarToLeftEdge,
|
||||
0 /* sideInset */, animate && !disallowAnimate,
|
||||
mForceWindowDrawsBarBackgrounds, state);
|
||||
mForceWindowDrawsBarBackgrounds, controller);
|
||||
boolean oldDrawLegacy = mDrawLegacyNavigationBarBackground;
|
||||
mDrawLegacyNavigationBarBackground = mNavigationColorViewState.visible
|
||||
&& (mWindow.getAttributes().flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) == 0;
|
||||
@@ -1172,7 +1172,7 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
|
||||
calculateStatusBarColor(), 0, mLastTopInset,
|
||||
false /* matchVertical */, statusBarNeedsLeftInset, statusBarSideInset,
|
||||
animate && !disallowAnimate,
|
||||
mForceWindowDrawsBarBackgrounds, state);
|
||||
mForceWindowDrawsBarBackgrounds, controller);
|
||||
|
||||
if (mHasCaption) {
|
||||
final int captionColor = calculateStatusBarColor();
|
||||
@@ -1193,7 +1193,7 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
|
||||
// SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION to indicate whether the app wants to handle it by
|
||||
// themselves.
|
||||
boolean hideNavigation = (sysUiVisibility & SYSTEM_UI_FLAG_HIDE_NAVIGATION) != 0
|
||||
|| !(state == null || state.getSource(ITYPE_NAVIGATION_BAR).isVisible());
|
||||
|| !(controller == null || controller.isRequestedVisible(ITYPE_NAVIGATION_BAR));
|
||||
boolean forceConsumingNavBar = (mForceWindowDrawsBarBackgrounds
|
||||
&& (attrs.flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) == 0
|
||||
&& (sysUiVisibility & SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) == 0
|
||||
@@ -1214,7 +1214,7 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
|
||||
// fullscreen, as othrewise we can expect the app to handle it.
|
||||
boolean fullscreen = (sysUiVisibility & SYSTEM_UI_FLAG_FULLSCREEN) != 0
|
||||
|| (attrs.flags & FLAG_FULLSCREEN) != 0
|
||||
|| !(state == null || state.getSource(ITYPE_STATUS_BAR).isVisible());
|
||||
|| !(controller == null || controller.isRequestedVisible(ITYPE_STATUS_BAR));
|
||||
boolean consumingStatusBar = (sysUiVisibility & SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN) == 0
|
||||
&& (attrs.flags & FLAG_LAYOUT_IN_SCREEN) == 0
|
||||
&& (attrs.flags & FLAG_LAYOUT_INSET_DECOR) == 0
|
||||
@@ -1354,10 +1354,12 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
|
||||
*/
|
||||
private void updateColorViewInt(final ColorViewState state, int sysUiVis, int color,
|
||||
int dividerColor, int size, boolean verticalBar, boolean seascape, int sideMargin,
|
||||
boolean animate, boolean force, InsetsState insetsState) {
|
||||
boolean animate, boolean force, WindowInsetsController controller) {
|
||||
state.present = ViewRootImpl.sNewInsetsMode != ViewRootImpl.NEW_INSETS_MODE_FULL
|
||||
? state.attributes.isPresent(sysUiVis, mWindow.getAttributes().flags, force)
|
||||
: state.attributes.isPresent(insetsState, mWindow.getAttributes().flags, force);
|
||||
: state.attributes.isPresent(
|
||||
controller.isRequestedVisible(state.attributes.insetsType),
|
||||
mWindow.getAttributes().flags, force);
|
||||
boolean show = state.attributes.isVisible(state.present, color,
|
||||
mWindow.getAttributes().flags, force);
|
||||
boolean showView = show && !isResizing() && !mHasCaption && size > 0;
|
||||
@@ -2624,8 +2626,8 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
|
||||
|| force);
|
||||
}
|
||||
|
||||
public boolean isPresent(InsetsState state, int windowFlags, boolean force) {
|
||||
return (state == null || state.getSource(insetsType).isVisible())
|
||||
public boolean isPresent(boolean requestedVisible, int windowFlags, boolean force) {
|
||||
return requestedVisible
|
||||
&& ((windowFlags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0 || force);
|
||||
}
|
||||
|
||||
@@ -2642,7 +2644,8 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
|
||||
}
|
||||
|
||||
public boolean isVisible(InsetsState state, int color, int windowFlags, boolean force) {
|
||||
final boolean present = isPresent(state, windowFlags, force);
|
||||
final boolean present = isPresent(state.getSource(insetsType).isVisible(), windowFlags,
|
||||
force);
|
||||
return isVisible(present, color, windowFlags, force);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,6 +77,9 @@ class InsetsPolicy {
|
||||
|
||||
/** Updates the target which can control system bars. */
|
||||
void updateBarControlTarget(@Nullable WindowState focusedWin) {
|
||||
if (mFocusedWin != focusedWin){
|
||||
abortTransient();
|
||||
}
|
||||
mFocusedWin = focusedWin;
|
||||
mStateController.onBarControlTargetChanged(getStatusControlTarget(focusedWin),
|
||||
getFakeStatusControlTarget(focusedWin),
|
||||
@@ -123,11 +126,13 @@ class InsetsPolicy {
|
||||
mPolicy.getStatusBarManagerInternal().showTransient(mDisplayContent.getDisplayId(),
|
||||
mShowingTransientTypes.toArray());
|
||||
updateBarControlTarget(mFocusedWin);
|
||||
InsetsState state = new InsetsState(mStateController.getRawInsetsState());
|
||||
startAnimation(true /* show */, () -> {
|
||||
synchronized (mDisplayContent.mWmService.mGlobalLock) {
|
||||
mStateController.notifyInsetsChanged();
|
||||
}
|
||||
});
|
||||
}, state);
|
||||
mStateController.onInsetsModified(mDummyControlTarget, state);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,13 +140,15 @@ class InsetsPolicy {
|
||||
if (mShowingTransientTypes.size() == 0) {
|
||||
return;
|
||||
}
|
||||
InsetsState state = new InsetsState(mStateController.getRawInsetsState());
|
||||
startAnimation(false /* show */, () -> {
|
||||
synchronized (mDisplayContent.mWmService.mGlobalLock) {
|
||||
mShowingTransientTypes.clear();
|
||||
mStateController.notifyInsetsChanged();
|
||||
updateBarControlTarget(mFocusedWin);
|
||||
}
|
||||
});
|
||||
}, state);
|
||||
mStateController.onInsetsModified(mDummyControlTarget, state);
|
||||
}
|
||||
|
||||
boolean isTransient(@InternalInsetsType int type) {
|
||||
@@ -152,14 +159,22 @@ class InsetsPolicy {
|
||||
* @see InsetsStateController#getInsetsForDispatch
|
||||
*/
|
||||
InsetsState getInsetsForDispatch(WindowState target) {
|
||||
InsetsState state = mStateController.getInsetsForDispatch(target);
|
||||
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);
|
||||
}
|
||||
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;
|
||||
@@ -206,6 +221,13 @@ class InsetsPolicy {
|
||||
}
|
||||
}
|
||||
|
||||
private void abortTransient() {
|
||||
mPolicy.getStatusBarManagerInternal().abortTransient(mDisplayContent.getDisplayId(),
|
||||
mShowingTransientTypes.toArray());
|
||||
mShowingTransientTypes.clear();
|
||||
updateBarControlTarget(mFocusedWin);
|
||||
}
|
||||
|
||||
private @Nullable InsetsControlTarget getFakeStatusControlTarget(
|
||||
@Nullable WindowState focused) {
|
||||
return getStatusControlTarget(focused) == mDummyControlTarget ? focused : null;
|
||||
@@ -286,19 +308,20 @@ class InsetsPolicy {
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void startAnimation(boolean show, Runnable callback) {
|
||||
void startAnimation(boolean show, Runnable callback, InsetsState state) {
|
||||
int typesReady = 0;
|
||||
final SparseArray<InsetsSourceControl> controls = new SparseArray<>();
|
||||
final IntArray showingTransientTypes = mShowingTransientTypes;
|
||||
for (int i = showingTransientTypes.size() - 1; i >= 0; i--) {
|
||||
InsetsSourceProvider provider =
|
||||
mStateController.getSourceProvider(showingTransientTypes.get(i));
|
||||
int type = showingTransientTypes.get(i);
|
||||
InsetsSourceProvider provider = mStateController.getSourceProvider(type);
|
||||
InsetsSourceControl control = provider.getControl(mDummyControlTarget);
|
||||
if (control == null || control.getLeash() == null) {
|
||||
continue;
|
||||
}
|
||||
typesReady |= InsetsState.toPublicType(showingTransientTypes.get(i));
|
||||
typesReady |= InsetsState.toPublicType(type);
|
||||
controls.put(control.getType(), new InsetsSourceControl(control));
|
||||
state.setSourceVisible(type, show);
|
||||
}
|
||||
controlAnimationUnchecked(typesReady, controls, show, callback);
|
||||
}
|
||||
|
||||
@@ -259,10 +259,13 @@ class InsetsSourceProvider {
|
||||
if (target == null) {
|
||||
// Cancelling the animation will invoke onAnimationCancelled, resetting all the fields.
|
||||
mWin.cancelAnimation();
|
||||
setClientVisible(InsetsState.getDefaultVisibility(mSource.getType()));
|
||||
return;
|
||||
}
|
||||
mAdapter = new ControlAdapter();
|
||||
setClientVisible(InsetsState.getDefaultVisibility(mSource.getType()));
|
||||
if (getSource().getType() == ITYPE_IME) {
|
||||
setClientVisible(InsetsState.getDefaultVisibility(mSource.getType()));
|
||||
}
|
||||
final Transaction t = mDisplayContent.getPendingTransaction();
|
||||
mWin.startAnimation(t, mAdapter, !mClientVisible /* hidden */,
|
||||
ANIMATION_TYPE_INSETS_CONTROL, null /* animationFinishedCallback */);
|
||||
|
||||
@@ -3974,7 +3974,12 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
|
||||
}
|
||||
pw.println(prefix + "isOnScreen=" + isOnScreen());
|
||||
pw.println(prefix + "isVisible=" + isVisible());
|
||||
pw.println(prefix + "mEmbeddedDisplayContents=" + mEmbeddedDisplayContents);
|
||||
if (!mEmbeddedDisplayContents.isEmpty()) {
|
||||
pw.println(prefix + "mEmbeddedDisplayContents=" + mEmbeddedDisplayContents);
|
||||
}
|
||||
if (dumpAll) {
|
||||
pw.println(prefix + "mRequestedInsetsState: " + mRequestedInsetsState);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -22,6 +22,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMAR
|
||||
import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
|
||||
import static android.view.InsetsState.ITYPE_STATUS_BAR;
|
||||
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;
|
||||
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
|
||||
@@ -29,13 +30,18 @@ import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
|
||||
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
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.doAnswer;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
import android.util.IntArray;
|
||||
@@ -164,45 +170,51 @@ public class InsetsPolicyTest extends WindowTestsBase {
|
||||
|
||||
@Test
|
||||
public void testShowTransientBars_bothCanBeTransient_appGetsBothFakeControls() {
|
||||
addWindow(TYPE_STATUS_BAR, "statusBar")
|
||||
addNonFocusableWindow(TYPE_STATUS_BAR, "statusBar")
|
||||
.getControllableInsetProvider().getSource().setVisible(false);
|
||||
addWindow(TYPE_NAVIGATION_BAR, "navBar")
|
||||
addNonFocusableWindow(TYPE_NAVIGATION_BAR, "navBar")
|
||||
.getControllableInsetProvider().getSource().setVisible(false);
|
||||
final WindowState app = addWindow(TYPE_APPLICATION, "app");
|
||||
|
||||
final InsetsPolicy policy = spy(mDisplayContent.getInsetsPolicy());
|
||||
doNothing().when(policy).startAnimation(anyBoolean(), any());
|
||||
policy.updateBarControlTarget(app);
|
||||
|
||||
doAnswer(invocation -> {
|
||||
((InsetsState) invocation.getArgument(2)).setSourceVisible(ITYPE_STATUS_BAR, true);
|
||||
((InsetsState) invocation.getArgument(2)).setSourceVisible(ITYPE_NAVIGATION_BAR, true);
|
||||
return null;
|
||||
}).when(policy).startAnimation(anyBoolean(), any(), any());
|
||||
|
||||
policy.updateBarControlTarget(mAppWindow);
|
||||
policy.showTransient(
|
||||
IntArray.wrap(new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR}));
|
||||
final InsetsSourceControl[] controls =
|
||||
mDisplayContent.getInsetsStateController().getControlsForDispatch(app);
|
||||
mDisplayContent.getInsetsStateController().getControlsForDispatch(mAppWindow);
|
||||
|
||||
// The app must get both fake controls.
|
||||
assertEquals(2, controls.length);
|
||||
for (int i = controls.length - 1; i >= 0; i--) {
|
||||
assertNull(controls[i].getLeash());
|
||||
}
|
||||
|
||||
assertTrue(mDisplayContent.getInsetsStateController().getRawInsetsState()
|
||||
.getSource(ITYPE_STATUS_BAR).isVisible());
|
||||
assertTrue(mDisplayContent.getInsetsStateController().getRawInsetsState()
|
||||
.getSource(ITYPE_NAVIGATION_BAR).isVisible());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShowTransientBars_statusBarCanBeTransient_appGetsStatusBarFakeControl() {
|
||||
// Adding app window before setting source visibility is to prevent the visibility from
|
||||
// being cleared by InsetsSourceProvider.updateVisibility.
|
||||
final WindowState app = addWindow(TYPE_APPLICATION, "app");
|
||||
|
||||
addWindow(TYPE_STATUS_BAR, "statusBar")
|
||||
addNonFocusableWindow(TYPE_STATUS_BAR, "statusBar")
|
||||
.getControllableInsetProvider().getSource().setVisible(false);
|
||||
addWindow(TYPE_NAVIGATION_BAR, "navBar")
|
||||
addNonFocusableWindow(TYPE_NAVIGATION_BAR, "navBar")
|
||||
.getControllableInsetProvider().getSource().setVisible(true);
|
||||
|
||||
final InsetsPolicy policy = spy(mDisplayContent.getInsetsPolicy());
|
||||
doNothing().when(policy).startAnimation(anyBoolean(), any());
|
||||
policy.updateBarControlTarget(app);
|
||||
doNothing().when(policy).startAnimation(anyBoolean(), any(), any());
|
||||
policy.updateBarControlTarget(mAppWindow);
|
||||
policy.showTransient(
|
||||
IntArray.wrap(new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR}));
|
||||
final InsetsSourceControl[] controls =
|
||||
mDisplayContent.getInsetsStateController().getControlsForDispatch(app);
|
||||
mDisplayContent.getInsetsStateController().getControlsForDispatch(mAppWindow);
|
||||
|
||||
// The app must get the fake control of the status bar, and must get the real control of the
|
||||
// navigation bar.
|
||||
@@ -219,19 +231,18 @@ public class InsetsPolicyTest extends WindowTestsBase {
|
||||
|
||||
@Test
|
||||
public void testAbortTransientBars_bothCanBeAborted_appGetsBothRealControls() {
|
||||
addWindow(TYPE_STATUS_BAR, "statusBar")
|
||||
addNonFocusableWindow(TYPE_STATUS_BAR, "statusBar")
|
||||
.getControllableInsetProvider().getSource().setVisible(false);
|
||||
addWindow(TYPE_NAVIGATION_BAR, "navBar")
|
||||
addNonFocusableWindow(TYPE_NAVIGATION_BAR, "navBar")
|
||||
.getControllableInsetProvider().getSource().setVisible(false);
|
||||
final WindowState app = addWindow(TYPE_APPLICATION, "app");
|
||||
|
||||
final InsetsPolicy policy = spy(mDisplayContent.getInsetsPolicy());
|
||||
doNothing().when(policy).startAnimation(anyBoolean(), any());
|
||||
policy.updateBarControlTarget(app);
|
||||
doNothing().when(policy).startAnimation(anyBoolean(), any(), any());
|
||||
policy.updateBarControlTarget(mAppWindow);
|
||||
policy.showTransient(
|
||||
IntArray.wrap(new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR}));
|
||||
InsetsSourceControl[] controls =
|
||||
mDisplayContent.getInsetsStateController().getControlsForDispatch(app);
|
||||
mDisplayContent.getInsetsStateController().getControlsForDispatch(mAppWindow);
|
||||
|
||||
// The app must get both fake controls.
|
||||
assertEquals(2, controls.length);
|
||||
@@ -239,12 +250,12 @@ public class InsetsPolicyTest extends WindowTestsBase {
|
||||
assertNull(controls[i].getLeash());
|
||||
}
|
||||
|
||||
final InsetsState state = policy.getInsetsForDispatch(app);
|
||||
final InsetsState state = policy.getInsetsForDispatch(mAppWindow);
|
||||
state.setSourceVisible(ITYPE_STATUS_BAR, true);
|
||||
state.setSourceVisible(ITYPE_NAVIGATION_BAR, true);
|
||||
policy.onInsetsModified(app, state);
|
||||
policy.onInsetsModified(mAppWindow, state);
|
||||
|
||||
controls = mDisplayContent.getInsetsStateController().getControlsForDispatch(app);
|
||||
controls = mDisplayContent.getInsetsStateController().getControlsForDispatch(mAppWindow);
|
||||
|
||||
// The app must get both real controls.
|
||||
assertEquals(2, controls.length);
|
||||
@@ -253,6 +264,33 @@ public class InsetsPolicyTest extends WindowTestsBase {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShowTransientBars_abortsWhenControlTargetChanges() {
|
||||
addNonFocusableWindow(TYPE_STATUS_BAR, "statusBar")
|
||||
.getControllableInsetProvider().getSource().setVisible(false);
|
||||
addNonFocusableWindow(TYPE_NAVIGATION_BAR, "navBar")
|
||||
.getControllableInsetProvider().getSource().setVisible(false);
|
||||
final WindowState app = addWindow(TYPE_APPLICATION, "app");
|
||||
final WindowState app2 = addWindow(TYPE_APPLICATION, "app");
|
||||
|
||||
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}));
|
||||
final InsetsSourceControl[] controls =
|
||||
mDisplayContent.getInsetsStateController().getControlsForDispatch(app);
|
||||
policy.updateBarControlTarget(app2);
|
||||
assertFalse(policy.isTransient(ITYPE_STATUS_BAR));
|
||||
assertFalse(policy.isTransient(ITYPE_NAVIGATION_BAR));
|
||||
}
|
||||
|
||||
private WindowState addNonFocusableWindow(int type, String name) {
|
||||
WindowState win = addWindow(type, name);
|
||||
win.mAttrs.flags |= FLAG_NOT_FOCUSABLE;
|
||||
return win;
|
||||
}
|
||||
|
||||
private WindowState addWindow(int type, String name) {
|
||||
final WindowState win = createWindow(null, type, name);
|
||||
mDisplayContent.getDisplayPolicy().addWindowLw(win, win.mAttrs);
|
||||
|
||||
@@ -41,6 +41,7 @@ import android.graphics.PixelFormat;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.Rect;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
import android.view.InsetsState;
|
||||
import android.view.Surface;
|
||||
import android.view.SurfaceControl;
|
||||
|
||||
@@ -87,7 +88,7 @@ public class TaskSnapshotSurfaceTest extends WindowTestsBase {
|
||||
0 /* systemUiVisibility */, false /* isTranslucent */);
|
||||
mSurface = new TaskSnapshotSurface(mWm, new Window(), new SurfaceControl(), snapshot, "Test",
|
||||
createTaskDescription(Color.WHITE, Color.RED, Color.BLUE), sysuiVis, windowFlags, 0,
|
||||
taskBounds, ORIENTATION_PORTRAIT, null /* insetsState */);
|
||||
taskBounds, ORIENTATION_PORTRAIT, new InsetsState());
|
||||
}
|
||||
|
||||
private static TaskDescription createTaskDescription(int background, int statusBar,
|
||||
|
||||
Reference in New Issue
Block a user