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

Commit 1ae474da authored by Chris Göllner's avatar Chris Göllner Committed by Android (Google) Code Review
Browse files

Merge "Per display ConfigurationController for Status Bar" into main

parents bd417aa3 06d462b5
Loading
Loading
Loading
Loading
+62 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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.window

import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.statusbar.core.StatusBarConnectedDisplays
import com.android.systemui.statusbar.policy.statusBarConfigurationController
import com.android.systemui.testKosmos
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.kotlin.any
import org.mockito.kotlin.never
import org.mockito.kotlin.verify

@SmallTest
@RunWith(AndroidJUnit4::class)
class StatusBarWindowControllerImplTest : SysuiTestCase() {

    private val kosmos =
        testKosmos().also { it.statusBarWindowViewInflater = it.fakeStatusBarWindowViewInflater }

    private val underTest = kosmos.statusBarWindowControllerImpl
    private val fakeStatusBarWindowViewInflater = kosmos.fakeStatusBarWindowViewInflater
    private val statusBarConfigurationController = kosmos.statusBarConfigurationController

    @Test
    @EnableFlags(StatusBarConnectedDisplays.FLAG_NAME)
    fun attach_connectedDisplaysFlagEnabled_setsConfigControllerOnWindowView() {
        val windowView = fakeStatusBarWindowViewInflater.inflatedMockViews.first()

        underTest.attach()

        verify(windowView).setStatusBarConfigurationController(statusBarConfigurationController)
    }

    @Test
    @DisableFlags(StatusBarConnectedDisplays.FLAG_NAME)
    fun attach_connectedDisplaysFlagDisabled_doesNotSetConfigControllerOnWindowView() {
        val mockWindowView = fakeStatusBarWindowViewInflater.inflatedMockViews.first()

        underTest.attach()

        verify(mockWindowView, never()).setStatusBarConfigurationController(any())
    }
}
+56 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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.window

import android.content.res.Configuration
import android.view.LayoutInflater
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.res.R
import com.android.systemui.statusbar.data.repository.StatusBarConfigurationController
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.kotlin.mock
import org.mockito.kotlin.verify

@SmallTest
@RunWith(AndroidJUnit4::class)
class StatusBarWindowViewTest : SysuiTestCase() {

    private val underTest =
        LayoutInflater.from(context).inflate(R.layout.super_status_bar, /* root= */ null)
            as StatusBarWindowView

    @Test
    fun onConfigurationChanged_configurationControllerSet_forwardsCall() {
        val configuration = Configuration()
        val configurationController = mock<StatusBarConfigurationController>()
        underTest.setStatusBarConfigurationController(configurationController)

        underTest.onConfigurationChanged(configuration)

        verify(configurationController).onConfigurationChanged(configuration)
    }

    @Test
    fun onConfigurationChanged_configurationControllerNotSet_doesNotCrash() {
        val configuration = Configuration()

        underTest.onConfigurationChanged(configuration)
    }
}
+3 −1
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@ package com.android.systemui.statusbar.data

import com.android.systemui.statusbar.data.repository.KeyguardStatusBarRepositoryModule
import com.android.systemui.statusbar.data.repository.RemoteInputRepositoryModule
import com.android.systemui.statusbar.data.repository.StatusBarConfigurationControllerModule
import com.android.systemui.statusbar.data.repository.StatusBarModeRepositoryModule
import com.android.systemui.statusbar.phone.data.StatusBarPhoneDataLayerModule
import dagger.Module
@@ -26,8 +27,9 @@ import dagger.Module
        [
            KeyguardStatusBarRepositoryModule::class,
            RemoteInputRepositoryModule::class,
            StatusBarConfigurationControllerModule::class,
            StatusBarModeRepositoryModule::class,
            StatusBarPhoneDataLayerModule::class
            StatusBarPhoneDataLayerModule::class,
        ]
)
object StatusBarDataLayerModule
+117 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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.GlobalConfig
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
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 com.android.systemui.statusbar.phone.ConfigurationControllerImpl
import com.android.systemui.statusbar.policy.ConfigurationController
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 [ConfigurationController]. */
interface StatusBarConfigurationController : ConfigurationController

/** Provides per display instances of [ConfigurationController], specifically for the Status Bar. */
interface StatusBarConfigurationControllerStore : PerDisplayStore<StatusBarConfigurationController>

@SysUISingleton
class MultiDisplayStatusBarConfigurationControllerStore
@Inject
constructor(
    @Background backgroundApplicationScope: CoroutineScope,
    displayRepository: DisplayRepository,
    private val displayWindowPropertiesRepository: DisplayWindowPropertiesRepository,
    private val configurationControllerFactory: ConfigurationControllerImpl.Factory,
) :
    StatusBarConfigurationControllerStore,
    PerDisplayStoreImpl<StatusBarConfigurationController>(
        backgroundApplicationScope,
        displayRepository,
    ) {

    init {
        StatusBarConnectedDisplays.assertInNewMode()
    }

    override fun createInstanceForDisplay(displayId: Int): StatusBarConfigurationController {
        val displayWindowProperties =
            displayWindowPropertiesRepository.get(displayId, TYPE_STATUS_BAR)
        return configurationControllerFactory.create(displayWindowProperties.context)
    }

    override val instanceClass = StatusBarConfigurationController::class.java
}

@SysUISingleton
class SingleDisplayStatusBarConfigurationControllerStore
@Inject
constructor(@GlobalConfig globalConfigurationController: ConfigurationController) :
    StatusBarConfigurationControllerStore,
    PerDisplayStore<StatusBarConfigurationController> by SingleDisplayStore(
        globalConfigurationController as StatusBarConfigurationController
    ) {

    init {
        StatusBarConnectedDisplays.assertInLegacyMode()
    }
}

@Module
object StatusBarConfigurationControllerModule {

    @Provides
    @SysUISingleton
    fun store(
        singleDisplayLazy: Lazy<SingleDisplayStatusBarConfigurationControllerStore>,
        multiDisplayLazy: Lazy<MultiDisplayStatusBarConfigurationControllerStore>,
    ): StatusBarConfigurationControllerStore {
        return if (StatusBarConnectedDisplays.isEnabled) {
            multiDisplayLazy.get()
        } else {
            singleDisplayLazy.get()
        }
    }

    @Provides
    @SysUISingleton
    @IntoMap
    @ClassKey(StatusBarConfigurationControllerStore::class)
    fun storeAsCoreStartable(
        multiDisplayLazy: Lazy<MultiDisplayStatusBarConfigurationControllerStore>
    ): CoreStartable {
        return if (StatusBarConnectedDisplays.isEnabled) {
            multiDisplayLazy.get()
        } else {
            CoreStartable.NOP
        }
    }
}
+2 −1
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.content.res.Configuration
import android.graphics.Rect
import android.os.LocaleList
import android.view.View.LAYOUT_DIRECTION_RTL
import com.android.systemui.statusbar.data.repository.StatusBarConfigurationController
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener
import dagger.assisted.Assisted
@@ -30,7 +31,7 @@ class ConfigurationControllerImpl
@AssistedInject
constructor(
    @Assisted private val context: Context,
) : ConfigurationController {
) : ConfigurationController, StatusBarConfigurationController {

    private val listeners: MutableList<ConfigurationListener> = ArrayList()
    private val lastConfig = Configuration()
Loading