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

Commit 7c425e66 authored by Ioana Alexandru's avatar Ioana Alexandru
Browse files

Fix empty shade string not updating on locale change

Fix: 392173478
Test: EmptyShadeViewModelTest
Flag: android.app.modes_ui
Change-Id: Ia674ab000a0cb3f589f55deab97509d93cb2ca75
parent 53d05392
Loading
Loading
Loading
Loading
+52 −0
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@ package com.android.systemui.statusbar.notification.emptyshade.ui.viewmodel

import android.app.Flags
import android.app.NotificationManager.Policy
import android.content.res.Configuration
import android.os.LocaleList
import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
import android.platform.test.flag.junit.FlagsParameterization
@@ -27,6 +29,7 @@ import androidx.test.filters.SmallTest
import com.android.settingslib.notification.data.repository.updateNotificationPolicy
import com.android.settingslib.notification.modes.TestModeBuilder
import com.android.systemui.SysuiTestCase
import com.android.systemui.common.ui.data.repository.fakeConfigurationRepository
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.flags.andSceneContainer
import com.android.systemui.kosmos.testScope
@@ -36,9 +39,12 @@ import com.android.systemui.statusbar.notification.emptyshade.shared.ModesEmptyS
import com.android.systemui.statusbar.policy.data.repository.zenModeRepository
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import java.util.Locale
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import platform.test.runner.parameterized.ParameterizedAndroidJunit4
@@ -53,6 +59,10 @@ class EmptyShadeViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
    private val zenModeRepository = kosmos.zenModeRepository
    private val activeNotificationListRepository = kosmos.activeNotificationListRepository
    private val fakeSecureSettingsRepository = kosmos.fakeSecureSettingsRepository
    private val fakeConfigurationRepository = kosmos.fakeConfigurationRepository

    /** Backup of the current locales, to be restored at the end of the test if they are changed. */
    private lateinit var originalLocales: LocaleList

    private val underTest by lazy { kosmos.emptyShadeViewModel }

@@ -68,6 +78,18 @@ class EmptyShadeViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
        mSetFlagsRule.setFlagsParameterization(flags)
    }

    @Before
    fun setUp() {
        originalLocales = context.resources.configuration.locales
        updateLocales(LocaleList(Locale.US))
    }

    @After
    fun tearDown() {
        // Make sure we restore the original locale even if a test fails after changing it
        updateLocales(originalLocales)
    }

    @Test
    fun areNotificationsHiddenInShade_true() =
        testScope.runTest {
@@ -142,6 +164,29 @@ class EmptyShadeViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
            assertThat(text).isEqualTo("Notifications paused by Do Not Disturb")
        }

    @Test
    @EnableFlags(ModesEmptyShadeFix.FLAG_NAME, Flags.FLAG_MODES_UI, Flags.FLAG_MODES_API)
    fun text_changesWhenLocaleChanges() =
        testScope.runTest {
            val text by collectLastValue(underTest.text)

            zenModeRepository.updateNotificationPolicy(
                suppressedVisualEffects = Policy.SUPPRESSED_EFFECT_NOTIFICATION_LIST
            )
            zenModeRepository.updateZenMode(Settings.Global.ZEN_MODE_OFF)
            runCurrent()

            assertThat(text).isEqualTo("No notifications")

            updateLocales(LocaleList(Locale.GERMAN))
            runCurrent()

            assertThat(text).isEqualTo("Keine Benachrichtigungen")

            // Make sure we restore the original locales
            updateLocales(originalLocales)
        }

    @Test
    @EnableFlags(ModesEmptyShadeFix.FLAG_NAME, Flags.FLAG_MODES_UI, Flags.FLAG_MODES_API)
    fun text_reflectsModesHidingNotifications() =
@@ -285,4 +330,11 @@ class EmptyShadeViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
            assertThat(onClick?.targetIntent?.action).isEqualTo(Settings.ACTION_ZEN_MODE_SETTINGS)
            assertThat(onClick?.backStack).isEmpty()
        }

    private fun updateLocales(locales: LocaleList) {
        val configuration = Configuration()
        configuration.setLocales(locales)
        context.resources.updateConfiguration(configuration, context.resources.displayMetrics)
        fakeConfigurationRepository.onConfigurationChange(configuration)
    }
}
+17 −4
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.systemui.statusbar.notification.emptyshade.ui.viewmodel

import android.content.Context
import android.icu.text.MessageFormat
import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dump.DumpManager
import com.android.systemui.modes.shared.ModesUi
@@ -36,9 +37,11 @@ import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onStart

/**
 * ViewModel for the empty shade (aka the "No notifications" text shown when there are no
@@ -51,6 +54,7 @@ constructor(
    zenModeInteractor: ZenModeInteractor,
    seenNotificationsInteractor: SeenNotificationsInteractor,
    notificationSettingsInteractor: NotificationSettingsInteractor,
    configurationInteractor: ConfigurationInteractor,
    @Background bgDispatcher: CoroutineDispatcher,
    dumpManager: DumpManager,
) : FlowDumperImpl(dumpManager) {
@@ -71,6 +75,13 @@ constructor(
            "hasFilteredOutSeenNotifications"
        )

    private val primaryLocale by lazy {
        configurationInteractor.configurationValues
            .map { it.locales.get(0) ?: Locale.getDefault() }
            .onStart { emit(Locale.getDefault()) }
            .distinctUntilChanged()
    }

    val text: Flow<String> by lazy {
        if (ModesEmptyShadeFix.isUnexpectedlyInLegacyMode()) {
            flowOf(context.getString(R.string.empty_shade_text))
@@ -79,14 +90,16 @@ constructor(
            // recommended architecture, and making it so it reacts to changes for the new Modes.
            // The former does not depend on the modes flags being on, but the latter does.
            if (ModesUi.isEnabled) {
                    zenModeInteractor.modesHidingNotifications.map { modes ->
                    combine(zenModeInteractor.modesHidingNotifications, primaryLocale) {
                        modes,
                        locale ->
                        // Create a string that is either "No notifications" if no modes are
                        // filtering
                        // them out, or something like "Notifications paused by SomeMode" otherwise.
                        // filtering them out, or something like "Notifications paused by SomeMode"
                        // otherwise.
                        val msgFormat =
                            MessageFormat(
                                context.getString(R.string.modes_suppressing_shade_text),
                                Locale.getDefault(),
                                locale,
                            )
                        val count = modes.count()
                        val args: MutableMap<String, Any> = HashMap()
+2 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.systemui.statusbar.notification.emptyshade.ui.viewmodel

import android.content.applicationContext
import com.android.systemui.common.ui.domain.interactor.configurationInteractor
import com.android.systemui.dump.dumpManager
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.testDispatcher
@@ -31,6 +32,7 @@ val Kosmos.emptyShadeViewModel by
            zenModeInteractor,
            seenNotificationsInteractor,
            notificationSettingsInteractor,
            configurationInteractor,
            testDispatcher,
            dumpManager,
        )