diff options
| author | 2025-03-03 18:21:27 +0000 | |
|---|---|---|
| committer | 2025-03-03 18:26:06 +0000 | |
| commit | b7e2164793303e279b0d66acf81cbdecf84ea973 (patch) | |
| tree | d2f5e72ddcf4f8f8cad03384866ff20ff310a012 | |
| parent | e5db5c65a4b40ef3f23666f6100dff93744af440 (diff) | |
Refactor ConfigurationStateStore to use PerDisplayRepository
The new version is cleaner, requires less code, has better logging, and doesn't require injecting params only needed in the superclass.
Bug: 362719719
Bug: 389600840
Test: PerDisplayInstanceRepositoryImplTest, Move shade between displays and check icon sizes
Flag: com.android.systemui.shade_window_goes_around
Flag: com.android.systemui.shared.status_bar_connected_displays
Change-Id: If929f9678f5b847e3274881ae3086f22b9ed90c1
7 files changed, 99 insertions, 128 deletions
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/PerDisplayInstanceRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/PerDisplayInstanceRepositoryImplTest.kt index 299105e2dabd..e41d46ce90af 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/PerDisplayInstanceRepositoryImplTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/PerDisplayInstanceRepositoryImplTest.kt @@ -20,6 +20,7 @@ import android.view.Display import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase +import com.android.systemui.dump.dumpManager import com.android.systemui.kosmos.testScope import com.android.systemui.kosmos.useUnconfinedTestDispatcher import com.android.systemui.testKosmos @@ -29,6 +30,9 @@ import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test import org.junit.runner.RunWith +import org.mockito.ArgumentMatchers.anyString +import org.mockito.kotlin.eq +import org.mockito.kotlin.verify @RunWith(AndroidJUnit4::class) @SmallTest @@ -99,6 +103,11 @@ class PerDisplayInstanceRepositoryImplTest : SysuiTestCase() { assertThat(fakePerDisplayInstanceProviderWithTeardown.destroyed).isEmpty() } + @Test + fun start_registersDumpable() { + verify(kosmos.dumpManager).registerNormalDumpable(anyString(), eq(underTest)) + } + private fun createDisplay(displayId: Int): Display = display(type = Display.TYPE_INTERNAL, id = displayId) diff --git a/packages/SystemUI/src/com/android/systemui/common/ui/ConfigurationState.kt b/packages/SystemUI/src/com/android/systemui/common/ui/ConfigurationState.kt index ba7e17bdd7a5..07cc136e6bc6 100644 --- a/packages/SystemUI/src/com/android/systemui/common/ui/ConfigurationState.kt +++ b/packages/SystemUI/src/com/android/systemui/common/ui/ConfigurationState.kt @@ -23,7 +23,6 @@ import androidx.annotation.ColorInt import androidx.annotation.DimenRes import androidx.annotation.LayoutRes import com.android.settingslib.Utils -import com.android.systemui.statusbar.data.repository.StatusBarConfigurationState import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.statusbar.policy.onDensityOrFontScaleChanged import com.android.systemui.statusbar.policy.onThemeChanged @@ -79,7 +78,7 @@ class ConfigurationStateImpl constructor( @Assisted private val configurationController: ConfigurationController, @Assisted private val context: Context, -) : ConfigurationState, StatusBarConfigurationState { +) : ConfigurationState { private val layoutInflater = LayoutInflater.from(context) diff --git a/packages/SystemUI/src/com/android/systemui/display/data/repository/PerDisplayRepository.kt b/packages/SystemUI/src/com/android/systemui/display/data/repository/PerDisplayRepository.kt index 3458c9549665..adf84900c8ba 100644 --- a/packages/SystemUI/src/com/android/systemui/display/data/repository/PerDisplayRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/display/data/repository/PerDisplayRepository.kt @@ -126,7 +126,7 @@ constructor( get() = perDisplayInstances.keys private suspend fun start() { - dumpManager.registerDumpable(this) + dumpManager.registerNormalDumpable("PerDisplayRepository-${debugName}", this) displayRepository.displayIds.collectLatest { displayIds -> val toRemove = perDisplayInstances.keys - displayIds toRemove.forEach { displayId -> @@ -198,3 +198,17 @@ class DefaultDisplayOnlyInstanceRepositoryImpl<T>( override fun get(displayId: Int): T? = lazyDefaultDisplayInstance } + +/** + * Always returns only one instance. + * + * This can be used to provide a single instance based on a flag value during a refactor. Similar to + * [DefaultDisplayOnlyInstanceRepositoryImpl], but also avoids creating the + * [PerDisplayInstanceProvider]. + */ +class SingleInstanceRepositoryImpl<T>(override val debugName: String, private val instance: T) : + PerDisplayRepository<T> { + override val displayIds: Set<Int> = setOf(Display.DEFAULT_DISPLAY) + + override fun get(displayId: Int): T? = instance +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/data/StatusBarDataLayerModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/data/StatusBarDataLayerModule.kt index 5e7e1793ab35..9db2f4b46dae 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/data/StatusBarDataLayerModule.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/data/StatusBarDataLayerModule.kt @@ -20,9 +20,9 @@ import com.android.systemui.statusbar.data.repository.KeyguardStatusBarRepositor import com.android.systemui.statusbar.data.repository.LightBarControllerStoreModule import com.android.systemui.statusbar.data.repository.RemoteInputRepositoryModule import com.android.systemui.statusbar.data.repository.StatusBarConfigurationControllerModule -import com.android.systemui.statusbar.data.repository.StatusBarConfigurationStateModule import com.android.systemui.statusbar.data.repository.StatusBarContentInsetsProviderStoreModule import com.android.systemui.statusbar.data.repository.StatusBarModeRepositoryModule +import com.android.systemui.statusbar.data.repository.StatusBarPerDisplayConfigurationStateModule import com.android.systemui.statusbar.data.repository.SystemEventChipAnimationControllerStoreModule import com.android.systemui.statusbar.phone.data.StatusBarPhoneDataLayerModule import dagger.Module @@ -35,7 +35,7 @@ import dagger.Module LightBarControllerStoreModule::class, RemoteInputRepositoryModule::class, StatusBarConfigurationControllerModule::class, - StatusBarConfigurationStateModule::class, + StatusBarPerDisplayConfigurationStateModule::class, StatusBarContentInsetsProviderStoreModule::class, StatusBarModeRepositoryModule::class, StatusBarPhoneDataLayerModule::class, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarConfigurationStateStore.kt b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarConfigurationStateStore.kt deleted file mode 100644 index 4e6c5ddc3066..000000000000 --- a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarConfigurationStateStore.kt +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (C) 2025 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.statusbar.data.repository - -import android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR -import com.android.systemui.CoreStartable -import com.android.systemui.common.ui.ConfigurationState -import com.android.systemui.common.ui.ConfigurationStateImpl -import com.android.systemui.dagger.SysUISingleton -import com.android.systemui.dagger.qualifiers.Background -import com.android.systemui.dagger.qualifiers.Main -import com.android.systemui.display.data.repository.DisplayRepository -import com.android.systemui.display.data.repository.DisplayWindowPropertiesRepository -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.core.StatusBarConnectedDisplays -import dagger.Lazy -import dagger.Module -import dagger.Provides -import dagger.multibindings.ClassKey -import dagger.multibindings.IntoMap -import javax.inject.Inject -import kotlinx.coroutines.CoroutineScope - -/** Status bar specific interface to disambiguate from the global [ConfigurationState]. */ -interface StatusBarConfigurationState : ConfigurationState - -/** Provides per display instances of [ConfigurationState], specifically for the Status Bar. */ -interface StatusBarConfigurationStateStore : PerDisplayStore<StatusBarConfigurationState> - -@SysUISingleton -class MultiDisplayStatusBarConfigurationStateStore -@Inject -constructor( - @Background backgroundApplicationScope: CoroutineScope, - displayRepository: DisplayRepository, - private val displayWindowPropertiesRepository: DisplayWindowPropertiesRepository, - private val statusBarConfigurationControllerStore: StatusBarConfigurationControllerStore, - private val factory: ConfigurationStateImpl.Factory, -) : - StatusBarConfigurationStateStore, - PerDisplayStoreImpl<StatusBarConfigurationState>( - backgroundApplicationScope, - displayRepository, - ) { - - init { - StatusBarConnectedDisplays.unsafeAssertInNewMode() - } - - override fun createInstanceForDisplay(displayId: Int): StatusBarConfigurationState? { - val displayWindowProperties = - displayWindowPropertiesRepository.get(displayId, TYPE_STATUS_BAR) ?: return null - val configController = - statusBarConfigurationControllerStore.forDisplay(displayId) ?: return null - return factory.create(displayWindowProperties.context, configController) - } - - override val instanceClass = StatusBarConfigurationState::class.java -} - -@SysUISingleton -class SingleDisplayStatusBarConfigurationStateStore -@Inject -constructor(@Main globalConfigState: ConfigurationState) : - StatusBarConfigurationStateStore, - PerDisplayStore<StatusBarConfigurationState> by SingleDisplayStore( - globalConfigState as StatusBarConfigurationState - ) { - - init { - StatusBarConnectedDisplays.assertInLegacyMode() - } -} - -@Module -object StatusBarConfigurationStateModule { - - @Provides - @SysUISingleton - fun store( - singleDisplayLazy: Lazy<SingleDisplayStatusBarConfigurationStateStore>, - multiDisplayLazy: Lazy<MultiDisplayStatusBarConfigurationStateStore>, - ): StatusBarConfigurationStateStore { - return if (StatusBarConnectedDisplays.isEnabled) { - multiDisplayLazy.get() - } else { - singleDisplayLazy.get() - } - } - - @Provides - @SysUISingleton - @IntoMap - @ClassKey(StatusBarConfigurationStateStore::class) - fun storeAsCoreStartable( - multiDisplayLazy: Lazy<MultiDisplayStatusBarConfigurationStateStore> - ): CoreStartable { - return if (StatusBarConnectedDisplays.isEnabled) { - multiDisplayLazy.get() - } else { - CoreStartable.NOP - } - } -} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarPerDisplayConfigurationStateRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarPerDisplayConfigurationStateRepository.kt new file mode 100644 index 000000000000..3168a22c56ad --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarPerDisplayConfigurationStateRepository.kt @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.data.repository + +import android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR +import com.android.systemui.common.ui.ConfigurationState +import com.android.systemui.common.ui.ConfigurationStateImpl +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.display.data.repository.DisplayWindowPropertiesRepository +import com.android.systemui.display.data.repository.PerDisplayInstanceProvider +import com.android.systemui.display.data.repository.PerDisplayInstanceRepositoryImpl +import com.android.systemui.display.data.repository.PerDisplayRepository +import com.android.systemui.display.data.repository.SingleInstanceRepositoryImpl +import com.android.systemui.statusbar.core.StatusBarConnectedDisplays +import dagger.Lazy +import dagger.Module +import dagger.Provides +import javax.inject.Inject + +@SysUISingleton +class StatusBarPerDisplayConfigurationStateProvider +@Inject +constructor( + private val displayWindowPropertiesRepository: DisplayWindowPropertiesRepository, + private val statusBarConfigurationControllerStore: StatusBarConfigurationControllerStore, + private val factory: ConfigurationStateImpl.Factory, +) : PerDisplayInstanceProvider<ConfigurationState> { + + override fun createInstance(displayId: Int): ConfigurationState? { + val displayWindowProperties = + displayWindowPropertiesRepository.get(displayId, TYPE_STATUS_BAR) ?: return null + val configController = + statusBarConfigurationControllerStore.forDisplay(displayId) ?: return null + return factory.create(displayWindowProperties.context, configController) + } +} + +@Module +object StatusBarPerDisplayConfigurationStateModule { + + @Provides + @SysUISingleton + fun store( + instanceProvider: Lazy<StatusBarPerDisplayConfigurationStateProvider>, + factory: PerDisplayInstanceRepositoryImpl.Factory<ConfigurationState>, + defaultInstance: ConfigurationState, + ): PerDisplayRepository<ConfigurationState> { + val name = "ConfigurationState" + return if (StatusBarConnectedDisplays.isEnabled) { + factory.create(name, instanceProvider.get()) + } else { + SingleInstanceRepositoryImpl(name, defaultInstance) + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerStatusBarViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerStatusBarViewBinder.kt index 30aec8dabcaa..147a5afea306 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerStatusBarViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerStatusBarViewBinder.kt @@ -20,8 +20,8 @@ import android.view.Display import androidx.lifecycle.lifecycleScope import com.android.app.tracing.traceSection import com.android.systemui.common.ui.ConfigurationState +import com.android.systemui.display.data.repository.PerDisplayRepository import com.android.systemui.lifecycle.repeatWhenAttached -import com.android.systemui.statusbar.data.repository.StatusBarConfigurationStateStore import com.android.systemui.statusbar.notification.collection.NotifCollection import com.android.systemui.statusbar.notification.icon.ui.viewbinder.NotificationIconContainerViewBinder.IconViewStore import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconContainerStatusBarViewModel @@ -36,7 +36,7 @@ class NotificationIconContainerStatusBarViewBinder @Inject constructor( private val viewModel: NotificationIconContainerStatusBarViewModel, - private val configurationStore: StatusBarConfigurationStateStore, + private val configurationStateRepository: PerDisplayRepository<ConfigurationState>, private val defaultConfigurationState: ConfigurationState, private val systemBarUtilsState: SystemBarUtilsState, private val failureTracker: StatusBarIconViewBindingFailureTracker, @@ -57,7 +57,7 @@ constructor( } } val configurationState: ConfigurationState = - configurationStore.forDisplay(displayId) ?: defaultConfigurationState + configurationStateRepository[displayId] ?: defaultConfigurationState lifecycleScope.launch { NotificationIconContainerViewBinder.bind( displayId = displayId, |