Translate the 3 navigation buttons to/from their in-app position when animating to/from the -1 screen, all apps and widgets.

Bug: 221455508
Test: opened all apps, widgets, -1 screen, notifications shade and keyboard in various combinations and orders; locked screen, launched app, returned home with the back/home buttons, opened overview
Change-Id: Ia0b406aacf72b34bd6b7ff1c01278ab6895a7da4
Merged-In: Ia0b406aacf72b34bd6b7ff1c01278ab6895a7da4
(cherry picked from commit 9c1a452a1d2663b183524b0efb9887d388b0c901)
diff --git a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
index 6abcbd5..2239102 100644
--- a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
@@ -24,6 +24,9 @@
 import static com.android.launcher3.config.FeatureFlags.ENABLE_SPLIT_FROM_WORKSPACE;
 import static com.android.launcher3.model.data.ItemInfo.NO_MATCHING_ID;
 import static com.android.launcher3.popup.QuickstepSystemShortcut.getSplitSelectShortcutByPosition;
+import static com.android.launcher3.taskbar.LauncherTaskbarUIController.ALL_APPS_PAGE_PROGRESS_INDEX;
+import static com.android.launcher3.taskbar.LauncherTaskbarUIController.MINUS_ONE_PAGE_PROGRESS_INDEX;
+import static com.android.launcher3.taskbar.LauncherTaskbarUIController.WIDGETS_PAGE_PROGRESS_INDEX;
 import static com.android.launcher3.util.DisplayController.CHANGE_ACTIVE_SCREEN;
 import static com.android.launcher3.util.DisplayController.CHANGE_NAVIGATION_MODE;
 import static com.android.launcher3.util.DisplayController.NavigationMode.TWO_BUTTONS;
@@ -229,6 +232,28 @@
     public void onScrollChanged(float progress) {
         super.onScrollChanged(progress);
         mDepthController.onOverlayScrollChanged(progress);
+        onTaskbarInAppDisplayProgressUpdate(progress, MINUS_ONE_PAGE_PROGRESS_INDEX);
+    }
+
+    @Override
+    public void onAllAppsTransition(float progress) {
+        super.onAllAppsTransition(progress);
+        onTaskbarInAppDisplayProgressUpdate(progress, ALL_APPS_PAGE_PROGRESS_INDEX);
+    }
+
+    @Override
+    public void onWidgetsTransition(float progress) {
+        super.onWidgetsTransition(progress);
+        onTaskbarInAppDisplayProgressUpdate(progress, WIDGETS_PAGE_PROGRESS_INDEX);
+    }
+
+    private void onTaskbarInAppDisplayProgressUpdate(float progress, int flag) {
+        if (mTaskbarManager == null
+                || mTaskbarManager.getCurrentActivityContext() == null
+                || mTaskbarUIController == null) {
+            return;
+        }
+        mTaskbarUIController.onTaskbarInAppDisplayProgressUpdate(progress, flag);
     }
 
     @Override
diff --git a/quickstep/src/com/android/launcher3/taskbar/DesktopTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/DesktopTaskbarUIController.java
index cf56248..e2359c0 100644
--- a/quickstep/src/com/android/launcher3/taskbar/DesktopTaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/DesktopTaskbarUIController.java
@@ -39,4 +39,10 @@
     protected void onDestroy() {
         mLauncher.getHotseat().setIconsAlpha(1f);
     }
+
+    @Override
+    /** Disable taskbar stashing in desktop environment. */
+    public boolean supportsVisualStashing() {
+        return false;
+    }
 }
diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
index 11dbe45..a3e8b5c 100644
--- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
@@ -22,6 +22,7 @@
 import android.annotation.ColorInt;
 import android.os.RemoteException;
 import android.util.Log;
+import android.util.SparseArray;
 import android.view.MotionEvent;
 import android.view.TaskTransitionSpec;
 import android.view.WindowManagerGlobal;
@@ -55,6 +56,13 @@
 
     private static final String TAG = "TaskbarUIController";
 
