From 0e3c478fabdf526d5b6f98cfe0768d6279ee1dac Mon Sep 17 00:00:00 2001 From: JianYang Liu Date: Thu, 7 May 2020 19:15:37 -0700 Subject: [PATCH] Updated CarNavigationBar to update status bar icon appearance on start. Bug: 155664476 Test: Manual, atest CarNavigationBarTest Change-Id: I83dac7499c8bdcb5570df6c33f483f4928fe6549 --- .../car/navigationbar/CarNavigationBar.java | 73 +++++++++++++++++++ .../navigationbar/CarNavigationBarTest.java | 49 +++++++++++-- 2 files changed, 117 insertions(+), 5 deletions(-) diff --git a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBar.java b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBar.java index 893efdc0991c6..8e114142972c4 100644 --- a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBar.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBar.java @@ -19,6 +19,7 @@ package com.android.systemui.car.navigationbar; import static android.view.InsetsState.ITYPE_NAVIGATION_BAR; import static android.view.InsetsState.ITYPE_STATUS_BAR; import static android.view.InsetsState.containsType; +import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS; import static com.android.systemui.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT; import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT; @@ -34,26 +35,31 @@ import android.view.Display; import android.view.Gravity; import android.view.View; import android.view.ViewGroup; +import android.view.WindowInsetsController; import android.view.WindowManager; import androidx.annotation.VisibleForTesting; import com.android.internal.statusbar.IStatusBarService; import com.android.internal.statusbar.RegisterStatusBarResult; +import com.android.internal.view.AppearanceRegion; import com.android.systemui.R; import com.android.systemui.SystemUI; import com.android.systemui.car.CarDeviceProvisionedController; import com.android.systemui.car.CarDeviceProvisionedListener; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dagger.qualifiers.UiBackground; +import com.android.systemui.plugins.DarkIconDispatcher; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.statusbar.AutoHideUiElement; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.phone.AutoHideController; import com.android.systemui.statusbar.phone.BarTransitions; +import com.android.systemui.statusbar.phone.LightBarController; import com.android.systemui.statusbar.phone.PhoneStatusBarPolicy; import com.android.systemui.statusbar.phone.StatusBarIconController; import com.android.systemui.statusbar.phone.StatusBarSignalPolicy; +import com.android.systemui.statusbar.phone.SysuiDarkIconDispatcher; import com.android.systemui.statusbar.policy.KeyguardStateController; import java.io.FileDescriptor; @@ -69,6 +75,7 @@ public class CarNavigationBar extends SystemUI implements CommandQueue.Callbacks private final Resources mResources; private final CarNavigationBarController mCarNavigationBarController; + private final SysuiDarkIconDispatcher mStatusBarIconController; private final WindowManager mWindowManager; private final CarDeviceProvisionedController mCarDeviceProvisionedController; private final CommandQueue mCommandQueue; @@ -106,6 +113,7 @@ public class CarNavigationBar extends SystemUI implements CommandQueue.Callbacks private boolean mDeviceIsSetUpForUser = true; private boolean mIsUserSetupInProgress = false; + private AppearanceRegion[] mAppearanceRegions = new AppearanceRegion[0]; @BarTransitions.TransitionMode private int mStatusBarMode; @BarTransitions.TransitionMode @@ -117,6 +125,9 @@ public class CarNavigationBar extends SystemUI implements CommandQueue.Callbacks public CarNavigationBar(Context context, @Main Resources resources, CarNavigationBarController carNavigationBarController, + // TODO(b/156052638): Should not need to inject LightBarController + LightBarController lightBarController, + DarkIconDispatcher darkIconDispatcher, WindowManager windowManager, CarDeviceProvisionedController deviceProvisionedController, CommandQueue commandQueue, @@ -133,6 +144,7 @@ public class CarNavigationBar extends SystemUI implements CommandQueue.Callbacks super(context); mResources = resources; mCarNavigationBarController = carNavigationBarController; + mStatusBarIconController = (SysuiDarkIconDispatcher) darkIconDispatcher; mWindowManager = windowManager; mCarDeviceProvisionedController = deviceProvisionedController; mCommandQueue = commandQueue; @@ -166,6 +178,9 @@ public class CarNavigationBar extends SystemUI implements CommandQueue.Callbacks ex.rethrowFromSystemServer(); } + onSystemBarAppearanceChanged(mDisplayId, result.mAppearance, result.mAppearanceRegions, + result.mNavbarColorManagedByIme); + // StatusBarManagerService has a back up of IME token and it's restored here. setImeWindowStatus(mDisplayId, result.mImeToken, result.mImeWindowVis, result.mImeBackDisposition, result.mShowImeSwitcher); @@ -446,6 +461,64 @@ public class CarNavigationBar extends SystemUI implements CommandQueue.Callbacks isKeyboardVisible ? View.GONE : View.VISIBLE); } + @Override + public void onSystemBarAppearanceChanged( + int displayId, + @WindowInsetsController.Appearance int appearance, + AppearanceRegion[] appearanceRegions, + boolean navbarColorManagedByIme) { + if (displayId != mDisplayId) { + return; + } + boolean barModeChanged = updateStatusBarMode( + mStatusBarTransientShown ? MODE_SEMI_TRANSPARENT : MODE_TRANSPARENT); + int numStacks = appearanceRegions.length; + boolean stackAppearancesChanged = mAppearanceRegions.length != numStacks; + for (int i = 0; i < numStacks && !stackAppearancesChanged; i++) { + stackAppearancesChanged |= !appearanceRegions[i].equals(mAppearanceRegions[i]); + } + if (stackAppearancesChanged || barModeChanged) { + mAppearanceRegions = appearanceRegions; + updateStatusBarAppearance(); + } + } + + private void updateStatusBarAppearance() { + int numStacks = mAppearanceRegions.length; + int numLightStacks = 0; + + // We can only have maximum one light stack. + int indexLightStack = -1; + + for (int i = 0; i < numStacks; i++) { + if (isLight(mAppearanceRegions[i].getAppearance())) { + numLightStacks++; + indexLightStack = i; + } + } + + // If all stacks are light, all icons become dark. + if (numLightStacks == numStacks) { + mStatusBarIconController.setIconsDarkArea(null); + mStatusBarIconController.getTransitionsController().setIconsDark( + /* dark= */ true, /* animate= */ false); + } else if (numLightStacks == 0) { + // If no one is light, all icons become white. + mStatusBarIconController.getTransitionsController().setIconsDark( + /* dark= */ false, /* animate= */ false); + } else { + // Not the same for every stack, update icons in area only. + mStatusBarIconController.setIconsDarkArea( + mAppearanceRegions[indexLightStack].getBounds()); + mStatusBarIconController.getTransitionsController().setIconsDark( + /* dark= */ true, /* animate= */ false); + } + } + + private static boolean isLight(int appearance) { + return (appearance & APPEARANCE_LIGHT_STATUS_BARS) != 0; + } + @Override public void showTransient(int displayId, int[] types) { if (displayId != mDisplayId) { diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarTest.java index 77eecaccaaa4a..04e0a7324adfd 100644 --- a/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarTest.java +++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarTest.java @@ -18,6 +18,8 @@ package com.android.systemui.car.navigationbar; import static android.view.InsetsState.ITYPE_NAVIGATION_BAR; import static android.view.InsetsState.ITYPE_STATUS_BAR; +import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS; +import static android.view.WindowInsetsController.APPEARANCE_OPAQUE_STATUS_BARS; import static com.google.common.truth.Truth.assertThat; @@ -25,6 +27,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.graphics.Rect; import android.os.Handler; import android.os.RemoteException; import android.testing.AndroidTestingRunner; @@ -44,8 +47,11 @@ import com.android.systemui.SysuiTestCase; import com.android.systemui.car.CarDeviceProvisionedController; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.phone.AutoHideController; +import com.android.systemui.statusbar.phone.LightBarController; +import com.android.systemui.statusbar.phone.LightBarTransitionsController; import com.android.systemui.statusbar.phone.PhoneStatusBarPolicy; import com.android.systemui.statusbar.phone.StatusBarIconController; +import com.android.systemui.statusbar.phone.SysuiDarkIconDispatcher; import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.util.concurrency.FakeExecutor; import com.android.systemui.util.time.FakeSystemClock; @@ -69,6 +75,12 @@ public class CarNavigationBarTest extends SysuiTestCase { @Mock private CarNavigationBarController mCarNavigationBarController; @Mock + private LightBarController mLightBarController; + @Mock + private SysuiDarkIconDispatcher mStatusBarIconController; + @Mock + private LightBarTransitionsController mLightBarTransitionsController; + @Mock private WindowManager mWindowManager; @Mock private CarDeviceProvisionedController mDeviceProvisionedController; @@ -88,6 +100,7 @@ public class CarNavigationBarTest extends SysuiTestCase { private StatusBarIconController mIconController; private RegisterStatusBarResult mBarResult; + private AppearanceRegion[] mAppearanceRegions; private FakeExecutor mUiBgExecutor; @Before @@ -96,11 +109,16 @@ public class CarNavigationBarTest extends SysuiTestCase { mTestableResources = mContext.getOrCreateTestableResources(); mHandler = Handler.getMain(); mUiBgExecutor = new FakeExecutor(new FakeSystemClock()); + when(mStatusBarIconController.getTransitionsController()).thenReturn( + mLightBarTransitionsController); + mAppearanceRegions = new AppearanceRegion[] { + new AppearanceRegion(APPEARANCE_LIGHT_STATUS_BARS, new Rect()) + }; mBarResult = new RegisterStatusBarResult( /* icons= */ new ArrayMap<>(), /* disabledFlags1= */ 0, /* appearance= */ 0, - /* appearanceRegions= */ new AppearanceRegion[]{}, + mAppearanceRegions, /* imeWindowVis= */ 0, /* imeBackDisposition= */ 0, /* showImeSwitcher= */ false, @@ -116,10 +134,11 @@ public class CarNavigationBarTest extends SysuiTestCase { e.printStackTrace(); } mCarNavigationBar = new CarNavigationBar(mContext, mTestableResources.getResources(), - mCarNavigationBarController, mWindowManager, mDeviceProvisionedController, - new CommandQueue(mContext), mAutoHideController, mButtonSelectionStateListener, - mHandler, mUiBgExecutor, mBarService, () -> mKeyguardStateController, - mButtonSelectionStateController, () -> mIconPolicy, () -> mIconController); + mCarNavigationBarController, mLightBarController, mStatusBarIconController, + mWindowManager, mDeviceProvisionedController, new CommandQueue(mContext), + mAutoHideController, mButtonSelectionStateListener, mHandler, mUiBgExecutor, + mBarService, () -> mKeyguardStateController, mButtonSelectionStateController, + () -> mIconPolicy, () -> mIconController); } @Test @@ -185,6 +204,26 @@ public class CarNavigationBarTest extends SysuiTestCase { verify(mCarNavigationBarController).hideAllKeyguardButtons(true); } + @Test + public void restartNavBars_lightAppearance_darkensAllIcons() { + mAppearanceRegions[0] = new AppearanceRegion(APPEARANCE_LIGHT_STATUS_BARS, new Rect()); + + mCarNavigationBar.start(); + + verify(mLightBarTransitionsController).setIconsDark( + /* dark= */ true, /* animate= */ false); + } + + @Test + public void restartNavBars_opaqueAppearance_lightensAllIcons() { + mAppearanceRegions[0] = new AppearanceRegion(APPEARANCE_OPAQUE_STATUS_BARS, new Rect()); + + mCarNavigationBar.start(); + + verify(mLightBarTransitionsController).setIconsDark( + /* dark= */ false, /* animate= */ false); + } + @Test public void showTransient_wrongDisplayId_transientModeNotUpdated() { mTestableResources.addOverride(R.bool.config_enableTopNavigationBar, true);