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 0000000000..a09e654ee7 Binary files /dev/null and b/quickstep/res/drawable-hdpi/nav_background.9.png 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 0000000000..aa7415349e Binary files /dev/null and b/quickstep/res/drawable-mdpi/nav_background.9.png 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 0000000000..3b521959ff Binary files /dev/null and b/quickstep/res/drawable-xhdpi/nav_background.9.png 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 0000000000..b35183c848 Binary files /dev/null and b/quickstep/res/drawable-xxhdpi/nav_background.9.png differ diff --git a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java index 63e1e01a93..b647a3e47f 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_B 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.navigationbar.KeyButtonRipple; 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 class NavbarButtonsViewController implements TaskbarControllers.LoggableT 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 mPropertyHolders = new ArrayList<>(); private final ArrayList mAllButtons = new ArrayList<>(); private int mState; @@ -162,6 +166,7 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT 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 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT 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 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT 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 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT 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 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT R.bool.floating_rotation_button_position_left); mControllers.rotationButtonController.setRotationButton(mFloatingRotationButton, mRotationButtonListener); + mTaskbarTransitions.init(); applyState(); mPropertyHolders.forEach(StatePropertyHolder::endAnimation); @@ -605,6 +620,39 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT 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 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT 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 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT } } + 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 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT + 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 5020206540..21a826870e 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.RecentsView; 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 @@ public class TaskbarActivityContext extends BaseTaskbarContext { 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 @@ public class TaskbarActivityContext extends BaseTaskbarContext { 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 @@ public class TaskbarActivityContext extends BaseTaskbarContext { 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 051bdc885d..b29420800d 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.AllAppsActionManager; 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 class TaskbarManager { } } + 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 class TaskbarManager { } } + 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 edaeb63381..77bd35ffe5 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarSharedState.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarSharedState.java @@ -56,12 +56,17 @@ public class TaskbarSharedState { // 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 0000000000..615db012ec --- /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 bfdc3dfe74..ee93cd6cef 100644 --- a/quickstep/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java @@ -70,6 +70,7 @@ import android.hardware.input.InputManager; 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.util.AssistUtils; 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 @@ public class TouchInteractionService extends Service { }); } + @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. *

@@ -358,6 +403,12 @@ public class TouchInteractionService extends Service { taskbarManager.onSystemBarAttributesChanged(displayId, behavior)); } + @Override + public void onTransitionModeUpdated(int barMode, boolean checkBarModes) { + executeForTaskbarManager(taskbarManager -> + taskbarManager.onTransitionModeUpdated(barMode, checkBarModes)); + } + @Override public void onNavButtonsDarkIntensityChanged(float darkIntensity) { executeForTaskbarManager(taskbarManager ->