Fix a couple of issues with insets
- Prevent any other animations running in WM that may override
the inset control.
- Ensure that we give the client control when the window gets
added.
Test: Show IME the first time
Bug: 111084606
Change-Id: I841d262103dc14e4aa71dbd37b696c76d822abd7
diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
index e49e4c0..e798203 100644
--- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
@@ -16,7 +16,13 @@
package com.android.server.wm;
+import static android.view.InsetsState.TYPE_IME;
+import static android.view.InsetsState.TYPE_NAVIGATION_BAR;
+import static android.view.InsetsState.TYPE_TOP_BAR;
+import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL;
+import static android.view.ViewRootImpl.NEW_INSETS_MODE_IME;
import static android.view.ViewRootImpl.NEW_INSETS_MODE_NONE;
+import static android.view.ViewRootImpl.sNewInsetsMode;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -59,6 +65,7 @@
*/
private boolean mServerVisible;
+ private final boolean mControllable;
InsetsSourceProvider(InsetsSource source, InsetsStateController stateController,
DisplayContent displayContent) {
@@ -66,6 +73,15 @@
mSource = source;
mDisplayContent = displayContent;
mStateController = stateController;
+
+ final int type = source.getType();
+ if (type == TYPE_TOP_BAR || type == TYPE_NAVIGATION_BAR) {
+ mControllable = sNewInsetsMode == NEW_INSETS_MODE_FULL;
+ } else if (type == TYPE_IME) {
+ mControllable = sNewInsetsMode >= NEW_INSETS_MODE_IME;
+ } else {
+ mControllable = false;
+ }
}
InsetsSource getSource() {
@@ -73,6 +89,13 @@
}
/**
+ * @return Whether the current flag configuration allows to control this source.
+ */
+ boolean isControllable() {
+ return mControllable;
+ }
+
+ /**
* Updates the window that currently backs this source.
*
* @param win The window that links to this source.
@@ -91,6 +114,9 @@
mSource.setFrame(new Rect());
} else {
mWin.setInsetProvider(this);
+ if (mControllingWin != null) {
+ updateControlForTarget(mControllingWin, true /* force */);
+ }
}
}
@@ -113,8 +139,12 @@
&& !mWin.mGivenInsetsPending);
}
- void updateControlForTarget(@Nullable WindowState target) {
- if (target == mControllingWin) {
+ void updateControlForTarget(@Nullable WindowState target, boolean force) {
+ if (mWin == null) {
+ mControllingWin = target;
+ return;
+ }
+ if (target == mControllingWin && !force) {
return;
}
if (target == null) {
@@ -161,7 +191,7 @@
}
boolean isClientVisible() {
- return ViewRootImpl.sNewInsetsMode == NEW_INSETS_MODE_NONE || mClientVisible;
+ return sNewInsetsMode == NEW_INSETS_MODE_NONE || mClientVisible;
}
private class ControlAdapter implements AnimationAdapter {
diff --git a/services/core/java/com/android/server/wm/InsetsStateController.java b/services/core/java/com/android/server/wm/InsetsStateController.java
index c99839e..bb0cbb1 100644
--- a/services/core/java/com/android/server/wm/InsetsStateController.java
+++ b/services/core/java/com/android/server/wm/InsetsStateController.java
@@ -148,10 +148,6 @@
* and visibility.
*/
void onBarControllingWindowChanged(@Nullable WindowState controllingWindow) {
- if (sNewInsetsMode != NEW_INSETS_MODE_FULL) {
- return;
- }
-
// TODO: Apply policy that determines whether controllingWindow is able to control system
// bars
@@ -167,18 +163,18 @@
}
private void onControlChanged(int type, @Nullable WindowState win) {
- if (sNewInsetsMode == NEW_INSETS_MODE_NONE) {
- return;
- }
final WindowState previous = mTypeWinControlMap.get(type);
if (win == previous) {
return;
}
- final InsetsSourceProvider controller = mControllers.get(type);
+ final InsetsSourceProvider controller = getSourceProvider(type);
if (controller == null) {
return;
}
- controller.updateControlForTarget(win);
+ if (!controller.isControllable()) {
+ return;
+ }
+ controller.updateControlForTarget(win, false /* force */);
if (previous != null) {
removeFromControlMaps(previous, type);
mPendingControlChanged.add(previous);
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 8f86c00..7d900e5 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -4371,6 +4371,12 @@
}
void startAnimation(Animation anim) {
+
+ // If we are an inset provider, all our animations are driven by the inset client.
+ if (mInsetProvider != null && mInsetProvider.isControllable()) {
+ return;
+ }
+
final DisplayInfo displayInfo = getDisplayContent().getDisplayInfo();
anim.initialize(mWindowFrames.mFrame.width(), mWindowFrames.mFrame.height(),
displayInfo.appWidth, displayInfo.appHeight);
@@ -4384,6 +4390,12 @@
}
private void startMoveAnimation(int left, int top) {
+
+ // If we are an inset provider, all our animations are driven by the inset client.
+ if (mInsetProvider != null && mInsetProvider.isControllable()) {
+ return;
+ }
+
if (DEBUG_ANIM) Slog.v(TAG, "Setting move animation on " + this);
final Point oldPosition = new Point();
final Point newPosition = new Point();
diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java
index 3740786..a498a1a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java
@@ -94,9 +94,9 @@
final WindowState target = createWindow(null, TYPE_APPLICATION, "target");
topBar.getFrameLw().set(0, 0, 500, 100);
mProvider.setWindow(topBar, null);
- mProvider.updateControlForTarget(target);
+ mProvider.updateControlForTarget(target, false /* force */);
assertNotNull(mProvider.getControl());
- mProvider.updateControlForTarget(null);
+ mProvider.updateControlForTarget(null, false /* force */);
assertNull(mProvider.getControl());
}
@@ -106,7 +106,7 @@
final WindowState target = createWindow(null, TYPE_APPLICATION, "target");
topBar.getFrameLw().set(0, 0, 500, 100);
mProvider.setWindow(topBar, null);
- mProvider.updateControlForTarget(target);
+ mProvider.updateControlForTarget(target, false /* force */);
InsetsState state = new InsetsState();
state.getSource(TYPE_TOP_BAR).setVisible(false);
mProvider.onInsetsModified(target, state.getSource(TYPE_TOP_BAR));