Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b7e21647 authored by Nicolo' Mazzucato's avatar Nicolo' Mazzucato
Browse files

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
parent e5db5c65
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -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)

+1 −2
Original line number Diff line number Diff line
@@ -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)

+15 −1
Original line number Diff line number Diff line
@@ -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
}
+2 −2
Original line number Diff line number Diff line
@@ -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,
+69 −0
Original line number Diff line number Diff line
@@ -17,104 +17,53 @@
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.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 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
class StatusBarPerDisplayConfigurationStateProvider
@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,
    ) {
) : PerDisplayInstanceProvider<ConfigurationState> {

    init {
        StatusBarConnectedDisplays.unsafeAssertInNewMode()
    }

    override fun createInstanceForDisplay(displayId: Int): StatusBarConfigurationState? {
    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)
    }

    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 {
object StatusBarPerDisplayConfigurationStateModule {

    @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 {
        instanceProvider: Lazy<StatusBarPerDisplayConfigurationStateProvider>,
        factory: PerDisplayInstanceRepositoryImpl.Factory<ConfigurationState>,
        defaultInstance: ConfigurationState,
    ): PerDisplayRepository<ConfigurationState> {
        val name = "ConfigurationState"
        return if (StatusBarConnectedDisplays.isEnabled) {
            multiDisplayLazy.get()
            factory.create(name, instanceProvider.get())
        } else {
            CoreStartable.NOP
            SingleInstanceRepositoryImpl(name, defaultInstance)
        }
    }
}
Loading