From 0a6ab4fe2ac5374fe4a32f04912d671ab329dafd Mon Sep 17 00:00:00 2001 From: Arthur Hung Date: Thu, 5 Jan 2023 15:16:44 +0000 Subject: [PATCH] Handling statusbar color when back navigation (1/2) Introduce SystemBarCustomizer so BackAnimationController could customize the status bar color according the background color when back animation is in progress. Bug: 259491355 Test: manual Change-Id: I967ec4555a94b270d91f498639140cb7d81dd266 --- .../android/wm/shell/back/BackAnimation.java | 6 +++ .../shell/back/BackAnimationBackground.java | 53 ++++++++++++++++++- .../wm/shell/back/BackAnimationConstants.java | 25 +++++++++ .../shell/back/BackAnimationController.java | 19 +++++++ .../wm/shell/back/CrossActivityAnimation.java | 5 +- .../wm/shell/back/CrossTaskBackAnimation.java | 5 +- .../back/CustomizeActivityAnimation.java | 8 +-- .../android/wm/shell/back/IBackAnimation.aidl | 8 ++- .../wm/shell/back/StatusBarCustomizer.java | 30 +++++++++++ .../gestural/EdgeBackGestureHandler.java | 22 ++++++-- .../statusbar/phone/LightBarController.java | 39 +++++++++++--- 11 files changed, 203 insertions(+), 17 deletions(-) create mode 100644 libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationConstants.java create mode 100644 libs/WindowManager/Shell/src/com/android/wm/shell/back/StatusBarCustomizer.java diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimation.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimation.java index 8cbe44b15e422..e84a78f426164 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimation.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimation.java @@ -52,4 +52,10 @@ public interface BackAnimation { * @param progressThreshold the max threshold to keep progressing back animation. */ void setSwipeThresholds(float triggerThreshold, float progressThreshold); + + /** + * Sets the system bar listener to control the system bar color. + * @param customizer the controller to control system bar color. + */ + void setStatusBarCustomizer(StatusBarCustomizer customizer); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationBackground.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationBackground.java index 36cf29a4c4f3d..9bf3b80d262e9 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationBackground.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationBackground.java @@ -17,11 +17,17 @@ package com.android.wm.shell.back; import static android.view.Display.DEFAULT_DISPLAY; +import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS; + +import static com.android.wm.shell.back.BackAnimationConstants.UPDATE_SYSUI_FLAGS_THRESHOLD; import android.annotation.NonNull; import android.graphics.Color; +import android.graphics.Rect; import android.view.SurfaceControl; +import com.android.internal.graphics.ColorUtils; +import com.android.internal.view.AppearanceRegion; import com.android.wm.shell.RootTaskDisplayAreaOrganizer; /** @@ -29,18 +35,35 @@ import com.android.wm.shell.RootTaskDisplayAreaOrganizer; */ public class BackAnimationBackground { private static final int BACKGROUND_LAYER = -1; + + private static final int NO_APPEARANCE = 0; + private final RootTaskDisplayAreaOrganizer mRootTaskDisplayAreaOrganizer; private SurfaceControl mBackgroundSurface; + private StatusBarCustomizer mCustomizer; + private boolean mIsRequestingStatusBarAppearance; + private boolean mBackgroundIsDark; + private Rect mStartBounds; + public BackAnimationBackground(RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer) { mRootTaskDisplayAreaOrganizer = rootTaskDisplayAreaOrganizer; } - void ensureBackground(int color, @NonNull SurfaceControl.Transaction transaction) { + /** + * Ensures the back animation background color layer is present. + * @param startRect The start bounds of the closing target. + * @param color The background color. + * @param transaction The animation transaction. + */ + void ensureBackground(Rect startRect, int color, + @NonNull SurfaceControl.Transaction transaction) { if (mBackgroundSurface != null) { return; } + mBackgroundIsDark = ColorUtils.calculateLuminance(color) < 0.5f; + final float[] colorComponents = new float[] { Color.red(color) / 255.f, Color.green(color) / 255.f, Color.blue(color) / 255.f }; @@ -54,6 +77,8 @@ public class BackAnimationBackground { transaction.setColor(mBackgroundSurface, colorComponents) .setLayer(mBackgroundSurface, BACKGROUND_LAYER) .show(mBackgroundSurface); + mStartBounds = startRect; + mIsRequestingStatusBarAppearance = false; } void removeBackground(@NonNull SurfaceControl.Transaction transaction) { @@ -65,5 +90,31 @@ public class BackAnimationBackground { transaction.remove(mBackgroundSurface); } mBackgroundSurface = null; + mIsRequestingStatusBarAppearance = false; + } + + void setStatusBarCustomizer(StatusBarCustomizer customizer) { + mCustomizer = customizer; + } + + void onBackProgressed(float progress) { + if (mCustomizer == null || mStartBounds.isEmpty()) { + return; + } + + final boolean shouldCustomizeSystemBar = progress > UPDATE_SYSUI_FLAGS_THRESHOLD; + if (shouldCustomizeSystemBar == mIsRequestingStatusBarAppearance) { + return; + } + + mIsRequestingStatusBarAppearance = shouldCustomizeSystemBar; + if (mIsRequestingStatusBarAppearance) { + final AppearanceRegion region = new AppearanceRegion(!mBackgroundIsDark + ? APPEARANCE_LIGHT_STATUS_BARS : NO_APPEARANCE, + mStartBounds); + mCustomizer.customizeStatusBarAppearance(region); + } else { + mCustomizer.customizeStatusBarAppearance(null); + } } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationConstants.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationConstants.java new file mode 100644 index 0000000000000..e06d3ef4e1abd --- /dev/null +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationConstants.java @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2023 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.wm.shell.back; + +/** + * The common constant values used in back animators. + */ +class BackAnimationConstants { + static final float UPDATE_SYSUI_FLAGS_THRESHOLD = 0.20f; + static final float PROGRESS_COMMIT_THRESHOLD = 0.1f; +} diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java index 6f993aebdc65a..210c9aab14d66 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java @@ -55,6 +55,7 @@ import android.window.IOnBackInvokedCallback; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.protolog.common.ProtoLog; +import com.android.internal.view.AppearanceRegion; import com.android.wm.shell.common.ExternalInterfaceBinder; import com.android.wm.shell.common.RemoteCallable; import com.android.wm.shell.common.ShellExecutor; @@ -142,6 +143,7 @@ public class BackAnimationController implements RemoteCallable BackAnimationController.this.setSwipeThresholds( triggerThreshold, progressThreshold)); } + + @Override + public void setStatusBarCustomizer(StatusBarCustomizer customizer) { + mCustomizer = customizer; + mAnimationBackground.setStatusBarCustomizer(customizer); + } } private static class IBackAnimationImpl extends IBackAnimation.Stub @@ -294,12 +302,23 @@ public class BackAnimationController implements RemoteCallable controller.customizeStatusBarAppearance(appearance)); + } + @Override public void invalidate() { mController = null; } } + private void customizeStatusBarAppearance(AppearanceRegion appearance) { + if (mCustomizer != null) { + mCustomizer.customizeStatusBarAppearance(appearance); + } + } + void registerAnimation(@BackNavigationInfo.BackTargetType int type, @NonNull BackAnimationRunner runner) { mAnimationDefinition.set(type, runner); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityAnimation.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityAnimation.java index da113cb579d65..22c90153bb39d 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityAnimation.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityAnimation.java @@ -19,6 +19,7 @@ package com.android.wm.shell.back; import static android.view.RemoteAnimationTarget.MODE_CLOSING; import static android.view.RemoteAnimationTarget.MODE_OPENING; +import static com.android.wm.shell.back.BackAnimationConstants.PROGRESS_COMMIT_THRESHOLD; import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_BACK_PREVIEW; import android.animation.Animator; @@ -89,7 +90,6 @@ class CrossActivityAnimation { private static final float WINDOW_X_SHIFT_DP = 96; private static final int SCALE_FACTOR = 100; // TODO(b/264710590): Use the progress commit threshold from ViewConfiguration once it exists. - private static final float PROGRESS_COMMIT_THRESHOLD = 0.1f; private static final float TARGET_COMMIT_PROGRESS = 0.5f; private static final float ENTER_ALPHA_THRESHOLD = 0.22f; @@ -184,7 +184,7 @@ class CrossActivityAnimation { mStartTaskRect.offsetTo(0, 0); // Draw background with task background color. - mBackground.ensureBackground( + mBackground.ensureBackground(mClosingTarget.windowConfiguration.getBounds(), mEnteringTarget.taskInfo.taskDescription.getBackgroundColor(), mTransaction); } @@ -244,6 +244,7 @@ class CrossActivityAnimation { : mapLinear(progress, 0, 1f, 0, TARGET_COMMIT_PROGRESS)) * SCALE_FACTOR; mLeavingProgressSpring.animateToFinalPosition(springProgress); mEnteringProgressSpring.animateToFinalPosition(springProgress); + mBackground.onBackProgressed(progress); } private void onGestureCommitted() { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossTaskBackAnimation.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossTaskBackAnimation.java index 99a434aff7991..a7dd27a0784f0 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossTaskBackAnimation.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossTaskBackAnimation.java @@ -141,7 +141,8 @@ class CrossTaskBackAnimation { mStartTaskRect.offsetTo(0, 0); // Draw background. - mBackground.ensureBackground(BACKGROUNDCOLOR, mTransaction); + mBackground.ensureBackground(mClosingTarget.windowConfiguration.getBounds(), + BACKGROUNDCOLOR, mTransaction); } private void updateGestureBackProgress(float progress, BackEvent event) { @@ -189,6 +190,8 @@ class CrossTaskBackAnimation { applyColorTransform(mClosingTarget.leash, closingColorScale); applyTransform(mEnteringTarget.leash, mEnteringCurrentRect, mCornerRadius); mTransaction.apply(); + + mBackground.onBackProgressed(progress); } private void updatePostCommitClosingAnimation(float progress) { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CustomizeActivityAnimation.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CustomizeActivityAnimation.java index 4eaedd3136f16..f0c5d8b29b2f5 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CustomizeActivityAnimation.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CustomizeActivityAnimation.java @@ -150,9 +150,11 @@ class CustomizeActivityAnimation { // Draw background with task background color. if (mEnteringTarget.taskInfo != null && mEnteringTarget.taskInfo.taskDescription != null) { - mBackground.ensureBackground(mNextBackgroundColor == Color.TRANSPARENT - ? mEnteringTarget.taskInfo.taskDescription.getBackgroundColor() - : mNextBackgroundColor, mTransaction); + mBackground.ensureBackground(mClosingTarget.windowConfiguration.getBounds(), + mNextBackgroundColor == Color.TRANSPARENT + ? mEnteringTarget.taskInfo.taskDescription.getBackgroundColor() + : mNextBackgroundColor, + mTransaction); } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/IBackAnimation.aidl b/libs/WindowManager/Shell/src/com/android/wm/shell/back/IBackAnimation.aidl index 2b2a0e3977925..1a35de47e977b 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/IBackAnimation.aidl +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/IBackAnimation.aidl @@ -16,8 +16,9 @@ package com.android.wm.shell.back; -import android.window.IOnBackInvokedCallback; +import com.android.internal.view.AppearanceRegion; import android.view.IRemoteAnimationRunner; +import android.window.IOnBackInvokedCallback; /** * Interface for Launcher process to register back invocation callbacks. @@ -34,4 +35,9 @@ interface IBackAnimation { * Clears the previously registered {@link IOnBackInvokedCallback}. */ void clearBackToLauncherCallback(); + + /** + * Uses launcher flags to update the system bar color. + */ + void customizeStatusBarAppearance(in AppearanceRegion appearance); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/StatusBarCustomizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/StatusBarCustomizer.java new file mode 100644 index 0000000000000..5e876127e9b45 --- /dev/null +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/StatusBarCustomizer.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2023 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.wm.shell.back; + +import com.android.internal.view.AppearanceRegion; + +/** + * Interface to customize the system bar color. + */ +public interface StatusBarCustomizer { + /** + * Called when the status bar color needs to be changed. + * @param appearance The region of appearance. + */ + void customizeStatusBarAppearance(AppearanceRegion appearance); +} diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java index 5817b3e0813ad..26b0e8dd98958 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java @@ -82,6 +82,7 @@ import com.android.systemui.shared.system.SysUiStatsLog; import com.android.systemui.shared.system.TaskStackChangeListener; import com.android.systemui.shared.system.TaskStackChangeListeners; import com.android.systemui.shared.tracing.ProtoTraceable; +import com.android.systemui.statusbar.phone.LightBarController; import com.android.systemui.tracing.ProtoTracer; import com.android.systemui.tracing.nano.EdgeBackGestureHandlerProto; import com.android.systemui.tracing.nano.SystemUiTraceProto; @@ -207,6 +208,7 @@ public class EdgeBackGestureHandler implements PluginListener mBackGestureTfClassifierProviderProvider; private final FeatureFlags mFeatureFlags; + private final Provider mLightBarControllerProvider; // The left side edge width where touch down is allowed private int mEdgeWidthLeft; @@ -352,7 +354,8 @@ public class EdgeBackGestureHandler implements PluginListener navigationBarEdgePanelProvider, Provider backGestureTfClassifierProviderProvider, - FeatureFlags featureFlags) { + FeatureFlags featureFlags, + Provider lightBarControllerProvider) { mContext = context; mDisplayId = context.getDisplayId(); mMainExecutor = executor; @@ -372,6 +375,7 @@ public class EdgeBackGestureHandler implements PluginListener