Fade back button in and out tied with the overview/shelf (2/3)

Back button changes opacity when moving the shelf during swipe up
between home screen and overview. The alpha changes depending on the
progress of the swipe up animation. When going from app to home and vice
versa, the fade animation does not tie with the swipe up progress. The
fade animation also masks the back button drawable when ime visibility
changes.

Change-Id: I51e42930640ba711e81880b385bb722d7ee8ad33
Fixes: 74581837
Fixes: 76900236
Test: swipe up from home screen to overview
diff --git a/quickstep/libs/sysui_shared.jar b/quickstep/libs/sysui_shared.jar
index 5e25fd8..53a6ceb 100644
--- a/quickstep/libs/sysui_shared.jar
+++ b/quickstep/libs/sysui_shared.jar
Binary files differ
diff --git a/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java b/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java
index 3e80d2c..b371677 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java
@@ -93,7 +93,11 @@
                     TYPE_ALL & ~TYPE_HIDE_BACK_BUTTON) == null;
         }
         OverviewInteractionState.getInstance(launcher)
-                .setBackButtonVisible(!shouldBackButtonBeHidden);
+                .setBackButtonAlpha(shouldBackButtonBeHidden ? 0 : 1, true /* animate */);
+    }
+
+    public static void setBackButtonAlpha(Launcher launcher, float alpha, boolean animate) {
+         OverviewInteractionState.getInstance(launcher).setBackButtonAlpha(alpha,animate);
     }
 
     public static void resetOverview(Launcher launcher) {
diff --git a/quickstep/src/com/android/quickstep/OverviewInteractionState.java b/quickstep/src/com/android/quickstep/OverviewInteractionState.java
index 420406c..d605746 100644
--- a/quickstep/src/com/android/quickstep/OverviewInteractionState.java
+++ b/quickstep/src/com/android/quickstep/OverviewInteractionState.java
@@ -17,7 +17,6 @@
 
 import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_DISABLE_QUICK_SCRUB;
 import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_DISABLE_SWIPE_UP;
-import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_HIDE_BACK_BUTTON;
 import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_SHOW_OVERVIEW_BUTTON;
 import static com.android.systemui.shared.system.SettingsCompat.SWIPE_UP_SETTING_NAME;
 
@@ -46,7 +45,6 @@
  *
  *   - FLAG_DISABLE_QUICK_SCRUB
  *   - FLAG_DISABLE_SWIPE_UP
- *   - FLAG_HIDE_BACK_BUTTON
  *   - FLAG_SHOW_OVERVIEW_BUTTON
  *
  * @see com.android.systemui.shared.system.NavigationBarCompat.InteractionType and associated flags.
@@ -81,7 +79,7 @@
     }
 
     private static final int MSG_SET_PROXY = 200;
-    private static final int MSG_SET_BACK_BUTTON_VISIBLE = 201;
+    private static final int MSG_SET_BACK_BUTTON_ALPHA = 201;
     private static final int MSG_SET_SWIPE_UP_ENABLED = 202;
 
     private final SwipeUpGestureEnabledSettingObserver mSwipeUpSettingObserver;
@@ -92,13 +90,16 @@
 
     // These are updated on the background thread
     private ISystemUiProxy mISystemUiProxy;
-    private boolean mBackButtonVisible = true;
     private boolean mSwipeUpEnabled = true;
 
     private Runnable mOnSwipeUpSettingChangedListener;
 
     private OverviewInteractionState(Context context) {
         mContext = context;
+
+        // Data posted to the uihandler will be sent to the bghandler. Data is sent to uihandler
+        // because of its high send frequency and data may be very different than the previous value
+        // For example, send back alpha on uihandler to avoid flickering when setting its visibility
         mUiHandler = new Handler(this::handleUiMessage);
         mBgHandler = new Handler(UiThreadHelper.getBackgroundLooper(), this::handleBgMessage);
 
@@ -116,9 +117,9 @@
         return mSwipeUpEnabled;
     }
 
-    public void setBackButtonVisible(boolean visible) {
-        mUiHandler.removeMessages(MSG_SET_BACK_BUTTON_VISIBLE);
-        mUiHandler.obtainMessage(MSG_SET_BACK_BUTTON_VISIBLE, visible ? 1 : 0, 0)
+    public void setBackButtonAlpha(float alpha, boolean animate) {
+        mUiHandler.removeMessages(MSG_SET_BACK_BUTTON_ALPHA);
+        mUiHandler.obtainMessage(MSG_SET_BACK_BUTTON_ALPHA, animate ? 1 : 0, 0, alpha)
                 .sendToTarget();
     }
 
@@ -127,7 +128,7 @@
     }
 
     private boolean handleUiMessage(Message msg) {
-        mBgHandler.obtainMessage(msg.what, msg.arg1, msg.arg2).sendToTarget();
+        mBgHandler.obtainMessage(msg.what, msg.arg1, msg.arg2, msg.obj).sendToTarget();
         return true;
     }
 
