From 987efd6ea4eb857dee1f00f0e3a4bcfe976799ef Mon Sep 17 00:00:00 2001 From: Brandon Dayauon Date: Tue, 28 May 2024 09:09:53 -0700 Subject: [PATCH] Fix private space icons disappearing from search state. This is because during onBind() that the icon alpha should be set to 0 ONLY in the case when animation + scroll is happening. The repro cuj is this: user has private space unlocked -> goes to toast and clicks qs tile -> onBind() happens and animationScrolling = true -> icon alpha is now 0. Instead we should check getAnimate() && scrolling() && isStateTransitioning() bug: 340836439 Test: manually - before: https://drive.google.com/file/d/1WLZRPsz-hm1d3fVRNGXs_Ps_AcdJhkPs/view?usp=sharing after: https://drive.google.com/file/d/1LidDKhx2ijOXmX_tcPAmng5P56WNPyyx/view?usp=sharing Flag: ACONFIG com.android.launcher3.Flags.private_space_animation NEXTFOOD Change-Id: I10b8ee5d8449acdb3d2c64e0e311f7dde89a464a --- .../launcher3/allapps/BaseAllAppsAdapter.java | 8 ++- .../allapps/PrivateProfileManager.java | 56 +++++++++++-------- .../launcher3/allapps/UserProfileManager.java | 2 + 3 files changed, 41 insertions(+), 25 deletions(-) diff --git a/src/com/android/launcher3/allapps/BaseAllAppsAdapter.java b/src/com/android/launcher3/allapps/BaseAllAppsAdapter.java index 1663096744..a67a3624f8 100644 --- a/src/com/android/launcher3/allapps/BaseAllAppsAdapter.java +++ b/src/com/android/launcher3/allapps/BaseAllAppsAdapter.java @@ -267,13 +267,15 @@ public abstract class BaseAllAppsAdapter ex PrivateProfileManager privateProfileManager = mApps.getPrivateProfileManager(); if (privateProfileManager != null) { // Set the alpha of the private space icon to 0 upon expanding the header so the - // alpha can animate -> 1. + // alpha can animate -> 1. This should only be in effect when doing a + // transitioning between Locked/Unlocked state. boolean isPrivateSpaceItem = privateProfileManager.isPrivateSpaceItem(adapterItem); if (icon.getAlpha() == 0 || icon.getAlpha() == 1) { icon.setAlpha(isPrivateSpaceItem - && (privateProfileManager.getAnimationScrolling() || - privateProfileManager.getAnimate()) + && privateProfileManager.isStateTransitioning() + && (privateProfileManager.isScrolling() || + privateProfileManager.getReadyToAnimate()) && privateProfileManager.getCurrentState() == STATE_ENABLED ? 0 : 1); } diff --git a/src/com/android/launcher3/allapps/PrivateProfileManager.java b/src/com/android/launcher3/allapps/PrivateProfileManager.java index 27340a3678..20dfb7790d 100644 --- a/src/com/android/launcher3/allapps/PrivateProfileManager.java +++ b/src/com/android/launcher3/allapps/PrivateProfileManager.java @@ -114,16 +114,21 @@ public class PrivateProfileManager extends UserProfileManager { public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); if (newState == RecyclerView.SCROLL_STATE_IDLE) { - mAnimationScrolling = false; + mIsScrolling = false; } } }; private Intent mAppInstallerIntent = new Intent(); private PrivateAppsSectionDecorator mPrivateAppsSectionDecorator; private boolean mPrivateSpaceSettingsAvailable; + // Returns if the animation is currently running. private boolean mIsAnimationRunning; - private boolean mAnimate; - private boolean mAnimationScrolling; + // mAnimate denotes if private space is ready to be animated. + private boolean mReadyToAnimate; + // Returns when the recyclerView is currently scrolling. + private boolean mIsScrolling; + // mIsStateTransitioning indicates that private space is transitioning between states. + private boolean mIsStateTransitioning; private Runnable mOnPSHeaderAdded; @Nullable private RelativeLayout mPSHeader; @@ -230,9 +235,11 @@ public class PrivateProfileManager extends UserProfileManager { if (mPSHeader != null) { mPSHeader.setAlpha(1); } - if (transitioningFromLockedToUnlocked(previousState, updatedState)) { + // It's possible that previousState is 0 when reset is first called. + mIsStateTransitioning = previousState != STATE_UNKNOWN && previousState != updatedState; + if (previousState == STATE_DISABLED && updatedState == STATE_ENABLED) { postUnlock(); - } else if (transitioningFromUnlockedToLocked(previousState, updatedState)){ + } else if (previousState == STATE_ENABLED && updatedState == STATE_DISABLED){ executeLock(); } resetPrivateSpaceDecorator(updatedState); @@ -321,7 +328,7 @@ public class PrivateProfileManager extends UserProfileManager { @Override public void setQuietMode(boolean enable) { super.setQuietMode(enable); - mAnimate = true; + mReadyToAnimate = true; } /** @@ -343,7 +350,7 @@ public class PrivateProfileManager extends UserProfileManager { void setAnimationRunning(boolean isAnimationRunning) { if (!isAnimationRunning) { - mAnimate = false; + mReadyToAnimate = false; } mIsAnimationRunning = isAnimationRunning; } @@ -352,14 +359,6 @@ public class PrivateProfileManager extends UserProfileManager { return mIsAnimationRunning; } - private boolean transitioningFromLockedToUnlocked(int previousState, int updatedState) { - return previousState == STATE_DISABLED && updatedState == STATE_ENABLED; - } - - private boolean transitioningFromUnlockedToLocked(int previousState, int updatedState) { - return previousState == STATE_ENABLED && updatedState == STATE_DISABLED; - } - @Override public Predicate getUserMatcher() { return mPrivateProfileMatcher; @@ -386,7 +385,7 @@ public class PrivateProfileManager extends UserProfileManager { } // Set the transition duration for the settings and lock button to animate. ViewGroup settingAndLockGroup = mPSHeader.findViewById(R.id.settingsAndLockGroup); - if (mAnimate) { + if (mReadyToAnimate) { enableLayoutTransition(settingAndLockGroup); } else { // Ensure any unwanted animations to not happen. @@ -681,6 +680,7 @@ public class PrivateProfileManager extends UserProfileManager { } }); animatorSet.addListener(forEndCallback(() -> { + mIsStateTransitioning = false; setAnimationRunning(false); getMainRecyclerView().setChildAttachedConsumer(child -> child.setAlpha(1)); mStatsLogManager.logger().sendToInteractionJankMonitor( @@ -773,7 +773,7 @@ public class PrivateProfileManager extends UserProfileManager { public void endTransition(LayoutTransition transition, ViewGroup viewGroup, View view, int i) { settingsAndLockGroup.setLayoutTransition(null); - mAnimate = false; + mReadyToAnimate = false; } }); settingsAndLockGroup.setLayoutTransition(settingsAndLockTransition); @@ -873,7 +873,7 @@ public class PrivateProfileManager extends UserProfileManager { /** Starts the smooth scroll with the provided smoothScroller and add idle listener. */ private void startAnimationScroll(AllAppsRecyclerView allAppsRecyclerView, RecyclerView.LayoutManager layoutManager, RecyclerView.SmoothScroller smoothScroller) { - mAnimationScrolling = true; + mIsScrolling = true; layoutManager.startSmoothScroll(smoothScroller); allAppsRecyclerView.removeOnScrollListener(mOnIdleScrollListener); allAppsRecyclerView.addOnScrollListener(mOnIdleScrollListener); @@ -887,12 +887,24 @@ public class PrivateProfileManager extends UserProfileManager { return mAllApps.mAH.get(ActivityAllAppsContainerView.AdapterHolder.MAIN).mRecyclerView; } - boolean getAnimate() { - return mAnimate; + /** Returns if private space is readily available to be animated. */ + boolean getReadyToAnimate() { + return mReadyToAnimate; } - boolean getAnimationScrolling() { - return mAnimationScrolling; + /** Returns when a smooth scroll is happening. */ + boolean isScrolling() { + return mIsScrolling; + } + + /** + * Returns when private space is in the process of transitioning. This is different from + * getAnimate() since mStateTransitioning checks from the time transitioning starts happening + * in reset() as oppose to when private space is animating. This should be used to ensure + * Private Space state during onBind(). + */ + boolean isStateTransitioning() { + return mIsStateTransitioning; } int getPsHeaderHeight() { diff --git a/src/com/android/launcher3/allapps/UserProfileManager.java b/src/com/android/launcher3/allapps/UserProfileManager.java index 3351ee33fc..eb74d20fae 100644 --- a/src/com/android/launcher3/allapps/UserProfileManager.java +++ b/src/com/android/launcher3/allapps/UserProfileManager.java @@ -40,11 +40,13 @@ import java.util.function.Predicate; * {@link PrivateProfileManager} which manages private profile state. */ public abstract class UserProfileManager { + public static final int STATE_UNKNOWN = 0; public static final int STATE_ENABLED = 1; public static final int STATE_DISABLED = 2; public static final int STATE_TRANSITION = 3; @IntDef(value = { + STATE_UNKNOWN, STATE_ENABLED, STATE_DISABLED, STATE_TRANSITION