Loading packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBar.java +73 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading Loading @@ -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 Loading @@ -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, Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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) { Loading packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarTest.java +44 −5 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -88,6 +100,7 @@ public class CarNavigationBarTest extends SysuiTestCase { private StatusBarIconController mIconController; private RegisterStatusBarResult mBarResult; private AppearanceRegion[] mAppearanceRegions; private FakeExecutor mUiBgExecutor; @Before Loading @@ -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, Loading @@ -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 Loading Loading @@ -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); Loading Loading
packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBar.java +73 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading Loading @@ -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 Loading @@ -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, Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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) { Loading
packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarTest.java +44 −5 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -88,6 +100,7 @@ public class CarNavigationBarTest extends SysuiTestCase { private StatusBarIconController mIconController; private RegisterStatusBarResult mBarResult; private AppearanceRegion[] mAppearanceRegions; private FakeExecutor mUiBgExecutor; @Before Loading @@ -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, Loading @@ -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 Loading Loading @@ -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); Loading