diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java index cf576dd6b9648..fe0ae33d17f11 100644 --- a/packages/SystemUI/src/com/android/systemui/Dependency.java +++ b/packages/SystemUI/src/com/android/systemui/Dependency.java @@ -49,6 +49,7 @@ import com.android.systemui.keyguard.WakefulnessLifecycle; import com.android.systemui.media.dialog.MediaOutputDialogFactory; import com.android.systemui.model.SysUiState; import com.android.systemui.navigationbar.NavigationBarController; +import com.android.systemui.navigationbar.NavigationBarOverlayController; import com.android.systemui.navigationbar.NavigationModeController; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.DarkIconDispatcher; @@ -340,6 +341,7 @@ public class Dependency { @Inject Lazy mProtoTracer; @Inject Lazy mMediaOutputDialogFactory; @Inject Lazy mDeviceConfigProxy; + @Inject Lazy mNavbarButtonsControllerLazy; @Inject public Dependency() { @@ -536,6 +538,8 @@ public class Dependency { mProviders.put(MediaOutputDialogFactory.class, mMediaOutputDialogFactory::get); + mProviders.put(NavigationBarOverlayController.class, mNavbarButtonsControllerLazy::get); + Dependency.setInstance(this); } diff --git a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java index f22fa326ee9de..726e2d06bf909 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java @@ -56,6 +56,7 @@ import com.android.systemui.dump.DumpManager; import com.android.systemui.keyguard.KeyguardViewMediator; import com.android.systemui.model.SysUiState; import com.android.systemui.navigationbar.NavigationBarController; +import com.android.systemui.navigationbar.NavigationBarOverlayController; import com.android.systemui.navigationbar.NavigationModeController; import com.android.systemui.plugins.PluginInitializerImpl; import com.android.systemui.plugins.statusbar.StatusBarStateController; @@ -81,8 +82,8 @@ import com.android.systemui.statusbar.policy.DeviceProvisionedController; import com.android.systemui.statusbar.policy.NetworkController; import com.android.systemui.theme.ThemeOverlayApplier; import com.android.systemui.util.leak.LeakDetector; -import com.android.wm.shell.pip.Pip; import com.android.wm.shell.legacysplitscreen.LegacySplitScreen; +import com.android.wm.shell.pip.Pip; import java.util.Optional; import java.util.concurrent.Executor; @@ -221,6 +222,7 @@ public class DependencyProvider { SystemActions systemActions, @Main Handler mainHandler, UiEventLogger uiEventLogger, + NavigationBarOverlayController navBarOverlayController, ConfigurationController configurationController) { return new NavigationBarController(context, windowManager, @@ -244,6 +246,7 @@ public class DependencyProvider { systemActions, mainHandler, uiEventLogger, + navBarOverlayController, configurationController); } diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java index f7a4aca4ebb1b..5d184efaa59e8 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java @@ -136,8 +136,8 @@ import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper; import com.android.systemui.statusbar.policy.BatteryController; import com.android.systemui.statusbar.policy.DeviceProvisionedController; -import com.android.wm.shell.pip.Pip; import com.android.wm.shell.legacysplitscreen.LegacySplitScreen; +import com.android.wm.shell.pip.Pip; import java.io.PrintWriter; import java.util.List; @@ -185,6 +185,7 @@ public class NavigationBar implements View.OnAttachStateChangeListener, private final Optional mRecentsOptional; private final SystemActions mSystemActions; private final Handler mHandler; + private final NavigationBarOverlayController mNavbarOverlayController; private final UiEventLogger mUiEventLogger; private Bundle mSavedState; @@ -415,6 +416,7 @@ public class NavigationBar implements View.OnAttachStateChangeListener, NotificationRemoteInputManager notificationRemoteInputManager, SystemActions systemActions, @Main Handler mainHandler, + NavigationBarOverlayController navbarOverlayController, UiEventLogger uiEventLogger) { mContext = context; mWindowManager = windowManager; @@ -438,6 +440,7 @@ public class NavigationBar implements View.OnAttachStateChangeListener, mRecentsOptional = recentsOptional; mSystemActions = systemActions; mHandler = mainHandler; + mNavbarOverlayController = navbarOverlayController; mUiEventLogger = uiEventLogger; } @@ -862,6 +865,13 @@ public class NavigationBar implements View.OnAttachStateChangeListener, rotationButtonController.onRotationProposal(rotation, winRotation, isValid); } + @Override + public void onRecentsAnimationStateChanged(boolean running) { + if (running) { + mNavbarOverlayController.setButtonState(/* visible */false, /* force */true); + } + } + /** Restores the appearance and the transient saved state to {@link NavigationBar}. */ public void restoreAppearanceAndTransientState() { final int barMode = barMode(mTransientShown, mAppearance); diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java index 461ab3aeb3c31..27ea64f85b11c 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java @@ -64,8 +64,8 @@ import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.DeviceProvisionedController; -import com.android.wm.shell.pip.Pip; import com.android.wm.shell.legacysplitscreen.LegacySplitScreen; +import com.android.wm.shell.pip.Pip; import java.io.FileDescriptor; import java.io.PrintWriter; @@ -107,6 +107,7 @@ public class NavigationBarController implements Callbacks, private final UiEventLogger mUiEventLogger; private final Handler mHandler; private final DisplayManager mDisplayManager; + private final NavigationBarOverlayController mNavBarOverlayController; /** A displayId - nav bar maps. */ @VisibleForTesting @@ -141,6 +142,7 @@ public class NavigationBarController implements Callbacks, SystemActions systemActions, @Main Handler mainHandler, UiEventLogger uiEventLogger, + NavigationBarOverlayController navBarOverlayController, ConfigurationController configurationController) { mContext = context; mWindowManager = windowManager; @@ -168,6 +170,7 @@ public class NavigationBarController implements Callbacks, commandQueue.addCallback(this); configurationController.addCallback(this); mConfigChanges.applyNewConfig(mContext.getResources()); + mNavBarOverlayController = navBarOverlayController; } @Override @@ -290,6 +293,7 @@ public class NavigationBarController implements Callbacks, mNotificationRemoteInputManager, mSystemActions, mHandler, + mNavBarOverlayController, mUiEventLogger); View navigationBarView = navBar.createView(savedState); diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarOverlayController.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarOverlayController.java new file mode 100644 index 0000000000000..c526c5d59552e --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarOverlayController.java @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2021 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.systemui.navigationbar; + +import android.annotation.ColorInt; +import android.content.Context; +import android.view.View; + +import com.android.systemui.dagger.SysUISingleton; + +import java.util.function.Consumer; + +import javax.inject.Inject; + +/** Contains logic that deals with showing buttons with navigation bar. */ +@SysUISingleton +public class NavigationBarOverlayController { + + protected final Context mContext; + + @Inject + public NavigationBarOverlayController(Context context) { + mContext = context; + } + + public Context getContext() { + return mContext; + } + + /** + * Initialize the controller with visibility change callback and light/dark icon color. + */ + public void init(Consumer visibilityChangeCallback, @ColorInt int lightIconColor, + @ColorInt int darkIconColor) {} + + /** + * Set whether the view can be shown. + */ + public void setCanShow(boolean canShow) {} + + /** + * Set the buttons visibility. + */ + public void setButtonState(boolean visible, boolean force) {} + + /** + * Register necessary listeners, called when NavigationBarView is attached to window. + */ + public void registerListeners() {} + + /** + * Unregister listeners, called when navigationBarView is detached from window. + */ + public void unregisterListeners() {} + + /** + * Set the dark intensity for all drawables. + */ + public void setDarkIntensity(float darkIntensity) {} + + /** + * Return the current view. + */ + public View getCurrentView() { + return null; + } + + /** + * Return the visibility of the view. + */ + public boolean isVisible() { + return false; + } +} diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarTransitions.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarTransitions.java index c0535b5fc77bf..b55fa4d612f9b 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarTransitions.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarTransitions.java @@ -192,6 +192,7 @@ public final class NavigationBarTransitions extends BarTransitions implements buttonDispatchers.valueAt(i).setDarkIntensity(darkIntensity); } mView.getRotationButtonController().setDarkIntensity(darkIntensity); + Dependency.get(NavigationBarOverlayController.class).setDarkIntensity(darkIntensity); for (DarkIntensityListener listener : mDarkIntensityListeners) { listener.onDarkIntensity(darkIntensity); } diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java index d6f0799938463..3c76e1d5b6091 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java @@ -92,8 +92,8 @@ import com.android.systemui.statusbar.phone.AutoHideController; import com.android.systemui.statusbar.phone.LightBarTransitionsController; import com.android.systemui.statusbar.phone.NotificationPanelViewController; import com.android.systemui.statusbar.phone.StatusBar; -import com.android.wm.shell.pip.Pip; import com.android.wm.shell.legacysplitscreen.LegacySplitScreen; +import com.android.wm.shell.pip.Pip; import java.io.PrintWriter; import java.util.function.Consumer; @@ -287,6 +287,13 @@ public class NavigationBarView extends FrameLayout implements notifyActiveTouchRegions(); }; + private final Consumer mNavbarOverlayVisibilityChangeCallback = (visible) -> { + if (visible) { + mAutoHideController.touchAutoHide(); + } + notifyActiveTouchRegions(); + }; + public NavigationBarView(Context context, AttributeSet attrs) { super(context, attrs); @@ -327,6 +334,9 @@ public class NavigationBarView extends FrameLayout implements isGesturalMode ? mFloatingRotationButton : rotateSuggestionButton, mRotationButtonListener); + Dependency.get(NavigationBarOverlayController.class).init( + mNavbarOverlayVisibilityChangeCallback, mLightIconColor, mDarkIconColor); + mConfiguration = new Configuration(); mTmpLastConfiguration = new Configuration(); mConfiguration.updateFrom(context.getResources().getConfiguration()); @@ -413,6 +423,11 @@ public class NavigationBarView extends FrameLayout implements void onTransientStateChanged(boolean isTransient) { mEdgeBackGestureHandler.onNavBarTransientStateChanged(isTransient); + + // The visibility of the navigation bar buttons is dependent on the transient state of + // the navigation bar. + Dependency.get(NavigationBarOverlayController.class).setButtonState( + isTransient, /* force */ false); } void onBarTransition(int newMode) { @@ -642,6 +657,7 @@ public class NavigationBarView extends FrameLayout implements } mImeVisible = visible; mRotationButtonController.getRotationButton().setCanShowRotationButton(!mImeVisible); + Dependency.get(NavigationBarOverlayController.class).setCanShow(!mImeVisible); } public void setDisabledFlags(int disabledFlags) { @@ -965,6 +981,11 @@ public class NavigationBarView extends FrameLayout implements } else { updateButtonLocation(getRotateSuggestionButton(), inScreenSpace); } + final NavigationBarOverlayController navBarButtonsController = + Dependency.get(NavigationBarOverlayController.class); + if (navBarButtonsController.isVisible()) { + updateButtonLocation(navBarButtonsController.getCurrentView(), inScreenSpace); + } return mTmpRegion; } @@ -1185,6 +1206,7 @@ public class NavigationBarView extends FrameLayout implements if (mRotationButtonController != null) { mRotationButtonController.registerListeners(); } + Dependency.get(NavigationBarOverlayController.class).registerListeners(); getViewTreeObserver().addOnComputeInternalInsetsListener(mOnComputeInternalInsetsListener); } @@ -1200,6 +1222,7 @@ public class NavigationBarView extends FrameLayout implements if (mRotationButtonController != null) { mRotationButtonController.unregisterListeners(); } + Dependency.get(NavigationBarOverlayController.class).unregisterListeners(); mEdgeBackGestureHandler.onNavBarDetached(); getViewTreeObserver().removeOnComputeInternalInsetsListener( diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerTest.java index 96f46eaaf1561..e761da4c4675c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerTest.java @@ -59,8 +59,8 @@ import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.DeviceProvisionedController; -import com.android.wm.shell.pip.Pip; import com.android.wm.shell.legacysplitscreen.LegacySplitScreen; +import com.android.wm.shell.pip.Pip; import org.junit.After; import org.junit.Before; @@ -106,6 +106,7 @@ public class NavigationBarControllerTest extends SysuiTestCase { mock(SystemActions.class), Dependency.get(Dependency.MAIN_HANDLER), mock(UiEventLogger.class), + mock(NavigationBarOverlayController.class), mock(ConfigurationController.class))); initializeNavigationBars(); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java index 851d4862dbbbe..2b76f1c2d76d8 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java @@ -76,8 +76,8 @@ import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper; import com.android.systemui.statusbar.policy.DeviceProvisionedController; import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.utils.leaks.LeakCheckedTest; -import com.android.wm.shell.pip.Pip; import com.android.wm.shell.legacysplitscreen.LegacySplitScreen; +import com.android.wm.shell.pip.Pip; import org.junit.Before; import org.junit.Rule; @@ -232,6 +232,7 @@ public class NavigationBarTest extends SysuiTestCase { mock(NotificationRemoteInputManager.class), mock(SystemActions.class), mHandler, + mock(NavigationBarOverlayController.class), mUiEventLogger)); }