summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/view/ImeInsetsSourceConsumer.java7
-rw-r--r--core/java/android/view/InsetsController.java123
-rw-r--r--core/java/android/view/InsetsSourceConsumer.java64
-rw-r--r--core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java4
-rw-r--r--core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java6
-rw-r--r--core/tests/coretests/src/android/view/InsetsControllerTest.java51
-rw-r--r--core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java17
7 files changed, 162 insertions, 110 deletions
diff --git a/core/java/android/view/ImeInsetsSourceConsumer.java b/core/java/android/view/ImeInsetsSourceConsumer.java
index e34aef97a8ab..b8cd7b9d177a 100644
--- a/core/java/android/view/ImeInsetsSourceConsumer.java
+++ b/core/java/android/view/ImeInsetsSourceConsumer.java
@@ -20,7 +20,6 @@ import static android.view.ImeInsetsSourceConsumerProto.INSETS_SOURCE_CONSUMER;
import static android.view.ImeInsetsSourceConsumerProto.IS_HIDE_ANIMATION_RUNNING;
import static android.view.ImeInsetsSourceConsumerProto.IS_REQUESTED_VISIBLE_AWAITING_CONTROL;
import static android.view.ImeInsetsSourceConsumerProto.IS_SHOW_REQUESTED_DURING_HIDE_ANIMATION;
-import static android.view.InsetsState.ITYPE_IME;
import android.annotation.Nullable;
import android.os.IBinder;
@@ -55,9 +54,9 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer {
private boolean mIsShowRequestedDuringHideAnimation;
public ImeInsetsSourceConsumer(
- InsetsState state, Supplier<Transaction> transactionSupplier,
+ int id, InsetsState state, Supplier<Transaction> transactionSupplier,
InsetsController controller) {
- super(ITYPE_IME, state, transactionSupplier, controller);
+ super(id, WindowInsets.Type.ime(), state, transactionSupplier, controller);
}
@Override
@@ -137,7 +136,7 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer {
// If we had a request before to show from IME (tracked with mImeRequestedShow), reaching
// this code here means that we now got control, so we can start the animation immediately.
// If client window is trying to control IME and IME is already visible, it is immediate.
- if (fromIme || (mState.getSource(getInternalType()).isVisible() && getControl() != null)) {
+ if (fromIme || (mState.getSource(getId()).isVisible() && getControl() != null)) {
return ShowResult.SHOW_IMMEDIATELY;
}
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index e1b27ffe035d..c074e84e5158 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -21,7 +21,6 @@ import static android.view.InsetsControllerProto.CONTROL;
import static android.view.InsetsControllerProto.STATE;
import static android.view.InsetsState.ITYPE_CAPTION_BAR;
import static android.view.InsetsState.ITYPE_IME;
-import static android.view.InsetsState.toPublicType;
import static android.view.ViewRootImpl.CAPTION_ON_SHELL;
import static android.view.WindowInsets.Type.FIRST;
import static android.view.WindowInsets.Type.LAST;
@@ -569,8 +568,9 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
private final InsetsState mLastDispatchedState = new InsetsState();
private final Rect mFrame = new Rect();
- private final BiFunction<InsetsController, Integer, InsetsSourceConsumer> mConsumerCreator;
+ private final BiFunction<InsetsController, InsetsSource, InsetsSourceConsumer> mConsumerCreator;
private final SparseArray<InsetsSourceConsumer> mSourceConsumers = new SparseArray<>();
+ private final InsetsSourceConsumer mImeSourceConsumer;
private final Host mHost;
private final Handler mHandler;
@@ -621,19 +621,20 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
this::invokeControllableInsetsChangedListeners;
public InsetsController(Host host) {
- this(host, (controller, type) -> {
- if (type == ITYPE_IME) {
- return new ImeInsetsSourceConsumer(controller.mState, Transaction::new, controller);
+ this(host, (controller, source) -> {
+ if (source.getType() == ime()) {
+ return new ImeInsetsSourceConsumer(source.getId(), controller.mState,
+ Transaction::new, controller);
} else {
- return new InsetsSourceConsumer(type, controller.mState, Transaction::new,
- controller);
+ return new InsetsSourceConsumer(source.getId(), source.getType(), controller.mState,
+ Transaction::new, controller);
}
}, host.getHandler());
}
@VisibleForTesting
public InsetsController(Host host,
- BiFunction<InsetsController, Integer, InsetsSourceConsumer> consumerCreator,
+ BiFunction<InsetsController, InsetsSource, InsetsSourceConsumer> consumerCreator,
Handler handler) {
mHost = host;
mConsumerCreator = consumerCreator;
@@ -683,6 +684,9 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
dispatchAnimationEnd(finishedAnimations.get(i));
}
};
+
+ // Make mImeSourceConsumer always non-null.
+ mImeSourceConsumer = getSourceConsumer(new InsetsSource(ITYPE_IME, ime()));
}
@VisibleForTesting
@@ -741,28 +745,37 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
private void updateState(InsetsState newState) {
mState.set(newState, 0 /* types */);
+ for (int i = mSourceConsumers.size() - 1; i >= 0; i--) {
+ final InsetsSourceConsumer consumer = mSourceConsumers.valueAt(i);
+ final InsetsSource source = newState.peekSource(consumer.getId());
+ if (source == null && consumer != mImeSourceConsumer) {
+ // IME source consumer should always be there since we need to communicate with
+ // InputMethodManager no matter we have the source or not.
+ mSourceConsumers.removeAt(i);
+ }
+ }
@InsetsType int existingTypes = 0;
@InsetsType int visibleTypes = 0;
@InsetsType int disabledUserAnimationTypes = 0;
@InsetsType int[] cancelledUserAnimationTypes = {0};
- for (@InternalInsetsType int type = 0; type < InsetsState.SIZE; type++) {
- InsetsSource source = newState.peekSource(type);
+ for (int i = 0; i < InsetsState.SIZE; i++) {
+ InsetsSource source = newState.peekSource(i);
if (source == null) continue;
- @InsetsType int insetsType = toPublicType(type);
- @AnimationType int animationType = getAnimationType(insetsType);
+ @InsetsType int type = source.getType();
+ @AnimationType int animationType = getAnimationType(type);
if (!source.isUserControllable()) {
// The user animation is not allowed when visible frame is empty.
- disabledUserAnimationTypes |= insetsType;
+ disabledUserAnimationTypes |= type;
if (animationType == ANIMATION_TYPE_USER) {
// Existing user animation needs to be cancelled.
animationType = ANIMATION_TYPE_NONE;
- cancelledUserAnimationTypes[0] |= insetsType;
+ cancelledUserAnimationTypes[0] |= type;
}
}
- getSourceConsumer(type).updateSource(source, animationType);
- existingTypes |= insetsType;
+ getSourceConsumer(source).updateSource(source, animationType);
+ existingTypes |= type;
if (source.isVisible()) {
- visibleTypes |= insetsType;
+ visibleTypes |= type;
}
}
@@ -899,25 +912,34 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
}
@InsetsType int controllableTypes = 0;
+ int consumedControlCount = 0;
final int[] showTypes = new int[1];
final int[] hideTypes = new int[1];
// Ensure to update all existing source consumers
for (int i = mSourceConsumers.size() - 1; i >= 0; i--) {
final InsetsSourceConsumer consumer = mSourceConsumers.valueAt(i);
- final InsetsSourceControl control = mTmpControlArray.get(consumer.getInternalType());
+ final InsetsSourceControl control = mTmpControlArray.get(consumer.getId());
+ if (control != null) {
+ controllableTypes |= control.getType();
+ consumedControlCount++;
+ }
// control may be null, but we still need to update the control to null if it got
// revoked.
consumer.setControl(control, showTypes, hideTypes);
}
- // Ensure to create source consumers if not available yet.
- for (int i = mTmpControlArray.size() - 1; i >= 0; i--) {
- final InsetsSourceControl control = mTmpControlArray.valueAt(i);
- final InsetsSourceConsumer consumer = getSourceConsumer(control.getId());
- consumer.setControl(control, showTypes, hideTypes);
- controllableTypes |= control.getType();
+ if (consumedControlCount != mTmpControlArray.size()) {
+ // Whoops! The server sent us some controls without sending corresponding sources.
+ for (int i = mTmpControlArray.size() - 1; i >= 0; i--) {
+ final InsetsSourceControl control = mTmpControlArray.valueAt(i);
+ final InsetsSourceConsumer consumer = mSourceConsumers.get(control.getId());
+ if (consumer == null) {
+ control.release(SurfaceControl::release);
+ Log.e(TAG, control + " has no consumer.");
+ }
+ }
}
if (mTmpControlArray.size() > 0) {
@@ -1144,11 +1166,11 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
types &= ~mDisabledUserAnimationInsetsTypes;
if (fromIme && (disabledTypes & ime()) != 0
- && !mState.getSource(ITYPE_IME).isVisible()) {
+ && !mState.getSource(mImeSourceConsumer.getId()).isVisible()) {
// We've requested IMM to show IME, but the IME is not controllable. We need to
// cancel the request.
setRequestedVisibleTypes(0 /* visibleTypes */, ime());
- if (getSourceConsumer(ITYPE_IME).onAnimationStateChanged(false /* running */)) {
+ if (mImeSourceConsumer.onAnimationStateChanged(false /* running */)) {
notifyVisibilityChanged();
}
}
@@ -1163,11 +1185,10 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
if (DEBUG) Log.d(TAG, "controlAnimation types: " + types);
mLastStartedAnimTypes |= types;
- final ArraySet<Integer> internalTypes = InsetsState.toInternalType(types);
final SparseArray<InsetsSourceControl> controls = new SparseArray<>();
Pair<Integer, Boolean> typesReadyPair = collectSourceControls(
- fromIme, internalTypes, controls, animationType);
+ fromIme, types, controls, animationType);
int typesReady = typesReadyPair.first;
boolean imeReady = typesReadyPair.second;
if (DEBUG) Log.d(TAG, String.format(
@@ -1257,13 +1278,15 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
/**
* @return Pair of (types ready to animate, IME ready to animate).
*/
- private Pair<Integer, Boolean> collectSourceControls(boolean fromIme,
- ArraySet<Integer> internalTypes, SparseArray<InsetsSourceControl> controls,
- @AnimationType int animationType) {
+ private Pair<Integer, Boolean> collectSourceControls(boolean fromIme, @InsetsType int types,
+ SparseArray<InsetsSourceControl> controls, @AnimationType int animationType) {
int typesReady = 0;
boolean imeReady = true;
- for (int i = internalTypes.size() - 1; i >= 0; i--) {
- final InsetsSourceConsumer consumer = getSourceConsumer(internalTypes.valueAt(i));
+ for (int i = mSourceConsumers.size() - 1; i >= 0; i--) {
+ final InsetsSourceConsumer consumer = mSourceConsumers.valueAt(i);
+ if ((consumer.getType() & types) == 0) {
+ continue;
+ }
boolean show = animationType == ANIMATION_TYPE_SHOW
|| animationType == ANIMATION_TYPE_USER;
boolean canRun = true;
@@ -1291,7 +1314,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
if (!canRun) {
if (WARN) Log.w(TAG, String.format(
"collectSourceControls can't continue show for type: %s fromIme: %b",
- InsetsState.typeToString(consumer.getInternalType()), fromIme));
+ WindowInsets.Type.toString(consumer.getType()), fromIme));
continue;
}
final InsetsSourceControl control = consumer.getControl();
@@ -1437,17 +1460,30 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
}
@VisibleForTesting
- public @NonNull InsetsSourceConsumer getSourceConsumer(int id) {
- InsetsSourceConsumer consumer = mSourceConsumers.get(id);
+ public @NonNull InsetsSourceConsumer getSourceConsumer(InsetsSource source) {
+ final int sourceId = source.getId();
+ InsetsSourceConsumer consumer = mSourceConsumers.get(sourceId);
if (consumer != null) {
return consumer;
}
- consumer = mConsumerCreator.apply(this, id);
- mSourceConsumers.put(id, consumer);
+ if (source.getType() == ime() && mImeSourceConsumer != null) {
+ // WindowInsets.Type.ime() should be only provided by one source.
+ mSourceConsumers.remove(mImeSourceConsumer.getId());
+ consumer = mImeSourceConsumer;
+ consumer.setId(sourceId);
+ } else {
+ consumer = mConsumerCreator.apply(this, source);
+ }
+ mSourceConsumers.put(sourceId, consumer);
return consumer;
}
@VisibleForTesting
+ public @NonNull InsetsSourceConsumer getImeSourceConsumer() {
+ return mImeSourceConsumer;
+ }
+
+ @VisibleForTesting
public void notifyVisibilityChanged() {
mHost.notifyInsetsChanged();
}
@@ -1467,14 +1503,14 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
* Called when current window gains focus.
*/
public void onWindowFocusGained(boolean hasViewFocused) {
- getSourceConsumer(ITYPE_IME).onWindowFocusGained(hasViewFocused);
+ mImeSourceConsumer.onWindowFocusGained(hasViewFocused);
}
/**
* Called when current window loses focus.
*/
public void onWindowFocusLost() {
- getSourceConsumer(ITYPE_IME).onWindowFocusLost();
+ mImeSourceConsumer.onWindowFocusLost();
}
@VisibleForTesting
@@ -1518,13 +1554,12 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
// TODO(b/166736352): We should only skip the animation of specific types, not all types.
boolean skipAnim = false;
if ((types & ime()) != 0) {
- final InsetsSourceConsumer consumer = mSourceConsumers.get(ITYPE_IME);
- final InsetsSourceControl imeControl = consumer != null ? consumer.getControl() : null;
+ final InsetsSourceControl imeControl = mImeSourceConsumer.getControl();
// Skip showing animation once that made by system for some reason.
// (e.g. starting window with IME snapshot)
if (imeControl != null) {
skipAnim = imeControl.getAndClearSkipAnimationOnce() && show
- && consumer.hasViewFocusWhenWindowFocusGain();
+ && mImeSourceConsumer.hasViewFocusWhenWindowFocusGain();
}
}
applyAnimation(types, show, fromIme, skipAnim, statsToken);
@@ -1683,7 +1718,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
@InsetsType int result = 0;
for (int i = mSourceConsumers.size() - 1; i >= 0; i--) {
InsetsSourceConsumer consumer = mSourceConsumers.valueAt(i);
- InsetsSource source = mState.peekSource(consumer.getInternalType());
+ InsetsSource source = mState.peekSource(consumer.getId());
if (consumer.getControl() != null && source != null && source.isUserControllable()) {
result |= consumer.getType();
}
diff --git a/core/java/android/view/InsetsSourceConsumer.java b/core/java/android/view/InsetsSourceConsumer.java
index 7aeada8e9def..f46eb34bd397 100644
--- a/core/java/android/view/InsetsSourceConsumer.java
+++ b/core/java/android/view/InsetsSourceConsumer.java
@@ -25,7 +25,6 @@ import static android.view.InsetsSourceConsumerProto.IS_REQUESTED_VISIBLE;
import static android.view.InsetsSourceConsumerProto.PENDING_FRAME;
import static android.view.InsetsSourceConsumerProto.PENDING_VISIBLE_FRAME;
import static android.view.InsetsSourceConsumerProto.SOURCE_CONTROL;
-import static android.view.InsetsState.getDefaultVisibility;
import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
@@ -34,7 +33,6 @@ import android.annotation.Nullable;
import android.graphics.Rect;
import android.util.Log;
import android.util.proto.ProtoOutputStream;
-import android.view.InsetsState.InternalInsetsType;
import android.view.SurfaceControl.Transaction;
import android.view.WindowInsets.Type.InsetsType;
@@ -72,7 +70,7 @@ public class InsetsSourceConsumer {
protected final InsetsController mController;
protected final InsetsState mState;
- private final @InternalInsetsType int mInternalType;
+ private int mId;
private final @InsetsType int mType;
private static final String TAG = "InsetsSourceConsumer";
@@ -88,16 +86,17 @@ public class InsetsSourceConsumer {
private Rect mPendingVisibleFrame;
/**
- * @param type The {@link InternalInsetsType} of the consumed insets.
+ * @param id The ID of the consumed insets.
+ * @param type The {@link InsetsType} of the consumed insets.
* @param state The current {@link InsetsState} of the consumed insets.
* @param transactionSupplier The source of new {@link Transaction} instances. The supplier
* must provide *new* instances, which will be explicitly closed by this class.
* @param controller The {@link InsetsController} to use for insets interaction.
*/
- public InsetsSourceConsumer(@InternalInsetsType int type, InsetsState state,
+ public InsetsSourceConsumer(int id, @InsetsType int type, InsetsState state,
Supplier<Transaction> transactionSupplier, InsetsController controller) {
- mType = InsetsState.toPublicType(type);
- mInternalType = type;
+ mId = id;
+ mType = type;
mState = state;
mTransactionSupplier = transactionSupplier;
mController = controller;
@@ -134,12 +133,11 @@ public class InsetsSourceConsumer {
mController.notifyControlRevoked(this);
// Check if we need to restore server visibility.
- final InsetsSource source = mState.getSource(mInternalType);
- final boolean serverVisibility =
- mController.getLastDispatchedState().getSourceOrDefaultVisibility(
- mInternalType);
- if (source.isVisible() != serverVisibility) {
- source.setVisible(serverVisibility);
+ final InsetsSource localSource = mState.peekSource(mId);
+ final InsetsSource serverSource = mController.getLastDispatchedState().peekSource(mId);
+ if (localSource != null && serverSource != null
+ && localSource.isVisible() != serverSource.isVisible()) {
+ localSource.setVisible(serverSource.isVisible());
mController.notifyVisibilityChanged();
}
} else {
@@ -196,12 +194,16 @@ public class InsetsSourceConsumer {
return (mController.getRequestedVisibleTypes() & mType) != 0;
}
- @InsetsType int getType() {
- return mType;
+ int getId() {
+ return mId;
}
- @InternalInsetsType int getInternalType() {
- return mInternalType;
+ void setId(int id) {
+ mId = id;
+ }
+
+ @InsetsType int getType() {
+ return mType;
}
/**
@@ -211,12 +213,14 @@ public class InsetsSourceConsumer {
public boolean onAnimationStateChanged(boolean running) {
boolean insetsChanged = false;
if (!running && mPendingFrame != null) {
- InsetsSource source = mState.getSource(mInternalType);
- source.setFrame(mPendingFrame);
- source.setVisibleFrame(mPendingVisibleFrame);
+ final InsetsSource source = mState.peekSource(mId);
+ if (source != null) {
+ source.setFrame(mPendingFrame);
+ source.setVisibleFrame(mPendingVisibleFrame);
+ insetsChanged = true;
+ }
mPendingFrame = null;
mPendingVisibleFrame = null;
- insetsChanged = true;
}
// We apply the visibility override after the animation is started. We don't do this before
@@ -248,25 +252,25 @@ public class InsetsSourceConsumer {
@VisibleForTesting(visibility = PACKAGE)
public boolean applyLocalVisibilityOverride() {
- final InsetsSource source = mState.peekSource(mInternalType);
- final boolean isVisible = source != null ? source.isVisible() : getDefaultVisibility(
- mInternalType);
- final boolean hasControl = mSourceControl != null;
+ final InsetsSource source = mState.peekSource(mId);
+ if (source == null) {
+ return false;
+ }
final boolean requestedVisible = (mController.getRequestedVisibleTypes() & mType) != 0;
// If we don't have control, we are not able to change the visibility.
- if (!hasControl) {
+ if (mSourceControl == null) {
if (DEBUG) Log.d(TAG, "applyLocalVisibilityOverride: No control in "
+ mController.getHost().getRootViewTitle()
+ " requestedVisible=" + requestedVisible);
return false;
}
- if (isVisible == requestedVisible) {
+ if (source.isVisible() == requestedVisible) {
return false;
}
if (DEBUG) Log.d(TAG, String.format("applyLocalVisibilityOverride: %s requestedVisible: %b",
mController.getHost().getRootViewTitle(), requestedVisible));
- mState.getSource(mInternalType).setVisible(requestedVisible);
+ source.setVisible(requestedVisible);
return true;
}
@@ -301,7 +305,7 @@ public class InsetsSourceConsumer {
@VisibleForTesting(visibility = PACKAGE)
public void updateSource(InsetsSource newSource, @AnimationType int animationType) {
- InsetsSource source = mState.peekSource(mInternalType);
+ InsetsSource source = mState.peekSource(mId);
if (source == null || animationType == ANIMATION_TYPE_NONE
|| source.getFrame().equals(newSource.getFrame())) {
mPendingFrame = null;
@@ -345,7 +349,7 @@ public class InsetsSourceConsumer {
void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
- proto.write(INTERNAL_INSETS_TYPE, InsetsState.typeToString(mInternalType));
+ proto.write(INTERNAL_INSETS_TYPE, WindowInsets.Type.toString(mType));
proto.write(HAS_WINDOW_FOCUS, mHasWindowFocus);
proto.write(IS_REQUESTED_VISIBLE, (mController.getRequestedVisibleTypes() & mType) != 0);
if (mSourceControl != null) {
diff --git a/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java b/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java
index 9b8a0e952beb..958fdc665cb2 100644
--- a/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java
+++ b/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java
@@ -60,7 +60,7 @@ import org.mockito.Spy;
public class ImeInsetsSourceConsumerTest {
Context mContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
- ImeInsetsSourceConsumer mImeConsumer;
+ InsetsSourceConsumer mImeConsumer;
@Spy InsetsController mController;
SurfaceControl mLeash;
@@ -86,7 +86,7 @@ public class ImeInsetsSourceConsumerTest {
false,
TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED,
SOFT_INPUT_ADJUST_RESIZE, 0, 0);
- mImeConsumer = (ImeInsetsSourceConsumer) mController.getSourceConsumer(ITYPE_IME);
+ mImeConsumer = mController.getImeSourceConsumer();
});
}
diff --git a/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java b/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java
index 597df0ba4949..cc5f7f87636c 100644
--- a/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java
+++ b/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java
@@ -89,7 +89,8 @@ public class InsetsAnimationControlImplTest {
mInsetsState = new InsetsState();
mInsetsState.getSource(ITYPE_STATUS_BAR).setFrame(new Rect(0, 0, 500, 100));
mInsetsState.getSource(ITYPE_NAVIGATION_BAR).setFrame(new Rect(400, 0, 500, 500));
- InsetsSourceConsumer topConsumer = new InsetsSourceConsumer(ITYPE_STATUS_BAR, mInsetsState,
+ InsetsSourceConsumer topConsumer = new InsetsSourceConsumer(ITYPE_STATUS_BAR,
+ WindowInsets.Type.statusBars(), mInsetsState,
() -> mMockTransaction, mMockController);
topConsumer.setControl(
new InsetsSourceControl(ITYPE_STATUS_BAR, WindowInsets.Type.statusBars(),
@@ -97,7 +98,8 @@ public class InsetsAnimationControlImplTest {
new int[1], new int[1]);
InsetsSourceConsumer navConsumer = new InsetsSourceConsumer(ITYPE_NAVIGATION_BAR,
- mInsetsState, () -> mMockTransaction, mMockController);
+ WindowInsets.Type.navigationBars(), mInsetsState,
+ () -> mMockTransaction, mMockController);
navConsumer.setControl(
new InsetsSourceControl(ITYPE_NAVIGATION_BAR, WindowInsets.Type.navigationBars(),
mNavLeash, true, new Point(400, 0), Insets.of(0, 0, 100, 0)),
diff --git a/core/tests/coretests/src/android/view/InsetsControllerTest.java b/core/tests/coretests/src/android/view/InsetsControllerTest.java
index 88249ad0db4c..c917302443ae 100644
--- a/core/tests/coretests/src/android/view/InsetsControllerTest.java
+++ b/core/tests/coretests/src/android/view/InsetsControllerTest.java
@@ -100,6 +100,9 @@ import java.util.concurrent.CountDownLatch;
@Presubmit
@RunWith(AndroidJUnit4.class)
public class InsetsControllerTest {
+ private InsetsSource mStatusSource;
+ private InsetsSource mNavSource;
+ private InsetsSource mImeSource;
private InsetsController mController;
private SurfaceSession mSession = new SurfaceSession();
private SurfaceControl mLeash;
@@ -125,10 +128,10 @@ public class InsetsControllerTest {
mTestClock = new OffsettableClock();
mTestHandler = new TestHandler(null, mTestClock);
mTestHost = spy(new TestHost(mViewRoot));
- mController = new InsetsController(mTestHost, (controller, type) -> {
- if (type == ITYPE_IME) {
- return new InsetsSourceConsumer(type, controller.getState(),
- Transaction::new, controller) {
+ mController = new InsetsController(mTestHost, (controller, source) -> {
+ if (source.getType() == ime()) {
+ return new InsetsSourceConsumer(source.getId(), source.getType(),
+ controller.getState(), Transaction::new, controller) {
private boolean mImeRequestedShow;
@@ -143,18 +146,25 @@ public class InsetsControllerTest {
}
};
} else {
- return new InsetsSourceConsumer(type, controller.getState(), Transaction::new,
- controller);
+ return new InsetsSourceConsumer(source.getId(), source.getType(),
+ controller.getState(), Transaction::new, controller);
}
}, mTestHandler);
final Rect rect = new Rect(5, 5, 5, 5);
- mController.getState().getSource(ITYPE_STATUS_BAR).setFrame(new Rect(0, 0, 100, 10));
- mController.getState().getSource(ITYPE_NAVIGATION_BAR).setFrame(
- new Rect(0, 90, 100, 100));
- mController.getState().getSource(ITYPE_IME).setFrame(new Rect(0, 50, 100, 100));
- mController.getState().setDisplayFrame(new Rect(0, 0, 100, 100));
- mController.getState().setDisplayCutout(new DisplayCutout(
+ mStatusSource = new InsetsSource(ITYPE_STATUS_BAR, statusBars());
+ mStatusSource.setFrame(new Rect(0, 0, 100, 10));
+ mNavSource = new InsetsSource(ITYPE_NAVIGATION_BAR, navigationBars());
+ mNavSource.setFrame(new Rect(0, 90, 100, 100));
+ mImeSource = new InsetsSource(ITYPE_IME, ime());
+ mImeSource.setFrame(new Rect(0, 0, 100, 10));
+ InsetsState state = new InsetsState();
+ state.addSource(mStatusSource);
+ state.addSource(mNavSource);
+ state.addSource(mImeSource);
+ state.setDisplayFrame(new Rect(0, 0, 100, 100));
+ state.setDisplayCutout(new DisplayCutout(
Insets.of(10, 10, 10, 10), rect, rect, rect, rect));
+ mController.onStateChanged(state);
mController.calculateInsets(
false,
false,
@@ -168,7 +178,7 @@ public class InsetsControllerTest {
@Test
public void testControlsChanged() {
mController.onControlsChanged(createSingletonControl(ITYPE_STATUS_BAR, statusBars()));
- assertNotNull(mController.getSourceConsumer(ITYPE_STATUS_BAR).getControl().getLeash());
+ assertNotNull(mController.getSourceConsumer(mStatusSource).getControl().getLeash());
mController.addOnControllableInsetsChangedListener(
((controller, typeMask) -> assertEquals(statusBars(), typeMask)));
}
@@ -180,7 +190,7 @@ public class InsetsControllerTest {
mController.addOnControllableInsetsChangedListener(listener);
mController.onControlsChanged(createSingletonControl(ITYPE_STATUS_BAR, statusBars()));
mController.onControlsChanged(new InsetsSourceControl[0]);
- assertNull(mController.getSourceConsumer(ITYPE_STATUS_BAR).getControl());
+ assertNull(mController.getSourceConsumer(mStatusSource).getControl());
InOrder inOrder = Mockito.inOrder(listener);
inOrder.verify(listener).onControllableInsetsChanged(eq(mController), eq(0));
inOrder.verify(listener).onControllableInsetsChanged(eq(mController), eq(statusBars()));
@@ -240,7 +250,7 @@ public class InsetsControllerTest {
WindowInsetsAnimationControlListener loggingListener =
mock(WindowInsetsAnimationControlListener.class);
mController.setSystemDrivenInsetsAnimationLoggingListener(loggingListener);
- mController.getSourceConsumer(ITYPE_IME).onWindowFocusGained(true);
+ mController.getSourceConsumer(mImeSource).onWindowFocusGained(true);
// since there is no focused view, forcefully make IME visible.
mController.show(WindowInsets.Type.ime(), true /* fromIme */, null /* statsToken */);
verify(loggingListener).onReady(notNull(), anyInt());
@@ -252,7 +262,7 @@ public class InsetsControllerTest {
prepareControls();
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
- mController.getSourceConsumer(ITYPE_IME).onWindowFocusGained(true);
+ mController.getSourceConsumer(mImeSource).onWindowFocusGained(true);
// since there is no focused view, forcefully make IME visible.
mController.show(WindowInsets.Type.ime(), true /* fromIme */, null /* statsToken */);
mController.show(all());
@@ -265,7 +275,7 @@ public class InsetsControllerTest {
mController.hide(all());
mController.cancelExistingAnimations();
assertEquals(0, mController.getRequestedVisibleTypes() & types);
- mController.getSourceConsumer(ITYPE_IME).onWindowFocusLost();
+ mController.getSourceConsumer(mImeSource).onWindowFocusLost();
});
InstrumentationRegistry.getInstrumentation().waitForIdleSync();
}
@@ -275,14 +285,14 @@ public class InsetsControllerTest {
InsetsSourceControl ime = createControl(ITYPE_IME, ime());
mController.onControlsChanged(new InsetsSourceControl[] { ime });
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
- mController.getSourceConsumer(ITYPE_IME).onWindowFocusGained(true);
+ mController.getSourceConsumer(mImeSource).onWindowFocusGained(true);
mController.show(WindowInsets.Type.ime(), true /* fromIme */, null /* statsToken */);
mController.cancelExistingAnimations();
assertTrue(isRequestedVisible(mController, ime()));
mController.hide(ime(), true /* fromIme */, null /* statsToken */);
mController.cancelExistingAnimations();
assertFalse(isRequestedVisible(mController, ime()));
- mController.getSourceConsumer(ITYPE_IME).onWindowFocusLost();
+ mController.getSourceConsumer(mImeSource).onWindowFocusLost();
});
InstrumentationRegistry.getInstrumentation().waitForIdleSync();
}
@@ -901,7 +911,8 @@ public class InsetsControllerTest {
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
// Simulate IME insets is not controllable
mController.onControlsChanged(new InsetsSourceControl[0]);
- final InsetsSourceConsumer imeInsetsConsumer = mController.getSourceConsumer(ITYPE_IME);
+ final InsetsSourceConsumer imeInsetsConsumer =
+ mController.getSourceConsumer(mImeSource);
assertNull(imeInsetsConsumer.getControl());
// Verify IME requested visibility should be updated to IME consumer from controller.
diff --git a/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java b/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java
index cec3fc5ba2d8..3a3eeee77d8d 100644
--- a/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java
+++ b/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java
@@ -100,7 +100,7 @@ public class InsetsSourceConsumerTest {
mState.addSource(mSpyInsetsSource);
mController = new InsetsController(new ViewRootInsetsControllerHost(mViewRoot));
- mConsumer = new InsetsSourceConsumer(ITYPE_STATUS_BAR, mState,
+ mConsumer = new InsetsSourceConsumer(ITYPE_STATUS_BAR, statusBars(), mState,
() -> mMockTransaction, mController) {
@Override
public void removeSurface() {
@@ -146,7 +146,7 @@ public class InsetsSourceConsumerTest {
InsetsController controller = new InsetsController(new ViewRootInsetsControllerHost(
mViewRoot));
InsetsSourceConsumer consumer = new InsetsSourceConsumer(
- ITYPE_IME, state, null, controller);
+ ITYPE_IME, ime(), state, null, controller);
InsetsSource source = new InsetsSource(ITYPE_IME, ime());
source.setFrame(0, 1, 2, 3);
@@ -216,9 +216,9 @@ public class InsetsSourceConsumerTest {
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
InsetsState state = new InsetsState();
ViewRootInsetsControllerHost host = new ViewRootInsetsControllerHost(mViewRoot);
- InsetsController insetsController = new InsetsController(host, (controller, type) -> {
- if (type == ITYPE_IME) {
- return new InsetsSourceConsumer(ITYPE_IME, state,
+ InsetsController insetsController = new InsetsController(host, (controller, source) -> {
+ if (source.getType() == ime()) {
+ return new InsetsSourceConsumer(ITYPE_IME, ime(), state,
() -> mMockTransaction, controller) {
@Override
public int requestShow(boolean fromController) {
@@ -226,10 +226,11 @@ public class InsetsSourceConsumerTest {
}
};
}
- return new InsetsSourceConsumer(type, controller.getState(), Transaction::new,
- controller);
+ return new InsetsSourceConsumer(source.getId(), source.getType(),
+ controller.getState(), Transaction::new, controller);
}, host.getHandler());
- InsetsSourceConsumer imeConsumer = insetsController.getSourceConsumer(ITYPE_IME);
+ InsetsSource imeSource = new InsetsSource(ITYPE_IME, ime());
+ InsetsSourceConsumer imeConsumer = insetsController.getSourceConsumer(imeSource);
// Initial IME insets source control with its leash.
imeConsumer.setControl(new InsetsSourceControl(ITYPE_IME, ime(), mLeash,