From 6198cf65449091ebe855f0efbbdbb6c7730e3f1e Mon Sep 17 00:00:00 2001 From: Jeremy Sim Date: Thu, 9 May 2024 15:49:23 -0700 Subject: [PATCH] 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 --- .../RecentsViewStateController.java | 6 +- .../NoButtonQuickSwitchTouchController.java | 2 +- .../FallbackRecentsStateController.java | 6 +- .../quickstep/views/OverviewActionsView.java | 63 +++++++++---------- .../android/quickstep/views/RecentsView.java | 10 +-- 5 files changed, 42 insertions(+), 45 deletions(-) diff --git a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java index 317e6f2145..e02ec41aff 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java @@ -40,6 +40,7 @@ import androidx.annotation.NonNull; 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; @@ -49,7 +50,6 @@ import com.android.quickstep.util.AnimUtils; import com.android.quickstep.util.SplitAnimationTimings; import com.android.quickstep.views.ClearAllButton; import com.android.quickstep.views.LauncherRecentsView; -import com.android.quickstep.views.OverviewActionsView; import com.android.quickstep.views.RecentsView; /** @@ -167,8 +167,8 @@ public final class RecentsViewStateController extends 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 fc0df76c10..7e0a10f4ff 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java @@ -248,7 +248,7 @@ public class NoButtonQuickSwitchTouchController implements TouchController, 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 1bf129c703..644e4f9704 100644 --- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java +++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java @@ -42,13 +42,13 @@ import android.view.animation.Interpolator; 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; import com.android.quickstep.views.RecentsView; /** @@ -96,8 +96,8 @@ public class FallbackRecentsStateController implements StateHandler extends FrameLayout implements OnClickListener, Insettable { - public static final FloatProperty> FLOAT_SETTER = - new FloatProperty<>("floatSetter") { - @Override - public void setValue(Consumer consumer, float v) { - consumer.accept(v); - } - - @Override - public Float get(Consumer consumer) { - return -1f; - } - }; - private final Rect mInsets = new Rect(); @IntDef(flag = true, value = { @@ -110,7 +95,13 @@ public class OverviewActionsView extends FrameLayo 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; @@ -161,11 +152,21 @@ public class OverviewActionsView extends FrameLayo // 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 @@ -222,7 +223,7 @@ public class OverviewActionsView extends FrameLayo mHiddenFlags &= ~visibilityFlags; } boolean isHidden = mHiddenFlags != 0; - setActionsAlpha(INDEX_HIDDEN_FLAGS_ALPHA, isHidden ? 0 : 1); + mAlphaProperties[INDEX_HIDDEN_FLAGS_ALPHA].updateValue(isHidden ? 0 : 1); } /** @@ -310,28 +311,24 @@ public class OverviewActionsView extends FrameLayo } } - 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 getContentAlphaSetter() { - return v -> setActionsAlpha(INDEX_CONTENT_ALPHA, v); + public AnimatedFloat getVisibilityAlpha() { + return mAlphaProperties[INDEX_VISIBILITY_ALPHA]; } - public Consumer getVisibilityAlphaSetter() { - return v -> setActionsAlpha(INDEX_VISIBILITY_ALPHA, v); + public AnimatedFloat getFullscreenAlpha() { + return mAlphaProperties[INDEX_FULLSCREEN_ALPHA]; } - public Consumer getFullscreenAlphaSetter() { - return v -> setActionsAlpha(INDEX_FULLSCREEN_ALPHA, v); + public AnimatedFloat getShareTargetAlpha() { + return mAlphaProperties[INDEX_SHARE_TARGET_ALPHA]; } - public Consumer getShareTargetAlphaSetter() { - return v -> setActionsAlpha(INDEX_SHARE_TARGET_ALPHA, v); - } - - public Consumer 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 a242e1d61d..731b839dd6 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -2029,7 +2029,7 @@ public abstract class RecentsView 0) { setVisibility(VISIBLE);