diff options
| author | 2022-07-26 11:34:54 +0000 | |
|---|---|---|
| committer | 2022-07-26 11:34:54 +0000 | |
| commit | 1f59906bf69aa5229f3ccfb068d2c76138f66310 (patch) | |
| tree | 311141d5846e20ea01fd3629380784f98cbecdef | |
| parent | 28aa7dd51fc258c2770b854b55b0577244ac5576 (diff) | |
| parent | 997fb3121ffb575f2f5361ab5ef31d570f15c7dc (diff) | |
Merge "Start using LetterboxAppearanceCalculator in SysUI" into tm-qpr-dev
7 files changed, 500 insertions, 31 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java index eda3446c8cb6..f4b7772a1453 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java @@ -57,10 +57,8 @@ import com.android.systemui.keyguard.WakefulnessLifecycle; import com.android.systemui.qs.QSPanelController; import com.android.systemui.shade.NotificationPanelView; import com.android.systemui.shade.NotificationPanelViewController; -import com.android.systemui.shade.NotificationShadeWindowView; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.DisableFlagsLogger; -import com.android.systemui.statusbar.SysuiStatusBarStateController; import com.android.systemui.statusbar.VibratorHelper; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController; import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent; @@ -91,19 +89,16 @@ public class CentralSurfacesCommandQueueCallbacks implements CommandQueue.Callba private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager; private final AssistManager mAssistManager; private final DozeServiceHost mDozeServiceHost; - private final SysuiStatusBarStateController mStatusBarStateController; - private final NotificationShadeWindowView mNotificationShadeWindowView; private final NotificationStackScrollLayoutController mNotificationStackScrollLayoutController; private final StatusBarHideIconsForBouncerManager mStatusBarHideIconsForBouncerManager; private final PowerManager mPowerManager; private final VibratorHelper mVibratorHelper; private final Optional<Vibrator> mVibratorOptional; - private final LightBarController mLightBarController; private final DisableFlagsLogger mDisableFlagsLogger; private final int mDisplayId; private final boolean mVibrateOnOpening; private final VibrationEffect mCameraLaunchGestureVibrationEffect; - + private final SystemBarAttributesListener mSystemBarAttributesListener; private static final VibrationAttributes HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES = VibrationAttributes.createForUsage(VibrationAttributes.USAGE_HARDWARE_FEEDBACK); @@ -126,16 +121,14 @@ public class CentralSurfacesCommandQueueCallbacks implements CommandQueue.Callba StatusBarKeyguardViewManager statusBarKeyguardViewManager, AssistManager assistManager, DozeServiceHost dozeServiceHost, - SysuiStatusBarStateController statusBarStateController, - NotificationShadeWindowView notificationShadeWindowView, NotificationStackScrollLayoutController notificationStackScrollLayoutController, StatusBarHideIconsForBouncerManager statusBarHideIconsForBouncerManager, PowerManager powerManager, VibratorHelper vibratorHelper, Optional<Vibrator> vibratorOptional, - LightBarController lightBarController, DisableFlagsLogger disableFlagsLogger, - @DisplayId int displayId) { + @DisplayId int displayId, + SystemBarAttributesListener systemBarAttributesListener) { mCentralSurfaces = centralSurfaces; mContext = context; @@ -152,20 +145,18 @@ public class CentralSurfacesCommandQueueCallbacks implements CommandQueue.Callba mStatusBarKeyguardViewManager = statusBarKeyguardViewManager; mAssistManager = assistManager; mDozeServiceHost = dozeServiceHost; - mStatusBarStateController = statusBarStateController; - mNotificationShadeWindowView = notificationShadeWindowView; mNotificationStackScrollLayoutController = notificationStackScrollLayoutController; mStatusBarHideIconsForBouncerManager = statusBarHideIconsForBouncerManager; mPowerManager = powerManager; mVibratorHelper = vibratorHelper; mVibratorOptional = vibratorOptional; - mLightBarController = lightBarController; mDisableFlagsLogger = disableFlagsLogger; mDisplayId = displayId; mVibrateOnOpening = resources.getBoolean(R.bool.config_vibrateOnIconAnimation); mCameraLaunchGestureVibrationEffect = getCameraGestureVibrationEffect( mVibratorOptional, resources); + mSystemBarAttributesListener = systemBarAttributesListener; } @Override @@ -472,14 +463,18 @@ public class CentralSurfacesCommandQueueCallbacks implements CommandQueue.Callba if (displayId != mDisplayId) { return; } - boolean barModeChanged = mCentralSurfaces.setAppearance(appearance); - - mLightBarController.onStatusBarAppearanceChanged(appearanceRegions, barModeChanged, - mCentralSurfaces.getBarMode(), navbarColorManagedByIme); - - mCentralSurfaces.updateBubblesVisibility(); - mStatusBarStateController.setSystemBarAttributes( - appearance, behavior, requestedVisibilities, packageName); + // SystemBarAttributesListener should __always__ be the top-level listener for system bar + // attributes changed. + mSystemBarAttributesListener.onSystemBarAttributesChanged( + displayId, + appearance, + appearanceRegions, + navbarColorManagedByIme, + behavior, + requestedVisibilities, + packageName, + letterboxDetails + ); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemBarAttributesListener.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemBarAttributesListener.kt new file mode 100644 index 000000000000..a0415f2f3d7c --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemBarAttributesListener.kt @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2022 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.statusbar.phone + +import android.view.InsetsVisibilities +import android.view.WindowInsetsController.Appearance +import android.view.WindowInsetsController.Behavior +import com.android.internal.statusbar.LetterboxDetails +import com.android.internal.view.AppearanceRegion +import com.android.systemui.dump.DumpManager +import com.android.systemui.flags.FeatureFlags +import com.android.systemui.flags.Flags +import com.android.systemui.statusbar.SysuiStatusBarStateController +import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent +import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent.CentralSurfacesScope +import java.io.PrintWriter +import javax.inject.Inject + +/** + * Top-level listener of system attributes changed. This class is __always the first__ one to be + * notified about changes. + * + * It is responsible for modifying any attributes if necessary, and then notifying the other + * downstream listeners. + */ +@CentralSurfacesScope +class SystemBarAttributesListener +@Inject +internal constructor( + private val centralSurfaces: CentralSurfaces, + private val featureFlags: FeatureFlags, + private val letterboxAppearanceCalculator: LetterboxAppearanceCalculator, + private val statusBarStateController: SysuiStatusBarStateController, + private val lightBarController: LightBarController, + private val dumpManager: DumpManager, +) : CentralSurfacesComponent.Startable, StatusBarBoundsProvider.BoundsChangeListener { + + private var lastLetterboxAppearance: LetterboxAppearance? = null + private var lastSystemBarAttributesParams: SystemBarAttributesParams? = null + + override fun start() { + dumpManager.registerDumpable(javaClass.simpleName, this::dump) + } + + override fun stop() { + dumpManager.unregisterDumpable(javaClass.simpleName) + } + + override fun onStatusBarBoundsChanged() { + val params = lastSystemBarAttributesParams + if (params != null && shouldUseLetterboxAppearance(params.letterboxesArray)) { + onSystemBarAttributesChanged( + params.displayId, + params.appearance, + params.appearanceRegionsArray, + params.navbarColorManagedByIme, + params.behavior, + params.requestedVisibilities, + params.packageName, + params.letterboxesArray) + } + } + + fun onSystemBarAttributesChanged( + displayId: Int, + @Appearance originalAppearance: Int, + originalAppearanceRegions: Array<AppearanceRegion>, + navbarColorManagedByIme: Boolean, + @Behavior behavior: Int, + requestedVisibilities: InsetsVisibilities, + packageName: String, + letterboxDetails: Array<LetterboxDetails> + ) { + lastSystemBarAttributesParams = + SystemBarAttributesParams( + displayId, + originalAppearance, + originalAppearanceRegions.toList(), + navbarColorManagedByIme, + behavior, + requestedVisibilities, + packageName, + letterboxDetails.toList()) + + val (appearance, appearanceRegions) = + modifyAppearanceIfNeeded( + originalAppearance, originalAppearanceRegions, letterboxDetails) + + val barModeChanged = centralSurfaces.setAppearance(appearance) + + lightBarController.onStatusBarAppearanceChanged( + appearanceRegions, barModeChanged, centralSurfaces.barMode, navbarColorManagedByIme) + + centralSurfaces.updateBubblesVisibility() + statusBarStateController.setSystemBarAttributes( + appearance, behavior, requestedVisibilities, packageName) + } + + private fun modifyAppearanceIfNeeded( + appearance: Int, + appearanceRegions: Array<AppearanceRegion>, + letterboxDetails: Array<LetterboxDetails> + ): Pair<Int, Array<AppearanceRegion>> = + if (shouldUseLetterboxAppearance(letterboxDetails)) { + val letterboxAppearance = + letterboxAppearanceCalculator.getLetterboxAppearance( + appearance, appearanceRegions, letterboxDetails) + lastLetterboxAppearance = letterboxAppearance + Pair(letterboxAppearance.appearance, letterboxAppearance.appearanceRegions) + } else { + lastLetterboxAppearance = null + Pair(appearance, appearanceRegions) + } + + private fun shouldUseLetterboxAppearance(letterboxDetails: Array<LetterboxDetails>) = + isLetterboxAppearanceFlagEnabled() && letterboxDetails.isNotEmpty() + + private fun isLetterboxAppearanceFlagEnabled() = + featureFlags.isEnabled(Flags.STATUS_BAR_LETTERBOX_APPEARANCE) + + private fun dump(printWriter: PrintWriter, strings: Array<String>) { + printWriter.println("lastSystemBarAttributesParams: $lastSystemBarAttributesParams") + printWriter.println("lastLetterboxAppearance: $lastLetterboxAppearance") + printWriter.println("letterbox appearance flag: ${isLetterboxAppearanceFlagEnabled()}") + } +} + +/** + * Keeps track of the parameters passed in + * [SystemBarAttributesListener.onSystemBarAttributesChanged]. + */ +private data class SystemBarAttributesParams( + val displayId: Int, + @Appearance val appearance: Int, + val appearanceRegions: List<AppearanceRegion>, + val navbarColorManagedByIme: Boolean, + @Behavior val behavior: Int, + val requestedVisibilities: InsetsVisibilities, + val packageName: String, + val letterboxes: List<LetterboxDetails>, +) { + val letterboxesArray = letterboxes.toTypedArray() + val appearanceRegionsArray = appearanceRegions.toTypedArray() +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesStartableModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesStartableModule.java index 590522fc8751..d57e6a791489 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesStartableModule.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesStartableModule.java @@ -17,6 +17,7 @@ package com.android.systemui.statusbar.phone.dagger; import com.android.systemui.statusbar.phone.LetterboxAppearanceCalculator; +import com.android.systemui.statusbar.phone.SystemBarAttributesListener; import java.util.Set; @@ -34,4 +35,9 @@ interface CentralSurfacesStartableModule { @IntoSet CentralSurfacesComponent.Startable letterboxAppearanceCalculator( LetterboxAppearanceCalculator letterboxAppearanceCalculator); + + @Binds + @IntoSet + CentralSurfacesComponent.Startable sysBarAttrsListener( + SystemBarAttributesListener systemBarAttributesListener); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java index b3bef07cb820..c4e7a8a2c17b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java @@ -53,10 +53,12 @@ import com.android.systemui.statusbar.notification.stack.NotificationStackScroll import com.android.systemui.statusbar.phone.KeyguardBottomAreaView; import com.android.systemui.statusbar.phone.LetterboxAppearanceCalculator; import com.android.systemui.statusbar.phone.NotificationIconAreaController; +import com.android.systemui.statusbar.phone.StatusBarBoundsProvider; import com.android.systemui.statusbar.phone.StatusBarHideIconsForBouncerManager; import com.android.systemui.statusbar.phone.StatusBarIconController; import com.android.systemui.statusbar.phone.StatusBarLocationPublisher; import com.android.systemui.statusbar.phone.StatusIconContainer; +import com.android.systemui.statusbar.phone.SystemBarAttributesListener; import com.android.systemui.statusbar.phone.TapAgainView; import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragment; import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragmentLogger; @@ -258,6 +260,11 @@ public abstract class StatusBarViewModule { LetterboxAppearanceCalculator letterboxAppearanceCalculator ); + @Binds + @IntoSet + abstract StatusBarBoundsProvider.BoundsChangeListener sysBarAttrsListenerAsBoundsListener( + SystemBarAttributesListener systemBarAttributesListener); + /** * Creates a new {@link CollapsedStatusBarFragment}. * diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java index d79f3361408b..7b7a48be5b17 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java @@ -22,26 +22,28 @@ import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyZeroInteractions; import static org.mockito.Mockito.when; import android.app.StatusBarManager; import android.os.PowerManager; import android.os.Vibrator; import android.testing.AndroidTestingRunner; +import android.view.InsetsVisibilities; import androidx.test.filters.SmallTest; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.testing.FakeMetricsLogger; +import com.android.internal.statusbar.LetterboxDetails; +import com.android.internal.view.AppearanceRegion; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.SysuiTestCase; import com.android.systemui.assist.AssistManager; import com.android.systemui.keyguard.WakefulnessLifecycle; import com.android.systemui.shade.NotificationPanelViewController; -import com.android.systemui.shade.NotificationShadeWindowView; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.DisableFlagsLogger; -import com.android.systemui.statusbar.StatusBarStateControllerImpl; import com.android.systemui.statusbar.VibratorHelper; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController; import com.android.systemui.statusbar.policy.DeviceProvisionedController; @@ -60,6 +62,7 @@ import java.util.Optional; @SmallTest @RunWith(AndroidTestingRunner.class) public class CentralSurfacesCommandQueueCallbacksTest extends SysuiTestCase { + @Mock private CentralSurfaces mCentralSurfaces; @Mock private ShadeController mShadeController; @Mock private CommandQueue mCommandQueue; @@ -74,14 +77,12 @@ public class CentralSurfacesCommandQueueCallbacksTest extends SysuiTestCase { @Mock private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager; @Mock private AssistManager mAssistManager; @Mock private DozeServiceHost mDozeServiceHost; - @Mock private StatusBarStateControllerImpl mStatusBarStateController; - @Mock private NotificationShadeWindowView mNotificationShadeWindowView; @Mock private NotificationStackScrollLayoutController mNotificationStackScrollLayoutController; @Mock private PowerManager mPowerManager; @Mock private VibratorHelper mVibratorHelper; @Mock private Vibrator mVibrator; - @Mock private LightBarController mLightBarController; @Mock private StatusBarHideIconsForBouncerManager mStatusBarHideIconsForBouncerManager; + @Mock private SystemBarAttributesListener mSystemBarAttributesListener; CentralSurfacesCommandQueueCallbacks mSbcqCallbacks; @@ -106,16 +107,14 @@ public class CentralSurfacesCommandQueueCallbacksTest extends SysuiTestCase { mStatusBarKeyguardViewManager, mAssistManager, mDozeServiceHost, - mStatusBarStateController, - mNotificationShadeWindowView, mNotificationStackScrollLayoutController, mStatusBarHideIconsForBouncerManager, mPowerManager, mVibratorHelper, Optional.of(mVibrator), - mLightBarController, new DisableFlagsLogger(), - DEFAULT_DISPLAY); + DEFAULT_DISPLAY, + mSystemBarAttributesListener); when(mDeviceProvisionedController.isCurrentUserSetup()).thenReturn(true); when(mRemoteInputQuickSettingsDisabler.adjustDisableFlags(anyInt())) @@ -170,5 +169,59 @@ public class CentralSurfacesCommandQueueCallbacksTest extends SysuiTestCase { verify(mDozeServiceHost).setAlwaysOnSuppressed(false); } + @Test + public void onSystemBarAttributesChanged_forwardsToSysBarAttrsListener() { + int displayId = DEFAULT_DISPLAY; + int appearance = 123; + AppearanceRegion[] appearanceRegions = new AppearanceRegion[]{}; + boolean navbarColorManagedByIme = true; + int behavior = 456; + InsetsVisibilities requestedVisibilities = new InsetsVisibilities(); + String packageName = "test package name"; + LetterboxDetails[] letterboxDetails = new LetterboxDetails[]{}; + + mSbcqCallbacks.onSystemBarAttributesChanged( + displayId, + appearance, + appearanceRegions, + navbarColorManagedByIme, + behavior, + requestedVisibilities, + packageName, + letterboxDetails); + + verify(mSystemBarAttributesListener).onSystemBarAttributesChanged( + displayId, + appearance, + appearanceRegions, + navbarColorManagedByIme, + behavior, + requestedVisibilities, + packageName, + letterboxDetails + ); + } + @Test + public void onSystemBarAttributesChanged_differentDisplayId_doesNotForwardToAttrsListener() { + int appearance = 123; + AppearanceRegion[] appearanceRegions = new AppearanceRegion[]{}; + boolean navbarColorManagedByIme = true; + int behavior = 456; + InsetsVisibilities requestedVisibilities = new InsetsVisibilities(); + String packageName = "test package name"; + LetterboxDetails[] letterboxDetails = new LetterboxDetails[]{}; + + mSbcqCallbacks.onSystemBarAttributesChanged( + DEFAULT_DISPLAY + 1, + appearance, + appearanceRegions, + navbarColorManagedByIme, + behavior, + requestedVisibilities, + packageName, + letterboxDetails); + + verifyZeroInteractions(mSystemBarAttributesListener); + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/SystemBarAttributesListenerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/SystemBarAttributesListenerTest.kt new file mode 100644 index 000000000000..fa7b2599c108 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/SystemBarAttributesListenerTest.kt @@ -0,0 +1,250 @@ +package com.android.systemui.statusbar.phone + +import android.graphics.Rect +import android.testing.AndroidTestingRunner +import android.view.Display +import android.view.InsetsVisibilities +import android.view.WindowInsetsController +import android.view.WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS +import android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS +import android.view.WindowInsetsController.APPEARANCE_LOW_PROFILE_BARS +import android.view.WindowInsetsController.Appearance +import androidx.test.filters.SmallTest +import com.android.internal.statusbar.LetterboxDetails +import com.android.internal.view.AppearanceRegion +import com.android.systemui.SysuiTestCase +import com.android.systemui.dump.DumpManager +import com.android.systemui.flags.FeatureFlags +import com.android.systemui.flags.Flags +import com.android.systemui.statusbar.SysuiStatusBarStateController +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.ArgumentMatchers.any +import org.mockito.ArgumentMatchers.anyBoolean +import org.mockito.ArgumentMatchers.anyInt +import org.mockito.ArgumentMatchers.eq +import org.mockito.Mock +import org.mockito.Mockito +import org.mockito.Mockito.reset +import org.mockito.Mockito.verify +import org.mockito.Mockito.verifyZeroInteractions +import org.mockito.Mockito.`when` as whenever +import org.mockito.MockitoAnnotations + +@SmallTest +@RunWith(AndroidTestingRunner::class) +class SystemBarAttributesListenerTest : SysuiTestCase() { + + @Mock private lateinit var dumpManager: DumpManager + @Mock private lateinit var lightBarController: LightBarController + @Mock private lateinit var statusBarStateController: SysuiStatusBarStateController + @Mock private lateinit var letterboxAppearanceCalculator: LetterboxAppearanceCalculator + @Mock private lateinit var featureFlags: FeatureFlags + @Mock private lateinit var centralSurfaces: CentralSurfaces + + private lateinit var sysBarAttrsListener: SystemBarAttributesListener + + @Before + fun setUp() { + MockitoAnnotations.initMocks(this) + + whenever( + letterboxAppearanceCalculator.getLetterboxAppearance( + anyInt(), anyObject(), anyObject())) + .thenReturn(TEST_LETTERBOX_APPEARANCE) + + sysBarAttrsListener = + SystemBarAttributesListener( + centralSurfaces, + featureFlags, + letterboxAppearanceCalculator, + statusBarStateController, + lightBarController, + dumpManager) + } + + @Test + fun onSysBarAttrsChanged_forwardsAppearanceToCentralSurfaces() { + val appearance = APPEARANCE_LIGHT_STATUS_BARS or APPEARANCE_LIGHT_NAVIGATION_BARS + + changeSysBarAttrs(appearance) + + verify(centralSurfaces).setAppearance(appearance) + } + + @Test + fun onSysBarAttrsChanged_flagTrue_forwardsLetterboxAppearanceToCentralSurfaces() { + whenever(featureFlags.isEnabled(Flags.STATUS_BAR_LETTERBOX_APPEARANCE)).thenReturn(true) + + changeSysBarAttrs(TEST_APPEARANCE, TEST_LETTERBOX_DETAILS) + + verify(centralSurfaces).setAppearance(TEST_LETTERBOX_APPEARANCE.appearance) + } + + @Test + fun onSysBarAttrsChanged_flagTrue_noLetterbox_forwardsOriginalAppearanceToCtrlSrfcs() { + whenever(featureFlags.isEnabled(Flags.STATUS_BAR_LETTERBOX_APPEARANCE)).thenReturn(true) + + changeSysBarAttrs(TEST_APPEARANCE, arrayOf<LetterboxDetails>()) + + verify(centralSurfaces).setAppearance(TEST_APPEARANCE) + } + + @Test + fun onSysBarAttrsChanged_forwardsAppearanceToStatusBarStateController() { + changeSysBarAttrs(TEST_APPEARANCE) + + verify(statusBarStateController) + .setSystemBarAttributes(eq(TEST_APPEARANCE), anyInt(), any(), any()) + } + + @Test + fun onSysBarAttrsChanged_flagTrue_forwardsLetterboxAppearanceToStatusBarStateCtrl() { + whenever(featureFlags.isEnabled(Flags.STATUS_BAR_LETTERBOX_APPEARANCE)).thenReturn(true) + + changeSysBarAttrs(TEST_APPEARANCE, TEST_LETTERBOX_DETAILS) + + verify(statusBarStateController) + .setSystemBarAttributes( + eq(TEST_LETTERBOX_APPEARANCE.appearance), anyInt(), any(), any()) + } + + @Test + fun onSysBarAttrsChanged_forwardsAppearanceToLightBarController() { + changeSysBarAttrs(TEST_APPEARANCE, TEST_APPEARANCE_REGIONS) + + verify(lightBarController) + .onStatusBarAppearanceChanged( + eq(TEST_APPEARANCE_REGIONS), anyBoolean(), anyInt(), anyBoolean()) + } + + @Test + fun onSysBarAttrsChanged_flagTrue_forwardsLetterboxAppearanceToLightBarController() { + whenever(featureFlags.isEnabled(Flags.STATUS_BAR_LETTERBOX_APPEARANCE)).thenReturn(true) + + changeSysBarAttrs(TEST_APPEARANCE, TEST_APPEARANCE_REGIONS, TEST_LETTERBOX_DETAILS) + + verify(lightBarController) + .onStatusBarAppearanceChanged( + eq(TEST_LETTERBOX_APPEARANCE.appearanceRegions), + anyBoolean(), + anyInt(), + anyBoolean()) + } + + @Test + fun onStatusBarBoundsChanged_forwardsLetterboxAppearanceToStatusBarStateController() { + whenever(featureFlags.isEnabled(Flags.STATUS_BAR_LETTERBOX_APPEARANCE)).thenReturn(true) + changeSysBarAttrs(TEST_APPEARANCE, TEST_APPEARANCE_REGIONS, TEST_LETTERBOX_DETAILS) + reset(centralSurfaces, lightBarController, statusBarStateController) + + sysBarAttrsListener.onStatusBarBoundsChanged() + + verify(statusBarStateController) + .setSystemBarAttributes( + eq(TEST_LETTERBOX_APPEARANCE.appearance), anyInt(), any(), any()) + } + + @Test + fun onStatusBarBoundsChanged_forwardsLetterboxAppearanceToLightBarController() { + whenever(featureFlags.isEnabled(Flags.STATUS_BAR_LETTERBOX_APPEARANCE)).thenReturn(true) + changeSysBarAttrs(TEST_APPEARANCE, TEST_APPEARANCE_REGIONS, TEST_LETTERBOX_DETAILS) + reset(centralSurfaces, lightBarController, statusBarStateController) + + sysBarAttrsListener.onStatusBarBoundsChanged() + + verify(lightBarController) + .onStatusBarAppearanceChanged( + eq(TEST_LETTERBOX_APPEARANCE.appearanceRegions), + anyBoolean(), + anyInt(), + anyBoolean()) + } + + @Test + fun onStatusBarBoundsChanged_forwardsLetterboxAppearanceToCentralSurfaces() { + whenever(featureFlags.isEnabled(Flags.STATUS_BAR_LETTERBOX_APPEARANCE)).thenReturn(true) + changeSysBarAttrs(TEST_APPEARANCE, TEST_APPEARANCE_REGIONS, TEST_LETTERBOX_DETAILS) + reset(centralSurfaces, lightBarController, statusBarStateController) + + sysBarAttrsListener.onStatusBarBoundsChanged() + + verify(centralSurfaces).setAppearance(TEST_LETTERBOX_APPEARANCE.appearance) + } + + @Test + fun onStatusBarBoundsChanged_previousCallEmptyLetterbox_doesNothing() { + whenever(featureFlags.isEnabled(Flags.STATUS_BAR_LETTERBOX_APPEARANCE)).thenReturn(true) + changeSysBarAttrs(TEST_APPEARANCE, TEST_APPEARANCE_REGIONS, arrayOf()) + reset(centralSurfaces, lightBarController, statusBarStateController) + + sysBarAttrsListener.onStatusBarBoundsChanged() + + verifyZeroInteractions(centralSurfaces, lightBarController, statusBarStateController) + } + + @Test + fun onStatusBarBoundsChanged_flagFalse_doesNothing() { + whenever(featureFlags.isEnabled(Flags.STATUS_BAR_LETTERBOX_APPEARANCE)).thenReturn(false) + changeSysBarAttrs(TEST_APPEARANCE, TEST_APPEARANCE_REGIONS, TEST_LETTERBOX_DETAILS) + reset(centralSurfaces, lightBarController, statusBarStateController) + + sysBarAttrsListener.onStatusBarBoundsChanged() + + verifyZeroInteractions(centralSurfaces, lightBarController, statusBarStateController) + } + + private fun changeSysBarAttrs(@Appearance appearance: Int) { + changeSysBarAttrs(appearance, arrayOf<LetterboxDetails>()) + } + + private fun changeSysBarAttrs( + @Appearance appearance: Int, + letterboxDetails: Array<LetterboxDetails> + ) { + changeSysBarAttrs(appearance, arrayOf(), letterboxDetails) + } + + private fun changeSysBarAttrs( + @Appearance appearance: Int, + appearanceRegions: Array<AppearanceRegion> + ) { + changeSysBarAttrs(appearance, appearanceRegions, arrayOf()) + } + + private fun changeSysBarAttrs( + @Appearance appearance: Int, + appearanceRegions: Array<AppearanceRegion>, + letterboxDetails: Array<LetterboxDetails> + ) { + sysBarAttrsListener.onSystemBarAttributesChanged( + Display.DEFAULT_DISPLAY, + appearance, + appearanceRegions, + /* navbarColorManagedByIme= */ false, + WindowInsetsController.BEHAVIOR_DEFAULT, + InsetsVisibilities(), + "package name", + letterboxDetails) + } + + companion object { + private const val TEST_APPEARANCE = + APPEARANCE_LIGHT_STATUS_BARS or APPEARANCE_LIGHT_NAVIGATION_BARS + private val TEST_APPEARANCE_REGION = AppearanceRegion(TEST_APPEARANCE, Rect(0, 0, 150, 300)) + private val TEST_APPEARANCE_REGIONS = arrayOf(TEST_APPEARANCE_REGION) + private val TEST_LETTERBOX_DETAILS = + arrayOf( + LetterboxDetails( + /* letterboxInnerBounds= */ Rect(0, 0, 0, 0), + /* letterboxFullBounds= */ Rect(0, 0, 0, 0), + /* appAppearance= */ 0)) + private val TEST_LETTERBOX_APPEARANCE = + LetterboxAppearance(/* appearance= */ APPEARANCE_LOW_PROFILE_BARS, arrayOf()) + } +} + +private fun <T> anyObject(): T { + return Mockito.anyObject<T>() +} diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java index 71b1bc2e24bc..bec3754536e2 100644 --- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java +++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java @@ -1207,7 +1207,7 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D private int mImeBackDisposition = 0; private boolean mShowImeSwitcher = false; private IBinder mImeToken = null; - private LetterboxDetails[] mLetterboxDetails; + private LetterboxDetails[] mLetterboxDetails = new LetterboxDetails[0]; private void setBarAttributes(@Appearance int appearance, AppearanceRegion[] appearanceRegions, boolean navbarColorManagedByIme, |