summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Yunfan Chen <yunfanc@google.com> 2019-12-05 14:51:09 +0900
committer Yunfan Chen <yunfanc@google.com> 2019-12-27 12:04:54 +0800
commit02abf55ab02cf120850018b05762f9fba5e2afb8 (patch)
tree5b3b022dbf7d7d710655ceed4dd503acaff2f16c
parent1c1d1c0f0da91cb41a2a72803fd06dc3daf1104b (diff)
Decoupling InsetsAnimationControlImpl and the client
Currently InsetsAnimationControlImpl is heavily rely on InsetsSourceConsumer and InsetsController on the client side, which caused difficulties to the server to re-use the code. Decoupling it to make it re-usable. This patch made the following changes: 1. Introduce a callback interface to let InsetsAnimationControlImpl talk to InsetsController. 2. Use InsetsSourceControl instead of InsetsSourceConsumer in the InsetsAnimationControlImpl. 3. Remove all the consumers in the InsetsAnimationControlImpl. Test: atest InsetsAnimationControlImplTest Test: manual test with the new insets API, it works as expected. Test: go/wm-smoke Test: atest FrameworksCoreTests:InsetsControllerTest Change-Id: I30f5aa73ff31e07c0dd8d61edbb208f16c5a6775
-rw-r--r--core/java/android/view/InsetsAnimationControlCallbacks.java55
-rw-r--r--core/java/android/view/InsetsAnimationControlImpl.java67
-rw-r--r--core/java/android/view/InsetsController.java50
-rw-r--r--core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java13
4 files changed, 122 insertions, 63 deletions
diff --git a/core/java/android/view/InsetsAnimationControlCallbacks.java b/core/java/android/view/InsetsAnimationControlCallbacks.java
new file mode 100644
index 000000000000..6fdadc60afea
--- /dev/null
+++ b/core/java/android/view/InsetsAnimationControlCallbacks.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+/**
+ * Provide an interface to let InsetsAnimationControlImpl call back into its owner.
+ * @hide
+ */
+public interface InsetsAnimationControlCallbacks {
+ /**
+ * Dispatch the animation started event to all listeners.
+ * @param animation
+ */
+ void dispatchAnimationStarted(WindowInsetsAnimationCallback.InsetsAnimation animation,
+ WindowInsetsAnimationCallback.AnimationBounds bounds);
+
+ /**
+ * Schedule the apply by posting the animation callback.
+ */
+ void scheduleApplyChangeInsets();
+
+ /**
+ * Finish the final steps after the animation.
+ * @param controller The controller used to control the animation.
+ * @param shown {@code true} if the insets are shown.
+ */
+ void notifyFinished(InsetsAnimationControlImpl controller, boolean shown);
+
+ /**
+ * Get the description of the insets state.
+ * @return {@link InsetsState} for adjusting corresponding {@link InsetsSource}.
+ */
+ InsetsState getState();
+
+ /**
+ * Apply the new params to the surface.
+ * @param params The {@link android.view.SyncRtSurfaceTransactionApplier.SurfaceParams} to
+ * apply.
+ */
+ void applySurfaceParams(SyncRtSurfaceTransactionApplier.SurfaceParams... params);
+}
diff --git a/core/java/android/view/InsetsAnimationControlImpl.java b/core/java/android/view/InsetsAnimationControlImpl.java
index cdfd397a732a..771695c2b873 100644
--- a/core/java/android/view/InsetsAnimationControlImpl.java
+++ b/core/java/android/view/InsetsAnimationControlImpl.java
@@ -40,7 +40,6 @@ import android.view.WindowManager.LayoutParams;
import com.android.internal.annotations.VisibleForTesting;
import java.util.ArrayList;
-import java.util.function.Supplier;
/**
* Implements {@link WindowInsetsAnimationController}
@@ -52,9 +51,9 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
private final Rect mTmpFrame = new Rect();
private final WindowInsetsAnimationControlListener mListener;
- private final SparseArray<InsetsSourceConsumer> mConsumers;
+ private final SparseArray<InsetsSourceControl> mControls;
private final SparseIntArray mTypeSideMap = new SparseIntArray();
- private final SparseSetArray<InsetsSourceConsumer> mSideSourceMap = new SparseSetArray<>();
+ private final SparseSetArray<InsetsSourceControl> mSideSourceMap = new SparseSetArray<>();
/** @see WindowInsetsAnimationController#getHiddenStateInsets */
private final Insets mHiddenInsets;
@@ -64,8 +63,7 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
private final Matrix mTmpMatrix = new Matrix();
private final InsetsState mInitialInsetsState;
private final @InsetsType int mTypes;
- private final Supplier<SyncRtSurfaceTransactionApplier> mTransactionApplierSupplier;
- private final InsetsController mController;
+ private final InsetsAnimationControlCallbacks mController;
private final WindowInsetsAnimationCallback.InsetsAnimation mAnimation;
private final Rect mFrame;
private final boolean mFade;
@@ -79,25 +77,23 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
private float mPendingAlpha;
@VisibleForTesting
- public InsetsAnimationControlImpl(SparseArray<InsetsSourceConsumer> consumers, Rect frame,
+ public InsetsAnimationControlImpl(SparseArray<InsetsSourceControl> controls, Rect frame,
InsetsState state, WindowInsetsAnimationControlListener listener,
@InsetsType int types,
- Supplier<SyncRtSurfaceTransactionApplier> transactionApplierSupplier,
- InsetsController controller, long durationMs, boolean fade) {
- mConsumers = consumers;
+ InsetsAnimationControlCallbacks controller, long durationMs, boolean fade) {
+ mControls = controls;
mListener = listener;
mTypes = types;
mFade = fade;
- mTransactionApplierSupplier = transactionApplierSupplier;
mController = controller;
mInitialInsetsState = new InsetsState(state, true /* copySources */);
mCurrentInsets = getInsetsFromState(mInitialInsetsState, frame, null /* typeSideMap */);
- mHiddenInsets = calculateInsets(mInitialInsetsState, frame, consumers, false /* shown */,
+ mHiddenInsets = calculateInsets(mInitialInsetsState, frame, controls, false /* shown */,
null /* typeSideMap */);
- mShownInsets = calculateInsets(mInitialInsetsState, frame, consumers, true /* shown */,
+ mShownInsets = calculateInsets(mInitialInsetsState, frame, controls, true /* shown */,
mTypeSideMap);
mFrame = new Rect(frame);
- buildTypeSourcesMap(mTypeSideMap, mSideSourceMap, mConsumers);
+ buildTypeSourcesMap(mTypeSideMap, mSideSourceMap, mControls);
// TODO: Check for controllability first and wait for IME if needed.
listener.onReady(this, types);
@@ -172,8 +168,7 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
updateLeashesForSide(ISIDE_FLOATING, 0 /* offset */, 0 /* inset */, 0 /* maxInset */,
params, state, alphaOffset);
- SyncRtSurfaceTransactionApplier applier = mTransactionApplierSupplier.get();
- applier.scheduleApply(params.toArray(new SurfaceParams[params.size()]));
+ mController.applySurfaceParams(params.toArray(new SurfaceParams[params.size()]));
mCurrentInsets = mPendingInsets;
mAnimation.setFraction(mPendingFraction);
mCurrentAlpha = 1 - alphaOffset;
@@ -189,9 +184,9 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
return;
}
InsetsState state = new InsetsState(mController.getState());
- for (int i = mConsumers.size() - 1; i >= 0; i--) {
- InsetsSourceConsumer consumer = mConsumers.valueAt(i);
- state.getSource(consumer.getType()).setVisible(shown);
+ for (int i = mControls.size() - 1; i >= 0; i--) {
+ InsetsSourceControl control = mControls.valueAt(i);
+ state.getSource(control.getType()).setVisible(shown);
}
Insets insets = getInsetsFromState(state, mFrame, null /* typeSideMap */);
setInsetsAndAlpha(insets, 1f /* alpha */, shown ? 1f : 0f /* fraction */);
@@ -222,10 +217,12 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
}
private Insets calculateInsets(InsetsState state, Rect frame,
- SparseArray<InsetsSourceConsumer> consumers, boolean shown,
+ SparseArray<InsetsSourceControl> controls, boolean shown,
@Nullable @InternalInsetsSide SparseIntArray typeSideMap) {
- for (int i = consumers.size() - 1; i >= 0; i--) {
- state.getSource(consumers.valueAt(i).getType()).setVisible(shown);
+ for (int i = controls.size() - 1; i >= 0; i--) {
+ // control may be null if it got revoked.
+ if (controls.valueAt(i) == null) continue;
+ state.getSource(controls.valueAt(i).getType()).setVisible(shown);
}
return getInsetsFromState(state, frame, typeSideMap);
}
@@ -233,7 +230,7 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
private Insets getInsetsFromState(InsetsState state, Rect frame,
@Nullable @InternalInsetsSide SparseIntArray typeSideMap) {
return state.calculateInsets(frame, false /* isScreenRound */,
- false /* alwaysConsumerNavBar */, null /* displayCutout */,
+ false /* alwaysConsumeSystemBars */, null /* displayCutout */,
null /* legacyContentInsets */, null /* legacyStableInsets */,
LayoutParams.SOFT_INPUT_ADJUST_RESIZE /* legacySoftInputMode*/, typeSideMap)
.getInsets(mTypes);
@@ -252,20 +249,19 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
private void updateLeashesForSide(@InternalInsetsSide int side, int offset, int inset,
int maxInset, ArrayList<SurfaceParams> surfaceParams, InsetsState state, Float alpha) {
- ArraySet<InsetsSourceConsumer> items = mSideSourceMap.get(side);
+ ArraySet<InsetsSourceControl> items = mSideSourceMap.get(side);
if (items == null) {
return;
}
// TODO: Implement behavior when inset spans over multiple types
for (int i = items.size() - 1; i >= 0; i--) {
- final InsetsSourceConsumer consumer = items.valueAt(i);
- final InsetsSource source = mInitialInsetsState.getSource(consumer.getType());
- final InsetsSourceControl control = consumer.getControl();
+ final InsetsSourceControl control = items.valueAt(i);
+ final InsetsSource source = mInitialInsetsState.getSource(control.getType());
if (control == null) {
- // Control may not be available for consumer yet or revoked.
+ // TODO: remove this check when we ensure the elements will not be null.
continue;
}
- final SurfaceControl leash = consumer.getControl().getLeash();
+ final SurfaceControl leash = control.getLeash();
mTmpMatrix.setTranslate(control.getSurfacePosition().x, control.getSurfacePosition().y);
mTmpFrame.set(source.getFrame());
@@ -279,7 +275,8 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
alpha = mFade ? ((float) maxInset / inset * 0.3f + 0.7f) : alpha;
surfaceParams.add(new SurfaceParams(leash, alpha, mTmpMatrix,
null /* windowCrop */, 0 /* layer */, 0f /* cornerRadius*/,
- side == ISIDE_FLOATING ? consumer.isVisible() : inset != 0 /* visible */));
+ side == ISIDE_FLOATING ? state.getSource(source.getType()).isVisible()
+ : inset != 0 /* visible */));
}
}
}
@@ -307,18 +304,18 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
}
private static void buildTypeSourcesMap(SparseIntArray typeSideMap,
- SparseSetArray<InsetsSourceConsumer> sideSourcesMap,
- SparseArray<InsetsSourceConsumer> consumers) {
+ SparseSetArray<InsetsSourceControl> sideSourcesMap,
+ SparseArray<InsetsSourceControl> controls) {
for (int i = typeSideMap.size() - 1; i >= 0; i--) {
final int type = typeSideMap.keyAt(i);
final int side = typeSideMap.valueAt(i);
- final InsetsSourceConsumer consumer = consumers.get(type);
- if (consumer == null) {
+ final InsetsSourceControl control = controls.get(type);
+ if (control == null) {
// If the types that we are controlling are less than the types that the system has,
- // there can be some null consumers.
+ // there can be some null controllers.
continue;
}
- sideSourcesMap.add(side, consumer);
+ sideSourcesMap.add(side, control);
}
}
}
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index 5563d629f25e..4d4ace27cac9 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -53,7 +53,7 @@ import java.util.ArrayList;
* Implements {@link WindowInsetsController} on the client.
* @hide
*/
-public class InsetsController implements WindowInsetsController {
+public class InsetsController implements WindowInsetsController, InsetsAnimationControlCallbacks {
private static final int ANIMATION_DURATION_SHOW_MS = 275;
private static final int ANIMATION_DURATION_HIDE_MS = 340;
@@ -186,6 +186,8 @@ public class InsetsController implements WindowInsetsController {
private int mLastLegacySoftInputMode;
+ private SyncRtSurfaceTransactionApplier mApplier;
+
public InsetsController(ViewRootImpl viewRoot) {
mViewRoot = viewRoot;
mAnimCallback = () -> {
@@ -375,9 +377,10 @@ public class InsetsController implements WindowInsetsController {
final ArraySet<Integer> internalTypes = mState.toInternalType(types);
final SparseArray<InsetsSourceConsumer> consumers = new SparseArray<>();
+ final SparseArray<InsetsSourceControl> controls = new SparseArray<>();
- Pair<Integer, Boolean> typesReadyPair = collectConsumers(
- fromIme, internalTypes, consumers, listener);
+ Pair<Integer, Boolean> typesReadyPair = collectSourceControls(
+ fromIme, internalTypes, controls, listener);
int typesReady = typesReadyPair.first;
boolean isReady = typesReadyPair.second;
if (!isReady) {
@@ -388,24 +391,23 @@ public class InsetsController implements WindowInsetsController {
}
// pending types from previous request.
- typesReady = collectPendingConsumers(typesReady, consumers);
+ typesReady = collectPendingTypes(typesReady);
if (typesReady == 0) {
listener.onCancelled();
return;
}
- final InsetsAnimationControlImpl controller = new InsetsAnimationControlImpl(consumers,
- frame, mState, listener, typesReady,
- () -> new SyncRtSurfaceTransactionApplier(mViewRoot.mView), this, durationMs, fade);
+ final InsetsAnimationControlImpl controller = new InsetsAnimationControlImpl(controls,
+ frame, mState, listener, typesReady, this, durationMs, fade);
mAnimationControls.add(controller);
}
/**
* @return Pair of (types ready to animate, is ready to animate).
*/
- private Pair<Integer, Boolean> collectConsumers(boolean fromIme,
- ArraySet<Integer> internalTypes, SparseArray<InsetsSourceConsumer> consumers,
+ private Pair<Integer, Boolean> collectSourceControls(boolean fromIme,
+ ArraySet<Integer> internalTypes, SparseArray<InsetsSourceControl> controls,
WindowInsetsAnimationControlListener listener) {
int typesReady = 0;
boolean isReady = true;
@@ -439,22 +441,14 @@ public class InsetsController implements WindowInsetsController {
}
typesReady |= InsetsState.toPublicType(consumer.getType());
}
- consumers.put(consumer.getType(), consumer);
+ controls.put(consumer.getType(), consumer.getControl());
}
return new Pair<>(typesReady, isReady);
}
- private int collectPendingConsumers(@InsetsType int typesReady,
- SparseArray<InsetsSourceConsumer> consumers) {
- if (mPendingTypesToShow != 0) {
- typesReady |= mPendingTypesToShow;
- final ArraySet<Integer> internalTypes = mState.toInternalType(mPendingTypesToShow);
- for (int i = internalTypes.size() - 1; i >= 0; i--) {
- InsetsSourceConsumer consumer = getSourceConsumer(internalTypes.valueAt(i));
- consumers.put(consumer.getType(), consumer);
- }
- mPendingTypesToShow = 0;
- }
+ private int collectPendingTypes(@InsetsType int typesReady) {
+ typesReady |= mPendingTypesToShow;
+ mPendingTypesToShow = 0;
return typesReady;
}
@@ -468,6 +462,7 @@ public class InsetsController implements WindowInsetsController {
}
@VisibleForTesting
+ @Override
public void notifyFinished(InsetsAnimationControlImpl controller, boolean shown) {
mAnimationControls.remove(controller);
if (shown) {
@@ -477,6 +472,17 @@ public class InsetsController implements WindowInsetsController {
}
}
+ @Override
+ public void applySurfaceParams(final SyncRtSurfaceTransactionApplier.SurfaceParams... params) {
+ if (mApplier == null) {
+ if (mViewRoot.mView == null) {
+ throw new IllegalStateException("View of the ViewRootImpl is not initiated.");
+ }
+ mApplier = new SyncRtSurfaceTransactionApplier(mViewRoot.mView);
+ }
+ mApplier.scheduleApply(params);
+ }
+
void notifyControlRevoked(InsetsSourceConsumer consumer) {
for (int i = mAnimationControls.size() - 1; i >= 0; i--) {
InsetsAnimationControlImpl control = mAnimationControls.get(i);
@@ -620,6 +626,7 @@ public class InsetsController implements WindowInsetsController {
}
@VisibleForTesting
+ @Override
public void dispatchAnimationStarted(InsetsAnimation animation, AnimationBounds bounds) {
mViewRoot.mView.dispatchWindowInsetsAnimationStarted(animation, bounds);
}
@@ -630,6 +637,7 @@ public class InsetsController implements WindowInsetsController {
}
@VisibleForTesting
+ @Override
public void scheduleApplyChangeInsets() {
if (!mAnimCallbackScheduled) {
mViewRoot.mChoreographer.postCallback(Choreographer.CALLBACK_INSETS_ANIMATION,
diff --git a/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java b/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java
index 68d95cd38497..179929f2aae0 100644
--- a/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java
+++ b/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java
@@ -76,7 +76,6 @@ public class InsetsAnimationControlImplTest {
@Mock Transaction mMockTransaction;
@Mock InsetsController mMockController;
@Mock WindowInsetsAnimationControlListener mMockListener;
- @Mock SyncRtSurfaceTransactionApplier mMockTransactionApplier;
@BeforeClass
public static void setupOnce() {
@@ -111,12 +110,12 @@ public class InsetsAnimationControlImplTest {
navConsumer.setControl(new InsetsSourceControl(ITYPE_NAVIGATION_BAR, mNavLeash,
new Point(400, 0)));
- SparseArray<InsetsSourceConsumer> consumers = new SparseArray<>();
- consumers.put(ITYPE_STATUS_BAR, topConsumer);
- consumers.put(ITYPE_NAVIGATION_BAR, navConsumer);
- mController = new InsetsAnimationControlImpl(consumers,
+ SparseArray<InsetsSourceControl> controls = new SparseArray<>();
+ controls.put(ITYPE_STATUS_BAR, topConsumer.getControl());
+ controls.put(ITYPE_NAVIGATION_BAR, navConsumer.getControl());
+ mController = new InsetsAnimationControlImpl(controls,
new Rect(0, 0, 500, 500), mInsetsState, mMockListener, systemBars(),
- () -> mMockTransactionApplier, mMockController, 10 /* durationMs */,
+ mMockController, 10 /* durationMs */,
false /* fade */);
}
@@ -137,7 +136,7 @@ public class InsetsAnimationControlImplTest {
assertEquals(1f, mController.getCurrentAlpha(), 1f - mController.getCurrentAlpha());
ArgumentCaptor<SurfaceParams> captor = ArgumentCaptor.forClass(SurfaceParams.class);
- verify(mMockTransactionApplier).scheduleApply(captor.capture());
+ verify(mMockController).applySurfaceParams(captor.capture());
List<SurfaceParams> params = captor.getAllValues();
assertEquals(2, params.size());
SurfaceParams first = params.get(0);