+    public static final int MINUS_ONE_PAGE_PROGRESS_INDEX = 0;
+    public static final int ALL_APPS_PAGE_PROGRESS_INDEX = 1;
+    public static final int WIDGETS_PAGE_PROGRESS_INDEX = 2;
+    public static final int SYSUI_SURFACE_PROGRESS_INDEX = 3;
+
+    private final SparseArray<Float> mTaskbarInAppDisplayProgress = new SparseArray<>(4);
+
     private final BaseQuickstepLauncher mLauncher;
 
     private final DeviceProfile.OnDeviceProfileChangeListener mOnDeviceProfileChangeListener =
@@ -92,10 +100,6 @@
         mLauncher.addOnDeviceProfileChangeListener(mOnDeviceProfileChangeListener);
     }
 
-    public boolean supportsVisualStashing() {
-        return mControllers.taskbarStashController.supportsVisualStashing();
-    }
-
     @Override
     protected void onDestroy() {
         super.onDestroy();
@@ -271,6 +275,53 @@
         forceHideBackground(inProgress);
     }
 
+    /**
+     * Animates Taskbar elements during a transition to a Launcher state that should use in-app
+     * layouts.
+     *
+     * @param progress [0, 1]
+     *                 0 => use home layout
+     *                 1 => use in-app layout
+     */
+    public void onTaskbarInAppDisplayProgressUpdate(float progress, int progressIndex) {
+        if (mControllers == null) {
+            // This method can be called before init() is called.
+            return;
+        }
+        mTaskbarInAppDisplayProgress.put(progressIndex, progress);
+        if (!mControllers.taskbarStashController.isInApp()
+                && !mTaskbarLauncherStateController.isAnimatingToLauncher()) {
+            // Only animate the nav buttons while home and not animating home, otherwise let
+            // the TaskbarViewController handle it.
+            mControllers.navbarButtonsViewController
+                    .getTaskbarNavButtonTranslationYForInAppDisplay()
+                    .updateValue(mLauncher.getDeviceProfile().getTaskbarOffsetY()
+                            * getInAppDisplayProgress());
+        }
+    }
+
+    /** Returns true iff any in-app display progress > 0. */
+    public boolean shouldUseInAppLayout() {
+        return getInAppDisplayProgress() > 0;
+    }
+
+    private float getInAppDisplayProgress(int index) {
+        if (!mTaskbarInAppDisplayProgress.contains(index)) {
+            mTaskbarInAppDisplayProgress.put(index, 0f);
+        }
+        return mTaskbarInAppDisplayProgress.get(index);
+    }
+
+    private float getInAppDisplayProgress() {
+        return Stream.of(
+                getInAppDisplayProgress(MINUS_ONE_PAGE_PROGRESS_INDEX),
+                getInAppDisplayProgress(ALL_APPS_PAGE_PROGRESS_INDEX),
+                getInAppDisplayProgress(WIDGETS_PAGE_PROGRESS_INDEX),
+                getInAppDisplayProgress(SYSUI_SURFACE_PROGRESS_INDEX))
+                .max(Float::compareTo)
+                .get();
+    }
+
     @Override
     public void dumpLogs(String prefix, PrintWriter pw) {
         super.dumpLogs(prefix, pw);
@@ -280,6 +331,28 @@
                 prefix,
                 mTaskbarOverrideBackgroundAlpha.value));
 
+        pw.println(String.format("%s\tTaskbar in-app display progress:", prefix));
+        if (mControllers == null) {
+            pw.println(String.format("%s\t\tMissing mControllers", prefix));
+        } else {
+            pw.println(String.format(
+                    "%s\t\tprogress at MINUS_ONE_PAGE_PROGRESS_INDEX=%.2f",
+                    prefix,
+                    getInAppDisplayProgress(MINUS_ONE_PAGE_PROGRESS_INDEX)));
+            pw.println(String.format(
+                    "%s\t\tprogress at ALL_APPS_PAGE_PROGRESS_INDEX=%.2f",
+                    prefix,
+                    getInAppDisplayProgress(ALL_APPS_PAGE_PROGRESS_INDEX)));
+            pw.println(String.format(
+                    "%s\t\tprogress at WIDGETS_PAGE_PROGRESS_INDEX=%.2f",
+                    prefix,
+                    getInAppDisplayProgress(WIDGETS_PAGE_PROGRESS_INDEX)));
+            pw.println(String.format(
+                    "%s\t\tprogress at SYSUI_SURFACE_PROGRESS_INDEX=%.2f",
+                    prefix,
+                    getInAppDisplayProgress(SYSUI_SURFACE_PROGRESS_INDEX)));
+        }
+
         mTaskbarLauncherStateController.dumpLogs(prefix + "\t", pw);
     }
 }
