summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/hardware/input/InputSettings.java51
-rw-r--r--core/java/android/provider/Settings.java11
-rw-r--r--core/proto/android/providers/settings/system.proto1
-rw-r--r--media/java/android/media/quality/MediaQualityManager.java18
-rw-r--r--packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java1
-rw-r--r--packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java1
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/DisplayWindowPropertiesRepositoryImplTest.kt50
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/PerDisplayStoreImplTest.kt6
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/core/StatusBarInitializerTest.kt4
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/LightBarControllerStoreImplTest.kt6
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/MultiDisplayDarkIconDispatcherStoreTest.kt4
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/MultiDisplayStatusBarContentInsetsProviderStoreTest.kt6
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/MultiDisplayStatusBarModeRepositoryStoreTest.kt4
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/SystemEventChipAnimationControllerStoreImplTest.kt4
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModelTest.kt6
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/MultiDisplayAutoHideControllerStoreTest.kt4
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/domain/interactor/LightsOutInteractorTest.kt6
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/window/MultiDisplayStatusBarWindowControllerStoreTest.kt4
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/ThreeFingerGestureRecognizerTest.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayWindowPropertiesRepository.kt33
-rw-r--r--packages/SystemUI/src/com/android/systemui/display/data/repository/PerDisplayStore.kt39
-rw-r--r--packages/SystemUI/src/com/android/systemui/display/domain/interactor/DisplayWindowPropertiesInteractor.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java53
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeDialogContextInteractor.kt12
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/core/CommandQueueInitializer.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarStarter.kt17
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarInitializer.kt54
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarInitializerStore.kt19
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/data/repository/DarkIconDispatcherStore.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/data/repository/LightBarControllerStore.kt9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/data/repository/PrivacyDotViewControllerStore.kt9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/data/repository/PrivacyDotWindowControllerStore.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarConfigurationControllerStore.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarContentInsetsProviderStore.kt10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/data/repository/SystemEventChipAnimationControllerStore.kt14
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/events/MultiDisplaySystemEventChipAnimationController.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotWindowController.kt18
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/ConnectedDisplaysStatusBarNotificationIconViewStore.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModel.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideControllerStore.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarControllerImpl.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusOverlayHoverListener.kt40
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/data/repository/DarkIconRepository.kt20
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/domain/interactor/LightsOutInteractor.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java49
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/HomeStatusBarComponent.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/HomeStatusBarModule.java30
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowControllerImpl.java23
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowControllerStore.kt12
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java15
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java25
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestableContext.java8
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/core/FakeStatusBarInitializerFactory.kt4
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/core/StatusBarInitializerKosmos.kt4
-rw-r--r--services/core/java/com/android/server/input/InputSettingsObserver.java8
-rw-r--r--services/core/java/com/android/server/input/NativeInputManagerService.java5
-rw-r--r--services/core/java/com/android/server/notification/NotificationManagerService.java46
-rw-r--r--services/core/java/com/android/server/notification/flags.aconfig10
-rw-r--r--services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java3
-rw-r--r--services/core/java/com/android/server/wm/InsetsSourceProvider.java2
-rw-r--r--services/core/java/com/android/server/wm/InsetsStateController.java2
-rw-r--r--services/core/jni/com_android_server_input_InputManagerService.cpp26
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java74
-rw-r--r--services/usage/java/com/android/server/usage/UsageStatsService.java16
67 files changed, 754 insertions, 213 deletions
diff --git a/core/java/android/hardware/input/InputSettings.java b/core/java/android/hardware/input/InputSettings.java
index 34c88e91a979..8da630c95135 100644
--- a/core/java/android/hardware/input/InputSettings.java
+++ b/core/java/android/hardware/input/InputSettings.java
@@ -28,6 +28,7 @@ import static com.android.hardware.input.Flags.keyboardA11yStickyKeysFlag;
import static com.android.hardware.input.Flags.mouseScrollingAcceleration;
import static com.android.hardware.input.Flags.mouseReverseVerticalScrolling;
import static com.android.hardware.input.Flags.mouseSwapPrimaryButton;
+import static com.android.hardware.input.Flags.pointerAcceleration;
import static com.android.hardware.input.Flags.touchpadSystemGestureDisable;
import static com.android.hardware.input.Flags.touchpadThreeFingerTapShortcut;
import static com.android.hardware.input.Flags.touchpadVisualizer;
@@ -418,6 +419,15 @@ public class InputSettings {
}
/**
+ * Returns true if the feature flag for the pointer acceleration toggle is
+ * enabled.
+ * @hide
+ */
+ public static boolean isPointerAccelerationFeatureFlagEnabled() {
+ return pointerAcceleration();
+ }
+
+ /**
* Returns true if the touchpad visualizer is allowed to appear.
*
* @param context The application context.
@@ -720,6 +730,47 @@ public class InputSettings {
}
/**
+ * Whether cursor acceleration is enabled or not for connected mice.
+ *
+ * @param context The application context.
+ *
+ * @hide
+ */
+ public static boolean isMousePointerAccelerationEnabled(@NonNull Context context) {
+ if (!isPointerAccelerationFeatureFlagEnabled()) {
+ return false;
+ }
+
+ return Settings.System.getIntForUser(context.getContentResolver(),
+ Settings.System.MOUSE_POINTER_ACCELERATION_ENABLED, 1, UserHandle.USER_CURRENT)
+ == 1;
+ }
+
+ /**
+ * Sets whether mouse acceleration is enabled.
+ *
+ * When enabled, the mouse cursor moves farther when it is moved faster.
+ * When disabled, the mouse cursor speed becomes directly proportional to
+ * the speed at which the mouse is moved.
+ *
+ * @param context The application context.
+ * @param enabled Will enable mouse acceleration if true, disable it if
+ * false.
+ * @hide
+ */
+ @RequiresPermission(Manifest.permission.WRITE_SETTINGS)
+ public static void setMouseAccelerationEnabled(@NonNull Context context,
+ boolean enabled) {
+ if (!isPointerAccelerationFeatureFlagEnabled()) {
+ return;
+ }
+ Settings.System.putIntForUser(context.getContentResolver(),
+ Settings.System.MOUSE_POINTER_ACCELERATION_ENABLED, enabled ? 1 : 0,
+ UserHandle.USER_CURRENT);
+ }
+
+
+ /**
* Whether Accessibility bounce keys feature is enabled.
*
* <p>
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 2ad6669979b7..6e58780ac7a7 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -6362,6 +6362,16 @@ public final class Settings {
public static final String MOUSE_SCROLLING_ACCELERATION = "mouse_scrolling_acceleration";
/**
+ * Whether mouse acceleration is enabled.
+ *
+ * When enabled, the mouse cursor will accelerate as the mouse moves faster.
+ *
+ * @hide
+ */
+ public static final String MOUSE_POINTER_ACCELERATION_ENABLED =
+ "mouse_pointer_acceleration_enabled";
+
+ /**
* Pointer fill style, specified by
* {@link android.view.PointerIcon.PointerIconVectorStyleFill} constants.
*
@@ -6610,6 +6620,7 @@ public final class Settings {
PRIVATE_SETTINGS.add(DEFAULT_DEVICE_FONT_SCALE);
PRIVATE_SETTINGS.add(MOUSE_REVERSE_VERTICAL_SCROLLING);
PRIVATE_SETTINGS.add(MOUSE_SWAP_PRIMARY_BUTTON);
+ PRIVATE_SETTINGS.add(MOUSE_POINTER_ACCELERATION_ENABLED);
PRIVATE_SETTINGS.add(PREFERRED_REGION);
PRIVATE_SETTINGS.add(MOUSE_SCROLLING_ACCELERATION);
}
diff --git a/core/proto/android/providers/settings/system.proto b/core/proto/android/providers/settings/system.proto
index dd9bfa51c634..0d99200f4e6f 100644
--- a/core/proto/android/providers/settings/system.proto
+++ b/core/proto/android/providers/settings/system.proto
@@ -228,6 +228,7 @@ message SystemSettingsProto {
optional SettingProto reverse_vertical_scrolling = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
optional SettingProto swap_primary_button = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
optional SettingProto scrolling_acceleration = 3 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto pointer_acceleration_enabled = 4 [ (android.privacy).dest = DEST_AUTOMATIC ];
}
optional Mouse mouse = 38;
diff --git a/media/java/android/media/quality/MediaQualityManager.java b/media/java/android/media/quality/MediaQualityManager.java
index 7e87462b64de..166b388d9b7b 100644
--- a/media/java/android/media/quality/MediaQualityManager.java
+++ b/media/java/android/media/quality/MediaQualityManager.java
@@ -276,16 +276,19 @@ public final class MediaQualityManager {
/**
* Sets preferred default picture profile.
*
- * @param id the ID of the default profile. {@code null} to unset the default profile.
+ * @param pictureProfileId the ID of the default profile. {@code null} to unset the default
+ * profile.
* @return {@code true} if it's set successfully; {@code false} otherwise.
*
+ * @see PictureProfile#getProfileId()
+ *
* @hide
*/
@SystemApi
@RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_PICTURE_QUALITY_SERVICE)
- public boolean setDefaultPictureProfile(@Nullable String id) {
+ public boolean setDefaultPictureProfile(@Nullable String pictureProfileId) {
try {
- return mService.setDefaultPictureProfile(id, mUserHandle);
+ return mService.setDefaultPictureProfile(pictureProfileId, mUserHandle);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -467,16 +470,19 @@ public final class MediaQualityManager {
/**
* Sets preferred default sound profile.
*
- * @param id the ID of the default profile. {@code null} to unset the default profile.
+ * @param soundProfileId the ID of the default profile. {@code null} to unset the default
+ * profile.
* @return {@code true} if it's set successfully; {@code false} otherwise.
*
+ * @see SoundProfile#getProfileId()
+ *
* @hide
*/
@SystemApi
@RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_SOUND_QUALITY_SERVICE)
- public boolean setDefaultSoundProfile(@Nullable String id) {
+ public boolean setDefaultSoundProfile(@Nullable String soundProfileId) {
try {
- return mService.setDefaultSoundProfile(id, mUserHandle);
+ return mService.setDefaultSoundProfile(soundProfileId, mUserHandle);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java
index f1bbfc62681a..5b4ee8bdb339 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java
@@ -110,6 +110,7 @@ public class SystemSettings {
Settings.System.MOUSE_REVERSE_VERTICAL_SCROLLING,
Settings.System.MOUSE_SCROLLING_ACCELERATION,
Settings.System.MOUSE_SWAP_PRIMARY_BUTTON,
+ Settings.System.MOUSE_POINTER_ACCELERATION_ENABLED,
Settings.System.TOUCHPAD_POINTER_SPEED,
Settings.System.TOUCHPAD_NATURAL_SCROLLING,
Settings.System.TOUCHPAD_TAP_TO_CLICK,
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java
index 6abd9b73e26d..0432eeacec4d 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java
@@ -226,6 +226,7 @@ public class SystemSettingsValidators {
VALIDATORS.put(System.MOUSE_REVERSE_VERTICAL_SCROLLING, BOOLEAN_VALIDATOR);
VALIDATORS.put(System.MOUSE_SWAP_PRIMARY_BUTTON, BOOLEAN_VALIDATOR);
VALIDATORS.put(System.MOUSE_SCROLLING_ACCELERATION, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(System.MOUSE_POINTER_ACCELERATION_ENABLED, BOOLEAN_VALIDATOR);
VALIDATORS.put(System.TOUCHPAD_POINTER_SPEED, new InclusiveIntegerRangeValidator(-7, 7));
VALIDATORS.put(System.TOUCHPAD_NATURAL_SCROLLING, BOOLEAN_VALIDATOR);
VALIDATORS.put(System.TOUCHPAD_TAP_TO_CLICK, BOOLEAN_VALIDATOR);
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/DisplayWindowPropertiesRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/DisplayWindowPropertiesRepositoryImplTest.kt
index f68a1b5a17e9..eae5728f586d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/DisplayWindowPropertiesRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/DisplayWindowPropertiesRepositoryImplTest.kt
@@ -16,7 +16,7 @@
package com.android.systemui.display.data.repository
-import android.content.testableContext
+import android.content.Context
import android.platform.test.annotations.EnableFlags
import android.view.Display
import android.view.layoutInflater
@@ -24,6 +24,7 @@ import android.view.mockWindowManager
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
+import com.android.systemui.SysuiTestableContext
import com.android.systemui.display.shared.model.DisplayWindowProperties
import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.kosmos.testScope
@@ -36,8 +37,12 @@ import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.Mockito.doAnswer
+import org.mockito.kotlin.any
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock
+import org.mockito.kotlin.spy
+import org.mockito.kotlin.whenever
@EnableFlags(StatusBarConnectedDisplays.FLAG_NAME)
@RunWith(AndroidJUnit4::class)
@@ -48,7 +53,8 @@ class DisplayWindowPropertiesRepositoryImplTest : SysuiTestCase() {
private val fakeDisplayRepository = kosmos.displayRepository
private val testScope = kosmos.testScope
- private val applicationContext = kosmos.testableContext
+ private val applicationContext = spy(context)
+
private val applicationWindowManager = kosmos.mockWindowManager
private val applicationLayoutInflater = kosmos.layoutInflater
@@ -64,6 +70,22 @@ class DisplayWindowPropertiesRepositoryImplTest : SysuiTestCase() {
}
@Before
+ fun setUpContext() {
+ doAnswer { createContextForDisplay(it.arguments[0] as Display) }
+ .whenever(applicationContext)
+ .createWindowContext(any(), any(), any())
+ }
+
+ private fun createContextForDisplay(display: Display): Context {
+ if (display.displayId == BEING_REMOVED_DISPLAY_ID) {
+ // Simulate what happens when a display is being removed.
+ // Return a context with the same display id as the original context.
+ return mContext
+ }
+ return SysuiTestableContext(mContext).also { it.display = display }
+ }
+
+ @Before
fun start() {
repo.start()
}
@@ -72,6 +94,7 @@ class DisplayWindowPropertiesRepositoryImplTest : SysuiTestCase() {
fun addDisplays() = runBlocking {
fakeDisplayRepository.addDisplay(createDisplay(DEFAULT_DISPLAY_ID))
fakeDisplayRepository.addDisplay(createDisplay(NON_DEFAULT_DISPLAY_ID))
+ fakeDisplayRepository.addDisplay(createDisplay(BEING_REMOVED_DISPLAY_ID))
}
@Test
@@ -94,7 +117,7 @@ class DisplayWindowPropertiesRepositoryImplTest : SysuiTestCase() {
@Test
fun get_nonDefaultDisplayId_returnsNewStatusBarContext() =
testScope.runTest {
- val displayContext = repo.get(NON_DEFAULT_DISPLAY_ID, WINDOW_TYPE_FOO)
+ val displayContext = repo.get(NON_DEFAULT_DISPLAY_ID, WINDOW_TYPE_FOO)!!
assertThat(displayContext.context).isNotSameInstanceAs(applicationContext)
}
@@ -102,7 +125,7 @@ class DisplayWindowPropertiesRepositoryImplTest : SysuiTestCase() {
@Test
fun get_nonDefaultDisplayId_returnsNewWindowManager() =
testScope.runTest {
- val displayContext = repo.get(NON_DEFAULT_DISPLAY_ID, WINDOW_TYPE_FOO)
+ val displayContext = repo.get(NON_DEFAULT_DISPLAY_ID, WINDOW_TYPE_FOO)!!
assertThat(displayContext.windowManager).isNotSameInstanceAs(applicationWindowManager)
}
@@ -110,7 +133,7 @@ class DisplayWindowPropertiesRepositoryImplTest : SysuiTestCase() {
@Test
fun get_nonDefaultDisplayId_returnsNewLayoutInflater() =
testScope.runTest {
- val displayContext = repo.get(NON_DEFAULT_DISPLAY_ID, WINDOW_TYPE_FOO)
+ val displayContext = repo.get(NON_DEFAULT_DISPLAY_ID, WINDOW_TYPE_FOO)!!
assertThat(displayContext.layoutInflater).isNotSameInstanceAs(applicationLayoutInflater)
}
@@ -154,17 +177,26 @@ class DisplayWindowPropertiesRepositoryImplTest : SysuiTestCase() {
.isNotSameInstanceAs(displayContext)
}
- @Test(expected = IllegalArgumentException::class)
- fun get_nonExistingDisplayId_throws() =
- testScope.runTest { repo.get(NON_EXISTING_DISPLAY_ID, WINDOW_TYPE_FOO) }
+ @Test
+ fun get_nonExistingDisplayId_returnsNull() =
+ testScope.runTest {
+ assertThat(repo.get(NON_EXISTING_DISPLAY_ID, WINDOW_TYPE_FOO)).isNull()
+ }
+
+ @Test
+ fun get_displayBeingRemoved_returnsNull() =
+ testScope.runTest {
+ assertThat(repo.get(BEING_REMOVED_DISPLAY_ID, WINDOW_TYPE_FOO)).isNull()
+ }
private fun createDisplay(displayId: Int) =
- mock<Display> { on { getDisplayId() } doReturn displayId }
+ mock<Display> { on { getDisplayId() } doReturn (displayId) }
companion object {
private const val DEFAULT_DISPLAY_ID = Display.DEFAULT_DISPLAY
private const val NON_DEFAULT_DISPLAY_ID = DEFAULT_DISPLAY_ID + 1
private const val NON_EXISTING_DISPLAY_ID = DEFAULT_DISPLAY_ID + 2
+ private const val BEING_REMOVED_DISPLAY_ID = DEFAULT_DISPLAY_ID + 4
private const val WINDOW_TYPE_FOO = 123
private const val WINDOW_TYPE_BAR = 321
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/PerDisplayStoreImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/PerDisplayStoreImplTest.kt
index 6a0781b3580f..73957eb488d0 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/PerDisplayStoreImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/PerDisplayStoreImplTest.kt
@@ -80,9 +80,9 @@ class PerDisplayStoreImplTest : SysuiTestCase() {
assertThat(store.forDisplay(NON_DEFAULT_DISPLAY_ID)).isNotSameInstanceAs(instance)
}
- @Test(expected = IllegalArgumentException::class)
- fun forDisplay_nonExistingDisplayId_throws() =
- testScope.runTest { store.forDisplay(NON_EXISTING_DISPLAY_ID) }
+ @Test
+ fun forDisplay_nonExistingDisplayId_returnsNull() =
+ testScope.runTest { assertThat(store.forDisplay(NON_EXISTING_DISPLAY_ID)).isNull() }
@Test
fun forDisplay_afterDisplayRemoved_onDisplayRemovalActionInvoked() =
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/core/StatusBarInitializerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/core/StatusBarInitializerTest.kt
index 009b33b9f808..3515c5649ca0 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/core/StatusBarInitializerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/core/StatusBarInitializerTest.kt
@@ -26,10 +26,12 @@ import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.fragments.FragmentHostManager
import com.android.systemui.kosmos.useUnconfinedTestDispatcher
+import com.android.systemui.plugins.fakeDarkIconDispatcher
import com.android.systemui.statusbar.data.repository.fakeStatusBarModePerDisplayRepository
import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragment
import com.android.systemui.statusbar.phone.fragment.dagger.HomeStatusBarComponent
import com.android.systemui.statusbar.pipeline.shared.ui.composable.StatusBarRootFactory
+import com.android.systemui.statusbar.policy.statusBarConfigurationController
import com.android.systemui.statusbar.window.StatusBarWindowController
import com.android.systemui.statusbar.window.StatusBarWindowControllerStore
import com.android.systemui.testKosmos
@@ -77,6 +79,8 @@ class StatusBarInitializerTest : SysuiTestCase() {
componentFactory = mock(HomeStatusBarComponent.Factory::class.java),
creationListeners = setOf(),
statusBarModePerDisplayRepository = statusBarModePerDisplayRepository,
+ darkIconDispatcher = kosmos.fakeDarkIconDispatcher,
+ statusBarConfigurationController = kosmos.statusBarConfigurationController,
)
@Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/LightBarControllerStoreImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/LightBarControllerStoreImplTest.kt
index 18eef33813f6..884c35c3457d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/LightBarControllerStoreImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/LightBarControllerStoreImplTest.kt
@@ -51,7 +51,7 @@ class LightBarControllerStoreImplTest : SysuiTestCase() {
@Test
fun forDisplay_startsInstance() =
testScope.runTest {
- val instance = underTest.forDisplay(DEFAULT_DISPLAY)
+ val instance = underTest.forDisplay(DEFAULT_DISPLAY)!!
verify(instance).start()
}
@@ -59,7 +59,7 @@ class LightBarControllerStoreImplTest : SysuiTestCase() {
@Test
fun beforeDisplayRemoved_doesNotStopInstances() =
testScope.runTest {
- val instance = underTest.forDisplay(DEFAULT_DISPLAY)
+ val instance = underTest.forDisplay(DEFAULT_DISPLAY)!!
verify(instance, never()).stop()
}
@@ -67,7 +67,7 @@ class LightBarControllerStoreImplTest : SysuiTestCase() {
@Test
fun displayRemoved_stopsInstance() =
testScope.runTest {
- val instance = underTest.forDisplay(DEFAULT_DISPLAY)
+ val instance = underTest.forDisplay(DEFAULT_DISPLAY)!!
fakeDisplayRepository.removeDisplay(DEFAULT_DISPLAY)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/MultiDisplayDarkIconDispatcherStoreTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/MultiDisplayDarkIconDispatcherStoreTest.kt
index a2c3c66f4448..f37648a639df 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/MultiDisplayDarkIconDispatcherStoreTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/MultiDisplayDarkIconDispatcherStoreTest.kt
@@ -56,7 +56,7 @@ class MultiDisplayDarkIconDispatcherStoreTest : SysuiTestCase() {
@Test
fun beforeDisplayRemoved_doesNotStopInstances() =
testScope.runTest {
- val instance = underTest.forDisplay(DEFAULT_DISPLAY)
+ val instance = underTest.forDisplay(DEFAULT_DISPLAY)!!
verify(instance, never()).stop()
}
@@ -64,7 +64,7 @@ class MultiDisplayDarkIconDispatcherStoreTest : SysuiTestCase() {
@Test
fun displayRemoved_stopsInstance() =
testScope.runTest {
- val instance = underTest.forDisplay(DEFAULT_DISPLAY)
+ val instance = underTest.forDisplay(DEFAULT_DISPLAY)!!
fakeDisplayRepository.removeDisplay(DEFAULT_DISPLAY)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/MultiDisplayStatusBarContentInsetsProviderStoreTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/MultiDisplayStatusBarContentInsetsProviderStoreTest.kt
index 4a26fdf20e6e..e0a1f273aa44 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/MultiDisplayStatusBarContentInsetsProviderStoreTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/MultiDisplayStatusBarContentInsetsProviderStoreTest.kt
@@ -51,7 +51,7 @@ class MultiDisplayStatusBarContentInsetsProviderStoreTest : SysuiTestCase() {
@Test
fun forDisplay_startsInstances() =
testScope.runTest {
- val instance = underTest.forDisplay(DEFAULT_DISPLAY)
+ val instance = underTest.forDisplay(DEFAULT_DISPLAY)!!
verify(instance).start()
}
@@ -59,7 +59,7 @@ class MultiDisplayStatusBarContentInsetsProviderStoreTest : SysuiTestCase() {
@Test
fun beforeDisplayRemoved_doesNotStopInstances() =
testScope.runTest {
- val instance = underTest.forDisplay(DEFAULT_DISPLAY)
+ val instance = underTest.forDisplay(DEFAULT_DISPLAY)!!
verify(instance, never()).stop()
}
@@ -67,7 +67,7 @@ class MultiDisplayStatusBarContentInsetsProviderStoreTest : SysuiTestCase() {
@Test
fun displayRemoved_stopsInstance() =
testScope.runTest {
- val instance = underTest.forDisplay(DEFAULT_DISPLAY)
+ val instance = underTest.forDisplay(DEFAULT_DISPLAY)!!
fakeDisplayRepository.removeDisplay(DEFAULT_DISPLAY)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/MultiDisplayStatusBarModeRepositoryStoreTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/MultiDisplayStatusBarModeRepositoryStoreTest.kt
index a9920ec5e29b..11fd902fc50c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/MultiDisplayStatusBarModeRepositoryStoreTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/MultiDisplayStatusBarModeRepositoryStoreTest.kt
@@ -53,7 +53,7 @@ class MultiDisplayStatusBarModeRepositoryStoreTest : SysuiTestCase() {
@Test
fun forDisplay_startsInstance() =
testScope.runTest {
- val instance = underTest.forDisplay(DEFAULT_DISPLAY)
+ val instance = underTest.forDisplay(DEFAULT_DISPLAY)!!
verify(instance).start()
}
@@ -61,7 +61,7 @@ class MultiDisplayStatusBarModeRepositoryStoreTest : SysuiTestCase() {
@Test
fun displayRemoved_stopsInstance() =
testScope.runTest {
- val instance = underTest.forDisplay(DEFAULT_DISPLAY)
+ val instance = underTest.forDisplay(DEFAULT_DISPLAY)!!
fakeDisplayRepository.removeDisplay(DEFAULT_DISPLAY)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/SystemEventChipAnimationControllerStoreImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/SystemEventChipAnimationControllerStoreImplTest.kt
index e65c04c45382..3cc592c94678 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/SystemEventChipAnimationControllerStoreImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/SystemEventChipAnimationControllerStoreImplTest.kt
@@ -56,7 +56,7 @@ class SystemEventChipAnimationControllerStoreImplTest : SysuiTestCase() {
@Test
fun beforeDisplayRemoved_doesNotStopInstances() =
testScope.runTest {
- val instance = underTest.forDisplay(DEFAULT_DISPLAY)
+ val instance = underTest.forDisplay(DEFAULT_DISPLAY)!!
verify(instance, never()).stop()
}
@@ -64,7 +64,7 @@ class SystemEventChipAnimationControllerStoreImplTest : SysuiTestCase() {
@Test
fun displayRemoved_stopsInstance() =
testScope.runTest {
- val instance = underTest.forDisplay(DEFAULT_DISPLAY)
+ val instance = underTest.forDisplay(DEFAULT_DISPLAY)!!
fakeDisplayRepository.removeDisplay(DEFAULT_DISPLAY)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModelTest.kt
index be20bc1bf9d4..d86c6efce284 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModelTest.kt
@@ -225,7 +225,7 @@ class NotificationIconContainerStatusBarViewModelTest(flags: FlagsParameterizati
val displayId = 123
darkIconRepository.darkState(displayId).value =
SysuiDarkIconDispatcher.DarkChange(emptyList(), 0f, 0xAABBCC)
- val iconColors by collectLastValue(underTest.iconColors(displayId))
+ val iconColors by collectLastValue(underTest.iconColors(displayId)!!)
assertThat(iconColors).isNotNull()
assertThat(iconColors!!.tint).isEqualTo(0xAABBCC)
@@ -241,7 +241,7 @@ class NotificationIconContainerStatusBarViewModelTest(flags: FlagsParameterizati
val displayId = 321
darkIconRepository.darkState(displayId).value =
SysuiDarkIconDispatcher.DarkChange(listOf(Rect(0, 0, 5, 5)), 0f, 0xAABBCC)
- val iconColors by collectLastValue(underTest.iconColors(displayId))
+ val iconColors by collectLastValue(underTest.iconColors(displayId)!!)
val staticDrawableColor = iconColors?.staticDrawableColor(Rect(6, 6, 7, 7))
assertThat(staticDrawableColor).isEqualTo(DarkIconDispatcher.DEFAULT_ICON_TINT)
}
@@ -252,7 +252,7 @@ class NotificationIconContainerStatusBarViewModelTest(flags: FlagsParameterizati
val displayId = 987
darkIconRepository.darkState(displayId).value =
SysuiDarkIconDispatcher.DarkChange(listOf(Rect(0, 0, 5, 5)), 0f, 0xAABBCC)
- val iconColors by collectLastValue(underTest.iconColors(displayId))
+ val iconColors by collectLastValue(underTest.iconColors(displayId)!!)
assertThat(iconColors!!.staticDrawableColor(Rect(6, 6, 7, 7)))
.isEqualTo(DarkIconDispatcher.DEFAULT_ICON_TINT)
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/MultiDisplayAutoHideControllerStoreTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/MultiDisplayAutoHideControllerStoreTest.kt
index 90506a1b9a7f..d16372611e88 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/MultiDisplayAutoHideControllerStoreTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/MultiDisplayAutoHideControllerStoreTest.kt
@@ -56,7 +56,7 @@ class MultiDisplayAutoHideControllerStoreTest : SysuiTestCase() {
@Test
fun beforeDisplayRemoved_doesNotStopInstances() =
testScope.runTest {
- val instance = underTest.forDisplay(DEFAULT_DISPLAY)
+ val instance = underTest.forDisplay(DEFAULT_DISPLAY)!!
verify(instance, never()).stop()
}
@@ -64,7 +64,7 @@ class MultiDisplayAutoHideControllerStoreTest : SysuiTestCase() {
@Test
fun displayRemoved_stopsInstance() =
testScope.runTest {
- val instance = underTest.forDisplay(DEFAULT_DISPLAY)
+ val instance = underTest.forDisplay(DEFAULT_DISPLAY)!!
fakeDisplayRepository.removeDisplay(DEFAULT_DISPLAY)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/domain/interactor/LightsOutInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/domain/interactor/LightsOutInteractorTest.kt
index 2d9880a48f80..659d91a95aa8 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/domain/interactor/LightsOutInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/domain/interactor/LightsOutInteractorTest.kt
@@ -39,7 +39,7 @@ class LightsOutInteractorTest : SysuiTestCase() {
fun isLowProfile_lightsOutStatusBarMode_false() = runTest {
statusBarModeRepository.defaultDisplay.statusBarMode.value = StatusBarMode.LIGHTS_OUT
- val actual by collectLastValue(interactor.isLowProfile(DISPLAY_ID))
+ val actual by collectLastValue(interactor.isLowProfile(DISPLAY_ID)!!)
assertThat(actual).isTrue()
}
@@ -49,7 +49,7 @@ class LightsOutInteractorTest : SysuiTestCase() {
statusBarModeRepository.defaultDisplay.statusBarMode.value =
StatusBarMode.LIGHTS_OUT_TRANSPARENT
- val actual by collectLastValue(interactor.isLowProfile(DISPLAY_ID))
+ val actual by collectLastValue(interactor.isLowProfile(DISPLAY_ID)!!)
assertThat(actual).isTrue()
}
@@ -58,7 +58,7 @@ class LightsOutInteractorTest : SysuiTestCase() {
fun isLowProfile_transparentStatusBarMode_false() = runTest {
statusBarModeRepository.defaultDisplay.statusBarMode.value = StatusBarMode.TRANSPARENT
- val actual by collectLastValue(interactor.isLowProfile(DISPLAY_ID))
+ val actual by collectLastValue(interactor.isLowProfile(DISPLAY_ID)!!)
assertThat(actual).isFalse()
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/window/MultiDisplayStatusBarWindowControllerStoreTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/window/MultiDisplayStatusBarWindowControllerStoreTest.kt
index 7a9d0179b239..769f012bfdf7 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/window/MultiDisplayStatusBarWindowControllerStoreTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/window/MultiDisplayStatusBarWindowControllerStoreTest.kt
@@ -53,7 +53,7 @@ class MultiDisplayStatusBarWindowControllerStoreTest : SysuiTestCase() {
@Test
fun beforeDisplayRemoved_doesNotStopInstances() =
testScope.runTest {
- val instance = underTest.forDisplay(DEFAULT_DISPLAY)
+ val instance = underTest.forDisplay(DEFAULT_DISPLAY)!!
verify(instance, never()).stop()
}
@@ -61,7 +61,7 @@ class MultiDisplayStatusBarWindowControllerStoreTest : SysuiTestCase() {
@Test
fun displayRemoved_stopsInstance() =
testScope.runTest {
- val instance = underTest.forDisplay(DEFAULT_DISPLAY)
+ val instance = underTest.forDisplay(DEFAULT_DISPLAY)!!
fakeDisplayRepository.removeDisplay(DEFAULT_DISPLAY)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/ThreeFingerGestureRecognizerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/ThreeFingerGestureRecognizerTest.kt
index 8972f3ec71af..8b526bb1d55b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/ThreeFingerGestureRecognizerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/ThreeFingerGestureRecognizerTest.kt
@@ -30,12 +30,14 @@ import com.android.systemui.touchpad.tutorial.ui.gesture.RecentAppsGestureRecogn
import com.android.systemui.touchpad.ui.gesture.FakeVelocityTracker
import com.google.common.truth.Truth.assertThat
import org.junit.Before
+import org.junit.Ignore
import org.junit.Test
import org.junit.runner.RunWith
import platform.test.runner.parameterized.ParameterizedAndroidJunit4
import platform.test.runner.parameterized.Parameters
@SmallTest
+@Ignore("b/386412866")
@RunWith(ParameterizedAndroidJunit4::class)
class ThreeFingerGestureRecognizerTest(
private val recognizer: GestureRecognizer,
diff --git a/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayWindowPropertiesRepository.kt b/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayWindowPropertiesRepository.kt
index f310b30c1a81..3390640fa6c6 100644
--- a/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayWindowPropertiesRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayWindowPropertiesRepository.kt
@@ -18,6 +18,8 @@ package com.android.systemui.display.data.repository
import android.annotation.SuppressLint
import android.content.Context
+import android.os.Bundle
+import android.util.Log
import android.view.Display
import android.view.LayoutInflater
import android.view.WindowManager
@@ -39,14 +41,13 @@ import kotlinx.coroutines.CoroutineScope
interface DisplayWindowPropertiesRepository {
/**
- * Returns a [DisplayWindowProperties] instance for a given display id and window type.
- *
- * @throws IllegalArgumentException if no display with the given display id exists.
+ * Returns a [DisplayWindowProperties] instance for a given display id and window type, or null
+ * if no display with the given display id exists.
*/
fun get(
displayId: Int,
@WindowManager.LayoutParams.WindowType windowType: Int,
- ): DisplayWindowProperties
+ ): DisplayWindowProperties?
}
@SysUISingleton
@@ -72,12 +73,10 @@ constructor(
override fun get(
displayId: Int,
@WindowManager.LayoutParams.WindowType windowType: Int,
- ): DisplayWindowProperties {
- val display =
- displayRepository.getDisplay(displayId)
- ?: throw IllegalArgumentException("Display with id $displayId doesn't exist")
+ ): DisplayWindowProperties? {
+ val display = displayRepository.getDisplay(displayId) ?: return null
return properties.get(displayId, windowType)
- ?: create(display, windowType).also { properties.put(displayId, windowType, it) }
+ ?: create(display, windowType)?.also { properties.put(displayId, windowType, it) }
}
override fun start() {
@@ -88,7 +87,7 @@ constructor(
}
}
- private fun create(display: Display, windowType: Int): DisplayWindowProperties {
+ private fun create(display: Display, windowType: Int): DisplayWindowProperties? {
val displayId = display.displayId
return if (displayId == Display.DEFAULT_DISPLAY) {
// For the default display, we can just reuse the global/application properties.
@@ -102,6 +101,14 @@ constructor(
)
} else {
val context = createWindowContext(display, windowType)
+ if (context.displayId != display.displayId) {
+ Log.e(
+ TAG,
+ "Returning null because the new context doesn't have the desired display id " +
+ "${display.displayId}. Display was already removed.",
+ )
+ return null
+ }
@SuppressLint("NonInjectedService") // Need to manually get the service
val windowManager = context.getSystemService(WindowManager::class.java) as WindowManager
val layoutInflater = LayoutInflater.from(context)
@@ -110,11 +117,15 @@ constructor(
}
private fun createWindowContext(display: Display, windowType: Int): Context =
- globalContext.createWindowContext(display, windowType, /* options= */ null).also {
+ globalContext.createWindowContext(display, windowType, /* options= */ Bundle.EMPTY).also {
it.setTheme(R.style.Theme_SystemUI)
}
override fun dump(pw: PrintWriter, args: Array<out String>) {
pw.write("perDisplayContexts: $properties")
}
+
+ private companion object {
+ const val TAG = "DisplayWindowPropsRepo"
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/display/data/repository/PerDisplayStore.kt b/packages/SystemUI/src/com/android/systemui/display/data/repository/PerDisplayStore.kt
index 711534f9dbf0..564588c159bd 100644
--- a/packages/SystemUI/src/com/android/systemui/display/data/repository/PerDisplayStore.kt
+++ b/packages/SystemUI/src/com/android/systemui/display/data/repository/PerDisplayStore.kt
@@ -16,6 +16,7 @@
package com.android.systemui.display.data.repository
+import android.util.Log
import android.view.Display
import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.systemui.CoreStartable
@@ -36,12 +37,10 @@ interface PerDisplayStore<T> {
val defaultDisplay: T
/**
- * Returns an instance for a specific display id.
- *
- * @throws IllegalArgumentException if [displayId] doesn't match the id of any existing
- * displays.
+ * Returns an instance for a specific display id, or null if [displayId] doesn't match the id of
+ * any existing displays.
*/
- fun forDisplay(displayId: Int): T
+ fun forDisplay(displayId: Int): T?
}
abstract class PerDisplayStoreImpl<T>(
@@ -58,7 +57,7 @@ abstract class PerDisplayStoreImpl<T>(
* Note that the id of the default display is [Display.DEFAULT_DISPLAY].
*/
override val defaultDisplay: T
- get() = forDisplay(Display.DEFAULT_DISPLAY)
+ get() = forDisplay(Display.DEFAULT_DISPLAY)!!
/**
* Returns an instance for a specific display id.
@@ -66,16 +65,30 @@ abstract class PerDisplayStoreImpl<T>(
* @throws IllegalArgumentException if [displayId] doesn't match the id of any existing
* displays.
*/
- override fun forDisplay(displayId: Int): T {
+ override fun forDisplay(displayId: Int): T? {
if (displayRepository.getDisplay(displayId) == null) {
- throw IllegalArgumentException("Display with id $displayId doesn't exist.")
+ Log.e(TAG, "<${instanceClass.simpleName}>: Display with id $displayId doesn't exist.")
+ return null
}
- return perDisplayInstances.computeIfAbsent(displayId) {
- createInstanceForDisplay(displayId)
+ synchronized(perDisplayInstances) {
+ val existingInstance = perDisplayInstances[displayId]
+ if (existingInstance != null) {
+ return existingInstance
+ }
+ val newInstance = createInstanceForDisplay(displayId)
+ if (newInstance == null) {
+ Log.e(
+ TAG,
+ "<${instanceClass.simpleName}> returning null because createInstanceForDisplay($displayId) returned null.",
+ )
+ } else {
+ perDisplayInstances[displayId] = newInstance
+ }
+ return newInstance
}
}
- protected abstract fun createInstanceForDisplay(displayId: Int): T
+ protected abstract fun createInstanceForDisplay(displayId: Int): T?
override fun start() {
val instanceType = instanceClass.simpleName
@@ -98,6 +111,10 @@ abstract class PerDisplayStoreImpl<T>(
override fun dump(pw: PrintWriter, args: Array<out String>) {
pw.println(perDisplayInstances)
}
+
+ private companion object {
+ const val TAG = "PerDisplayStore"
+ }
}
class SingleDisplayStore<T>(defaultInstance: T) : PerDisplayStore<T> {
diff --git a/packages/SystemUI/src/com/android/systemui/display/domain/interactor/DisplayWindowPropertiesInteractor.kt b/packages/SystemUI/src/com/android/systemui/display/domain/interactor/DisplayWindowPropertiesInteractor.kt
index 22e467bd5e3c..99c9ca98bae9 100644
--- a/packages/SystemUI/src/com/android/systemui/display/domain/interactor/DisplayWindowPropertiesInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/display/domain/interactor/DisplayWindowPropertiesInteractor.kt
@@ -33,7 +33,7 @@ interface DisplayWindowPropertiesInteractor {
*
* @throws IllegalArgumentException if no display with the given display id exists.
*/
- fun getForStatusBar(displayId: Int): DisplayWindowProperties
+ fun getForStatusBar(displayId: Int): DisplayWindowProperties?
}
@SysUISingleton
@@ -42,7 +42,7 @@ class DisplayWindowPropertiesInteractorImpl
constructor(private val repo: DisplayWindowPropertiesRepository) :
DisplayWindowPropertiesInteractor {
- override fun getForStatusBar(displayId: Int): DisplayWindowProperties {
+ override fun getForStatusBar(displayId: Int): DisplayWindowProperties? {
return repo.get(displayId, TYPE_STATUS_BAR)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java
index c895732f79f6..f9df67661b49 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java
@@ -720,9 +720,24 @@ public class NavigationBar extends ViewController<NavigationBarView> implements
if (DEBUG) Log.v(TAG, "addNavigationBar: about to add " + mView);
- mViewCaptureAwareWindowManager.addView(mFrame,
- getBarLayoutParams(mContext.getResources().getConfiguration().windowConfiguration
- .getRotation()));
+ try {
+ mViewCaptureAwareWindowManager.addView(
+ mFrame,
+ getBarLayoutParams(
+ mContext.getResources()
+ .getConfiguration()
+ .windowConfiguration
+ .getRotation()));
+ } catch (WindowManager.InvalidDisplayException e) {
+ // Wrapping this in a try/catch to avoid crashes when a display is instantly removed
+ // after being added, and initialization hasn't finished yet.
+ Log.e(
+ TAG,
+ "Unable to add view to WindowManager. Display with id "
+ + mDisplayId
+ + " does not exist anymore",
+ e);
+ }
mDisplayId = mContext.getDisplayId();
mIsOnDefaultDisplay = mDisplayId == mDisplayTracker.getDefaultDisplayId();
@@ -764,6 +779,15 @@ public class NavigationBar extends ViewController<NavigationBarView> implements
Trace.beginSection("NavigationBar#removeViewImmediate");
try {
mViewCaptureAwareWindowManager.removeViewImmediate(mView.getRootView());
+ } catch (IllegalArgumentException e) {
+ // Wrapping this in a try/catch to avoid crashes when a display is instantly removed
+ // after being added, and initialization hasn't finished yet.
+ // When that happens, adding the View to WindowManager fails, and therefore removing
+ // it here will fail too, since it wasn't added in the first place.
+ Log.e(
+ TAG,
+ "Failed to removed view from WindowManager. The View wasn't attached.",
+ e);
} finally {
Trace.endSection();
}
@@ -859,7 +883,15 @@ public class NavigationBar extends ViewController<NavigationBarView> implements
if (mOrientationHandle != null) {
resetSecondaryHandle();
getBarTransitions().removeDarkIntensityListener(mOrientationHandleIntensityListener);
- mViewCaptureAwareWindowManager.removeView(mOrientationHandle);
+ try {
+ mViewCaptureAwareWindowManager.removeView(mOrientationHandle);
+ } catch (IllegalArgumentException e) {
+ // Wrapping this in a try/catch to avoid crashes when a display is instantly removed
+ // after being added, and initialization hasn't finished yet.
+ // When that happens, adding the View to WindowManager fails, and therefore removing
+ // it here will fail too, since it wasn't added in the first place.
+ Log.e(TAG, "Trying to remove a View that is not attached", e);
+ }
mOrientationHandle.getViewTreeObserver().removeOnGlobalLayoutListener(
mOrientationHandleGlobalLayoutListener);
}
@@ -930,7 +962,18 @@ public class NavigationBar extends ViewController<NavigationBarView> implements
mOrientationParams.setTitle("SecondaryHomeHandle" + mContext.getDisplayId());
mOrientationParams.privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION
| WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT;
- mViewCaptureAwareWindowManager.addView(mOrientationHandle, mOrientationParams);
+ try {
+ mViewCaptureAwareWindowManager.addView(mOrientationHandle, mOrientationParams);
+ } catch (WindowManager.InvalidDisplayException e) {
+ // Wrapping this in a try/catch to avoid crashes when a display is instantly removed
+ // after being added, and initialization hasn't finished yet.
+ Log.e(
+ TAG,
+ "Unable to add view to WindowManager. Display with id "
+ + mDisplayId
+ + " does not exist anymore",
+ e);
+ }
mOrientationHandle.setVisibility(View.GONE);
logNavbarOrientation("initSecondaryHomeHandleForRotation");
diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeDialogContextInteractor.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeDialogContextInteractor.kt
index 201dc0339a0a..4edba2785e89 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeDialogContextInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeDialogContextInteractor.kt
@@ -77,7 +77,17 @@ constructor(
private fun getContextOrDefault(displayId: Int): Context {
return try {
traceSection({ "Getting dialog context for displayId=$displayId" }) {
- displayWindowPropertyRepository.get().get(displayId, DIALOG_WINDOW_TYPE).context
+ val displayWindowProperties =
+ displayWindowPropertyRepository.get().get(displayId, DIALOG_WINDOW_TYPE)
+ if (displayWindowProperties == null) {
+ Log.e(
+ TAG,
+ "DisplayWindowPropertiesRepository returned null for display $displayId. Returning default one",
+ )
+ defaultContext
+ } else {
+ displayWindowProperties.context
+ }
}
} catch (e: Exception) {
// This can happen if the display was disconnected in the meantime.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/core/CommandQueueInitializer.kt b/packages/SystemUI/src/com/android/systemui/statusbar/core/CommandQueueInitializer.kt
index d24eddaf321f..d25ca285c53b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/core/CommandQueueInitializer.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/core/CommandQueueInitializer.kt
@@ -72,7 +72,7 @@ constructor(
private fun initializeStatusBarForDisplay(displayId: Int, result: RegisterStatusBarResult) {
if ((result.mTransientBarTypes and WindowInsets.Type.statusBars()) != 0) {
- statusBarModeRepository.forDisplay(displayId).showTransient()
+ statusBarModeRepository.forDisplay(displayId)?.showTransient()
}
val commandQueueCallbacks = commandQueueCallbacksLazy.get()
commandQueueCallbacks.onSystemBarAttributesChanged(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarStarter.kt b/packages/SystemUI/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarStarter.kt
index 9e9a38e87924..b057fb0433fe 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarStarter.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarStarter.kt
@@ -89,21 +89,26 @@ constructor(
}
private fun createAndStartOrchestratorForDisplay(displayId: Int) {
+ val statusBarModeRepository = statusBarModeRepositoryStore.forDisplay(displayId) ?: return
+ val statusBarInitializer = initializerStore.forDisplay(displayId) ?: return
+ val statusBarWindowController =
+ statusBarWindowControllerStore.forDisplay(displayId) ?: return
+ val autoHideController = autoHideControllerStore.forDisplay(displayId) ?: return
statusBarOrchestratorFactory
.create(
displayId,
displayScopeRepository.scopeForDisplay(displayId),
statusBarWindowStateRepositoryStore.forDisplay(displayId),
- statusBarModeRepositoryStore.forDisplay(displayId),
- initializerStore.forDisplay(displayId),
- statusBarWindowControllerStore.forDisplay(displayId),
- autoHideControllerStore.forDisplay(displayId),
+ statusBarModeRepository,
+ statusBarInitializer,
+ statusBarWindowController,
+ autoHideController,
)
.start()
}
private fun createAndStartInitializerForDisplay(displayId: Int) {
- statusBarInitializerStore.forDisplay(displayId).start()
+ statusBarInitializerStore.forDisplay(displayId)?.start()
}
private fun startPrivacyDotForDisplay(displayId: Int) {
@@ -111,6 +116,6 @@ constructor(
// For the default display, privacy dot is started via ScreenDecorations
return
}
- privacyDotWindowControllerStore.forDisplay(displayId).start()
+ privacyDotWindowControllerStore.forDisplay(displayId)?.start()
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarInitializer.kt b/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarInitializer.kt
index 4c54fc49e536..1e127ee054e7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarInitializer.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarInitializer.kt
@@ -20,9 +20,11 @@ import android.view.ViewGroup
import androidx.annotation.VisibleForTesting
import com.android.systemui.CoreStartable
import com.android.systemui.fragments.FragmentHostManager
+import com.android.systemui.plugins.DarkIconDispatcher
import com.android.systemui.res.R
import com.android.systemui.statusbar.core.StatusBarInitializer.OnStatusBarViewInitializedListener
import com.android.systemui.statusbar.core.StatusBarInitializer.OnStatusBarViewUpdatedListener
+import com.android.systemui.statusbar.data.repository.StatusBarConfigurationController
import com.android.systemui.statusbar.data.repository.StatusBarModePerDisplayRepository
import com.android.systemui.statusbar.phone.PhoneStatusBarTransitions
import com.android.systemui.statusbar.phone.PhoneStatusBarView
@@ -34,7 +36,6 @@ import com.android.systemui.statusbar.window.StatusBarWindowController
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
-import java.lang.IllegalStateException
import javax.inject.Provider
/**
@@ -75,6 +76,8 @@ interface StatusBarInitializer : CoreStartable {
fun create(
statusBarWindowController: StatusBarWindowController,
statusBarModePerDisplayRepository: StatusBarModePerDisplayRepository,
+ statusBarConfigurationController: StatusBarConfigurationController,
+ darkIconDispatcher: DarkIconDispatcher,
): StatusBarInitializer
}
}
@@ -84,6 +87,8 @@ class StatusBarInitializerImpl
constructor(
@Assisted private val statusBarWindowController: StatusBarWindowController,
@Assisted private val statusBarModePerDisplayRepository: StatusBarModePerDisplayRepository,
+ @Assisted private val statusBarConfigurationController: StatusBarConfigurationController,
+ @Assisted private val darkIconDispatcher: DarkIconDispatcher,
private val collapsedStatusBarFragmentProvider: Provider<CollapsedStatusBarFragment>,
private val statusBarRootFactory: StatusBarRootFactory,
private val componentFactory: HomeStatusBarComponent.Factory,
@@ -131,23 +136,32 @@ constructor(
->
val phoneStatusBarView = cv.findViewById<PhoneStatusBarView>(R.id.status_bar)
component =
- componentFactory.create(phoneStatusBarView).also { component ->
- // CollapsedStatusBarFragment used to be responsible initializing
- component.init()
-
- statusBarViewUpdatedListener?.onStatusBarViewUpdated(
- component.phoneStatusBarViewController,
- component.phoneStatusBarTransitions,
+ componentFactory
+ .create(
+ phoneStatusBarView,
+ statusBarConfigurationController,
+ statusBarWindowController,
+ darkIconDispatcher,
)
-
- if (StatusBarConnectedDisplays.isEnabled) {
- statusBarModePerDisplayRepository.onStatusBarViewInitialized(component)
- } else {
- creationListeners.forEach { listener ->
- listener.onStatusBarViewInitialized(component)
+ .also { component ->
+ // CollapsedStatusBarFragment used to be responsible initializing
+ component.init()
+
+ statusBarViewUpdatedListener?.onStatusBarViewUpdated(
+ component.phoneStatusBarViewController,
+ component.phoneStatusBarTransitions,
+ )
+
+ if (StatusBarConnectedDisplays.isEnabled) {
+ statusBarModePerDisplayRepository.onStatusBarViewInitialized(
+ component
+ )
+ } else {
+ creationListeners.forEach { listener ->
+ listener.onStatusBarViewInitialized(component)
+ }
}
}
- }
}
// Add the new compose view to the hierarchy because we don't use fragment transactions
@@ -163,9 +177,11 @@ constructor(
CollapsedStatusBarFragment.TAG,
object : FragmentHostManager.FragmentListener {
override fun onFragmentViewCreated(tag: String, fragment: Fragment) {
- component =
- (fragment as CollapsedStatusBarFragment).homeStatusBarComponent
- ?: throw IllegalStateException()
+ val statusBarFragment = fragment as CollapsedStatusBarFragment
+ if (statusBarFragment.homeStatusBarComponent == null) {
+ return
+ }
+ component = fragment.homeStatusBarComponent
statusBarViewUpdatedListener?.onStatusBarViewUpdated(
component!!.phoneStatusBarViewController,
component!!.phoneStatusBarTransitions,
@@ -195,6 +211,8 @@ constructor(
override fun create(
statusBarWindowController: StatusBarWindowController,
statusBarModePerDisplayRepository: StatusBarModePerDisplayRepository,
+ statusBarConfigurationController: StatusBarConfigurationController,
+ darkIconDispatcher: DarkIconDispatcher,
): StatusBarInitializerImpl
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarInitializerStore.kt b/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarInitializerStore.kt
index 4f815c1f0b31..de6cd072afd7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarInitializerStore.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarInitializerStore.kt
@@ -22,6 +22,8 @@ import com.android.systemui.display.data.repository.DisplayRepository
import com.android.systemui.display.data.repository.PerDisplayStore
import com.android.systemui.display.data.repository.PerDisplayStoreImpl
import com.android.systemui.display.data.repository.SingleDisplayStore
+import com.android.systemui.statusbar.data.repository.DarkIconDispatcherStore
+import com.android.systemui.statusbar.data.repository.StatusBarConfigurationControllerStore
import com.android.systemui.statusbar.data.repository.StatusBarModeRepositoryStore
import com.android.systemui.statusbar.window.StatusBarWindowControllerStore
import javax.inject.Inject
@@ -39,6 +41,8 @@ constructor(
private val factory: StatusBarInitializer.Factory,
private val statusBarWindowControllerStore: StatusBarWindowControllerStore,
private val statusBarModeRepositoryStore: StatusBarModeRepositoryStore,
+ private val statusBarConfigurationControllerStore: StatusBarConfigurationControllerStore,
+ private val darkIconDispatcherStore: DarkIconDispatcherStore,
) :
StatusBarInitializerStore,
PerDisplayStoreImpl<StatusBarInitializer>(backgroundApplicationScope, displayRepository) {
@@ -47,10 +51,19 @@ constructor(
StatusBarConnectedDisplays.assertInNewMode()
}
- override fun createInstanceForDisplay(displayId: Int): StatusBarInitializer {
+ override fun createInstanceForDisplay(displayId: Int): StatusBarInitializer? {
+ val statusBarWindowController =
+ statusBarWindowControllerStore.forDisplay(displayId) ?: return null
+ val statusBarModePerDisplayRepository =
+ statusBarModeRepositoryStore.forDisplay(displayId) ?: return null
+ val statusBarConfigurationController =
+ statusBarConfigurationControllerStore.forDisplay(displayId) ?: return null
+ val darkIconDispatcher = darkIconDispatcherStore.forDisplay(displayId) ?: return null
return factory.create(
- statusBarWindowController = statusBarWindowControllerStore.forDisplay(displayId),
- statusBarModePerDisplayRepository = statusBarModeRepositoryStore.forDisplay(displayId),
+ statusBarWindowController,
+ statusBarModePerDisplayRepository,
+ statusBarConfigurationController,
+ darkIconDispatcher,
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/DarkIconDispatcherStore.kt b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/DarkIconDispatcherStore.kt
index 8183a487cee2..041f3c816149 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/DarkIconDispatcherStore.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/DarkIconDispatcherStore.kt
@@ -65,8 +65,9 @@ constructor(
StatusBarConnectedDisplays.assertInNewMode()
}
- override fun createInstanceForDisplay(displayId: Int): SysuiDarkIconDispatcher {
- val properties = displayWindowPropertiesRepository.get(displayId, TYPE_STATUS_BAR)
+ override fun createInstanceForDisplay(displayId: Int): SysuiDarkIconDispatcher? {
+ val properties =
+ displayWindowPropertiesRepository.get(displayId, TYPE_STATUS_BAR) ?: return null
return factory.create(displayId, properties.context)
}
@@ -103,7 +104,7 @@ constructor(private val store: SysuiDarkIconDispatcherStore) : DarkIconDispatche
override val defaultDisplay: DarkIconDispatcher
get() = store.defaultDisplay
- override fun forDisplay(displayId: Int): DarkIconDispatcher = store.forDisplay(displayId)
+ override fun forDisplay(displayId: Int): DarkIconDispatcher? = store.forDisplay(displayId)
}
@Module
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/LightBarControllerStore.kt b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/LightBarControllerStore.kt
index e4987555833b..c629d10b90b0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/LightBarControllerStore.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/LightBarControllerStore.kt
@@ -49,13 +49,16 @@ constructor(
LightBarControllerStore,
PerDisplayStoreImpl<LightBarController>(backgroundApplicationScope, displayRepository) {
- override fun createInstanceForDisplay(displayId: Int): LightBarController {
+ override fun createInstanceForDisplay(displayId: Int): LightBarController? {
+ val darkIconDispatcher = darkIconDispatcherStore.forDisplay(displayId) ?: return null
+ val statusBarModePerDisplayRepository =
+ statusBarModeRepositoryStore.forDisplay(displayId) ?: return null
return factory
.create(
displayId,
displayScopeRepository.scopeForDisplay(displayId),
- darkIconDispatcherStore.forDisplay(displayId),
- statusBarModeRepositoryStore.forDisplay(displayId),
+ darkIconDispatcher,
+ statusBarModePerDisplayRepository,
)
.also { it.start() }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/PrivacyDotViewControllerStore.kt b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/PrivacyDotViewControllerStore.kt
index bd61c44e3d9b..d48c94bd0893 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/PrivacyDotViewControllerStore.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/PrivacyDotViewControllerStore.kt
@@ -52,11 +52,14 @@ constructor(
PrivacyDotViewControllerStore,
PerDisplayStoreImpl<PrivacyDotViewController>(backgroundApplicationScope, displayRepository) {
- override fun createInstanceForDisplay(displayId: Int): PrivacyDotViewController {
+ override fun createInstanceForDisplay(displayId: Int): PrivacyDotViewController? {
+ val configurationController =
+ statusBarConfigurationControllerStore.forDisplay(displayId) ?: return null
+ val contentInsetsProvider = contentInsetsProviderStore.forDisplay(displayId) ?: return null
return factory.create(
displayScopeRepository.scopeForDisplay(displayId),
- statusBarConfigurationControllerStore.forDisplay(displayId),
- contentInsetsProviderStore.forDisplay(displayId),
+ configurationController,
+ contentInsetsProvider,
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/PrivacyDotWindowControllerStore.kt b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/PrivacyDotWindowControllerStore.kt
index a1f56552629b..086cc99957ce 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/PrivacyDotWindowControllerStore.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/PrivacyDotWindowControllerStore.kt
@@ -58,15 +58,18 @@ constructor(
StatusBarConnectedDisplays.assertInNewMode()
}
- override fun createInstanceForDisplay(displayId: Int): PrivacyDotWindowController {
+ override fun createInstanceForDisplay(displayId: Int): PrivacyDotWindowController? {
if (displayId == Display.DEFAULT_DISPLAY) {
throw IllegalArgumentException("This class should only be used for connected displays")
}
val displayWindowProperties =
displayWindowPropertiesRepository.get(displayId, TYPE_NAVIGATION_BAR_PANEL)
+ ?: return null
+ val privacyDotViewController =
+ privacyDotViewControllerStore.forDisplay(displayId) ?: return null
return windowControllerFactory.create(
displayId = displayId,
- privacyDotViewController = privacyDotViewControllerStore.forDisplay(displayId),
+ privacyDotViewController = privacyDotViewController,
viewCaptureAwareWindowManager =
viewCaptureAwareWindowManagerFactory.create(displayWindowProperties.windowManager),
inflater = displayWindowProperties.layoutInflater,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarConfigurationControllerStore.kt b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarConfigurationControllerStore.kt
index 6cf2c73a7138..38cea832ad76 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarConfigurationControllerStore.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarConfigurationControllerStore.kt
@@ -62,9 +62,9 @@ constructor(
StatusBarConnectedDisplays.assertInNewMode()
}
- override fun createInstanceForDisplay(displayId: Int): StatusBarConfigurationController {
+ override fun createInstanceForDisplay(displayId: Int): StatusBarConfigurationController? {
val displayWindowProperties =
- displayWindowPropertiesRepository.get(displayId, TYPE_STATUS_BAR)
+ displayWindowPropertiesRepository.get(displayId, TYPE_STATUS_BAR) ?: return null
return configurationControllerFactory.create(displayWindowProperties.context)
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarContentInsetsProviderStore.kt b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarContentInsetsProviderStore.kt
index e471b12c1d58..554c46f6c219 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarContentInsetsProviderStore.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarContentInsetsProviderStore.kt
@@ -59,13 +59,17 @@ constructor(
displayRepository,
) {
- override fun createInstanceForDisplay(displayId: Int): StatusBarContentInsetsProvider {
- val context = displayWindowPropertiesRepository.get(displayId, TYPE_STATUS_BAR).context
+ override fun createInstanceForDisplay(displayId: Int): StatusBarContentInsetsProvider? {
+ val displayWindowProperties =
+ displayWindowPropertiesRepository.get(displayId, TYPE_STATUS_BAR) ?: return null
+ val context = displayWindowProperties.context
+ val configurationController =
+ statusBarConfigurationControllerStore.forDisplay(displayId) ?: return null
val cameraProtectionLoader = cameraProtectionLoaderFactory.create(context)
return factory
.create(
context,
- statusBarConfigurationControllerStore.forDisplay(displayId),
+ configurationController,
sysUICutoutProviderFactory.create(context, cameraProtectionLoader),
)
.also { it.start() }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/SystemEventChipAnimationControllerStore.kt b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/SystemEventChipAnimationControllerStore.kt
index 7760f58805c9..ffc125539521 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/SystemEventChipAnimationControllerStore.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/SystemEventChipAnimationControllerStore.kt
@@ -62,11 +62,17 @@ constructor(
StatusBarConnectedDisplays.assertInNewMode()
}
- override fun createInstanceForDisplay(displayId: Int): SystemEventChipAnimationController {
+ override fun createInstanceForDisplay(displayId: Int): SystemEventChipAnimationController? {
+ val displayWindowProperties =
+ displayWindowPropertiesRepository.get(displayId, TYPE_STATUS_BAR) ?: return null
+ val statusBarWindowController =
+ statusBarWindowControllerStore.forDisplay(displayId) ?: return null
+ val contentInsetsProvider =
+ statusBarContentInsetsProviderStore.forDisplay(displayId) ?: return null
return factory.create(
- displayWindowPropertiesRepository.get(displayId, TYPE_STATUS_BAR).context,
- statusBarWindowControllerStore.forDisplay(displayId),
- statusBarContentInsetsProviderStore.forDisplay(displayId),
+ displayWindowProperties.context,
+ statusBarWindowController,
+ contentInsetsProvider,
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/MultiDisplaySystemEventChipAnimationController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/MultiDisplaySystemEventChipAnimationController.kt
index f2bb7b16439d..4b9721ea4fe5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/events/MultiDisplaySystemEventChipAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/MultiDisplaySystemEventChipAnimationController.kt
@@ -72,5 +72,5 @@ constructor(
}
private fun controllersForAllDisplays() =
- displayRepository.displays.value.map { controllerStore.forDisplay(it.displayId) }
+ displayRepository.displays.value.mapNotNull { controllerStore.forDisplay(it.displayId) }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotWindowController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotWindowController.kt
index 9928ac67f185..f7799bb75ae0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotWindowController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotWindowController.kt
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar.events
+import android.util.Log
import android.view.Display
import android.view.DisplayCutout.BOUNDS_POSITION_BOTTOM
import android.view.DisplayCutout.BOUNDS_POSITION_LEFT
@@ -23,6 +24,7 @@ import android.view.DisplayCutout.BOUNDS_POSITION_RIGHT
import android.view.DisplayCutout.BOUNDS_POSITION_TOP
import android.view.LayoutInflater
import android.view.View
+import android.view.WindowManager.InvalidDisplayException
import android.view.WindowManager.LayoutParams.WRAP_CONTENT
import android.widget.FrameLayout
import com.android.app.viewcapture.ViewCaptureAwareWindowManager
@@ -97,7 +99,17 @@ constructor(
// PrivacyDotViewController expects the dot view to have a FrameLayout parent.
val rootView = FrameLayout(context)
rootView.addView(this)
- viewCaptureAwareWindowManager.addView(rootView, params)
+ try {
+ // Wrapping this in a try/catch to avoid crashes when a display is instantly removed
+ // after being added, and initialization hasn't finished yet.
+ viewCaptureAwareWindowManager.addView(rootView, params)
+ } catch (e: InvalidDisplayException) {
+ Log.e(
+ TAG,
+ "Unable to add view to WM. Display with id $displayId does not exist anymore",
+ e,
+ )
+ }
}
@AssistedFactory
@@ -109,4 +121,8 @@ constructor(
inflater: LayoutInflater,
): PrivacyDotWindowController
}
+
+ private companion object {
+ const val TAG = "PrivacyDotWindowController"
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/ConnectedDisplaysStatusBarNotificationIconViewStore.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/ConnectedDisplaysStatusBarNotificationIconViewStore.kt
index 227a1fefb982..eb55856d994b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/ConnectedDisplaysStatusBarNotificationIconViewStore.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/ConnectedDisplaysStatusBarNotificationIconViewStore.kt
@@ -62,8 +62,10 @@ constructor(
override fun iconView(key: String): StatusBarIconView? {
val entry = notifCollection.getEntry(key) ?: return null
+ val displayWindowProperties =
+ displayWindowPropertiesInteractor.getForStatusBar(displayId) ?: return null
return cachedIcons.computeIfAbsent(key) {
- val context = displayWindowPropertiesInteractor.getForStatusBar(displayId).context
+ val context = displayWindowProperties.context
iconManager.createSbIconView(context, entry)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModel.kt
index 2ba28a660116..e1032820fb71 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModel.kt
@@ -68,13 +68,14 @@ constructor(
.distinctUntilChanged()
/** The colors with which to display the notification icons. */
- fun iconColors(displayId: Int): Flow<NotificationIconColors> =
- darkIconInteractor
+ fun iconColors(displayId: Int): Flow<NotificationIconColors> {
+ return darkIconInteractor
.darkState(displayId)
.map { (areas: Collection<Rect>, tint: Int) -> IconColorsImpl(tint, areas) }
.flowOn(bgContext)
.conflate()
.distinctUntilChanged()
+ }
/** [NotificationIconsViewData] indicating which icons to display in the view. */
val icons: Flow<NotificationIconsViewData> =
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideControllerStore.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideControllerStore.kt
index 744f96918eef..2ae38dd488bd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideControllerStore.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideControllerStore.kt
@@ -47,9 +47,9 @@ constructor(
StatusBarConnectedDisplays.assertInNewMode()
}
- override fun createInstanceForDisplay(displayId: Int): AutoHideController {
+ override fun createInstanceForDisplay(displayId: Int): AutoHideController? {
val displayWindowProperties =
- displayWindowPropertiesRepository.get(displayId, TYPE_STATUS_BAR)
+ displayWindowPropertiesRepository.get(displayId, TYPE_STATUS_BAR) ?: return null
return autoHideControllerFactory.create(displayWindowProperties.context)
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarControllerImpl.java
index ea67f1cdb60a..ca0c1ac9ce7c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarControllerImpl.java
@@ -499,9 +499,9 @@ public class LightBarControllerImpl implements
/** Creates a {@link LightBarControllerImpl}. */
LightBarControllerImpl create(
int displayId,
- CoroutineScope coroutineScope,
- DarkIconDispatcher darkIconDispatcher,
- StatusBarModePerDisplayRepository statusBarModePerDisplayRepository);
+ @NonNull CoroutineScope coroutineScope,
+ @NonNull DarkIconDispatcher darkIconDispatcher,
+ @NonNull StatusBarModePerDisplayRepository statusBarModePerDisplayRepository);
}
public static class LegacyFactory implements LightBarController.Factory {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusOverlayHoverListener.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusOverlayHoverListener.kt
index 394502b2d31f..031754db3c57 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusOverlayHoverListener.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusOverlayHoverListener.kt
@@ -33,6 +33,7 @@ import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.plugins.DarkIconDispatcher
import com.android.systemui.res.R
+import com.android.systemui.statusbar.data.repository.StatusBarConfigurationController
import com.android.systemui.statusbar.data.repository.StatusBarConfigurationControllerStore
import com.android.systemui.statusbar.data.repository.SysuiDarkIconDispatcherStore
import com.android.systemui.statusbar.phone.SysuiDarkIconDispatcher.DarkChange
@@ -54,7 +55,7 @@ constructor(
) {
/** Creates listener always using the same light color for overlay */
- fun createListener(view: View) =
+ fun createListener(view: View): StatusOverlayHoverListener =
StatusOverlayHoverListener(
view,
configurationController,
@@ -65,8 +66,10 @@ constructor(
/**
* Creates listener using [DarkIconDispatcher] to determine light or dark color of the overlay
*/
- fun createDarkAwareListener(view: View) =
- createDarkAwareListener(view, view.darkIconDispatcher.darkChangeFlow())
+ fun createDarkAwareListener(view: View): StatusOverlayHoverListener? {
+ val darkIconDispatcher = view.darkIconDispatcher ?: return null
+ return createDarkAwareListener(view, darkIconDispatcher.darkChangeFlow())
+ }
/**
* Creates listener using [DarkIconDispatcher] to determine light or dark color of the overlay
@@ -78,27 +81,34 @@ constructor(
rightHoverMargin: Int = 0,
topHoverMargin: Int = 0,
bottomHoverMargin: Int = 0,
- ) =
- createDarkAwareListener(
+ ): StatusOverlayHoverListener? {
+ val darkIconDispatcher = view.darkIconDispatcher ?: return null
+ return createDarkAwareListener(
view,
- view.darkIconDispatcher.darkChangeFlow(),
+ darkIconDispatcher.darkChangeFlow(),
leftHoverMargin,
rightHoverMargin,
topHoverMargin,
bottomHoverMargin,
)
+ }
/**
* Creates listener using provided [DarkChange] producer to determine light or dark color of the
* overlay
*/
- fun createDarkAwareListener(view: View, darkFlow: StateFlow<DarkChange>) =
- StatusOverlayHoverListener(
+ fun createDarkAwareListener(
+ view: View,
+ darkFlow: StateFlow<DarkChange>,
+ ): StatusOverlayHoverListener? {
+ val configurationController = view.statusBarConfigurationController ?: return null
+ return StatusOverlayHoverListener(
view,
- view.statusBarConfigurationController,
+ configurationController,
view.resources,
darkFlow.map { toHoverTheme(view, it) },
)
+ }
private fun createDarkAwareListener(
view: View,
@@ -107,10 +117,11 @@ constructor(
rightHoverMargin: Int = 0,
topHoverMargin: Int = 0,
bottomHoverMargin: Int = 0,
- ) =
- StatusOverlayHoverListener(
+ ): StatusOverlayHoverListener? {
+ val configurationController = view.statusBarConfigurationController ?: return null
+ return StatusOverlayHoverListener(
view,
- view.statusBarConfigurationController,
+ configurationController,
view.resources,
darkFlow.map { toHoverTheme(view, it) },
leftHoverMargin,
@@ -118,11 +129,12 @@ constructor(
topHoverMargin,
bottomHoverMargin,
)
+ }
- private val View.statusBarConfigurationController
+ private val View.statusBarConfigurationController: StatusBarConfigurationController?
get() = statusBarConfigurationControllerStore.forDisplay(context.displayId)
- private val View.darkIconDispatcher
+ private val View.darkIconDispatcher: SysuiDarkIconDispatcher?
get() = darkIconDispatcherStore.forDisplay(context.displayId)
private fun toHoverTheme(view: View, darkChange: DarkChange): HoverTheme {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.kt
index 4f32aaa2654e..037dda91fb00 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.kt
@@ -31,8 +31,10 @@ import com.android.systemui.statusbar.core.StatusBarInitializerImpl
import com.android.systemui.statusbar.core.StatusBarInitializerStore
import com.android.systemui.statusbar.core.StatusBarOrchestrator
import com.android.systemui.statusbar.core.StatusBarRootModernization
+import com.android.systemui.statusbar.data.repository.DarkIconDispatcherStore
import com.android.systemui.statusbar.data.repository.PrivacyDotViewControllerStoreModule
import com.android.systemui.statusbar.data.repository.PrivacyDotWindowControllerStoreModule
+import com.android.systemui.statusbar.data.repository.StatusBarConfigurationControllerStore
import com.android.systemui.statusbar.data.repository.StatusBarModeRepositoryStore
import com.android.systemui.statusbar.events.PrivacyDotViewControllerModule
import com.android.systemui.statusbar.phone.AutoHideControllerStore
@@ -107,10 +109,14 @@ interface StatusBarPhoneModule {
implFactory: StatusBarInitializerImpl.Factory,
statusBarWindowControllerStore: StatusBarWindowControllerStore,
statusBarModeRepositoryStore: StatusBarModeRepositoryStore,
+ statusBarConfigurationControllerStore: StatusBarConfigurationControllerStore,
+ darkIconDispatcherStore: DarkIconDispatcherStore,
): StatusBarInitializerImpl {
return implFactory.create(
statusBarWindowControllerStore.defaultDisplay,
statusBarModeRepositoryStore.defaultDisplay,
+ statusBarConfigurationControllerStore.defaultDisplay,
+ darkIconDispatcherStore.defaultDisplay,
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/data/repository/DarkIconRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/data/repository/DarkIconRepository.kt
index 49356eba2842..04646549bfdc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/data/repository/DarkIconRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/data/repository/DarkIconRepository.kt
@@ -15,12 +15,14 @@
*/
package com.android.systemui.statusbar.phone.data.repository
+import android.util.Log
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.statusbar.data.repository.SysuiDarkIconDispatcherStore
import com.android.systemui.statusbar.phone.SysuiDarkIconDispatcher.DarkChange
import dagger.Binds
import dagger.Module
import javax.inject.Inject
+import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
/** Dark-mode state for tinting icons. */
@@ -33,8 +35,22 @@ class DarkIconRepositoryImpl
@Inject
constructor(private val darkIconDispatcherStore: SysuiDarkIconDispatcherStore) :
DarkIconRepository {
- override fun darkState(displayId: Int): StateFlow<DarkChange> =
- darkIconDispatcherStore.forDisplay(displayId).darkChangeFlow()
+ override fun darkState(displayId: Int): StateFlow<DarkChange> {
+ val perDisplayDakIconDispatcher = darkIconDispatcherStore.forDisplay(displayId)
+ if (perDisplayDakIconDispatcher == null) {
+ Log.e(
+ TAG,
+ "DarkIconDispatcher for display $displayId is null. Returning flow of " +
+ "DarkChange.EMPTY",
+ )
+ return MutableStateFlow(DarkChange.EMPTY)
+ }
+ return perDisplayDakIconDispatcher.darkChangeFlow()
+ }
+
+ private companion object {
+ const val TAG = "DarkIconRepositoryImpl"
+ }
}
@Module
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/domain/interactor/LightsOutInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/domain/interactor/LightsOutInteractor.kt
index ed8b3e8922f3..b15fffb8dd29 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/domain/interactor/LightsOutInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/domain/interactor/LightsOutInteractor.kt
@@ -34,8 +34,8 @@ class LightsOutInteractor
@Inject
constructor(private val repository: StatusBarModeRepositoryStore) {
- fun isLowProfile(displayId: Int): Flow<Boolean> =
- repository.forDisplay(displayId).statusBarMode.map {
+ fun isLowProfile(displayId: Int): Flow<Boolean>? =
+ repository.forDisplay(displayId)?.statusBarMode?.map {
when (it) {
StatusBarMode.LIGHTS_OUT,
StatusBarMode.LIGHTS_OUT_TRANSPARENT -> true
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
index d257288637df..c31e34c50b06 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
@@ -47,6 +47,7 @@ import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.demomode.DemoMode;
import com.android.systemui.demomode.DemoModeController;
import com.android.systemui.dump.DumpManager;
+import com.android.systemui.plugins.DarkIconDispatcher;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.res.R;
import com.android.systemui.scene.shared.flag.SceneContainerFlag;
@@ -59,6 +60,9 @@ import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips;
import com.android.systemui.statusbar.core.StatusBarConnectedDisplays;
import com.android.systemui.statusbar.core.StatusBarRootModernization;
+import com.android.systemui.statusbar.data.repository.DarkIconDispatcherStore;
+import com.android.systemui.statusbar.data.repository.StatusBarConfigurationController;
+import com.android.systemui.statusbar.data.repository.StatusBarConfigurationControllerStore;
import com.android.systemui.statusbar.disableflags.DisableFlagsLogger;
import com.android.systemui.statusbar.events.SystemStatusAnimationCallback;
import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler;
@@ -78,6 +82,8 @@ import com.android.systemui.statusbar.pipeline.shared.ui.binder.HomeStatusBarVie
import com.android.systemui.statusbar.pipeline.shared.ui.binder.StatusBarVisibilityChangeListener;
import com.android.systemui.statusbar.pipeline.shared.ui.viewmodel.HomeStatusBarViewModel;
import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.statusbar.window.StatusBarWindowController;
+import com.android.systemui.statusbar.window.StatusBarWindowControllerStore;
import com.android.systemui.statusbar.window.StatusBarWindowStateController;
import com.android.systemui.statusbar.window.StatusBarWindowStateListener;
import com.android.systemui.util.CarrierConfigTracker;
@@ -156,6 +162,9 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
private final NotificationIconContainerStatusBarViewBinder mNicViewBinder;
private final DemoModeController mDemoModeController;
+ private final StatusBarWindowControllerStore mStatusBarWindowControllerStore;
+ private final StatusBarConfigurationControllerStore mStatusBarConfigurationControllerStore;
+ private final DarkIconDispatcherStore mDarkIconDispatcherStore;
private List<String> mBlockedIcons = new ArrayList<>();
private Map<Startable, Startable.State> mStartableStates = new ArrayMap<>();
@@ -263,7 +272,10 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
DumpManager dumpManager,
StatusBarWindowStateController statusBarWindowStateController,
KeyguardUpdateMonitor keyguardUpdateMonitor,
- DemoModeController demoModeController) {
+ DemoModeController demoModeController,
+ StatusBarWindowControllerStore statusBarWindowControllerStore,
+ StatusBarConfigurationControllerStore statusBarConfigurationControllerStore,
+ DarkIconDispatcherStore darkIconDispatcherStore) {
mHomeStatusBarComponentFactory = homeStatusBarComponentFactory;
mOngoingCallController = ongoingCallController;
mAnimationScheduler = animationScheduler;
@@ -287,6 +299,9 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
mStatusBarWindowStateController = statusBarWindowStateController;
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
mDemoModeController = demoModeController;
+ mStatusBarWindowControllerStore = statusBarWindowControllerStore;
+ mStatusBarConfigurationControllerStore = statusBarConfigurationControllerStore;
+ mDarkIconDispatcherStore = darkIconDispatcherStore;
}
private final DemoMode mDemoModeCallback = new DemoMode() {
@@ -337,8 +352,27 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mDumpManager.registerDumpable(getDumpableName(), this);
- mHomeStatusBarComponent = mHomeStatusBarComponentFactory.create(
- (PhoneStatusBarView) getView());
+ int displayId = view.getContext().getDisplayId();
+ StatusBarConfigurationController configurationController =
+ mStatusBarConfigurationControllerStore.forDisplay(displayId);
+ if (configurationController == null) {
+ return;
+ }
+ StatusBarWindowController statusBarWindowController =
+ mStatusBarWindowControllerStore.forDisplay(displayId);
+ if (statusBarWindowController == null) {
+ return;
+ }
+ DarkIconDispatcher darkIconDispatcher = mDarkIconDispatcherStore.forDisplay(displayId);
+ if (darkIconDispatcher == null) {
+ return;
+ }
+ mHomeStatusBarComponent =
+ mHomeStatusBarComponentFactory.create(
+ (PhoneStatusBarView) getView(),
+ configurationController,
+ statusBarWindowController,
+ darkIconDispatcher);
mHomeStatusBarComponent.init();
mStartableStates.clear();
for (Startable startable : mHomeStatusBarComponent.getStartables()) {
@@ -453,6 +487,9 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
@Override
public void onResume() {
super.onResume();
+ if (mHomeStatusBarComponent == null) {
+ return;
+ }
mCommandQueue.addCallback(this);
mStatusBarStateController.addCallback(this);
initOngoingCallChip();
@@ -468,6 +505,9 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
@Override
public void onPause() {
super.onPause();
+ if (mHomeStatusBarComponent == null) {
+ return;
+ }
mCommandQueue.removeCallback(this);
mStatusBarStateController.removeCallback(this);
if (!StatusBarRootModernization.isEnabled()) {
@@ -480,6 +520,9 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
@Override
public void onDestroyView() {
super.onDestroyView();
+ if (mHomeStatusBarComponent == null) {
+ return;
+ }
mStatusBarIconController.removeIconGroup(mDarkIconManager);
mCarrierConfigTracker.removeCallback(mCarrierConfigCallback);
mCarrierConfigTracker.removeDataSubscriptionChangedListener(mDefaultDataListener);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/HomeStatusBarComponent.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/HomeStatusBarComponent.java
index f8ad0f2324bc..5837752abdaf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/HomeStatusBarComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/HomeStatusBarComponent.java
@@ -20,6 +20,7 @@ import com.android.systemui.battery.BatteryMeterViewController;
import com.android.systemui.dagger.qualifiers.DisplaySpecific;
import com.android.systemui.dagger.qualifiers.RootView;
import com.android.systemui.plugins.DarkIconDispatcher;
+import com.android.systemui.statusbar.data.repository.StatusBarConfigurationController;
import com.android.systemui.statusbar.notification.shared.NotificationsLiveDataStoreRefactor;
import com.android.systemui.statusbar.phone.HeadsUpAppearanceController;
import com.android.systemui.statusbar.phone.LegacyLightsOutNotifController;
@@ -29,6 +30,7 @@ import com.android.systemui.statusbar.phone.PhoneStatusBarViewController;
import com.android.systemui.statusbar.phone.StatusBarBoundsProvider;
import com.android.systemui.statusbar.phone.StatusBarDemoMode;
import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragment;
+import com.android.systemui.statusbar.window.StatusBarWindowController;
import dagger.BindsInstance;
import dagger.Subcomponent;
@@ -57,7 +59,10 @@ public interface HomeStatusBarComponent {
interface Factory {
/** */
HomeStatusBarComponent create(
- @BindsInstance @RootView PhoneStatusBarView phoneStatusBarView);
+ @BindsInstance @RootView PhoneStatusBarView phoneStatusBarView,
+ @BindsInstance StatusBarConfigurationController configurationController,
+ @BindsInstance StatusBarWindowController statusBarWindowController,
+ @BindsInstance @DisplaySpecific DarkIconDispatcher darkIconDispatcher);
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/HomeStatusBarModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/HomeStatusBarModule.java
index 182f8d7e2fd6..6a331b938cf1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/HomeStatusBarModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/HomeStatusBarModule.java
@@ -22,19 +22,14 @@ import android.view.ViewStub;
import com.android.systemui.battery.BatteryMeterView;
import com.android.systemui.dagger.qualifiers.DisplaySpecific;
import com.android.systemui.dagger.qualifiers.RootView;
-import com.android.systemui.plugins.DarkIconDispatcher;
import com.android.systemui.res.R;
import com.android.systemui.statusbar.HeadsUpStatusBarView;
-import com.android.systemui.statusbar.data.repository.DarkIconDispatcherStore;
-import com.android.systemui.statusbar.data.repository.StatusBarConfigurationController;
-import com.android.systemui.statusbar.data.repository.StatusBarConfigurationControllerStore;
import com.android.systemui.statusbar.phone.PhoneStatusBarTransitions;
import com.android.systemui.statusbar.phone.PhoneStatusBarView;
import com.android.systemui.statusbar.phone.PhoneStatusBarViewController;
import com.android.systemui.statusbar.phone.StatusBarLocation;
import com.android.systemui.statusbar.policy.Clock;
import com.android.systemui.statusbar.window.StatusBarWindowController;
-import com.android.systemui.statusbar.window.StatusBarWindowControllerStore;
import dagger.Module;
import dagger.Provides;
@@ -149,29 +144,4 @@ public interface HomeStatusBarModule {
static int displayId(@RootView PhoneStatusBarView view) {
return view.getContext().getDisplayId();
}
-
- /** */
- @Provides
- @HomeStatusBarScope
- static StatusBarConfigurationController configurationController(
- @DisplaySpecific int displayId, StatusBarConfigurationControllerStore store) {
- return store.forDisplay(displayId);
- }
-
- /** */
- @Provides
- @HomeStatusBarScope
- static StatusBarWindowController provideWindowController(
- @DisplaySpecific int displayId, StatusBarWindowControllerStore store) {
- return store.forDisplay(displayId);
- }
-
- /** */
- @Provides
- @HomeStatusBarScope
- @DisplaySpecific
- static DarkIconDispatcher darkIconDispatcher(
- @DisplaySpecific int displayId, DarkIconDispatcherStore store) {
- return store.forDisplay(displayId);
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt
index c3299bbd40e6..7243ba7def58 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt
@@ -70,6 +70,8 @@ constructor(
) {
fun create(root: ViewGroup, andThen: (ViewGroup) -> Unit): ComposeView {
val composeView = ComposeView(root.context)
+ val darkIconDispatcher =
+ darkIconDispatcherStore.forDisplay(root.context.displayId) ?: return composeView
composeView.apply {
setContent {
StatusBarRoot(
@@ -80,7 +82,7 @@ constructor(
darkIconManagerFactory = darkIconManagerFactory,
iconController = iconController,
ongoingCallController = ongoingCallController,
- darkIconDispatcher = darkIconDispatcherStore.forDisplay(root.context.displayId),
+ darkIconDispatcher = darkIconDispatcher,
eventAnimationInteractor = eventAnimationInteractor,
onViewCreated = andThen,
)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt
index dcfbc5d6432d..c9cc17389c17 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt
@@ -63,6 +63,7 @@ import kotlinx.coroutines.flow.conflate
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.emptyFlow
import kotlinx.coroutines.flow.filter
+import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
@@ -216,7 +217,7 @@ constructor(
} else {
combine(
notificationsInteractor.areAnyNotificationsPresent,
- lightsOutInteractor.isLowProfile(displayId),
+ lightsOutInteractor.isLowProfile(displayId) ?: flowOf(false),
) { hasNotifications, isLowProfile ->
hasNotifications && isLowProfile
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowControllerImpl.java
index 811a2ec44ccc..848e91d6f896 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowControllerImpl.java
@@ -163,7 +163,18 @@ public class StatusBarWindowControllerImpl implements StatusBarWindowController
mLp = getBarLayoutParams(mContext.getDisplay().getRotation());
Trace.endSection();
- mWindowManager.addView(mStatusBarWindowView, mLp);
+ try {
+ mWindowManager.addView(mStatusBarWindowView, mLp);
+ } catch (WindowManager.InvalidDisplayException e) {
+ // Wrapping this in a try/catch to avoid crashes when a display is instantly removed
+ // after being added, and initialization hasn't finished yet.
+ Log.e(
+ TAG,
+ "Unable to add view to WindowManager. Display with id "
+ + mContext.getDisplayId()
+ + " doesn't exist anymore.",
+ e);
+ }
mLpChanged.copyFrom(mLp);
mContentInsetsProvider.addCallback(this::calculateStatusBarLocationsForAllRotations);
@@ -176,7 +187,15 @@ public class StatusBarWindowControllerImpl implements StatusBarWindowController
public void stop() {
StatusBarConnectedDisplays.assertInNewMode();
- mWindowManager.removeView(mStatusBarWindowView);
+ try {
+ mWindowManager.removeView(mStatusBarWindowView);
+ } catch (IllegalArgumentException e) {
+ // Wrapping this in a try/catch to avoid crashes when a display is instantly removed
+ // after being added, and initialization hasn't finished yet.
+ // When that happens, adding the View to WindowManager fails, and therefore removing
+ // it here will fail too, since it wasn't added in the first place.
+ Log.e(TAG, "Failed to remove View from WindowManager. View was not attached", e);
+ }
if (StatusBarRootModernization.isEnabled()) {
return;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowControllerStore.kt b/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowControllerStore.kt
index 74031612f28e..f7688d2feab5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowControllerStore.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowControllerStore.kt
@@ -54,19 +54,23 @@ constructor(
StatusBarConnectedDisplays.assertInNewMode()
}
- override fun createInstanceForDisplay(displayId: Int): StatusBarWindowController {
+ override fun createInstanceForDisplay(displayId: Int): StatusBarWindowController? {
val statusBarDisplayContext =
displayWindowPropertiesRepository.get(
displayId = displayId,
windowType = WindowManager.LayoutParams.TYPE_STATUS_BAR,
- )
+ ) ?: return null
+ val statusBarConfigurationController =
+ statusBarConfigurationControllerStore.forDisplay(displayId) ?: return null
+ val contentInsetsProvider =
+ statusBarContentInsetsProviderStore.forDisplay(displayId) ?: return null
val viewCaptureAwareWindowManager =
viewCaptureAwareWindowManagerFactory.create(statusBarDisplayContext.windowManager)
return controllerFactory.create(
statusBarDisplayContext.context,
viewCaptureAwareWindowManager,
- statusBarConfigurationControllerStore.forDisplay(displayId),
- statusBarContentInsetsProviderStore.forDisplay(displayId),
+ statusBarConfigurationController,
+ contentInsetsProvider,
)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
index 411c81d13e0b..1fcf02d417e1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
@@ -36,6 +36,8 @@ import static com.android.systemui.statusbar.phone.CentralSurfaces.MSG_DISMISS_K
import static com.google.common.truth.Truth.assertThat;
+import static kotlinx.coroutines.flow.FlowKt.flowOf;
+
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
@@ -54,8 +56,6 @@ import static org.mockito.Mockito.when;
import static java.util.Collections.emptySet;
-import static kotlinx.coroutines.flow.FlowKt.flowOf;
-
import android.app.ActivityManager;
import android.app.IWallpaperManager;
import android.app.NotificationManager;
@@ -132,6 +132,7 @@ import com.android.systemui.navigationbar.NavigationBarController;
import com.android.systemui.notetask.NoteTaskController;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
+import com.android.systemui.plugins.DarkIconDispatcher;
import com.android.systemui.plugins.PluginDependencyProvider;
import com.android.systemui.plugins.PluginManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
@@ -175,6 +176,7 @@ import com.android.systemui.statusbar.StatusBarStateControllerImpl;
import com.android.systemui.statusbar.core.StatusBarConnectedDisplays;
import com.android.systemui.statusbar.core.StatusBarInitializerImpl;
import com.android.systemui.statusbar.data.repository.FakeStatusBarModeRepository;
+import com.android.systemui.statusbar.data.repository.StatusBarConfigurationController;
import com.android.systemui.statusbar.data.repository.StatusBarModePerDisplayRepository;
import com.android.systemui.statusbar.notification.NotifPipelineFlags;
import com.android.systemui.statusbar.notification.NotificationActivityStarter;
@@ -216,6 +218,10 @@ import com.android.systemui.volume.VolumeComponent;
import com.android.wm.shell.bubbles.Bubbles;
import com.android.wm.shell.startingsurface.StartingSurface;
+import dagger.Lazy;
+
+import kotlinx.coroutines.test.TestScope;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -232,9 +238,6 @@ import java.util.Set;
import javax.inject.Provider;
-import dagger.Lazy;
-import kotlinx.coroutines.test.TestScope;
-
@SmallTest
@RunWith(AndroidJUnit4.class)
@RunWithLooper(setAsMainLooper = true)
@@ -536,6 +539,8 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
new StatusBarInitializerImpl(
mStatusBarWindowController,
mStatusBarModePerDisplayRepository,
+ mock(StatusBarConfigurationController.class),
+ mock(DarkIconDispatcher.class),
mCollapsedStatusBarFragmentProvider,
mock(StatusBarRootFactory.class),
mock(HomeStatusBarComponent.Factory.class),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java
index 0b4436755fa5..3a99328fa8ed 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java
@@ -25,6 +25,7 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -61,6 +62,9 @@ import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.OperatorNameViewController;
import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips;
import com.android.systemui.statusbar.core.StatusBarRootModernization;
+import com.android.systemui.statusbar.data.repository.DarkIconDispatcherStore;
+import com.android.systemui.statusbar.data.repository.StatusBarConfigurationController;
+import com.android.systemui.statusbar.data.repository.StatusBarConfigurationControllerStore;
import com.android.systemui.statusbar.disableflags.DisableFlagsLogger;
import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler;
import com.android.systemui.statusbar.notification.icon.ui.viewbinder.NotificationIconContainerStatusBarViewBinder;
@@ -75,6 +79,8 @@ import com.android.systemui.statusbar.pipeline.shared.ui.viewmodel.FakeHomeStatu
import com.android.systemui.statusbar.pipeline.shared.ui.viewmodel.FakeHomeStatusBarViewModel;
import com.android.systemui.statusbar.pipeline.shared.ui.viewmodel.StatusBarOperatorNameViewModel;
import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.statusbar.window.StatusBarWindowController;
+import com.android.systemui.statusbar.window.StatusBarWindowControllerStore;
import com.android.systemui.statusbar.window.StatusBarWindowStateController;
import com.android.systemui.statusbar.window.StatusBarWindowStateListener;
import com.android.systemui.util.CarrierConfigTracker;
@@ -134,6 +140,12 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest {
private StatusBarWindowStateController mStatusBarWindowStateController;
@Mock
private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
+ @Mock private StatusBarWindowControllerStore mStatusBarWindowControllerStore;
+ @Mock private StatusBarWindowController mStatusBarWindowController;
+ @Mock private StatusBarConfigurationControllerStore mStatusBarConfigurationControllerStore;
+ @Mock private StatusBarConfigurationController mStatusBarConfigurationController;
+ @Mock private DarkIconDispatcherStore mDarkIconDispatcherStore;
+ @Mock private DarkIconDispatcher mDarkIconDispatcher;
@Rule
public final AnimatorTestRule mAnimatorTestRule = new AnimatorTestRule(this);
@@ -145,6 +157,12 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest {
@Before
public void setup() {
+ when(mStatusBarWindowControllerStore.forDisplay(anyInt()))
+ .thenReturn(mStatusBarWindowController);
+ when(mStatusBarConfigurationControllerStore.forDisplay(anyInt()))
+ .thenReturn(mStatusBarConfigurationController);
+ when(mDarkIconDispatcherStore.forDisplay(anyInt())).thenReturn(mDarkIconDispatcher);
+
injectLeakCheckedDependencies(ALL_SUPPORTED_CLASSES);
mDependency.injectMockDependency(DarkIconDispatcher.class);
@@ -1276,11 +1294,14 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest {
mDumpManager,
mStatusBarWindowStateController,
mKeyguardUpdateMonitor,
- mock(DemoModeController.class));
+ mock(DemoModeController.class),
+ mStatusBarWindowControllerStore,
+ mStatusBarConfigurationControllerStore,
+ mDarkIconDispatcherStore);
}
private void setUpDaggerComponent() {
- when(mStatusBarFragmentComponentFactory.create(any()))
+ when(mStatusBarFragmentComponentFactory.create(any(), any(), any(), any()))
.thenReturn(mHomeStatusBarComponent);
when(mHomeStatusBarComponent.getHeadsUpAppearanceController())
.thenReturn(mHeadsUpAppearanceController);
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestableContext.java b/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestableContext.java
index b8be6aa50015..64d89c5ac8ba 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestableContext.java
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestableContext.java
@@ -81,6 +81,14 @@ public class SysuiTestableContext extends TestableContext {
return super.getDisplay();
}
+ @Override
+ public int getDisplayId() {
+ if (mCustomDisplay != null) {
+ return mCustomDisplay.getDisplayId();
+ }
+ return super.getDisplayId();
+ }
+
public SysuiTestableContext createDefaultDisplayContext() {
Display display = getBaseContext().getSystemService(DisplayManager.class).getDisplays()[0];
return (SysuiTestableContext) createDisplayContext(display);
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/core/FakeStatusBarInitializerFactory.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/core/FakeStatusBarInitializerFactory.kt
index 50a19a9bc68a..fb2e2a3b76a9 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/core/FakeStatusBarInitializerFactory.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/core/FakeStatusBarInitializerFactory.kt
@@ -16,6 +16,8 @@
package com.android.systemui.statusbar.core
+import com.android.systemui.plugins.DarkIconDispatcher
+import com.android.systemui.statusbar.data.repository.StatusBarConfigurationController
import com.android.systemui.statusbar.data.repository.StatusBarModePerDisplayRepository
import com.android.systemui.statusbar.window.StatusBarWindowController
@@ -24,5 +26,7 @@ class FakeStatusBarInitializerFactory() : StatusBarInitializer.Factory {
override fun create(
statusBarWindowController: StatusBarWindowController,
statusBarModePerDisplayRepository: StatusBarModePerDisplayRepository,
+ statusBarConfigurationController: StatusBarConfigurationController,
+ darkIconDispatcher: DarkIconDispatcher,
): StatusBarInitializer = FakeStatusBarInitializer()
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/core/StatusBarInitializerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/core/StatusBarInitializerKosmos.kt
index 6e990277df6b..b8dafb23b206 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/core/StatusBarInitializerKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/core/StatusBarInitializerKosmos.kt
@@ -19,7 +19,9 @@ package com.android.systemui.statusbar.core
import com.android.systemui.display.data.repository.displayRepository
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.statusbar.data.repository.darkIconDispatcherStore
import com.android.systemui.statusbar.data.repository.fakeStatusBarModeRepository
+import com.android.systemui.statusbar.data.repository.statusBarConfigurationControllerStore
import com.android.systemui.statusbar.window.fakeStatusBarWindowControllerStore
val Kosmos.fakeStatusBarInitializer by Kosmos.Fixture { FakeStatusBarInitializer() }
@@ -39,6 +41,8 @@ val Kosmos.multiDisplayStatusBarInitializerStore by
fakeStatusBarInitializerFactory,
fakeStatusBarWindowControllerStore,
fakeStatusBarModeRepository,
+ statusBarConfigurationControllerStore,
+ darkIconDispatcherStore,
)
}
diff --git a/services/core/java/com/android/server/input/InputSettingsObserver.java b/services/core/java/com/android/server/input/InputSettingsObserver.java
index 56cb6f49f6c4..febf24edc294 100644
--- a/services/core/java/com/android/server/input/InputSettingsObserver.java
+++ b/services/core/java/com/android/server/input/InputSettingsObserver.java
@@ -71,6 +71,9 @@ class InputSettingsObserver extends ContentObserver {
(reason) -> updateMouseSwapPrimaryButton()),
Map.entry(Settings.System.getUriFor(Settings.System.MOUSE_SCROLLING_ACCELERATION),
(reason) -> updateMouseScrollingAcceleration()),
+ Map.entry(Settings.System.getUriFor(
+ Settings.System.MOUSE_POINTER_ACCELERATION_ENABLED),
+ (reason) -> updateMouseAccelerationEnabled()),
Map.entry(Settings.System.getUriFor(Settings.System.TOUCHPAD_POINTER_SPEED),
(reason) -> updateTouchpadPointerSpeed()),
Map.entry(Settings.System.getUriFor(Settings.System.TOUCHPAD_NATURAL_SCROLLING),
@@ -191,6 +194,11 @@ class InputSettingsObserver extends ContentObserver {
InputSettings.isMouseScrollingAccelerationEnabled(mContext));
}
+ private void updateMouseAccelerationEnabled() {
+ mNative.setMouseAccelerationEnabled(
+ InputSettings.isMousePointerAccelerationEnabled(mContext));
+ }
+
private void updateTouchpadPointerSpeed() {
mNative.setTouchpadPointerSpeed(
constrainPointerSpeedValue(InputSettings.getTouchpadPointerSpeed(mContext)));
diff --git a/services/core/java/com/android/server/input/NativeInputManagerService.java b/services/core/java/com/android/server/input/NativeInputManagerService.java
index ab5a680867e9..7dbde64a6412 100644
--- a/services/core/java/com/android/server/input/NativeInputManagerService.java
+++ b/services/core/java/com/android/server/input/NativeInputManagerService.java
@@ -138,6 +138,8 @@ interface NativeInputManagerService {
void setMouseSwapPrimaryButtonEnabled(boolean enabled);
+ void setMouseAccelerationEnabled(boolean enabled);
+
void setTouchpadPointerSpeed(int speed);
void setTouchpadNaturalScrollingEnabled(boolean enabled);
@@ -429,6 +431,9 @@ interface NativeInputManagerService {
public native void setMouseSwapPrimaryButtonEnabled(boolean enabled);
@Override
+ public native void setMouseAccelerationEnabled(boolean enabled);
+
+ @Override
public native void setTouchpadPointerSpeed(int speed);
@Override
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index eeae6166873a..f50e8aa7eb7b 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -3082,16 +3082,42 @@ public class NotificationManagerService extends SystemService {
private void sendRegisteredOnlyBroadcast(Intent baseIntent) {
int[] userIds = mUmInternal.getProfileIds(mAmi.getCurrentUserId(), true);
- Intent intent = new Intent(baseIntent).addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
- for (int userId : userIds) {
- getContext().sendBroadcastAsUser(intent, UserHandle.of(userId), null);
- }
- // explicitly send the broadcast to all DND packages, even if they aren't currently running
- for (int userId : userIds) {
- for (String pkg : mConditionProviders.getAllowedPackages(userId)) {
- Intent pkgIntent = new Intent(baseIntent).setPackage(pkg).setFlags(
- Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
- getContext().sendBroadcastAsUser(pkgIntent, UserHandle.of(userId));
+ if (Flags.nmBinderPerfReduceZenBroadcasts()) {
+ for (int userId : userIds) {
+ Context userContext = getContext().createContextAsUser(UserHandle.of(userId), 0);
+ String[] dndPackages = mConditionProviders.getAllowedPackages(userId)
+ .toArray(new String[0]);
+
+ // We send the broadcast to all DND packages in the second step, so leave them out
+ // of this first broadcast for *running* receivers. That ensures each package only
+ // receives it once.
+ Intent registeredOnlyIntent = new Intent(baseIntent)
+ .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+ userContext.sendBroadcastMultiplePermissions(registeredOnlyIntent,
+ /* receiverPermissions= */ new String[0],
+ /* excludedPermissions= */ new String[0],
+ /* excludedPackages= */ dndPackages);
+
+ for (String pkg : dndPackages) {
+ Intent pkgIntent = new Intent(baseIntent).setPackage(pkg)
+ .setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
+ userContext.sendBroadcast(pkgIntent);
+ }
+ }
+ } else {
+ Intent intent = new Intent(baseIntent).addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+ for (int userId : userIds) {
+ getContext().sendBroadcastAsUser(intent, UserHandle.of(userId), null);
+ }
+
+ // explicitly send the broadcast to all DND packages, even if they aren't currently
+ // running
+ for (int userId : userIds) {
+ for (String pkg : mConditionProviders.getAllowedPackages(userId)) {
+ Intent pkgIntent = new Intent(baseIntent).setPackage(pkg).setFlags(
+ Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
+ getContext().sendBroadcastAsUser(pkgIntent, UserHandle.of(userId));
+ }
}
}
}
diff --git a/services/core/java/com/android/server/notification/flags.aconfig b/services/core/java/com/android/server/notification/flags.aconfig
index 65a38ae1fcde..f15c23e110a4 100644
--- a/services/core/java/com/android/server/notification/flags.aconfig
+++ b/services/core/java/com/android/server/notification/flags.aconfig
@@ -187,3 +187,13 @@ flag {
description: "Enables sound uri with vibration source in notification channel"
bug: "351975435"
}
+
+flag {
+ name: "nm_binder_perf_reduce_zen_broadcasts"
+ namespace: "systemui"
+ description: "Don't send duplicate zen-related (policy changed, etc) broadcasts"
+ bug: "324376849"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+} \ No newline at end of file
diff --git a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
index cba606cf2b0c..98ed6f76b2f9 100644
--- a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
@@ -101,7 +101,8 @@ final class ImeInsetsSourceProvider extends InsetsSourceProvider {
// isLeashReadyForDispatching (used to dispatch the leash of the control) is
// depending on mGivenInsetsReady. Therefore, triggering notifyControlChanged here
// again, so that the control with leash can be eventually dispatched
- if (!mGivenInsetsReady && isServerVisible() && !givenInsetsPending) {
+ if (!mGivenInsetsReady && isServerVisible() && !givenInsetsPending
+ && mControlTarget != null) {
mGivenInsetsReady = true;
ImeTracker.forLogging().onProgress(mStatsToken,
ImeTracker.PHASE_WM_POST_LAYOUT_NOTIFY_CONTROLS_CHANGED);
diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
index 7276007481ab..d1585d06ae40 100644
--- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
@@ -384,7 +384,7 @@ class InsetsSourceProvider {
}
final boolean serverVisibleChanged = mServerVisible != isServerVisible;
setServerVisible(isServerVisible);
- if (mControl != null) {
+ if (mControl != null && mControlTarget != null) {
final boolean positionChanged = updateInsetsControlPosition(windowState);
if (!(positionChanged || mHasPendingPosition)
// The insets hint would be updated while changing the position. Here updates it
diff --git a/services/core/java/com/android/server/wm/InsetsStateController.java b/services/core/java/com/android/server/wm/InsetsStateController.java
index ce8518449230..9df65f60e8d7 100644
--- a/services/core/java/com/android/server/wm/InsetsStateController.java
+++ b/services/core/java/com/android/server/wm/InsetsStateController.java
@@ -371,7 +371,7 @@ class InsetsStateController {
array.add(provider);
}
- void notifyControlChanged(InsetsControlTarget target, InsetsSourceProvider provider) {
+ void notifyControlChanged(@NonNull InsetsControlTarget target, InsetsSourceProvider provider) {
addToPendingControlMaps(target, provider);
notifyPendingInsetsControlChanged();
}
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index 813fec1454a7..f634beb77329 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -345,6 +345,7 @@ public:
void setMouseReverseVerticalScrollingEnabled(bool enabled);
void setMouseScrollingAccelerationEnabled(bool enabled);
void setMouseSwapPrimaryButtonEnabled(bool enabled);
+ void setMouseAccelerationEnabled(bool enabled);
void setTouchpadPointerSpeed(int32_t speed);
void setTouchpadNaturalScrollingEnabled(bool enabled);
void setTouchpadTapToClickEnabled(bool enabled);
@@ -502,6 +503,9 @@ private:
// True if the mouse primary button is swapped (left/right buttons).
bool mouseSwapPrimaryButtonEnabled{false};
+ // True if the mouse cursor will accelerate as the mouse moves faster.
+ bool mousePointerAccelerationEnabled{true};
+
// The touchpad pointer speed, as a number from -7 (slowest) to 7 (fastest).
int32_t touchpadPointerSpeed{0};
@@ -847,6 +851,7 @@ void NativeInputManager::getReaderConfiguration(InputReaderConfiguration* outCon
outConfig->mouseReverseVerticalScrollingEnabled =
mLocked.mouseReverseVerticalScrollingEnabled;
outConfig->mouseSwapPrimaryButtonEnabled = mLocked.mouseSwapPrimaryButtonEnabled;
+ outConfig->mousePointerAccelerationEnabled = mLocked.mousePointerAccelerationEnabled;
outConfig->touchpadPointerSpeed = mLocked.touchpadPointerSpeed;
outConfig->touchpadNaturalScrollingEnabled = mLocked.touchpadNaturalScrollingEnabled;
@@ -1458,6 +1463,21 @@ void NativeInputManager::setMouseSwapPrimaryButtonEnabled(bool enabled) {
InputReaderConfiguration::Change::MOUSE_SETTINGS);
}
+void NativeInputManager::setMouseAccelerationEnabled(bool enabled) {
+ { // acquire lock
+ std::scoped_lock _l(mLock);
+
+ if (mLocked.mousePointerAccelerationEnabled == enabled) {
+ return;
+ }
+
+ mLocked.mousePointerAccelerationEnabled = enabled;
+ } // release lock
+
+ mInputManager->getReader().requestRefreshConfiguration(
+ InputReaderConfiguration::Change::POINTER_SPEED);
+}
+
void NativeInputManager::setPointerSpeed(int32_t speed) {
{ // acquire lock
std::scoped_lock _l(mLock);
@@ -3220,6 +3240,11 @@ static void nativeSetMouseSwapPrimaryButtonEnabled(JNIEnv* env, jobject nativeIm
im->setMouseSwapPrimaryButtonEnabled(enabled);
}
+static void nativeSetMouseAccelerationEnabled(JNIEnv* env, jobject nativeImplObj, bool enabled) {
+ NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
+ im->setMouseAccelerationEnabled(enabled);
+}
+
static jboolean nativeSetKernelWakeEnabled(JNIEnv* env, jobject nativeImplObj, jint deviceId,
jboolean enabled) {
NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
@@ -3280,6 +3305,7 @@ static const JNINativeMethod gInputManagerMethods[] = {
{"setMouseScrollingAccelerationEnabled", "(Z)V",
(void*)nativeSetMouseScrollingAccelerationEnabled},
{"setMouseSwapPrimaryButtonEnabled", "(Z)V", (void*)nativeSetMouseSwapPrimaryButtonEnabled},
+ {"setMouseAccelerationEnabled", "(Z)V", (void*)nativeSetMouseAccelerationEnabled},
{"setTouchpadPointerSpeed", "(I)V", (void*)nativeSetTouchpadPointerSpeed},
{"setTouchpadNaturalScrollingEnabled", "(Z)V",
(void*)nativeSetTouchpadNaturalScrollingEnabled},
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index bcda2c0662ca..301165f8151d 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -644,6 +644,9 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
doNothing().when(mContext).sendBroadcast(any(), anyString());
doNothing().when(mContext).sendBroadcastAsUser(any(), any());
doNothing().when(mContext).sendBroadcastAsUser(any(), any(), any());
+ doNothing().when(mContext).sendBroadcastMultiplePermissions(any(), any(), any(), any());
+ doReturn(mContext).when(mContext).createContextAsUser(eq(mUser), anyInt());
+
TestableContentResolver cr = mock(TestableContentResolver.class);
when(mContext.getContentResolver()).thenReturn(cr);
doNothing().when(cr).registerContentObserver(any(), anyBoolean(), any(), anyInt());
@@ -11235,7 +11238,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
}
@Test
- public void onZenModeChanged_sendsBroadcasts() throws Exception {
+ @DisableFlags(Flags.FLAG_NM_BINDER_PERF_REDUCE_ZEN_BROADCASTS)
+ public void onZenModeChanged_sendsBroadcasts_oldBehavior() throws Exception {
when(mAmi.getCurrentUserId()).thenReturn(100);
when(mUmInternal.getProfileIds(eq(100), anyBoolean())).thenReturn(new int[]{100, 101, 102});
when(mConditionProviders.getAllowedPackages(anyInt())).then(new Answer<List<String>>() {
@@ -11288,6 +11292,74 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
}
@Test
+ @EnableFlags(Flags.FLAG_NM_BINDER_PERF_REDUCE_ZEN_BROADCASTS)
+ public void onZenModeChanged_sendsBroadcasts() throws Exception {
+ when(mAmi.getCurrentUserId()).thenReturn(100);
+ when(mUmInternal.getProfileIds(eq(100), anyBoolean())).thenReturn(new int[]{100, 101, 102});
+ when(mConditionProviders.getAllowedPackages(anyInt())).then(new Answer<List<String>>() {
+ @Override
+ public List<String> answer(InvocationOnMock invocation) {
+ int userId = invocation.getArgument(0);
+ switch (userId) {
+ case 100:
+ return Lists.newArrayList("a", "b", "c");
+ case 101:
+ return Lists.newArrayList();
+ case 102:
+ return Lists.newArrayList("b");
+ default:
+ throw new IllegalArgumentException(
+ "Why would you ask for packages of userId " + userId + "?");
+ }
+ }
+ });
+ Context context100 = mock(Context.class);
+ doReturn(context100).when(mContext).createContextAsUser(eq(UserHandle.of(100)), anyInt());
+ Context context101 = mock(Context.class);
+ doReturn(context101).when(mContext).createContextAsUser(eq(UserHandle.of(101)), anyInt());
+ Context context102 = mock(Context.class);
+ doReturn(context102).when(mContext).createContextAsUser(eq(UserHandle.of(102)), anyInt());
+
+ mService.getBinderService().setZenMode(Settings.Global.ZEN_MODE_NO_INTERRUPTIONS, null,
+ "testing!", false);
+ waitForIdle();
+
+ // Verify broadcasts per user: registered receivers first, then DND packages.
+ InOrder inOrder = inOrder(context100, context101, context102);
+
+ inOrder.verify(context100).sendBroadcastMultiplePermissions(
+ eqIntent(new Intent(ACTION_INTERRUPTION_FILTER_CHANGED)
+ .setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY)),
+ eq(new String[0]), eq(new String[0]), eq(new String[] {"a", "b", "c"}));
+ inOrder.verify(context100).sendBroadcast(
+ eqIntent(new Intent(ACTION_INTERRUPTION_FILTER_CHANGED)
+ .setPackage("a")
+ .setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT)));
+ inOrder.verify(context100).sendBroadcast(
+ eqIntent(new Intent(ACTION_INTERRUPTION_FILTER_CHANGED)
+ .setPackage("b")
+ .setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT)));
+ inOrder.verify(context100).sendBroadcast(
+ eqIntent(new Intent(ACTION_INTERRUPTION_FILTER_CHANGED)
+ .setPackage("c")
+ .setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT)));
+
+ inOrder.verify(context101).sendBroadcastMultiplePermissions(
+ eqIntent(new Intent(ACTION_INTERRUPTION_FILTER_CHANGED)
+ .setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY)),
+ eq(new String[0]), eq(new String[0]), eq(new String[] {}));
+
+ inOrder.verify(context102).sendBroadcastMultiplePermissions(
+ eqIntent(new Intent(ACTION_INTERRUPTION_FILTER_CHANGED)
+ .setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY)),
+ eq(new String[0]), eq(new String[0]), eq(new String[] {"b"}));
+ inOrder.verify(context102).sendBroadcast(
+ eqIntent(new Intent(ACTION_INTERRUPTION_FILTER_CHANGED)
+ .setPackage("b")
+ .setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT)));
+ }
+
+ @Test
@EnableFlags(android.app.Flags.FLAG_MODES_API)
public void onAutomaticRuleStatusChanged_sendsBroadcastToRuleOwner() throws Exception {
mService.mZenModeHelper.getCallbacks().forEach(c -> c.onAutomaticRuleStatusChanged(
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index e7c9e927b311..e27dbe588183 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -1869,10 +1869,18 @@ public class UsageStatsService extends SystemService implements
}
private boolean shouldDeleteObsoleteData(UserHandle userHandle) {
- final DevicePolicyManagerInternal dpmInternal = getDpmInternal();
- // If a profile owner is not defined for the given user, obsolete data should be deleted
- return dpmInternal == null
- || dpmInternal.getProfileOwnerOrDeviceOwnerSupervisionComponent(userHandle) == null;
+ if (android.app.supervision.flags.Flags.deprecateDpmSupervisionApis()) {
+ final SupervisionManagerInternal smInternal = getSupervisionManagerInternal();
+ // If supervision is not enabled for the given user, obsolete data should be deleted.
+ return smInternal == null
+ || !smInternal.isSupervisionEnabledForUser(userHandle.getIdentifier());
+ } else {
+ final DevicePolicyManagerInternal dpmInternal = getDpmInternal();
+ // If a profile owner is not defined for the given user, obsolete data should be deleted
+ return dpmInternal == null
+ || dpmInternal.getProfileOwnerOrDeviceOwnerSupervisionComponent(userHandle)
+ == null;
+ }
}
private String buildFullToken(String packageName, String token) {