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
This commit is contained in:
Brandon Dayauon
2024-05-28 09:09:53 -07:00
parent a2bbe1c5c8
commit 987efd6ea4
3 changed files with 41 additions and 25 deletions
@@ -267,13 +267,15 @@ public abstract class BaseAllAppsAdapter<T extends Context & ActivityContext> 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);
}
@@ -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<UserHandle> 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() {
@@ -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