diff --git a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
index f65b907..349dd0a 100644
--- a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
@@ -16,6 +16,7 @@
 package com.android.launcher3.taskbar;
 
 import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_X;
+import static com.android.launcher3.taskbar.LauncherTaskbarUIController.SYSUI_SURFACE_PROGRESS_INDEX;
 import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_A11Y;
 import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_BACK;
 import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_HOME;
@@ -126,11 +127,13 @@
 
     private final AnimatedFloat mTaskbarNavButtonTranslationY = new AnimatedFloat(
             this::updateNavButtonTranslationY);
+    private final AnimatedFloat mTaskbarNavButtonTranslationYForInAppDisplay = new AnimatedFloat(
+            this::updateNavButtonTranslationY);
     private final AnimatedFloat mTaskbarNavButtonTranslationYForIme = new AnimatedFloat(
             this::updateNavButtonTranslationY);
-    // Only applies to mTaskbarNavButtonTranslationY
-    private final AnimatedFloat mNavButtonTranslationYMultiplier = new AnimatedFloat(
-            this::updateNavButtonTranslationY);
+    // Used for System UI state updates that should translate the nav button for in-app display.
+    private final AnimatedFloat mNavButtonInAppDisplayProgressForSysui = new AnimatedFloat(
+            this::updateNavButtonInAppDisplayProgressForSysui);
     private final AnimatedFloat mTaskbarNavButtonDarkIntensity = new AnimatedFloat(
             this::updateNavButtonDarkIntensity);
     private final AnimatedFloat mNavButtonDarkIntensityMultiplier = new AnimatedFloat(
@@ -173,7 +176,6 @@
     public void init(TaskbarControllers controllers) {
         mControllers = controllers;
         mNavButtonsView.getLayoutParams().height = mContext.getDeviceProfile().taskbarSize;
-        mNavButtonTranslationYMultiplier.value = 1;
 
         boolean isThreeButtonNav = mContext.isThreeButtonNav();
         mIsImeRenderingNavButtons =
@@ -205,9 +207,9 @@
         // Make sure to remove nav bar buttons translation when notification shade is expanded or
         // IME is showing (add separate translation for IME).
         int flagsToRemoveTranslation = FLAG_NOTIFICATION_SHADE_EXPANDED | FLAG_IME_VISIBLE;
-        mPropertyHolders.add(new StatePropertyHolder(mNavButtonTranslationYMultiplier,
+        mPropertyHolders.add(new StatePropertyHolder(mNavButtonInAppDisplayProgressForSysui,
                 flags -> (flags & flagsToRemoveTranslation) != 0, AnimatedFloat.VALUE,
-                0, 1));
+                1, 0));
         // Center nav buttons in new height for IME.
         float transForIme = (mContext.getDeviceProfile().taskbarSize
                 - mControllers.taskbarInsetsController.getTaskbarHeightForIme()) / 2f;
@@ -526,6 +528,11 @@
         return mTaskbarNavButtonTranslationY;
     }
 
+    /** Use to set the translationY for the all nav+contextual buttons when in Launcher */
+    public AnimatedFloat getTaskbarNavButtonTranslationYForInAppDisplay() {
+        return mTaskbarNavButtonTranslationYForInAppDisplay;
+    }
+
     /** Use to set the dark intensity for the all nav+contextual buttons */
     public AnimatedFloat getTaskbarNavButtonDarkIntensity() {
         return mTaskbarNavButtonDarkIntensity;
@@ -554,11 +561,26 @@
         }
     }
 
