summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/view/InsetsAnimationControlImpl.java17
-rw-r--r--core/java/android/view/InsetsController.java47
-rw-r--r--core/java/android/view/InsetsSourceConsumer.java3
-rw-r--r--core/java/android/view/InsetsState.java22
-rw-r--r--core/java/android/view/WindowInsetsAnimation.java5
-rw-r--r--core/tests/coretests/src/android/view/InsetsStateTest.java24
-rw-r--r--packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java3
7 files changed, 83 insertions, 38 deletions
diff --git a/core/java/android/view/InsetsAnimationControlImpl.java b/core/java/android/view/InsetsAnimationControlImpl.java
index 9247f4a29bdd..44ecb545c37f 100644
--- a/core/java/android/view/InsetsAnimationControlImpl.java
+++ b/core/java/android/view/InsetsAnimationControlImpl.java
@@ -76,8 +76,8 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
private boolean mFinished;
private boolean mCancelled;
private boolean mShownOnFinish;
- private float mCurrentAlpha;
- private float mPendingAlpha;
+ private float mCurrentAlpha = 1.0f;
+ private float mPendingAlpha = 1.0f;
@VisibleForTesting
public InsetsAnimationControlImpl(SparseArray<InsetsSourceControl> controls, Rect frame,
@@ -153,7 +153,7 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
}
mPendingFraction = sanitize(fraction);
mPendingInsets = sanitize(insets);
- mPendingAlpha = 1 - sanitize(alpha);
+ mPendingAlpha = sanitize(alpha);
mController.scheduleApplyChangeInsets();
}
@@ -182,7 +182,8 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
mController.applySurfaceParams(params.toArray(new SurfaceParams[params.size()]));
mCurrentInsets = mPendingInsets;
mAnimation.setFraction(mPendingFraction);
- mCurrentAlpha = 1 - alphaOffset;
+ mCurrentAlpha = mPendingAlpha;
+ mAnimation.setAlpha(mPendingAlpha);
if (mFinished) {
mController.notifyFinished(this, mShownOnFinish);
}
@@ -238,7 +239,8 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
private Insets getInsetsFromState(InsetsState state, Rect frame,
@Nullable @InternalInsetsSide SparseIntArray typeSideMap) {
- return state.calculateInsets(frame, false /* isScreenRound */,
+ return state.calculateInsets(frame, null /* ignoringVisibilityState */,
+ false /* isScreenRound */,
false /* alwaysConsumeSystemBars */, null /* displayCutout */,
null /* legacyContentInsets */, null /* legacyStableInsets */,
LayoutParams.SOFT_INPUT_ADJUST_RESIZE /* legacySoftInputMode*/,
@@ -257,8 +259,8 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
return alpha >= 1 ? 1 : (alpha <= 0 ? 0 : alpha);
}
- private void updateLeashesForSide(@InternalInsetsSide int side, int offset, int inset,
- int maxInset, ArrayList<SurfaceParams> surfaceParams, InsetsState state, Float alpha) {
+ private void updateLeashesForSide(@InternalInsetsSide int side, int offset, int maxInset,
+ int inset, ArrayList<SurfaceParams> surfaceParams, InsetsState state, Float alpha) {
ArraySet<InsetsSourceControl> items = mSideSourceMap.get(side);
if (items == null) {
return;
@@ -273,6 +275,7 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
mTmpFrame.set(source.getFrame());
addTranslationToMatrix(side, offset, mTmpMatrix, mTmpFrame);
+ state.getSource(source.getType()).setVisible(side == ISIDE_FLOATING || inset != 0);
state.getSource(source.getType()).setFrame(mTmpFrame);
// If the system is controlling the insets source, the leash can be null.
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index 4cb8e1388858..573d8fc65c84 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -233,6 +233,12 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
final InsetsAnimationControlImpl control;
final @AnimationType int type;
+
+ /**
+ * Whether {@link WindowInsetsAnimation.Callback#onStart(WindowInsetsAnimation, Bounds)} has
+ * been dispatched already for this animation.
+ */
+ boolean startDispatched;
}
/**
@@ -276,9 +282,9 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
private final SparseArray<InsetsSourceControl> mTmpControlArray = new SparseArray<>();
private final ArrayList<RunningAnimation> mRunningAnimations = new ArrayList<>();
- private final ArrayList<WindowInsetsAnimation> mRunningInsetsAnimations = new ArrayList<>();
- private final List<WindowInsetsAnimation> mUnmodifiableRunningInsetsAnimations =
- Collections.unmodifiableList(mRunningInsetsAnimations);
+ private final ArrayList<WindowInsetsAnimation> mTmpRunningAnims = new ArrayList<>();
+ private final List<WindowInsetsAnimation> mUnmodifiableTmpRunningAnims =
+ Collections.unmodifiableList(mTmpRunningAnims);
private final ArrayList<InsetsAnimationControlImpl> mTmpFinishedControls = new ArrayList<>();
private WindowInsets mLastInsets;
@@ -294,6 +300,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
private int mLastLegacySoftInputMode;
private int mLastLegacySystemUiFlags;
+ private DisplayCutout mLastDisplayCutout;
private boolean mStartingAnimation;
private SyncRtSurfaceTransactionApplier mApplier;
@@ -329,20 +336,28 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
}
mTmpFinishedControls.clear();
+ mTmpRunningAnims.clear();
InsetsState state = new InsetsState(mState, true /* copySources */);
for (int i = mRunningAnimations.size() - 1; i >= 0; i--) {
- InsetsAnimationControlImpl control = mRunningAnimations.get(i).control;
+ RunningAnimation runningAnimation = mRunningAnimations.get(i);
+ InsetsAnimationControlImpl control = runningAnimation.control;
+
+ // Keep track of running animation to be dispatched. Aggregate it here such that if
+ // it gets finished within applyChangeInsets we still dispatch it to onProgress.
+ if (runningAnimation.startDispatched) {
+ mTmpRunningAnims.add(control.getAnimation());
+ }
if (control.applyChangeInsets(state)) {
mTmpFinishedControls.add(control);
}
}
- WindowInsets insets = state.calculateInsets(mFrame, mLastInsets.isRound(),
- mLastInsets.shouldAlwaysConsumeSystemBars(), mLastInsets.getDisplayCutout(),
- mLastLegacyContentInsets, mLastLegacyStableInsets, mLastLegacySoftInputMode,
- mLastLegacySystemUiFlags, null /* typeSideMap */);
+ WindowInsets insets = state.calculateInsets(mFrame, mState /* ignoringVisibilityState*/,
+ mLastInsets.isRound(), mLastInsets.shouldAlwaysConsumeSystemBars(),
+ mLastDisplayCutout, mLastLegacyContentInsets, mLastLegacyStableInsets,
+ mLastLegacySoftInputMode, mLastLegacySystemUiFlags, null /* typeSideMap */);
mViewRoot.mView.dispatchWindowInsetsAnimationProgress(insets,
- mUnmodifiableRunningInsetsAnimations);
+ mUnmodifiableTmpRunningAnims);
for (int i = mTmpFinishedControls.size() - 1; i >= 0; i--) {
dispatchAnimationEnd(mTmpFinishedControls.get(i).getAnimation());
@@ -394,8 +409,10 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
mLastLegacyStableInsets.set(legacyStableInsets);
mLastLegacySoftInputMode = legacySoftInputMode;
mLastLegacySystemUiFlags = legacySystemUiFlags;
- mLastInsets = mState.calculateInsets(mFrame, isScreenRound, alwaysConsumeSystemBars, cutout,
- legacyContentInsets, legacyStableInsets, legacySoftInputMode, legacySystemUiFlags,
+ mLastDisplayCutout = cutout;
+ mLastInsets = mState.calculateInsets(mFrame, null /* ignoringVisibilityState*/,
+ isScreenRound, alwaysConsumeSystemBars, cutout, legacyContentInsets,
+ legacyStableInsets, legacySoftInputMode, legacySystemUiFlags,
null /* typeSideMap */);
return mLastInsets;
}
@@ -584,7 +601,6 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
frame, mState, listener, typesReady, this, durationMs, interpolator, fade,
layoutInsetsDuringAnimation, animationType);
mRunningAnimations.add(new RunningAnimation(controller, animationType));
- mRunningInsetsAnimations.add(controller.getAnimation());
cancellationSignal.setOnCancelListener(controller::onCancelled);
return cancellationSignal;
}
@@ -736,7 +752,6 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
for (int i = mRunningAnimations.size() - 1; i >= 0; i--) {
if (mRunningAnimations.get(i).control == control) {
mRunningAnimations.remove(i);
- mRunningInsetsAnimations.remove(i);
break;
}
}
@@ -903,6 +918,12 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
if (controller.isCancelled()) {
return true;
}
+ for (int i = mRunningAnimations.size() - 1; i >= 0; i--) {
+ RunningAnimation runningAnimation = mRunningAnimations.get(i);
+ if (runningAnimation.control == controller) {
+ runningAnimation.startDispatched = true;
+ }
+ }
mViewRoot.mView.dispatchWindowInsetsAnimationStart(animation, bounds);
mStartingAnimation = true;
listener.onReady(controller, types);
diff --git a/core/java/android/view/InsetsSourceConsumer.java b/core/java/android/view/InsetsSourceConsumer.java
index 6d07a13091bd..92ac4259c349 100644
--- a/core/java/android/view/InsetsSourceConsumer.java
+++ b/core/java/android/view/InsetsSourceConsumer.java
@@ -160,7 +160,8 @@ public class InsetsSourceConsumer {
}
boolean applyLocalVisibilityOverride() {
- final boolean isVisible = mState.getSource(mType).isVisible();
+ InsetsSource source = mState.peekSource(mType);
+ final boolean isVisible = source != null && source.isVisible();
final boolean hasControl = mSourceControl != null;
// We still need to let the legacy app know the visibility change even if we don't have the
diff --git a/core/java/android/view/InsetsState.java b/core/java/android/view/InsetsState.java
index c877c454be91..b740c58ec15f 100644
--- a/core/java/android/view/InsetsState.java
+++ b/core/java/android/view/InsetsState.java
@@ -147,10 +147,13 @@ public class InsetsState implements Parcelable {
* Calculates {@link WindowInsets} based on the current source configuration.
*
* @param frame The frame to calculate the insets relative to.
+ * @param ignoringVisibilityState {@link InsetsState} used to calculate
+ * {@link WindowInsets#getInsetsIgnoringVisibility(int)} information, or pass
+ * {@code null} to use this state to calculate that information.
* @return The calculated insets.
*/
- public WindowInsets calculateInsets(Rect frame, boolean isScreenRound,
- boolean alwaysConsumeSystemBars, DisplayCutout cutout,
+ public WindowInsets calculateInsets(Rect frame, @Nullable InsetsState ignoringVisibilityState,
+ boolean isScreenRound, boolean alwaysConsumeSystemBars, DisplayCutout cutout,
@Nullable Rect legacyContentInsets, @Nullable Rect legacyStableInsets,
int legacySoftInputMode, int legacySystemUiFlags,
@Nullable @InternalInsetsSide SparseIntArray typeSideMap) {
@@ -188,8 +191,15 @@ public class InsetsState implements Parcelable {
// IME won't be reported in max insets as the size depends on the EditorInfo of the IME
// target.
if (source.getType() != ITYPE_IME) {
- processSource(source, relativeFrameMax, true /* ignoreVisibility */,
- typeMaxInsetsMap, null /* typeSideMap */, null /* typeVisibilityMap */);
+ InsetsSource ignoringVisibilitySource = ignoringVisibilityState != null
+ ? ignoringVisibilityState.getSource(type)
+ : source;
+ if (ignoringVisibilitySource == null) {
+ continue;
+ }
+ processSource(ignoringVisibilitySource, relativeFrameMax,
+ true /* ignoreVisibility */, typeMaxInsetsMap, null /* typeSideMap */,
+ null /* typeVisibilityMap */);
}
}
final int softInputAdjustMode = legacySoftInputMode & SOFT_INPUT_MASK_ADJUST;
@@ -297,6 +307,10 @@ public class InsetsState implements Parcelable {
return mSources.computeIfAbsent(type, InsetsSource::new);
}
+ public @Nullable InsetsSource peekSource(@InternalInsetsType int type) {
+ return mSources.get(type);
+ }
+
public void setDisplayFrame(Rect frame) {
mDisplayFrame.set(frame);
}
diff --git a/core/java/android/view/WindowInsetsAnimation.java b/core/java/android/view/WindowInsetsAnimation.java
index 396da4acb5bc..e32648809f8f 100644
--- a/core/java/android/view/WindowInsetsAnimation.java
+++ b/core/java/android/view/WindowInsetsAnimation.java
@@ -264,6 +264,11 @@ public final class WindowInsetsAnimation {
WindowInsets.insetInsets(
mUpperBound, insets.left, insets.top, insets.right, insets.bottom));
}
+
+ @Override
+ public String toString() {
+ return "Bounds{lower=" + mLowerBound + " upper=" + mUpperBound + "}";
+ }
}
/**
diff --git a/core/tests/coretests/src/android/view/InsetsStateTest.java b/core/tests/coretests/src/android/view/InsetsStateTest.java
index 79ac2b77dda5..1d8e0a3186e8 100644
--- a/core/tests/coretests/src/android/view/InsetsStateTest.java
+++ b/core/tests/coretests/src/android/view/InsetsStateTest.java
@@ -72,8 +72,8 @@ public class InsetsStateTest {
mState.getSource(ITYPE_IME).setFrame(new Rect(0, 200, 100, 300));
mState.getSource(ITYPE_IME).setVisible(true);
SparseIntArray typeSideMap = new SparseIntArray();
- WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), false, false,
- DisplayCutout.NO_CUTOUT, null, null, SOFT_INPUT_ADJUST_RESIZE, 0, typeSideMap);
+ WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), null, false,
+ false, DisplayCutout.NO_CUTOUT, null, null, SOFT_INPUT_ADJUST_RESIZE, 0, typeSideMap);
assertEquals(Insets.of(0, 100, 0, 100), insets.getSystemWindowInsets());
assertEquals(Insets.of(0, 100, 0, 100), insets.getInsets(Type.all()));
assertEquals(ISIDE_TOP, typeSideMap.get(ITYPE_STATUS_BAR));
@@ -91,8 +91,8 @@ public class InsetsStateTest {
mState.getSource(ITYPE_NAVIGATION_BAR).setVisible(true);
mState.getSource(ITYPE_IME).setFrame(new Rect(0, 100, 100, 300));
mState.getSource(ITYPE_IME).setVisible(true);
- WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), false, false,
- DisplayCutout.NO_CUTOUT, null, null, SOFT_INPUT_ADJUST_RESIZE, 0, null);
+ WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), null, false,
+ false, DisplayCutout.NO_CUTOUT, null, null, SOFT_INPUT_ADJUST_RESIZE, 0, null);
assertEquals(100, insets.getStableInsetBottom());
assertEquals(Insets.of(0, 0, 0, 100), insets.getInsetsIgnoringVisibility(Type.systemBars()));
assertEquals(Insets.of(0, 0, 0, 200), insets.getSystemWindowInsets());
@@ -110,8 +110,8 @@ public class InsetsStateTest {
mState.getSource(ITYPE_STATUS_BAR).setVisible(true);
mState.getSource(ITYPE_NAVIGATION_BAR).setFrame(new Rect(80, 0, 100, 300));
mState.getSource(ITYPE_NAVIGATION_BAR).setVisible(true);
- WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), false, false,
- DisplayCutout.NO_CUTOUT, null, null, 0, 0, null);
+ WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), null, false,
+ false, DisplayCutout.NO_CUTOUT, null, null, 0, 0, null);
assertEquals(Insets.of(0, 100, 20, 0), insets.getSystemWindowInsets());
assertEquals(Insets.of(0, 100, 0, 0), insets.getInsets(Type.statusBars()));
assertEquals(Insets.of(0, 0, 20, 0), insets.getInsets(Type.navigationBars()));
@@ -126,8 +126,8 @@ public class InsetsStateTest {
mState.getSource(ITYPE_STATUS_BAR).setVisible(true);
mState.getSource(ITYPE_IME).setFrame(new Rect(0, 200, 100, 300));
mState.getSource(ITYPE_IME).setVisible(true);
- WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), false, false,
- DisplayCutout.NO_CUTOUT, null, null, SOFT_INPUT_ADJUST_NOTHING, 0, null);
+ WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), null, false,
+ false, DisplayCutout.NO_CUTOUT, null, null, SOFT_INPUT_ADJUST_NOTHING, 0, null);
assertEquals(0, insets.getSystemWindowInsetBottom());
assertEquals(100, insets.getInsets(ime()).bottom);
assertTrue(insets.isVisible(ime()));
@@ -142,11 +142,11 @@ public class InsetsStateTest {
mState.getSource(ITYPE_STATUS_BAR).setVisible(false);
mState.getSource(ITYPE_IME).setFrame(new Rect(0, 200, 100, 300));
mState.getSource(ITYPE_IME).setVisible(true);
- WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), false, false,
- DisplayCutout.NO_CUTOUT, null, null, SOFT_INPUT_ADJUST_NOTHING,
+ WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), null, false,
+ false, DisplayCutout.NO_CUTOUT, null, null, SOFT_INPUT_ADJUST_NOTHING,
SYSTEM_UI_FLAG_LAYOUT_STABLE, null);
assertEquals(100, insets.getSystemWindowInsetTop());
- insets = mState.calculateInsets(new Rect(0, 0, 100, 300), false, false,
+ insets = mState.calculateInsets(new Rect(0, 0, 100, 300), null, false, false,
DisplayCutout.NO_CUTOUT, null, null, SOFT_INPUT_ADJUST_NOTHING,
0 /* legacySystemUiFlags */, null);
assertEquals(0, insets.getSystemWindowInsetTop());
@@ -160,7 +160,7 @@ public class InsetsStateTest {
mState.getSource(ITYPE_IME).setFrame(new Rect(0, 200, 100, 300));
mState.getSource(ITYPE_IME).setVisible(true);
mState.removeSource(ITYPE_IME);
- WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), false, false,
+ WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), null, false, false,
DisplayCutout.NO_CUTOUT, null, null, SOFT_INPUT_ADJUST_RESIZE, 0, null);
assertEquals(0, insets.getSystemWindowInsetBottom());
}
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
index 375d9bbbd4fe..be9fcbf19f12 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
@@ -328,7 +328,8 @@ public class DividerView extends FrameLayout implements OnTouchListener,
// Our window doesn't cover entire display, so we use the display frame to re-calculate
// the insets.
final InsetsState state = getWindowInsetsController().getState();
- insets = state.calculateInsets(state.getDisplayFrame(), insets.isRound(),
+ insets = state.calculateInsets(state.getDisplayFrame(),
+ null /* ignoringVisibilityState */, insets.isRound(),
insets.shouldAlwaysConsumeSystemBars(), insets.getDisplayCutout(),
null /* legacyContentInsets */, null /* legacyStableInsets */,
0 /* legacySystemUiFlags */,