Pipe nav bar transitions logic into task bar
Bug: 349155860
Test: manual
Flag: com.android.wm.shell.enable_taskbar_on_phones
Change-Id: Idaf7ecc7b964a2c406ddf4329b64971b08f5d7de
diff --git a/quickstep/res/drawable-hdpi/nav_background.9.png b/quickstep/res/drawable-hdpi/nav_background.9.png
new file mode 100644
index 0000000..a09e654
--- /dev/null
+++ b/quickstep/res/drawable-hdpi/nav_background.9.png
Binary files differ
diff --git a/quickstep/res/drawable-mdpi/nav_background.9.png b/quickstep/res/drawable-mdpi/nav_background.9.png
new file mode 100644
index 0000000..aa74153
--- /dev/null
+++ b/quickstep/res/drawable-mdpi/nav_background.9.png
Binary files differ
diff --git a/quickstep/res/drawable-xhdpi/nav_background.9.png b/quickstep/res/drawable-xhdpi/nav_background.9.png
new file mode 100644
index 0000000..3b52195
--- /dev/null
+++ b/quickstep/res/drawable-xhdpi/nav_background.9.png
Binary files differ
diff --git a/quickstep/res/drawable-xxhdpi/nav_background.9.png b/quickstep/res/drawable-xxhdpi/nav_background.9.png
new file mode 100644
index 0000000..b35183c
--- /dev/null
+++ b/quickstep/res/drawable-xxhdpi/nav_background.9.png
Binary files differ
diff --git a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
index 63e1e01..b647a3e 100644
--- a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
@@ -41,6 +41,7 @@
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_HOME_DISABLED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SHOWING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SWITCHER_SHOWING;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NAV_BAR_HIDDEN;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_QUICK_SETTINGS_EXPANDED;
@@ -106,6 +107,7 @@
import com.android.systemui.shared.rotation.FloatingRotationButton;
import com.android.systemui.shared.rotation.RotationButton;
import com.android.systemui.shared.rotation.RotationButtonController;
+import com.android.systemui.shared.statusbar.phone.BarTransitions;
import com.android.systemui.shared.system.QuickStepContract;
import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags;
@@ -154,6 +156,8 @@
public static final int ALPHA_INDEX_SUW = 2;
private static final int NUM_ALPHA_CHANNELS = 3;
+ private static final long AUTODIM_TIMEOUT_MS = 2250;
+
private final ArrayList<StatePropertyHolder> mPropertyHolders = new ArrayList<>();
private final ArrayList<ImageView> mAllButtons = new ArrayList<>();
private int mState;
@@ -162,6 +166,7 @@
private final @Nullable Context mNavigationBarPanelContext;
private final WindowManagerProxy mWindowManagerProxy;
private final NearestTouchFrame mNavButtonsView;
+ private final Handler mHandler;
private final LinearLayout mNavButtonContainer;
// Used for IME+A11Y buttons
private final ViewGroup mEndContextualContainer;
@@ -183,7 +188,7 @@
this::updateNavButtonInAppDisplayProgressForSysui);
/** Expected nav button dark intensity communicated via the framework. */
private final AnimatedFloat mTaskbarNavButtonDarkIntensity = new AnimatedFloat(
- this::updateNavButtonColor);
+ this::onDarkIntensityChanged);
/** {@code 1} if the Taskbar background color is fully opaque. */
private final AnimatedFloat mOnTaskbarBackgroundNavButtonColorOverride = new AnimatedFloat(
this::updateNavButtonColor);
@@ -219,12 +224,19 @@
private ImageView mRecentsButton;
private Space mSpace;
+ private TaskbarTransitions mTaskbarTransitions;
+ private @BarTransitions.TransitionMode int mTransitionMode;
+
+ private final Runnable mAutoDim = () -> mTaskbarTransitions.setAutoDim(true);
+
public NavbarButtonsViewController(TaskbarActivityContext context,
- @Nullable Context navigationBarPanelContext, NearestTouchFrame navButtonsView) {
+ @Nullable Context navigationBarPanelContext, NearestTouchFrame navButtonsView,
+ Handler handler) {
mContext = context;
mNavigationBarPanelContext = navigationBarPanelContext;
mWindowManagerProxy = WindowManagerProxy.INSTANCE.get(mContext);
mNavButtonsView = navButtonsView;
+ mHandler = handler;
mNavButtonContainer = mNavButtonsView.findViewById(R.id.end_nav_buttons);
mEndContextualContainer = mNavButtonsView.findViewById(R.id.end_contextual_buttons);
mStartContextualContainer = mNavButtonsView.findViewById(R.id.start_contextual_buttons);
@@ -234,6 +246,8 @@
mOnBackgroundIconColor = Utilities.isDarkTheme(context)
? context.getColor(R.color.taskbar_nav_icon_light_color)
: context.getColor(R.color.taskbar_nav_icon_dark_color);
+
+ mTaskbarTransitions = new TaskbarTransitions(mContext, mNavButtonsView);
}
/**
@@ -345,6 +359,7 @@
R.bool.floating_rotation_button_position_left);
mControllers.rotationButtonController.setRotationButton(mFloatingRotationButton,
mRotationButtonListener);
+ mTaskbarTransitions.init();
applyState();
mPropertyHolders.forEach(StatePropertyHolder::endAnimation);
@@ -605,6 +620,39 @@
mBackButton.setAccessibilityDelegate(accessibilityDelegate);
}
+ public void setWallpaperVisible(boolean isVisible) {
+ mTaskbarTransitions.setWallpaperVisibility(isVisible);
+ }
+
+ public void onTransitionModeUpdated(int barMode, boolean checkBarModes) {
+ mTransitionMode = barMode;
+ if (checkBarModes) {
+ checkNavBarModes();
+ }
+ }
+
+ public void checkNavBarModes() {
+ boolean isBarHidden = (mSysuiStateFlags & SYSUI_STATE_NAV_BAR_HIDDEN) != 0;
+ mTaskbarTransitions.transitionTo(mTransitionMode, !isBarHidden);
+ }
+
+ public void finishBarAnimations() {
+ mTaskbarTransitions.finishAnimations();
+ }
+
+ public void touchAutoDim(boolean reset) {
+ mTaskbarTransitions.setAutoDim(false);
+ mHandler.removeCallbacks(mAutoDim);
+ if (reset) {
+ mHandler.postDelayed(mAutoDim, AUTODIM_TIMEOUT_MS);
+ }
+ }
+
+ public void transitionTo(@BarTransitions.TransitionMode int barMode,
+ boolean animate) {
+ mTaskbarTransitions.transitionTo(barMode, animate);
+ }
+
/** Use to set the translationY for the all nav+contextual buttons */
public AnimatedFloat getTaskbarNavButtonTranslationY() {
return mTaskbarNavButtonTranslationY;
@@ -680,8 +728,7 @@
mDarkIconColorOnHome);
final int iconColor;
- if (ENABLE_TASKBAR_NAVBAR_UNIFICATION && enableTaskbarOnPhones()
- && mContext.isPhoneMode()) {
+ if (ENABLE_TASKBAR_NAVBAR_UNIFICATION && mContext.isPhoneMode()) {
iconColor = sysUiNavButtonIconColorOnHome;
} else {
// Override the color from framework if nav buttons are over an opaque Taskbar surface.
@@ -703,6 +750,11 @@
}
}
+ private void onDarkIntensityChanged() {
+ updateNavButtonColor();
+ mTaskbarTransitions.onDarkIntensityChanged(mTaskbarNavButtonDarkIntensity.value);
+ }
+
protected ImageView addButton(@DrawableRes int drawableId, @TaskbarButton int buttonType,
ViewGroup parent, TaskbarNavButtonController navButtonController, @IdRes int id) {
return addButton(drawableId, buttonType, parent, navButtonController, id,
@@ -1048,6 +1100,7 @@
+ mOnBackgroundNavButtonColorOverrideMultiplier.value);
mNavButtonsView.dumpLogs(prefix + "\t", pw);
+ mTaskbarTransitions.dumpLogs(prefix + "\t", pw);
}
private static String getStateString(int flags) {
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index 5020206..21a8268 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -139,6 +139,7 @@
import com.android.quickstep.views.TaskView;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.rotation.RotationButtonController;
+import com.android.systemui.shared.statusbar.phone.BarTransitions;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags;
import com.android.systemui.unfold.updates.RotationChangeProvider;
@@ -275,7 +276,8 @@
mControllers = new TaskbarControllers(this,
new TaskbarDragController(this),
buttonController,
- new NavbarButtonsViewController(this, mNavigationBarPanelContext, navButtonsView),
+ new NavbarButtonsViewController(this, mNavigationBarPanelContext, navButtonsView,
+ getMainThreadHandler()),
rotationButtonController,
new TaskbarDragLayerController(this, mDragLayer),
new TaskbarViewController(this, taskbarView),
@@ -799,6 +801,27 @@
mControllers.taskbarStashController.setSetupUIVisible(isVisible);
}
+ public void setWallpaperVisible(boolean isVisible) {
+ mControllers.navbarButtonsViewController.setWallpaperVisible(isVisible);
+ }
+
+ public void checkNavBarModes() {
+ mControllers.navbarButtonsViewController.checkNavBarModes();
+ }
+
+ public void finishBarAnimations() {
+ mControllers.navbarButtonsViewController.finishBarAnimations();
+ }
+
+ public void touchAutoDim(boolean reset) {
+ mControllers.navbarButtonsViewController.touchAutoDim(reset);
+ }
+
+ public void transitionTo(@BarTransitions.TransitionMode int barMode,
+ boolean animate) {
+ mControllers.navbarButtonsViewController.transitionTo(barMode, animate);
+ }
+
/**
* Called when this instance of taskbar is no longer needed
*/
@@ -876,6 +899,9 @@
mControllers.rotationButtonController.onBehaviorChanged(displayId, behavior);
}
+ public void onTransitionModeUpdated(int barMode, boolean checkBarModes) {
+ mControllers.navbarButtonsViewController.onTransitionModeUpdated(barMode, checkBarModes);
+ }
public void onNavButtonsDarkIntensityChanged(float darkIntensity) {
mControllers.navbarButtonsViewController.getTaskbarNavButtonDarkIntensity()
.updateValue(darkIntensity);
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
index 051bdc8..b294208 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
@@ -72,6 +72,7 @@
import com.android.quickstep.RecentsActivity;
import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.util.AssistUtils;
+import com.android.systemui.shared.statusbar.phone.BarTransitions;
import com.android.systemui.shared.system.QuickStepContract;
import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags;
import com.android.systemui.unfold.UnfoldTransitionProgressProvider;
@@ -519,6 +520,36 @@
}
}
+ public void setWallpaperVisible(boolean isVisible) {
+ mSharedState.wallpaperVisible = isVisible;
+ if (mTaskbarActivityContext != null) {
+ mTaskbarActivityContext.setWallpaperVisible(isVisible);
+ }
+ }
+
+ public void checkNavBarModes() {
+ if (mTaskbarActivityContext != null) {
+ mTaskbarActivityContext.checkNavBarModes();
+ }
+ }
+
+ public void finishBarAnimations() {
+ if (mTaskbarActivityContext != null) {
+ mTaskbarActivityContext.finishBarAnimations();
+ }
+ }
+
+ public void touchAutoDim(boolean reset) {
+ if (mTaskbarActivityContext != null) {
+ mTaskbarActivityContext.touchAutoDim(reset);
+ }
+ }
+
+ public void transitionTo(@BarTransitions.TransitionMode int barMode,
+ boolean animate) {
+ mTaskbarActivityContext.transitionTo(barMode, animate);
+ }
+
private boolean isTaskbarEnabled(DeviceProfile deviceProfile) {
return ENABLE_TASKBAR_NAVBAR_UNIFICATION || deviceProfile.isTaskbarPresent;
}
@@ -546,6 +577,13 @@
}
}
+ public void onTransitionModeUpdated(int barMode, boolean checkBarModes) {
+ mSharedState.barMode = barMode;
+ if (mTaskbarActivityContext != null) {
+ mTaskbarActivityContext.onTransitionModeUpdated(barMode, checkBarModes);
+ }
+ }
+
public void onNavButtonsDarkIntensityChanged(float darkIntensity) {
mSharedState.navButtonsDarkIntensity = darkIntensity;
if (mTaskbarActivityContext != null) {
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarSharedState.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarSharedState.java
index edaeb63..77bd35f 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarSharedState.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarSharedState.java
@@ -56,12 +56,17 @@
// TaskbarManager#onNavButtonsDarkIntensityChanged()
public float navButtonsDarkIntensity;
+ // TaskbarManager#onTransitionModeUpdated()
+ public int barMode;
+
// TaskbarManager#onNavigationBarLumaSamplingEnabled()
public int mLumaSamplingDisplayId = DEFAULT_DISPLAY;
public boolean mIsLumaSamplingEnabled = true;
public boolean setupUIVisible = false;
+ public boolean wallpaperVisible = false;
+
public boolean allAppsVisible = false;
// LauncherTaskbarUIController#mTaskbarInAppDisplayProgressMultiProp
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarTransitions.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarTransitions.java
new file mode 100644
index 0000000..615db01
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarTransitions.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3.taskbar;
+
+import android.view.View;
+
+import com.android.launcher3.R;
+import com.android.launcher3.taskbar.navbutton.NearestTouchFrame;
+import com.android.systemui.shared.statusbar.phone.BarTransitions;
+
+import java.io.PrintWriter;
+
+/** Manages task bar transitions */
+public class TaskbarTransitions extends BarTransitions implements
+ TaskbarControllers.LoggableTaskbarController {
+
+ private final TaskbarActivityContext mContext;
+
+ private boolean mWallpaperVisible;
+
+ private boolean mLightsOut;
+ private boolean mAutoDim;
+ private View mNavButtons;
+ private float mDarkIntensity;
+
+ private final NearestTouchFrame mView;
+
+ public TaskbarTransitions(TaskbarActivityContext context, NearestTouchFrame view) {
+ super(view, R.drawable.nav_background);
+
+ mContext = context;
+ mView = view;
+ }
+
+ void init() {
+ mView.addOnLayoutChangeListener(
+ (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> {
+ mNavButtons = mView.findViewById(R.id.end_nav_buttons);
+ applyLightsOut(false, true);
+ });
+ mNavButtons = mView.findViewById(R.id.end_nav_buttons);
+
+ applyModeBackground(-1, getMode(), false /*animate*/);
+ applyLightsOut(false /*animate*/, true /*force*/);
+ if (mContext.isPhoneButtonNavMode()) {
+ mBarBackground.setOverrideAlpha(1);
+ }
+ }
+
+ void setWallpaperVisibility(boolean visible) {
+ mWallpaperVisible = visible;
+ applyLightsOut(true, false);
+ }
+
+ @Override
+ public void setAutoDim(boolean autoDim) {
+ // Ensure we aren't in gestural nav if we are triggering auto dim
+ if (autoDim && !mContext.isPhoneButtonNavMode()) {
+ return;
+ }
+ if (mAutoDim == autoDim) return;
+ mAutoDim = autoDim;
+ applyLightsOut(true, false);
+ }
+
+ @Override
+ protected void onTransition(int oldMode, int newMode, boolean animate) {
+ super.onTransition(oldMode, newMode, animate);
+ applyLightsOut(animate, false /*force*/);
+ }
+
+ private void applyLightsOut(boolean animate, boolean force) {
+ // apply to lights out
+ applyLightsOut(isLightsOut(getMode()), animate, force);
+ }
+
+ private void applyLightsOut(boolean lightsOut, boolean animate, boolean force) {
+ if (!force && lightsOut == mLightsOut) return;
+
+ mLightsOut = lightsOut;
+ if (mNavButtons == null) return;
+
+ // ok, everyone, stop it right there
+ mNavButtons.animate().cancel();
+
+ // Bump percentage by 10% if dark.
+ float darkBump = mDarkIntensity / 10;
+ final float navButtonsAlpha = lightsOut ? 0.6f + darkBump : 1f;
+
+ if (!animate) {
+ mNavButtons.setAlpha(navButtonsAlpha);
+ } else {
+ final int duration = lightsOut ? LIGHTS_OUT_DURATION : LIGHTS_IN_DURATION;
+ mNavButtons.animate()
+ .alpha(navButtonsAlpha)
+ .setDuration(duration)
+ .start();
+ }
+ }
+
+ void onDarkIntensityChanged(float darkIntensity) {
+ mDarkIntensity = darkIntensity;
+ if (mAutoDim) {
+ applyLightsOut(false, true);
+ }
+ }
+
+ @Override
+ public void dumpLogs(String prefix, PrintWriter pw) {
+ pw.println(prefix + "TaskbarTransitions:");
+
+ pw.println(prefix + "\tmMode=" + getMode());
+ pw.println(prefix + "\tmAlwaysOpaque: " + isAlwaysOpaque());
+ pw.println(prefix + "\tmWallpaperVisible: " + mWallpaperVisible);
+ pw.println(prefix + "\tmLightsOut: " + mLightsOut);
+ pw.println(prefix + "\tmAutoDim: " + mAutoDim);
+ pw.println(prefix + "\tbg overrideAlpha: " + mBarBackground.getOverrideAlpha());
+ pw.println(prefix + "\tbg color: " + mBarBackground.getColor());
+ pw.println(prefix + "\tbg frame: " + mBarBackground.getFrame());
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index bfdc3df..ee93cd6 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -70,6 +70,7 @@
import android.os.Bundle;
import android.os.IBinder;
import android.os.Looper;
+import android.os.RemoteException;
import android.os.SystemClock;
import android.os.Trace;
import android.util.ArraySet;
@@ -126,6 +127,7 @@
import com.android.quickstep.views.RecentsViewContainer;
import com.android.systemui.shared.recents.IOverviewProxy;
import com.android.systemui.shared.recents.ISystemUiProxy;
+import com.android.systemui.shared.statusbar.phone.BarTransitions;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.InputChannelCompat.InputEventReceiver;
import com.android.systemui.shared.system.InputConsumerController;
@@ -330,6 +332,49 @@
});
}
+ @BinderThread
+ @Override
+ public void updateWallpaperVisibility(int displayId, boolean visible) {
+ MAIN_EXECUTOR.execute(() -> executeForTouchInteractionService(tis ->
+ executeForTaskbarManager(
+ taskbarManager -> taskbarManager.setWallpaperVisible(visible))
+ ));
+ }
+
+ @BinderThread
+ @Override
+ public void checkNavBarModes() {
+ MAIN_EXECUTOR.execute(() -> executeForTouchInteractionService(tis ->
+ executeForTaskbarManager(TaskbarManager::checkNavBarModes)
+ ));
+ }
+
+ @BinderThread
+ @Override
+ public void finishBarAnimations() {
+ MAIN_EXECUTOR.execute(() -> executeForTouchInteractionService(tis ->
+ executeForTaskbarManager(TaskbarManager::finishBarAnimations)
+ ));
+ }
+
+ @BinderThread
+ @Override
+ public void touchAutoDim(boolean reset) {
+ MAIN_EXECUTOR.execute(() -> executeForTouchInteractionService(tis ->
+ executeForTaskbarManager(taskbarManager -> taskbarManager.touchAutoDim(reset))
+ ));
+ }
+
+ @BinderThread
+ @Override
+ public void transitionTo(@BarTransitions.TransitionMode int barMode,
+ boolean animate) {
+ MAIN_EXECUTOR.execute(() -> executeForTouchInteractionService(tis ->
+ executeForTaskbarManager(
+ taskbarManager -> taskbarManager.transitionTo(barMode, animate))
+ ));
+ }
+
/**
* Preloads the Overview activity.
* <p>
@@ -359,6 +404,12 @@
}
@Override
+ public void onTransitionModeUpdated(int barMode, boolean checkBarModes) {
+ executeForTaskbarManager(taskbarManager ->
+ taskbarManager.onTransitionModeUpdated(barMode, checkBarModes));
+ }
+
+ @Override
public void onNavButtonsDarkIntensityChanged(float darkIntensity) {
executeForTaskbarManager(taskbarManager ->
taskbarManager.onNavButtonsDarkIntensityChanged(darkIntensity));