+    private void updateNavButtonInAppDisplayProgressForSysui() {
+        TaskbarUIController uiController = mControllers.uiController;
+        if (uiController instanceof LauncherTaskbarUIController) {
+            ((LauncherTaskbarUIController) uiController).onTaskbarInAppDisplayProgressUpdate(
+                    mNavButtonInAppDisplayProgressForSysui.value, SYSUI_SURFACE_PROGRESS_INDEX);
+        }
+    }
+
     private void updateNavButtonTranslationY() {
-        float normalTranslationY = mTaskbarNavButtonTranslationY.value
-                * mNavButtonTranslationYMultiplier.value;
-        float otherTranslationY = mTaskbarNavButtonTranslationYForIme.value;
-        mNavButtonsView.setTranslationY(normalTranslationY + otherTranslationY);
+        final float normalTranslationY = mTaskbarNavButtonTranslationY.value;
+        final float imeAdjustmentTranslationY = mTaskbarNavButtonTranslationYForIme.value;
+        TaskbarUIController uiController = mControllers.uiController;
+        final float inAppDisplayAdjustmentTranslationY =
+                (uiController instanceof LauncherTaskbarUIController
+                        && ((LauncherTaskbarUIController) uiController).shouldUseInAppLayout())
+                        ? mTaskbarNavButtonTranslationYForInAppDisplay.value : 0;
+
+        mNavButtonsView.setTranslationY(normalTranslationY
+                + imeAdjustmentTranslationY
+                + inAppDisplayAdjustmentTranslationY);
     }
 
     private void updateNavButtonDarkIntensity() {
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index b349637..2f32219 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -199,7 +199,7 @@
                 new TaskbarInsetsController(this));
     }
 