@@ -136,9 +137,9 @@
             case MSG_SET_PROXY:
                 mISystemUiProxy = (ISystemUiProxy) msg.obj;
                 break;
-            case MSG_SET_BACK_BUTTON_VISIBLE:
-                mBackButtonVisible = msg.arg1 != 0;
-                break;
+            case MSG_SET_BACK_BUTTON_ALPHA:
+                applyBackButtonAlpha((float) msg.obj, msg.arg1 == 1);
+                return true;
             case MSG_SET_SWIPE_UP_ENABLED:
                 mSwipeUpEnabled = msg.arg1 != 0;
                 resetHomeBounceSeenOnQuickstepEnabledFirstTime();
@@ -162,10 +163,8 @@
             return;
         }
 
-        int flags;
-        if (mSwipeUpEnabled) {
-            flags = mBackButtonVisible ? 0 : FLAG_HIDE_BACK_BUTTON;
-        } else {
+        int flags = 0;
+        if (!mSwipeUpEnabled) {
             flags = FLAG_DISABLE_SWIPE_UP | FLAG_DISABLE_QUICK_SCRUB | FLAG_SHOW_OVERVIEW_BUTTON;
         }
         try {
@@ -175,6 +174,18 @@
         }
     }
 
+    @WorkerThread
+    private void applyBackButtonAlpha(float alpha, boolean animate) {
+        if (mISystemUiProxy == null) {
+            return;
+        }
+        try {
+            mISystemUiProxy.setBackButtonAlpha(alpha, animate);
+        } catch (RemoteException e) {
+            Log.w(TAG, "Unable to update overview back button alpha", e);
+        }
+    }
+
     private class SwipeUpGestureEnabledSettingObserver extends ContentObserver {
         private Handler mHandler;
         private ContentResolver mResolver;
diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
index 2c3e3ee..b5c821a 100644
--- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java
+++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
@@ -25,9 +25,11 @@
 import com.android.launcher3.LauncherStateManager.AnimationConfig;
 import com.android.launcher3.LauncherStateManager.StateHandler;
 import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
 import com.android.launcher3.anim.AnimationSuccessListener;
 import com.android.launcher3.anim.AnimatorSetBuilder;
 import com.android.launcher3.anim.PropertySetter;
+import com.android.launcher3.uioverrides.UiFactory;
 import com.android.launcher3.util.Themes;
 import com.android.launcher3.views.ScrimView;
 
@@ -182,6 +184,13 @@
         anim.setDuration(config.duration);
         anim.setInterpolator(builder.getInterpolator(ANIM_VERTICAL_PROGRESS, interpolator));
         anim.addListener(getProgressAnimatorListener());
+        if (toState.hideBackButton) {
+            anim.addUpdateListener(animation -> {
+                final float alpha = (float) animation.getAnimatedValue();
+                UiFactory.setBackButtonAlpha(mLauncher, 1 - Utilities.boundToRange(alpha, 0, 1),
+                        false /* animate */);
+            });
+        }
 
         builder.play(anim);
 
diff --git a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
index e29250a..8ffa628 100644
--- a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
+++ b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
@@ -42,6 +42,7 @@
 import com.android.launcher3.anim.AnimationSuccessListener;
 import com.android.launcher3.anim.AnimatorPlaybackController;
 import com.android.launcher3.anim.AnimatorSetBuilder;
+import com.android.launcher3.uioverrides.UiFactory;
 import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
 import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
 import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
@@ -221,6 +222,8 @@
             cancelAtomicComponentsController();
         }
         mProgressMultiplier = initCurrentAnimation(animComponents);
+        mCurrentAnimation.getAnimationPlayer().addUpdateListener(animation ->
+                setBackButtonAlphaWithProgress((float) animation.getAnimatedValue()));
         mCurrentAnimation.dispatchOnStart();
         return true;
     }
@@ -279,6 +282,7 @@
             mAtomicComponentsController.setPlayFraction(fraction - mAtomicComponentsStartProgress);
         }
         maybeUpdateAtomicAnim(mFromState, mToState, fraction);
+        setBackButtonAlphaWithProgress(fraction);
     }
 
     /**
@@ -471,6 +475,14 @@
         }
     }
 
+    private void setBackButtonAlphaWithProgress(float progress) {
+        if (mFromState.hideBackButton ^ mToState.hideBackButton) {
+            progress = Utilities.boundToRange(progress, 0, 1);
+            final float alpha = mToState.hideBackButton ? 1 - progress : progress;
+            UiFactory.setBackButtonAlpha(mLauncher, alpha, false /* animate */);
+        }
+    }
+
     private void logReachedState(int logAction) {
         // Transition complete. log the action
         mLauncher.getUserEventDispatcher().logStateChangeAction(logAction,
diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java b/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java
index e93dd5a..db98f9a 100644
--- a/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java
+++ b/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java
@@ -56,4 +56,6 @@
     }
 
     public static void prepareToShowOverview(Launcher launcher) { }
+
+    public static void setBackButtonAlpha(Launcher launcher, float alpha, boolean animate) { }
 }