Fix bug with flickering actions bar
This CL fixes a bug caused by ag/27148514. The bug occurred because:
1) The new way we use FloatProperty to set the alpha did not have a working `get()` function, so it just returned a junk value, set to `-1f` (I didn't think `get()` would ever be called meaningfully for this property).
2) However, during certain UI interactions, `RecentsView#updateActionsViewFocusedScroll()` is called many times in a loop, which repeatedly tries to re-start the fade-in animation for actions bar. Pre ag/27148514, even though the fade-in animation was called repeatedly, it would start and then immediately stop running because it realized that it was already set to the desired alpha. However now that we return a junk value for `get()`, it didn't know to skip and just ran the full fade-in animation again and again.
Fixed by refactoring FLOAT_SETTER (now ALPHA_PROPERTY) and creating a new data class, OverviewActionsAlphaProperty, that handles some of the intricacies of this increasingly complicated alpha system.
Fixes: 339545510
Test: Swipe to Overview, move tiles around, actions bar does not flicker.
Flag: ACONFIG com.android.wm.shell.enable_app_pairs NEXTFOOD
Change-Id: I1093363780db5e0780deda2ff14b4f7361d63940
Merged-In: I1093363780db5e0780deda2ff14b4f7361d63940
diff --git a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
index 954db67..3eb6d1b 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
@@ -40,6 +40,7 @@
import com.android.launcher3.LauncherState;
import com.android.launcher3.Utilities;
+import com.android.launcher3.anim.AnimatedFloat;
import com.android.launcher3.anim.AnimatorListeners;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.anim.PropertySetter;
@@ -167,8 +168,8 @@
propertySetter.setFloat(mRecentsView.getClearAllButton(), ClearAllButton.VISIBILITY_ALPHA,
clearAllButtonAlpha, LINEAR);
float overviewButtonAlpha = state.areElementsVisible(mLauncher, OVERVIEW_ACTIONS) ? 1 : 0;
- propertySetter.setFloat(mLauncher.getActionsView().getVisibilityAlphaSetter(),
- OverviewActionsView.FLOAT_SETTER, overviewButtonAlpha, config.getInterpolator(
+ propertySetter.setFloat(mLauncher.getActionsView().getVisibilityAlpha(),
+ AnimatedFloat.VALUE, overviewButtonAlpha, config.getInterpolator(
ANIM_OVERVIEW_ACTIONS_FADE, LINEAR));
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
index 2fdff9e..3ba7239 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
@@ -254,7 +254,7 @@
TASK_THUMBNAIL_SPLASH_ALPHA.set(mRecentsView, fromState.showTaskThumbnailSplash() ? 1f : 0);
mRecentsView.setContentAlpha(1);
mRecentsView.setFullscreenProgress(fromState.getOverviewFullscreenProgress());
- mLauncher.getActionsView().getVisibilityAlphaSetter().accept(
+ mLauncher.getActionsView().getVisibilityAlpha().updateValue(
(fromState.getVisibleElements(mLauncher) & OVERVIEW_ACTIONS) != 0 ? 1f : 0f);
mRecentsView.setTaskIconScaledDown(true);
diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java
index 0820477..66f394d 100644
--- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java
+++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java
@@ -42,13 +42,13 @@
import androidx.annotation.NonNull;
+import com.android.launcher3.anim.AnimatedFloat;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.anim.PropertySetter;
import com.android.launcher3.statemanager.StateManager.StateHandler;
import com.android.launcher3.states.StateAnimationConfig;
import com.android.quickstep.RecentsActivity;
import com.android.quickstep.views.ClearAllButton;
-import com.android.quickstep.views.OverviewActionsView;
/**
* State controller for fallback recents activity
@@ -95,8 +95,8 @@
setter.setFloat(mRecentsView.getClearAllButton(), ClearAllButton.VISIBILITY_ALPHA,
clearAllButtonAlpha, LINEAR);
float overviewButtonAlpha = state.hasOverviewActions() ? 1 : 0;
- setter.setFloat(mActivity.getActionsView().getVisibilityAlphaSetter(),
- OverviewActionsView.FLOAT_SETTER, overviewButtonAlpha, LINEAR);
+ setter.setFloat(mActivity.getActionsView().getVisibilityAlpha(),
+ AnimatedFloat.VALUE, overviewButtonAlpha, LINEAR);
float[] scaleAndOffset = state.getOverviewScaleAndOffset(mActivity);
setter.setFloat(mRecentsView, RECENTS_SCALE_PROPERTY, scaleAndOffset[0],
diff --git a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
index 8a917d6..4360cbc 100644
--- a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
+++ b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
@@ -34,6 +34,7 @@
import com.android.launcher3.Flags;
import com.android.launcher3.Insettable;
import com.android.launcher3.R;
+import com.android.launcher3.anim.AnimatedFloat;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.MultiValueAlpha;
import com.android.launcher3.util.NavigationMode;
@@ -42,27 +43,14 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+
import java.util.Arrays;
-import java.util.function.Consumer;
/**
* View for showing action buttons in Overview
*/
public class OverviewActionsView<T extends OverlayUICallbacks> extends FrameLayout
implements OnClickListener, Insettable {
- public static final FloatProperty<Consumer<Float>> FLOAT_SETTER =
- new FloatProperty<>("floatSetter") {
- @Override
- public void setValue(Consumer<Float> consumer, float v) {
- consumer.accept(v);
- }
-
- @Override
- public Float get(Consumer<Float> consumer) {
- return -1f;
- }
- };
-
private final Rect mInsets = new Rect();
@IntDef(flag = true, value = {
@@ -109,7 +97,13 @@
public @interface SplitButtonHiddenFlags { }
public static final int FLAG_SMALL_SCREEN_HIDE_SPLIT = 1 << 0;
- /** Holds MultiValueAlpha values for all actions buttons */
+ /**
+ * Holds an AnimatedFloat for each alpha property, used to set or animate alpha values in
+ * {@link #mMultiValueAlphas}.
+ */
+ private final AnimatedFloat[] mAlphaProperties = new AnimatedFloat[NUM_ALPHAS];
+
+ /** Holds MultiValueAlpha values for all actions bars */
private final MultiValueAlpha[] mMultiValueAlphas = new MultiValueAlpha[2];
/** Index used for single-task actions in the mMultiValueAlphas array */
private static final int ACTIONS_ALPHAS = 0;
@@ -159,11 +153,21 @@
// These will take up the same space on the screen and alternate visibility as needed.
mActionButtons = findViewById(R.id.action_buttons);
mGroupActionButtons = findViewById(R.id.group_action_buttons);
- // Initialize a list to set alpha on mActionButtons and mGroupActionButtons simultaneously.
+ // Initialize a list to hold alphas for mActionButtons and mGroupActionButtons.
mMultiValueAlphas[ACTIONS_ALPHAS] = new MultiValueAlpha(mActionButtons, NUM_ALPHAS);
mMultiValueAlphas[GROUP_ACTIONS_ALPHAS] =
new MultiValueAlpha(mGroupActionButtons, NUM_ALPHAS);
Arrays.stream(mMultiValueAlphas).forEach(a -> a.setUpdateVisibility(true));
+ // To control alpha simultaneously on mActionButtons and mGroupActionButtons, we set up an
+ // AnimatedFloat for each alpha property.
+ for (int i = 0; i < NUM_ALPHAS; i++) {
+ final int index = i;
+ mAlphaProperties[index] = new AnimatedFloat(() -> {
+ for (MultiValueAlpha multiValueAlpha : mMultiValueAlphas) {
+ multiValueAlpha.get(index).setValue(mAlphaProperties[index].value);
+ }
+ }, 1f /* initialValue */);
+ }
// The screenshot button is implemented as a Button in launcher3 and NexusLauncher, but is
// an ImageButton in go launcher (does not share a common class with Button). Take care when
@@ -220,7 +224,7 @@
mHiddenFlags &= ~visibilityFlags;
}
boolean isHidden = mHiddenFlags != 0;
- setActionsAlpha(INDEX_HIDDEN_FLAGS_ALPHA, isHidden ? 0 : 1);
+ mAlphaProperties[INDEX_HIDDEN_FLAGS_ALPHA].updateValue(isHidden ? 0 : 1);
}
/**
@@ -305,28 +309,24 @@
}
}
- private void setActionsAlpha(int index, float value) {
- Arrays.stream(mMultiValueAlphas).forEach(a -> a.get(index).setValue(value));
+ public AnimatedFloat getContentAlpha() {
+ return mAlphaProperties[INDEX_CONTENT_ALPHA];
}
- public Consumer<Float> getContentAlphaSetter() {
- return v -> setActionsAlpha(INDEX_CONTENT_ALPHA, v);
+ public AnimatedFloat getVisibilityAlpha() {
+ return mAlphaProperties[INDEX_VISIBILITY_ALPHA];
}
- public Consumer<Float> getVisibilityAlphaSetter() {
- return v -> setActionsAlpha(INDEX_VISIBILITY_ALPHA, v);
+ public AnimatedFloat getFullscreenAlpha() {
+ return mAlphaProperties[INDEX_FULLSCREEN_ALPHA];
}
- public Consumer<Float> getFullscreenAlphaSetter() {
- return v -> setActionsAlpha(INDEX_FULLSCREEN_ALPHA, v);
+ public AnimatedFloat getShareTargetAlpha() {
+ return mAlphaProperties[INDEX_SHARE_TARGET_ALPHA];
}
- public Consumer<Float> getShareTargetAlphaSetter() {
- return v -> setActionsAlpha(INDEX_SHARE_TARGET_ALPHA, v);
- }
-
- public Consumer<Float> getIndexScrollAlphaSetter() {
- return v -> setActionsAlpha(INDEX_SCROLL_ALPHA, v);
+ public AnimatedFloat getIndexScrollAlpha() {
+ return mAlphaProperties[INDEX_SCROLL_ALPHA];
}
/**
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 8920c98..12f83eb 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -2025,7 +2025,7 @@
mClearAllButton.setFullscreenProgress(fullscreenProgress);
// Fade out the actions view quickly (0.1 range)
- mActionsView.getFullscreenAlphaSetter().accept(
+ mActionsView.getFullscreenAlpha().updateValue(
mapToRange(fullscreenProgress, 0, 0.1f, 1f, 0f, LINEAR));
}
@@ -2284,8 +2284,8 @@
}
private void animateActionsViewAlpha(float alphaValue, long duration) {
- mActionsViewAlphaAnimator = ObjectAnimator.ofFloat(mActionsView.getVisibilityAlphaSetter(),
- OverviewActionsView.FLOAT_SETTER, alphaValue);
+ mActionsViewAlphaAnimator = ObjectAnimator.ofFloat(mActionsView.getVisibilityAlpha(),
+ AnimatedFloat.VALUE, alphaValue);
mActionsViewAlphaAnimatorFinalValue = alphaValue;
mActionsViewAlphaAnimator.setDuration(duration);
// Set autocancel to prevent race-conditiony setting of alpha from other animations
@@ -2304,7 +2304,7 @@
mClearAllButton.onRecentsViewScroll(scroll, mOverviewGridEnabled);
// Clear all button alpha was set by the previous line.
- mActionsView.getIndexScrollAlphaSetter().accept(1 - mClearAllButton.getScrollAlpha());
+ mActionsView.getIndexScrollAlpha().updateValue(1 - mClearAllButton.getScrollAlpha());
}
@Override
@@ -4312,7 +4312,7 @@
int alphaInt = Math.round(alpha * 255);
mEmptyMessagePaint.setAlpha(alphaInt);
mEmptyIcon.setAlpha(alphaInt);
- mActionsView.getContentAlphaSetter().accept(mContentAlpha);
+ mActionsView.getContentAlpha().updateValue(mContentAlpha);
if (alpha > 0) {
setVisibility(VISIBLE);