-    public void init(TaskbarSharedState sharedState) {
+    public void init(@NonNull TaskbarSharedState sharedState) {
         mLastRequestedNonFullscreenHeight = getDefaultTaskbarWindowHeight();
         mWindowLayoutParams = createDefaultWindowLayoutParams();
 
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java
index e4c96b2..449e0a7 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java
@@ -61,6 +61,8 @@
     private boolean mAreAllControllersInitialized;
     private final List<Runnable> mPostInitCallbacks = new ArrayList<>();
 
+    @Nullable private TaskbarSharedState mSharedState = null;
+
     public TaskbarControllers(TaskbarActivityContext taskbarActivityContext,
             TaskbarDragController taskbarDragController,
             TaskbarNavButtonController navButtonController,
@@ -104,8 +106,9 @@
      * TaskbarControllers instance, but should be careful to only access things that were created
      * in constructors for now, as some controllers may still be waiting for init().
      */
-    public void init(TaskbarSharedState sharedState) {
+    public void init(@NonNull TaskbarSharedState sharedState) {
         mAreAllControllersInitialized = false;
+        mSharedState = sharedState;
 
         taskbarDragController.init(this);
         navbarButtonsViewController.init(this);
@@ -116,11 +119,11 @@
         taskbarUnfoldAnimationController.init(this);
         taskbarKeyguardController.init(navbarButtonsViewController);
         stashedHandleViewController.init(this);
-        taskbarStashController.init(this, sharedState);
+        taskbarStashController.init(this, sharedState.setupUIVisible);
         taskbarEduController.init(this);
         taskbarPopupController.init(this);
         taskbarForceVisibleImmersiveController.init(this);
-        taskbarAllAppsController.init(this, sharedState);
+        taskbarAllAppsController.init(this, sharedState.allAppsVisible);
         navButtonController.init(this);
         taskbarInsetsController.init(this);
 
@@ -139,6 +142,12 @@
         mPostInitCallbacks.clear();
     }
 
+    @Nullable
+    public TaskbarSharedState getSharedState() {
+        // This should only be null if called before init() and after destroy().
+        return mSharedState;
+    }
+
     public void onConfigurationChanged(@Config int configChanges) {
         navbarButtonsViewController.onConfigurationChanged(configChanges);
     }
@@ -147,6 +156,8 @@
      * Cleans up all controllers.
      */
     public void onDestroy() {
+        mSharedState = null;
+
         navbarButtonsViewController.onDestroy();
         uiController.onDestroy();
         rotationButtonController.onDestroy();
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
index e02a9d7..2e37170 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
@@ -194,6 +194,9 @@
      * Sets a {@link StatefulActivity} to act as taskbar callback
      */
     public void setActivity(@NonNull StatefulActivity activity) {
+        if (mActivity == activity) {
+            return;
+        }
         mActivity = activity;
         mUnfoldProgressProvider.setSourceProvider(getUnfoldTransitionProgressProviderForActivity(
                 activity));
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarSharedState.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarSharedState.java
index a5c55b0..87b3789 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarSharedState.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarSharedState.java
@@ -25,5 +25,4 @@
     public boolean setupUIVisible = false;
 
     public boolean allAppsVisible = false;
-
 }
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
index c92feed..c07ba2d 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
@@ -167,7 +167,7 @@
         mStashedHeight = mActivity.getDeviceProfile().stashedTaskbarSize;
     }
 
-    public void init(TaskbarControllers controllers, TaskbarSharedState sharedState) {
+    public void init(TaskbarControllers controllers, boolean setupUIVisible) {
         mControllers = controllers;
 
         TaskbarDragLayerController dragLayerController = controllers.taskbarDragLayerController;
@@ -188,7 +188,7 @@
 
         boolean isManuallyStashedInApp = supportsManualStashing()
                 && mPrefs.getBoolean(SHARED_PREFS_STASHED_KEY, DEFAULT_STASHED_PREF);
-        boolean isInSetup = !mActivity.isUserSetupComplete() || sharedState.setupUIVisible;
+        boolean isInSetup = !mActivity.isUserSetupComplete() || setupUIVisible;
         updateStateForFlag(FLAG_STASHED_IN_APP_MANUAL, isManuallyStashedInApp);
         updateStateForFlag(FLAG_STASHED_IN_APP_SETUP, isInSetup);
         updateStateForFlag(FLAG_IN_SETUP, isInSetup);
@@ -202,7 +202,7 @@
      * state.
      */
     public boolean supportsVisualStashing() {
-        return !mActivity.isThreeButtonNav();
+        return mControllers.uiController.supportsVisualStashing();
     }
 
     /**
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
index 6c2d179..fcc34c6 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
@@ -49,6 +49,11 @@
         return true;
     }
 
+    public boolean supportsVisualStashing() {
+        if (mControllers == null) return false;
+        return !mControllers.taskbarActivityContext.isThreeButtonNav();
+    }
+
     protected void onStashedInAppChanged() { }
 
     public Stream<ItemInfoWithIcon> getAppIconsForEdu() {
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
index 6967cc5..9b6cc66 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
@@ -73,6 +73,7 @@
     private final AnimatedFloat mTaskbarIconTranslationYForStash = new AnimatedFloat(
             this::updateTranslationY);
     private AnimatedFloat mTaskbarNavButtonTranslationY;
+    private AnimatedFloat mTaskbarNavButtonTranslationYForInAppDisplay;
 
     private final AnimatedFloat mThemeIconsBackground = new AnimatedFloat(
             this::updateIconsBackground);
@@ -112,6 +113,8 @@
         }
         mTaskbarNavButtonTranslationY =
                 controllers.navbarButtonsViewController.getTaskbarNavButtonTranslationY();
+        mTaskbarNavButtonTranslationYForInAppDisplay = controllers.navbarButtonsViewController
+                .getTaskbarNavButtonTranslationYForInAppDisplay();
     }
 
     public void onDestroy() {
@@ -242,6 +245,7 @@
         int offsetY = launcherDp.getTaskbarOffsetY();
         setter.setFloat(mTaskbarIconTranslationYForHome, VALUE, -offsetY, LINEAR);
         setter.setFloat(mTaskbarNavButtonTranslationY, VALUE, -offsetY, LINEAR);
+        setter.setFloat(mTaskbarNavButtonTranslationYForInAppDisplay, VALUE, offsetY, LINEAR);
 
         if (Utilities.isDarkTheme(mTaskbarView.getContext())) {
             setter.addFloat(mThemeIconsBackground, VALUE, 0f, 1f, LINEAR);
diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java
index 9fca8eb..eaf9384 100644
--- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java
@@ -38,7 +38,6 @@
 import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.taskbar.TaskbarActivityContext;
 import com.android.launcher3.taskbar.TaskbarControllers;
-import com.android.launcher3.taskbar.TaskbarSharedState;
 import com.android.systemui.shared.system.TaskStackChangeListener;
 import com.android.systemui.shared.system.TaskStackChangeListeners;
 
@@ -72,7 +71,6 @@
     };
 
     private TaskbarControllers mControllers;
-    private TaskbarSharedState mSharedState;
     /** Window context for all apps if it is open. */
     private @Nullable TaskbarAllAppsContext mAllAppsContext;
 
@@ -88,18 +86,17 @@
     }
 
     /** Initialize the controller. */
-    public void init(TaskbarControllers controllers, TaskbarSharedState sharedState) {
+    public void init(TaskbarControllers controllers, boolean allAppsVisible) {
         if (!FeatureFlags.ENABLE_ALL_APPS_IN_TASKBAR.get()) {
             return;
         }
         mControllers = controllers;
-        mSharedState = sharedState;
 
         /*
          * Recreate All Apps if it was open in the previous Taskbar instance (e.g. the configuration
          * changed).
          */
-        if (mSharedState.allAppsVisible) {
+        if (allAppsVisible) {
             show(false);
         }
     }
@@ -141,7 +138,9 @@
             return;
         }
         mProxyView.show();
-        mSharedState.allAppsVisible = true;
+        // mControllers and getSharedState should never be null here. Do not handle null-pointer
+        // to catch invalid states.
+        mControllers.getSharedState().allAppsVisible = true;
 
         mAllAppsContext = new TaskbarAllAppsContext(mTaskbarContext,
                 this,
@@ -176,7 +175,9 @@
             return;
         }
         mProxyView.close(false);
-        mSharedState.allAppsVisible = false;
+        // mControllers and getSharedState should never be null here. Do not handle null-pointer
+        // to catch invalid states.
+        mControllers.getSharedState().allAppsVisible = false;
         onDestroy();
     }
 
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 4b42ecb..1c62ded 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -3168,6 +3168,24 @@
         return new DragOptions();
     }
 
+    /**
+     * Animates Launcher elements during a transition to the All Apps page.
+     *
+     * @param progress Transition progress from 0 to 1; where 0 => home and 1 => all apps.
+     */
+    public void onAllAppsTransition(float progress) {
+        // No-Op
+    }
+
+    /**
+     * Animates Launcher elements during a transition to the Widgets pages.
+     *
+     * @param progress Transition progress from 0 to 1; where 0 => home and 1 => widgets.
+     */
+    public void onWidgetsTransition(float progress) {
+        // No-Op
+    }
+
     private static class NonConfigInstance {
         public Configuration config;
         public Bitmap snapshot;
diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
index 637a418..bf34df1 100644
--- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java
+++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
@@ -190,6 +190,7 @@
     public void setProgress(float progress) {
         mProgress = progress;
         getAppsViewProgressTranslationY().set(mAppsView, mProgress * mShiftRange);
+        mLauncher.onAllAppsTransition(1 - progress);
     }
 
     public float getProgress() {
diff --git a/src/com/android/launcher3/widget/BaseWidgetSheet.java b/src/com/android/launcher3/widget/BaseWidgetSheet.java
index b12574f..c7bb612 100644
--- a/src/com/android/launcher3/widget/BaseWidgetSheet.java
+++ b/src/com/android/launcher3/widget/BaseWidgetSheet.java
@@ -44,6 +44,7 @@
 import com.android.launcher3.util.SystemUiController;
 import com.android.launcher3.util.Themes;
 import com.android.launcher3.views.AbstractSlideInView;
+import com.android.launcher3.views.ActivityContext;
 import com.android.launcher3.views.ArrowTipView;
 
 /**
@@ -306,4 +307,11 @@
         return mActivityContext.getSharedPrefs().getBoolean(KEY_WIDGETS_EDUCATION_TIP_SEEN, false)
                 || Utilities.IS_RUNNING_IN_TEST_HARNESS;
     }
+
+    @Override
+    protected void setTranslationShift(float translationShift) {
+        super.setTranslationShift(translationShift);
+        Launcher launcher = ActivityContext.lookupContext(getContext());
+        launcher.onWidgetsTransition(1 - translationShift);
+    }
 }