summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/view/ImeInsetsSourceConsumer.java9
-rw-r--r--core/java/android/view/InsetsAnimationControlCallbacks.java7
-rw-r--r--core/java/android/view/InsetsAnimationControlImpl.java10
-rw-r--r--core/java/android/view/InsetsAnimationControlRunner.java28
-rw-r--r--core/java/android/view/InsetsAnimationThreadControlRunner.java42
-rw-r--r--core/java/android/view/InsetsController.java21
-rw-r--r--core/java/android/view/InsetsResizeAnimationRunner.java5
-rw-r--r--core/java/android/view/InsetsSourceConsumer.java71
-rw-r--r--core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java13
-rw-r--r--core/tests/coretests/src/android/view/InsetsControllerTest.java7
-rw-r--r--core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java39
-rw-r--r--services/core/java/com/android/server/wm/InsetsSourceProvider.java78
12 files changed, 194 insertions, 136 deletions
diff --git a/core/java/android/view/ImeInsetsSourceConsumer.java b/core/java/android/view/ImeInsetsSourceConsumer.java
index e90b1c0fc167..229e8ee75844 100644
--- a/core/java/android/view/ImeInsetsSourceConsumer.java
+++ b/core/java/android/view/ImeInsetsSourceConsumer.java
@@ -26,7 +26,6 @@ import android.annotation.Nullable;
import android.os.IBinder;
import android.os.Trace;
import android.util.proto.ProtoOutputStream;
-import android.view.SurfaceControl.Transaction;
import android.view.inputmethod.Flags;
import android.view.inputmethod.ImeTracker;
import android.view.inputmethod.InputMethodManager;
@@ -34,8 +33,6 @@ import android.view.inputmethod.InputMethodManager;
import com.android.internal.inputmethod.ImeTracing;
import com.android.internal.inputmethod.SoftInputShowHideReason;
-import java.util.function.Supplier;
-
/**
* Controls the visibility and animations of IME window insets source.
* @hide
@@ -54,10 +51,8 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer {
*/
private boolean mIsRequestedVisibleAwaitingLeash;
- public ImeInsetsSourceConsumer(
- int id, InsetsState state, Supplier<Transaction> transactionSupplier,
- InsetsController controller) {
- super(id, WindowInsets.Type.ime(), state, transactionSupplier, controller);
+ public ImeInsetsSourceConsumer(int id, InsetsState state, InsetsController controller) {
+ super(id, WindowInsets.Type.ime(), state, controller);
}
@Override
diff --git a/core/java/android/view/InsetsAnimationControlCallbacks.java b/core/java/android/view/InsetsAnimationControlCallbacks.java
index 04bb6091672b..a0d8a173c3e5 100644
--- a/core/java/android/view/InsetsAnimationControlCallbacks.java
+++ b/core/java/android/view/InsetsAnimationControlCallbacks.java
@@ -54,13 +54,6 @@ public interface InsetsAnimationControlCallbacks {
void notifyFinished(InsetsAnimationControlRunner runner, boolean shown);
/**
- * Apply the new params to the surface.
- * @param params The {@link android.view.SyncRtSurfaceTransactionApplier.SurfaceParams} to
- * apply.
- */
- void applySurfaceParams(SyncRtSurfaceTransactionApplier.SurfaceParams... params);
-
- /**
* Post a message to release the Surface, guaranteed to happen after all
* previous calls to applySurfaceParams.
*/
diff --git a/core/java/android/view/InsetsAnimationControlImpl.java b/core/java/android/view/InsetsAnimationControlImpl.java
index 91e9230cdc6a..97facc1ba472 100644
--- a/core/java/android/view/InsetsAnimationControlImpl.java
+++ b/core/java/android/view/InsetsAnimationControlImpl.java
@@ -99,6 +99,7 @@ public class InsetsAnimationControlImpl implements InternalInsetsAnimationContro
private final @InsetsType int mTypes;
private @InsetsType int mControllingTypes;
private final InsetsAnimationControlCallbacks mController;
+ private final SurfaceParamsApplier mSurfaceParamsApplier;
private final WindowInsetsAnimation mAnimation;
private final long mDurationMs;
private final Interpolator mInterpolator;
@@ -123,6 +124,7 @@ public class InsetsAnimationControlImpl implements InternalInsetsAnimationContro
public InsetsAnimationControlImpl(SparseArray<InsetsSourceControl> controls,
@Nullable Rect frame, InsetsState state, WindowInsetsAnimationControlListener listener,
@InsetsType int types, InsetsAnimationControlCallbacks controller,
+ SurfaceParamsApplier surfaceParamsApplier,
InsetsAnimationSpec insetsAnimationSpec, @AnimationType int animationType,
@LayoutInsetsDuringAnimation int layoutInsetsDuringAnimation,
CompatibilityInfo.Translator translator, @Nullable ImeTracker.Token statsToken) {
@@ -131,6 +133,7 @@ public class InsetsAnimationControlImpl implements InternalInsetsAnimationContro
mTypes = types;
mControllingTypes = types;
mController = controller;
+ mSurfaceParamsApplier = surfaceParamsApplier;
mInitialInsetsState = new InsetsState(state, true /* copySources */);
if (frame != null) {
final SparseIntArray idSideMap = new SparseIntArray();
@@ -258,6 +261,11 @@ public class InsetsAnimationControlImpl implements InternalInsetsAnimationContro
}
@Override
+ public SurfaceParamsApplier getSurfaceParamsApplier() {
+ return mSurfaceParamsApplier;
+ }
+
+ @Override
@Nullable
public ImeTracker.Token getStatsToken() {
return mStatsToken;
@@ -305,7 +313,7 @@ public class InsetsAnimationControlImpl implements InternalInsetsAnimationContro
updateLeashesForSide(SIDE_RIGHT, offset.right, params, outState, mPendingAlpha);
updateLeashesForSide(SIDE_BOTTOM, offset.bottom, params, outState, mPendingAlpha);
- mController.applySurfaceParams(params.toArray(new SurfaceParams[params.size()]));
+ mSurfaceParamsApplier.applySurfaceParams(params.toArray(new SurfaceParams[params.size()]));
mCurrentInsets = mPendingInsets;
mAnimation.setFraction(mPendingFraction);
mCurrentAlpha = mPendingAlpha;
diff --git a/core/java/android/view/InsetsAnimationControlRunner.java b/core/java/android/view/InsetsAnimationControlRunner.java
index 8cb8b47dd0ec..4f102da4692a 100644
--- a/core/java/android/view/InsetsAnimationControlRunner.java
+++ b/core/java/android/view/InsetsAnimationControlRunner.java
@@ -77,6 +77,11 @@ public interface InsetsAnimationControlRunner {
@AnimationType int getAnimationType();
/**
+ * @return The {@link SurfaceParamsApplier} this runner is using.
+ */
+ SurfaceParamsApplier getSurfaceParamsApplier();
+
+ /**
* @return The token tracking the current IME request or {@code null} otherwise.
*/
@Nullable
@@ -99,4 +104,27 @@ public interface InsetsAnimationControlRunner {
* @param fieldId FieldId of the implementation class
*/
void dumpDebug(ProtoOutputStream proto, long fieldId);
+
+ /**
+ * Interface applying given surface operations.
+ */
+ interface SurfaceParamsApplier {
+
+ SurfaceParamsApplier DEFAULT = params -> {
+ final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
+ for (int i = params.length - 1; i >= 0; i--) {
+ SyncRtSurfaceTransactionApplier.applyParams(t, params[i], new float[9]);
+ }
+ t.apply();
+ t.close();
+ };
+
+ /**
+ * Apply the new params to the surface.
+ *
+ * @param params The {@link SyncRtSurfaceTransactionApplier.SurfaceParams} to apply.
+ */
+ void applySurfaceParams(SyncRtSurfaceTransactionApplier.SurfaceParams... params);
+
+ }
}
diff --git a/core/java/android/view/InsetsAnimationThreadControlRunner.java b/core/java/android/view/InsetsAnimationThreadControlRunner.java
index fc185bc73735..8c2c4951a9f7 100644
--- a/core/java/android/view/InsetsAnimationThreadControlRunner.java
+++ b/core/java/android/view/InsetsAnimationThreadControlRunner.java
@@ -17,7 +17,6 @@
package android.view;
import static android.view.InsetsController.DEBUG;
-import static android.view.SyncRtSurfaceTransactionApplier.applyParams;
import android.annotation.Nullable;
import android.annotation.UiThread;
@@ -30,7 +29,6 @@ import android.util.SparseArray;
import android.util.proto.ProtoOutputStream;
import android.view.InsetsController.AnimationType;
import android.view.InsetsController.LayoutInsetsDuringAnimation;
-import android.view.SyncRtSurfaceTransactionApplier.SurfaceParams;
import android.view.WindowInsets.Type.InsetsType;
import android.view.WindowInsetsAnimation.Bounds;
import android.view.inputmethod.ImeTracker;
@@ -50,8 +48,6 @@ public class InsetsAnimationThreadControlRunner implements InsetsAnimationContro
private final InsetsAnimationControlCallbacks mCallbacks =
new InsetsAnimationControlCallbacks() {
- private final float[] mTmpFloat9 = new float[9];
-
@Override
@UiThread
public <T extends InsetsAnimationControlRunner & InternalInsetsAnimationController>
@@ -81,19 +77,6 @@ public class InsetsAnimationThreadControlRunner implements InsetsAnimationContro
}
@Override
- public void applySurfaceParams(SurfaceParams... params) {
- if (DEBUG) Log.d(TAG, "applySurfaceParams");
- SurfaceControl.Transaction t = new SurfaceControl.Transaction();
- for (int i = params.length - 1; i >= 0; i--) {
- SyncRtSurfaceTransactionApplier.SurfaceParams surfaceParams = params[i];
- applyParams(t, surfaceParams, mTmpFloat9);
- }
- t.setFrameTimelineVsync(Choreographer.getInstance().getVsyncId());
- t.apply();
- t.close();
- }
-
- @Override
public void releaseSurfaceControlFromRt(SurfaceControl sc) {
if (DEBUG) Log.d(TAG, "releaseSurfaceControlFromRt");
// Since we don't push the SurfaceParams to the RT we can release directly
@@ -106,6 +89,22 @@ public class InsetsAnimationThreadControlRunner implements InsetsAnimationContro
}
};
+ private SurfaceParamsApplier mSurfaceParamsApplier = new SurfaceParamsApplier() {
+
+ private final float[] mTmpFloat9 = new float[9];
+
+ @Override
+ public void applySurfaceParams(SyncRtSurfaceTransactionApplier.SurfaceParams... params) {
+ final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
+ for (int i = params.length - 1; i >= 0; i--) {
+ SyncRtSurfaceTransactionApplier.applyParams(t, params[i], mTmpFloat9);
+ }
+ t.setFrameTimelineVsync(Choreographer.getInstance().getVsyncId());
+ t.apply();
+ t.close();
+ }
+ };
+
@UiThread
public InsetsAnimationThreadControlRunner(SparseArray<InsetsSourceControl> controls,
@Nullable Rect frame, InsetsState state, WindowInsetsAnimationControlListener listener,
@@ -117,8 +116,8 @@ public class InsetsAnimationThreadControlRunner implements InsetsAnimationContro
mMainThreadHandler = mainThreadHandler;
mOuterCallbacks = controller;
mControl = new InsetsAnimationControlImpl(controls, frame, state, listener, types,
- mCallbacks, insetsAnimationSpec, animationType, layoutInsetsDuringAnimation,
- translator, statsToken);
+ mCallbacks, mSurfaceParamsApplier, insetsAnimationSpec, animationType,
+ layoutInsetsDuringAnimation, translator, statsToken);
InsetsAnimationThread.getHandler().post(() -> {
if (mControl.isCancelled()) {
return;
@@ -187,6 +186,11 @@ public class InsetsAnimationThreadControlRunner implements InsetsAnimationContro
}
@Override
+ public SurfaceParamsApplier getSurfaceParamsApplier() {
+ return mSurfaceParamsApplier;
+ }
+
+ @Override
public void updateLayoutInsetsDuringAnimation(
@LayoutInsetsDuringAnimation int layoutInsetsDuringAnimation) {
InsetsAnimationThread.getHandler().post(
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index 8fdf91a2d87c..e38281ffd020 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -55,7 +55,6 @@ import android.util.Pair;
import android.util.SparseArray;
import android.util.proto.ProtoOutputStream;
import android.view.InsetsSourceConsumer.ShowResult;
-import android.view.SurfaceControl.Transaction;
import android.view.WindowInsets.Type;
import android.view.WindowInsets.Type.InsetsType;
import android.view.WindowInsetsAnimation.Bounds;
@@ -85,7 +84,8 @@ import java.util.Objects;
* Implements {@link WindowInsetsController} on the client.
* @hide
*/
-public class InsetsController implements WindowInsetsController, InsetsAnimationControlCallbacks {
+public class InsetsController implements WindowInsetsController, InsetsAnimationControlCallbacks,
+ InsetsAnimationControlRunner.SurfaceParamsApplier {
private int mTypesBeingCancelled;
@@ -307,7 +307,6 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
}
/** Not running an animation. */
- @VisibleForTesting
public static final int ANIMATION_TYPE_NONE = -1;
/** Running animation will show insets */
@@ -317,11 +316,9 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
public static final int ANIMATION_TYPE_HIDE = 1;
/** Running animation is controlled by user via {@link #controlWindowInsetsAnimation} */
- @VisibleForTesting(visibility = PACKAGE)
public static final int ANIMATION_TYPE_USER = 2;
/** Running animation will resize insets */
- @VisibleForTesting
public static final int ANIMATION_TYPE_RESIZE = 3;
@Retention(RetentionPolicy.SOURCE)
@@ -757,11 +754,9 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
public InsetsController(Host host) {
this(host, (controller, id, type) -> {
if (!Flags.refactorInsetsController() && type == ime()) {
- return new ImeInsetsSourceConsumer(id, controller.mState,
- Transaction::new, controller);
+ return new ImeInsetsSourceConsumer(id, controller.mState, controller);
} else {
- return new InsetsSourceConsumer(id, type, controller.mState,
- Transaction::new, controller);
+ return new InsetsSourceConsumer(id, type, controller.mState, controller);
}
}, host.getHandler());
}
@@ -1525,9 +1520,15 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
insetsAnimationSpec, animationType, layoutInsetsDuringAnimation,
mHost.getTranslator(), mHost.getHandler(), statsToken)
: new InsetsAnimationControlImpl(controls,
- frame, mState, listener, typesReady, this, insetsAnimationSpec,
+ frame, mState, listener, typesReady, this, this, insetsAnimationSpec,
animationType, layoutInsetsDuringAnimation, mHost.getTranslator(),
statsToken);
+ for (int i = controls.size() - 1; i >= 0; i--) {
+ final InsetsSourceConsumer consumer = mSourceConsumers.get(controls.keyAt(i));
+ if (consumer != null) {
+ consumer.setSurfaceParamsApplier(runner.getSurfaceParamsApplier());
+ }
+ }
if ((typesReady & WindowInsets.Type.ime()) != 0) {
ImeTracing.getInstance().triggerClientDump("InsetsAnimationControlImpl",
mHost.getInputMethodManager(), null /* icProto */);
diff --git a/core/java/android/view/InsetsResizeAnimationRunner.java b/core/java/android/view/InsetsResizeAnimationRunner.java
index f90b8411e333..5262751cc6ed 100644
--- a/core/java/android/view/InsetsResizeAnimationRunner.java
+++ b/core/java/android/view/InsetsResizeAnimationRunner.java
@@ -94,6 +94,11 @@ public class InsetsResizeAnimationRunner implements InsetsAnimationControlRunner
}
@Override
+ public SurfaceParamsApplier getSurfaceParamsApplier() {
+ return SurfaceParamsApplier.DEFAULT;
+ }
+
+ @Override
@Nullable
public ImeTracker.Token getStatsToken() {
// Return null as resizing the IME view is not explicitly tracked.
diff --git a/core/java/android/view/InsetsSourceConsumer.java b/core/java/android/view/InsetsSourceConsumer.java
index 391d757365e6..2e2ff1d49dfe 100644
--- a/core/java/android/view/InsetsSourceConsumer.java
+++ b/core/java/android/view/InsetsSourceConsumer.java
@@ -17,6 +17,7 @@
package android.view;
import static android.view.InsetsController.ANIMATION_TYPE_NONE;
+import static android.view.InsetsController.ANIMATION_TYPE_RESIZE;
import static android.view.InsetsController.AnimationType;
import static android.view.InsetsController.DEBUG;
import static android.view.InsetsSourceConsumerProto.ANIMATION_STATE;
@@ -32,12 +33,13 @@ import static com.android.window.flags.Flags.insetsControlSeq;
import android.annotation.IntDef;
import android.annotation.Nullable;
+import android.graphics.Matrix;
+import android.graphics.Point;
import android.graphics.Rect;
import android.os.IBinder;
import android.text.TextUtils;
import android.util.Log;
import android.util.proto.ProtoOutputStream;
-import android.view.SurfaceControl.Transaction;
import android.view.WindowInsets.Type.InsetsType;
import android.view.inputmethod.Flags;
import android.view.inputmethod.ImeTracker;
@@ -48,7 +50,6 @@ import com.android.internal.inputmethod.ImeTracing;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Objects;
-import java.util.function.Supplier;
/**
* Controls the visibility and animations of a single window insets source.
@@ -92,10 +93,12 @@ public class InsetsSourceConsumer {
private final int mType;
private static final String TAG = "InsetsSourceConsumer";
- private final Supplier<Transaction> mTransactionSupplier;
@Nullable
private InsetsSourceControl mSourceControl;
private boolean mHasWindowFocus;
+ private InsetsAnimationControlRunner.SurfaceParamsApplier mSurfaceParamsApplier =
+ InsetsAnimationControlRunner.SurfaceParamsApplier.DEFAULT;
+ private final Matrix mTmpMatrix = new Matrix();
/**
* Whether the view has focus returned by {@link #onWindowFocusGained(boolean)}.
@@ -108,16 +111,13 @@ public class InsetsSourceConsumer {
* @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(int id, @InsetsType int type, InsetsState state,
- Supplier<Transaction> transactionSupplier, InsetsController controller) {
+ InsetsController controller) {
mId = id;
mType = type;
mState = state;
- mTransactionSupplier = transactionSupplier;
mController = controller;
}
@@ -162,6 +162,9 @@ public class InsetsSourceConsumer {
if (localVisible != serverVisible) {
mController.notifyVisibilityChanged();
}
+
+ // Reset the applier to the default one which has the most lightweight implementation.
+ setSurfaceParamsApplier(InsetsAnimationControlRunner.SurfaceParamsApplier.DEFAULT);
} else {
final boolean requestedVisible = isRequestedVisibleAwaitingControl();
final SurfaceControl oldLeash = lastControl != null ? lastControl.getLeash() : null;
@@ -184,10 +187,11 @@ public class InsetsSourceConsumer {
mController.notifyVisibilityChanged();
}
- // If we have a new leash, make sure visibility is up-to-date, even though we
- // didn't want to run an animation above.
- if (mController.getAnimationType(mType) == ANIMATION_TYPE_NONE) {
- applyRequestedVisibilityToControl();
+ // If there is no animation controlling the leash, make sure the visibility and the
+ // position is up-to-date. Note: ANIMATION_TYPE_RESIZE doesn't control the leash.
+ final int animType = mController.getAnimationType(mType);
+ if (animType == ANIMATION_TYPE_NONE || animType == ANIMATION_TYPE_RESIZE) {
+ applyRequestedVisibilityAndPositionToControl();
}
// Remove the surface that owned by last control when it lost.
@@ -229,6 +233,15 @@ public class InsetsSourceConsumer {
}
/**
+ * Sets the SurfaceParamsApplier that the latest animation runner is using. The leash owned by
+ * this class is always applied by the applier, so that the transaction order can always be
+ * aligned with the calling sequence.
+ */
+ void setSurfaceParamsApplier(InsetsAnimationControlRunner.SurfaceParamsApplier applier) {
+ mSurfaceParamsApplier = applier;
+ }
+
+ /**
* Called right after the animation is started or finished.
*/
@VisibleForTesting(visibility = PACKAGE)
@@ -431,24 +444,30 @@ public class InsetsSourceConsumer {
if (DEBUG) Log.d(TAG, "updateSource: " + newSource);
}
- private void applyRequestedVisibilityToControl() {
- if (mSourceControl == null || mSourceControl.getLeash() == null) {
+ private void applyRequestedVisibilityAndPositionToControl() {
+ if (mSourceControl == null) {
return;
}
-
- final boolean requestedVisible = (mController.getRequestedVisibleTypes() & mType) != 0;
- try (Transaction t = mTransactionSupplier.get()) {
- if (DEBUG) Log.d(TAG, "applyRequestedVisibilityToControl: " + requestedVisible);
- if (requestedVisible) {
- t.show(mSourceControl.getLeash());
- } else {
- t.hide(mSourceControl.getLeash());
- }
- // Ensure the alpha value is aligned with the actual requested visibility.
- t.setAlpha(mSourceControl.getLeash(), requestedVisible ? 1 : 0);
- t.apply();
+ final SurfaceControl leash = mSourceControl.getLeash();
+ if (leash == null) {
+ return;
}
- onPerceptible(requestedVisible);
+
+ final boolean visible = (mController.getRequestedVisibleTypes() & mType) != 0;
+ final Point surfacePosition = mSourceControl.getSurfacePosition();
+
+ if (DEBUG) Log.d(TAG, "applyRequestedVisibilityAndPositionToControl: visible=" + visible
+ + " position=" + surfacePosition);
+
+ mTmpMatrix.setTranslate(surfacePosition.x, surfacePosition.y);
+ mSurfaceParamsApplier.applySurfaceParams(
+ new SyncRtSurfaceTransactionApplier.SurfaceParams.Builder(leash)
+ .withVisibility(visible)
+ .withAlpha(visible ? 1 : 0)
+ .withMatrix(mTmpMatrix)
+ .build());
+
+ onPerceptible(visible);
}
void dumpDebug(ProtoOutputStream proto, long fieldId) {
diff --git a/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java b/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java
index 786f1e84728d..ba6f62c6ed19 100644
--- a/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java
+++ b/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java
@@ -38,7 +38,6 @@ import android.graphics.Rect;
import android.graphics.RectF;
import android.platform.test.annotations.Presubmit;
import android.util.SparseArray;
-import android.view.SurfaceControl.Transaction;
import android.view.SyncRtSurfaceTransactionApplier.SurfaceParams;
import android.view.animation.Interpolator;
import android.view.animation.LinearInterpolator;
@@ -79,7 +78,6 @@ public class InsetsAnimationControlImplTest {
private SurfaceControl mNavLeash;
private InsetsState mInsetsState;
- @Mock Transaction mMockTransaction;
@Mock InsetsController mMockController;
@Mock WindowInsetsAnimationControlListener mMockListener;
@@ -98,16 +96,14 @@ public class InsetsAnimationControlImplTest {
mInsetsState.getOrCreateSource(ID_NAVIGATION_BAR, navigationBars())
.setFrame(new Rect(400, 0, 500, 500));
InsetsSourceConsumer topConsumer = new InsetsSourceConsumer(ID_STATUS_BAR,
- WindowInsets.Type.statusBars(), mInsetsState,
- () -> mMockTransaction, mMockController);
+ WindowInsets.Type.statusBars(), mInsetsState, mMockController);
topConsumer.setControl(
new InsetsSourceControl(ID_STATUS_BAR, WindowInsets.Type.statusBars(),
mStatusLeash, true, new Point(0, 0), Insets.of(0, 100, 0, 0)),
new int[1], new int[1]);
InsetsSourceConsumer navConsumer = new InsetsSourceConsumer(ID_NAVIGATION_BAR,
- WindowInsets.Type.navigationBars(), mInsetsState,
- () -> mMockTransaction, mMockController);
+ WindowInsets.Type.navigationBars(), mInsetsState, mMockController);
navConsumer.setControl(
new InsetsSourceControl(ID_NAVIGATION_BAR, WindowInsets.Type.navigationBars(),
mNavLeash, true, new Point(400, 0), Insets.of(0, 0, 100, 0)),
@@ -131,8 +127,9 @@ public class InsetsAnimationControlImplTest {
mController = new InsetsAnimationControlImpl(controls,
new Rect(0, 0, 500, 500), mInsetsState, mMockListener, systemBars(),
- mMockController, spec /* insetsAnimationSpecCreator */, 0 /* animationType */,
- 0 /* layoutInsetsDuringAnimation */, null /* translator */, null /* statsToken */);
+ mMockController, mMockController, spec /* insetsAnimationSpecCreator */,
+ 0 /* animationType */, 0 /* layoutInsetsDuringAnimation */, null /* translator */,
+ null /* statsToken */);
mController.setReadyDispatched(true);
}
diff --git a/core/tests/coretests/src/android/view/InsetsControllerTest.java b/core/tests/coretests/src/android/view/InsetsControllerTest.java
index bec8b1f76394..4516e9ce72fc 100644
--- a/core/tests/coretests/src/android/view/InsetsControllerTest.java
+++ b/core/tests/coretests/src/android/view/InsetsControllerTest.java
@@ -63,7 +63,6 @@ import android.graphics.Point;
import android.graphics.Rect;
import android.os.CancellationSignal;
import android.platform.test.annotations.Presubmit;
-import android.view.SurfaceControl.Transaction;
import android.view.WindowInsets.Type.InsetsType;
import android.view.WindowInsetsController.OnControllableInsetsChangedListener;
import android.view.WindowManager.BadTokenException;
@@ -138,8 +137,7 @@ public class InsetsControllerTest {
mTestHost = spy(new TestHost(mViewRoot));
mController = new InsetsController(mTestHost, (controller, id, type) -> {
if (!Flags.refactorInsetsController() && type == ime()) {
- return new InsetsSourceConsumer(id, type, controller.getState(),
- Transaction::new, controller) {
+ return new InsetsSourceConsumer(id, type, controller.getState(), controller) {
private boolean mImeRequestedShow;
@@ -155,8 +153,7 @@ public class InsetsControllerTest {
}
};
} else {
- return new InsetsSourceConsumer(id, type, controller.getState(),
- Transaction::new, controller);
+ return new InsetsSourceConsumer(id, type, controller.getState(), controller);
}
}, mTestHandler);
final Rect rect = new Rect(5, 5, 5, 5);
diff --git a/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java b/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java
index 655cb4519d3c..d6d45e839f2f 100644
--- a/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java
+++ b/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java
@@ -28,10 +28,7 @@ import static junit.framework.TestCase.assertFalse;
import static junit.framework.TestCase.assertTrue;
import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
import android.app.Instrumentation;
import android.content.Context;
@@ -39,7 +36,6 @@ import android.graphics.Insets;
import android.graphics.Point;
import android.graphics.Rect;
import android.platform.test.annotations.Presubmit;
-import android.view.SurfaceControl.Transaction;
import android.view.WindowManager.BadTokenException;
import android.view.WindowManager.LayoutParams;
import android.view.inputmethod.ImeTracker;
@@ -51,7 +47,6 @@ import androidx.test.platform.app.InstrumentationRegistry;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
@@ -75,9 +70,9 @@ public class InsetsSourceConsumerTest {
private SurfaceSession mSession = new SurfaceSession();
private SurfaceControl mLeash;
- @Mock Transaction mMockTransaction;
private InsetsSource mSpyInsetsSource;
private boolean mRemoveSurfaceCalled = false;
+ private boolean mSurfaceParamsApplied = false;
private InsetsController mController;
private InsetsState mState;
private ViewRootImpl mViewRoot;
@@ -102,9 +97,14 @@ public class InsetsSourceConsumerTest {
mSpyInsetsSource = Mockito.spy(new InsetsSource(ID_STATUS_BAR, statusBars()));
mState.addSource(mSpyInsetsSource);
- mController = new InsetsController(new ViewRootInsetsControllerHost(mViewRoot));
- mConsumer = new InsetsSourceConsumer(ID_STATUS_BAR, statusBars(), mState,
- () -> mMockTransaction, mController) {
+ mController = new InsetsController(new ViewRootInsetsControllerHost(mViewRoot)) {
+ @Override
+ public void applySurfaceParams(
+ final SyncRtSurfaceTransactionApplier.SurfaceParams... params) {
+ mSurfaceParamsApplied = true;
+ }
+ };
+ mConsumer = new InsetsSourceConsumer(ID_STATUS_BAR, statusBars(), mState, mController) {
@Override
public void removeSurface() {
super.removeSurface();
@@ -148,8 +148,7 @@ public class InsetsSourceConsumerTest {
InsetsState state = new InsetsState();
InsetsController controller = new InsetsController(new ViewRootInsetsControllerHost(
mViewRoot));
- InsetsSourceConsumer consumer = new InsetsSourceConsumer(
- ID_IME, ime(), state, null, controller);
+ InsetsSourceConsumer consumer = new InsetsSourceConsumer(ID_IME, ime(), state, controller);
InsetsSource source = new InsetsSource(ID_IME, ime());
source.setFrame(0, 1, 2, 3);
@@ -182,9 +181,9 @@ public class InsetsSourceConsumerTest {
public void testRestore() {
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
mConsumer.setControl(null, new int[1], new int[1]);
- reset(mMockTransaction);
+ mSurfaceParamsApplied = false;
mController.setRequestedVisibleTypes(0 /* visibleTypes */, statusBars());
- verifyZeroInteractions(mMockTransaction);
+ assertFalse(mSurfaceParamsApplied);
int[] hideTypes = new int[1];
mConsumer.setControl(
new InsetsSourceControl(ID_STATUS_BAR, statusBars(), mLeash,
@@ -200,8 +199,9 @@ public class InsetsSourceConsumerTest {
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
mController.setRequestedVisibleTypes(0 /* visibleTypes */, statusBars());
mConsumer.setControl(null, new int[1], new int[1]);
- reset(mMockTransaction);
- verifyZeroInteractions(mMockTransaction);
+ mLeash = new SurfaceControl.Builder(mSession)
+ .setName("testSurface")
+ .build();
mRemoveSurfaceCalled = false;
int[] hideTypes = new int[1];
mConsumer.setControl(
@@ -221,8 +221,7 @@ public class InsetsSourceConsumerTest {
ViewRootInsetsControllerHost host = new ViewRootInsetsControllerHost(mViewRoot);
InsetsController insetsController = new InsetsController(host, (ic, id, type) -> {
if (type == ime()) {
- return new InsetsSourceConsumer(ID_IME, ime(), state,
- () -> mMockTransaction, ic) {
+ return new InsetsSourceConsumer(ID_IME, ime(), state, ic) {
@Override
public int requestShow(boolean fromController,
ImeTracker.Token statsToken) {
@@ -230,14 +229,14 @@ public class InsetsSourceConsumerTest {
}
};
}
- return new InsetsSourceConsumer(id, type, ic.getState(), Transaction::new, ic);
+ return new InsetsSourceConsumer(id, type, ic.getState(), ic);
}, host.getHandler());
InsetsSourceConsumer imeConsumer = insetsController.getSourceConsumer(ID_IME, ime());
// Initial IME insets source control with its leash.
imeConsumer.setControl(new InsetsSourceControl(ID_IME, ime(), mLeash,
false /* initialVisible */, new Point(), Insets.NONE), new int[1], new int[1]);
- reset(mMockTransaction);
+ mSurfaceParamsApplied = false;
// Verify when the app requests controlling show IME animation, the IME leash
// visibility won't be updated when the consumer received the same leash in setControl.
@@ -246,7 +245,7 @@ public class InsetsSourceConsumerTest {
assertEquals(ANIMATION_TYPE_USER, insetsController.getAnimationType(ime()));
imeConsumer.setControl(new InsetsSourceControl(ID_IME, ime(), mLeash,
true /* initialVisible */, new Point(), Insets.NONE), new int[1], new int[1]);
- verify(mMockTransaction, never()).show(mLeash);
+ assertFalse(mSurfaceParamsApplied);
});
}
}
diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
index f0a4763796e3..57b879277326 100644
--- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
@@ -75,7 +75,8 @@ class InsetsSourceProvider {
private final Rect mTmpRect = new Rect();
private final InsetsSourceControl mFakeControl;
- private final Consumer<Transaction> mSetLeashPositionConsumer;
+ private final Point mPosition = new Point();
+ private final Consumer<Transaction> mSetControlPositionConsumer;
private @Nullable InsetsControlTarget mPendingControlTarget;
private @Nullable InsetsControlTarget mFakeControlTarget;
@@ -126,13 +127,14 @@ class InsetsSourceProvider {
source.getId(), source.getType(), null /* leash */, false /* initialVisible */,
new Point(), Insets.NONE);
mControllable = (InsetsPolicy.CONTROLLABLE_TYPES & source.getType()) != 0;
- mSetLeashPositionConsumer = t -> {
- if (mControl != null) {
- final SurfaceControl leash = mControl.getLeash();
- if (leash != null) {
- final Point position = mControl.getSurfacePosition();
- t.setPosition(leash, position.x, position.y);
- }
+ mSetControlPositionConsumer = t -> {
+ if (mControl == null || mControlTarget == null) {
+ return;
+ }
+ boolean changed = mControl.setSurfacePosition(mPosition.x, mPosition.y);
+ final SurfaceControl leash = mControl.getLeash();
+ if (changed && leash != null) {
+ t.setPosition(leash, mPosition.x, mPosition.y);
}
if (mHasPendingPosition) {
mHasPendingPosition = false;
@@ -140,9 +142,22 @@ class InsetsSourceProvider {
mStateController.notifyControlTargetChanged(mPendingControlTarget, this);
}
}
+ changed |= updateInsetsHint();
+ if (changed) {
+ mStateController.notifyControlChanged(mControlTarget, this);
+ }
};
}
+ private boolean updateInsetsHint() {
+ final Insets insetsHint = getInsetsHint();
+ if (!mControl.getInsetsHint().equals(insetsHint)) {
+ mControl.setInsetsHint(insetsHint);
+ return true;
+ }
+ return false;
+ }
+
InsetsSource getSource() {
return mSource;
}
@@ -363,26 +378,32 @@ class InsetsSourceProvider {
}
final boolean serverVisibleChanged = mServerVisible != isServerVisible;
setServerVisible(isServerVisible);
- updateInsetsControlPosition(windowState, serverVisibleChanged);
- }
-
- void updateInsetsControlPosition(WindowState windowState) {
- updateInsetsControlPosition(windowState, false);
+ final boolean positionChanged = updateInsetsControlPosition(windowState);
+ if (mControl != null && !positionChanged
+ // The insets hint would be updated if the position is changed. Here updates it for
+ // the possible change of the bounds or the server visibility.
+ && (updateInsetsHint()
+ || serverVisibleChanged
+ && android.view.inputmethod.Flags.refactorInsetsController())) {
+ // Only call notifyControlChanged here when the position is not changed. Otherwise, it
+ // is called or is scheduled to be called during updateInsetsControlPosition.
+ mStateController.notifyControlChanged(mControlTarget, this);
+ }
}
- private void updateInsetsControlPosition(WindowState windowState,
- boolean serverVisibleChanged) {
+ /**
+ * @return {#code true} if the surface position of the control is changed.
+ */
+ boolean updateInsetsControlPosition(WindowState windowState) {
if (mControl == null) {
- return;
+ return false;
}
- boolean changed = false;
final Point position = getWindowFrameSurfacePosition();
- if (mControl.setSurfacePosition(position.x, position.y) && mControlTarget != null) {
- changed = true;
+ if (!mPosition.equals(position)) {
+ mPosition.set(position.x, position.y);
if (windowState != null && windowState.getWindowFrames().didFrameSizeChange()
&& windowState.mWinAnimator.getShown() && mWindowContainer.okToDisplay()) {
- mHasPendingPosition = true;
- windowState.applyWithNextDraw(mSetLeashPositionConsumer);
+ windowState.applyWithNextDraw(mSetControlPositionConsumer);
} else {
Transaction t = mWindowContainer.getSyncTransaction();
if (windowState != null) {
@@ -399,20 +420,11 @@ class InsetsSourceProvider {
}
}
}
- mSetLeashPositionConsumer.accept(t);
+ mSetControlPositionConsumer.accept(t);
}
+ return true;
}
- final Insets insetsHint = getInsetsHint();
- if (!mControl.getInsetsHint().equals(insetsHint)) {
- mControl.setInsetsHint(insetsHint);
- changed = true;
- }
- if (android.view.inputmethod.Flags.refactorInsetsController() && serverVisibleChanged) {
- changed = true;
- }
- if (changed) {
- mStateController.notifyControlChanged(mControlTarget, this);
- }
+ return false;
}
private Point getWindowFrameSurfacePosition() {