Start using LetterboxAppearanceCalculator in SysUI

Start using LetterboxAppearanceCalculator in
CentralSurfacesCommandQueueCallbacks, to override the status bar
appearance when apps are letterboxed.

+ Flag guarded for now
+ Also refactors all the logic that was in onSysBarAttrsChanged into its
  own class, to avoid having much logic and state in the
  CentralSurfacesCommandQueueCallbacks class

Test: CentralSurfacesCommandQueueCallbacksTest.java
Test: SystemBarAttributesListenerTest.kt
Test: Manually
Bug: 238741157
Change-Id: I31e0fa200b5da7d46a82712f5b69c4d874de72f8
This commit is contained in:
Christian Go??llner
2022-07-25 14:20:45 +02:00
parent 4c08e92742
commit 997fb3121f
7 changed files with 500 additions and 31 deletions

View File

@@ -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

View File

@@ -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()
}

View File

@@ -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);
}

View File

@@ -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}.
*

View File

@@ -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);
}
}

View File

@@ -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>()
}

View File

@@ -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,