Loading core/java/android/app/notification.aconfig +10 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,16 @@ flag { bug: "270703654" } flag { name: "modes_ui_icons" namespace: "systemui" description: "Shows current Priority Mode icon in lockscreen, status bar, and QS; dependent on flags modes_api and modes_ui" bug: "360399800" metadata { purpose: PURPOSE_BUGFIX } } flag { name: "modes_ui_test" namespace: "systemui" Loading packages/SettingsLib/src/com/android/settingslib/notification/data/repository/FakeZenModeRepository.kt +6 −4 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.settingslib.notification.data.repository import android.app.AutomaticZenRule import android.app.NotificationManager import android.provider.Settings import com.android.settingslib.notification.modes.TestModeBuilder Loading Loading @@ -58,8 +59,9 @@ class FakeZenModeRepository : ZenModeRepository { mutableModesFlow.value += zenModes } fun addMode(id: String, active: Boolean = false) { mutableModesFlow.value += newMode(id, active) fun addMode(id: String, @AutomaticZenRule.Type type: Int = AutomaticZenRule.TYPE_UNKNOWN, active: Boolean = false) { mutableModesFlow.value += newMode(id, type, active) } fun removeMode(id: String) { Loading Loading @@ -128,6 +130,6 @@ fun FakeZenModeRepository.updateNotificationPolicy( ) ) private fun newMode(id: String, active: Boolean = false): ZenMode { return TestModeBuilder().setId(id).setName("Mode $id").setActive(active).build() private fun newMode(id: String, @AutomaticZenRule.Type type: Int, active: Boolean): ZenMode { return TestModeBuilder().setId(id).setName("Mode $id").setType(type).setActive(active).build() } packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenMode.java +1 −1 Original line number Diff line number Diff line Loading @@ -112,7 +112,7 @@ public class ZenMode implements Parcelable { }; // Manual DND first, Bedtime/Driving, then alphabetically. static final Comparator<ZenMode> PRIORITIZING_COMPARATOR = Comparator public static final Comparator<ZenMode> PRIORITIZING_COMPARATOR = Comparator .comparing(ZenMode::isManualDnd).reversed() .thenComparing(ZenMode::getType, PRIORITIZED_TYPE_COMPARATOR) .thenComparing(ZenMode::getName); Loading packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileDataInteractorTest.kt +76 −2 Original line number Diff line number Diff line Loading @@ -16,19 +16,24 @@ package com.android.systemui.qs.tiles.impl.modes.domain.interactor import android.app.AutomaticZenRule import android.app.Flags import android.graphics.drawable.TestStubDrawable import android.os.UserHandle 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.common.shared.model.asIcon import com.android.systemui.coroutines.collectValues import com.android.systemui.kosmos.testDispatcher import com.android.systemui.kosmos.testScope import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesTileModel import com.android.systemui.shared.notifications.data.repository.NotificationSettingsRepository import com.android.systemui.statusbar.policy.data.repository.fakeZenModeRepository import com.android.systemui.statusbar.policy.domain.interactor.ZenModeInteractor import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi Loading @@ -36,8 +41,10 @@ import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.toCollection import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.kotlin.mock @OptIn(ExperimentalCoroutinesApi::class) @SmallTest Loading @@ -48,7 +55,20 @@ class ModesTileDataInteractorTest : SysuiTestCase() { private val dispatcher = kosmos.testDispatcher private val zenModeRepository = kosmos.fakeZenModeRepository private val underTest = ModesTileDataInteractor(zenModeRepository, dispatcher) private val underTest = ModesTileDataInteractor( context, ZenModeInteractor(zenModeRepository, mock<NotificationSettingsRepository>()), dispatcher ) @Before fun setUp() { context.orCreateTestableResources.apply { addOverride(com.android.internal.R.drawable.ic_zen_mode_type_bedtime, BEDTIME_DRAWABLE) addOverride(com.android.internal.R.drawable.ic_zen_mode_type_driving, DRIVING_DRAWABLE) } } @EnableFlags(Flags.FLAG_MODES_UI) @Test Loading Loading @@ -110,8 +130,62 @@ class ModesTileDataInteractorTest : SysuiTestCase() { assertThat(dataList.map { it.activeModes }.last()).isEmpty() } private companion object { @Test @EnableFlags(Flags.FLAG_MODES_UI, Flags.FLAG_MODES_UI_ICONS) fun changesIconWhenActiveModesChange() = testScope.runTest { val dataList: List<ModesTileModel> by collectValues( underTest.tileData(TEST_USER, flowOf(DataUpdateTrigger.InitialRequest)) ) runCurrent() assertThat(dataList.map { it.icon }).containsExactly(null).inOrder() // Add an inactive mode: state hasn't changed, so this shouldn't cause another emission zenModeRepository.addMode(id = "Mode", active = false) runCurrent() assertThat(dataList.map { it.icon }).containsExactly(null).inOrder() // Add an active mode: icon should be the mode icon zenModeRepository.addMode( id = "Bedtime", type = AutomaticZenRule.TYPE_BEDTIME, active = true ) runCurrent() assertThat(dataList.map { it.icon }).containsExactly(null, BEDTIME_ICON).inOrder() // Add another, less-prioritized mode: icon should remain the first mode icon zenModeRepository.addMode( id = "Driving", type = AutomaticZenRule.TYPE_DRIVING, active = true ) runCurrent() assertThat(dataList.map { it.icon }) .containsExactly(null, BEDTIME_ICON, BEDTIME_ICON) .inOrder() // Deactivate more important mode: icon should be the less important, still active mode. zenModeRepository.deactivateMode("Bedtime") runCurrent() assertThat(dataList.map { it.icon }) .containsExactly(null, BEDTIME_ICON, BEDTIME_ICON, DRIVING_ICON) .inOrder() // Deactivate remaining mode: no icon zenModeRepository.deactivateMode("Driving") runCurrent() assertThat(dataList.map { it.icon }) .containsExactly(null, BEDTIME_ICON, BEDTIME_ICON, DRIVING_ICON, null) .inOrder() } private companion object { val TEST_USER = UserHandle.of(1)!! val BEDTIME_DRAWABLE = TestStubDrawable("bedtime") val DRIVING_DRAWABLE = TestStubDrawable("driving") val BEDTIME_ICON = BEDTIME_DRAWABLE.asIcon() val DRIVING_ICON = DRIVING_DRAWABLE.asIcon() } } packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/ui/ModesTileMapperTest.kt +16 −0 Original line number Diff line number Diff line Loading @@ -16,10 +16,13 @@ package com.android.systemui.qs.tiles.impl.modes.ui import android.app.Flags import android.graphics.drawable.TestStubDrawable 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.common.shared.model.Icon import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesTileModel import com.android.systemui.qs.tiles.viewmodel.QSTileConfigTestBuilder import com.android.systemui.qs.tiles.viewmodel.QSTileState Loading @@ -31,6 +34,7 @@ import org.junit.runner.RunWith @SmallTest @RunWith(AndroidJUnit4::class) @EnableFlags(Flags.FLAG_MODES_UI) class ModesTileMapperTest : SysuiTestCase() { val config = QSTileConfigTestBuilder.build { Loading Loading @@ -85,4 +89,16 @@ class ModesTileMapperTest : SysuiTestCase() { assertThat(state.iconRes).isEqualTo(R.drawable.qs_dnd_icon_on) assertThat(state.secondaryLabel).isEqualTo("3 modes are active") } @Test @EnableFlags(Flags.FLAG_MODES_UI_ICONS) fun activeState_withIcon() { val icon = Icon.Resource(1234, contentDescription = null) val model = ModesTileModel(isActivated = true, activeModes = listOf("DND"), icon = icon) val state = underTest.map(config, model) assertThat(state.iconRes).isNull() assertThat(state.icon()).isEqualTo(icon) } } Loading
core/java/android/app/notification.aconfig +10 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,16 @@ flag { bug: "270703654" } flag { name: "modes_ui_icons" namespace: "systemui" description: "Shows current Priority Mode icon in lockscreen, status bar, and QS; dependent on flags modes_api and modes_ui" bug: "360399800" metadata { purpose: PURPOSE_BUGFIX } } flag { name: "modes_ui_test" namespace: "systemui" Loading
packages/SettingsLib/src/com/android/settingslib/notification/data/repository/FakeZenModeRepository.kt +6 −4 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.settingslib.notification.data.repository import android.app.AutomaticZenRule import android.app.NotificationManager import android.provider.Settings import com.android.settingslib.notification.modes.TestModeBuilder Loading Loading @@ -58,8 +59,9 @@ class FakeZenModeRepository : ZenModeRepository { mutableModesFlow.value += zenModes } fun addMode(id: String, active: Boolean = false) { mutableModesFlow.value += newMode(id, active) fun addMode(id: String, @AutomaticZenRule.Type type: Int = AutomaticZenRule.TYPE_UNKNOWN, active: Boolean = false) { mutableModesFlow.value += newMode(id, type, active) } fun removeMode(id: String) { Loading Loading @@ -128,6 +130,6 @@ fun FakeZenModeRepository.updateNotificationPolicy( ) ) private fun newMode(id: String, active: Boolean = false): ZenMode { return TestModeBuilder().setId(id).setName("Mode $id").setActive(active).build() private fun newMode(id: String, @AutomaticZenRule.Type type: Int, active: Boolean): ZenMode { return TestModeBuilder().setId(id).setName("Mode $id").setType(type).setActive(active).build() }
packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenMode.java +1 −1 Original line number Diff line number Diff line Loading @@ -112,7 +112,7 @@ public class ZenMode implements Parcelable { }; // Manual DND first, Bedtime/Driving, then alphabetically. static final Comparator<ZenMode> PRIORITIZING_COMPARATOR = Comparator public static final Comparator<ZenMode> PRIORITIZING_COMPARATOR = Comparator .comparing(ZenMode::isManualDnd).reversed() .thenComparing(ZenMode::getType, PRIORITIZED_TYPE_COMPARATOR) .thenComparing(ZenMode::getName); Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileDataInteractorTest.kt +76 −2 Original line number Diff line number Diff line Loading @@ -16,19 +16,24 @@ package com.android.systemui.qs.tiles.impl.modes.domain.interactor import android.app.AutomaticZenRule import android.app.Flags import android.graphics.drawable.TestStubDrawable import android.os.UserHandle 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.common.shared.model.asIcon import com.android.systemui.coroutines.collectValues import com.android.systemui.kosmos.testDispatcher import com.android.systemui.kosmos.testScope import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesTileModel import com.android.systemui.shared.notifications.data.repository.NotificationSettingsRepository import com.android.systemui.statusbar.policy.data.repository.fakeZenModeRepository import com.android.systemui.statusbar.policy.domain.interactor.ZenModeInteractor import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi Loading @@ -36,8 +41,10 @@ import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.toCollection import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.kotlin.mock @OptIn(ExperimentalCoroutinesApi::class) @SmallTest Loading @@ -48,7 +55,20 @@ class ModesTileDataInteractorTest : SysuiTestCase() { private val dispatcher = kosmos.testDispatcher private val zenModeRepository = kosmos.fakeZenModeRepository private val underTest = ModesTileDataInteractor(zenModeRepository, dispatcher) private val underTest = ModesTileDataInteractor( context, ZenModeInteractor(zenModeRepository, mock<NotificationSettingsRepository>()), dispatcher ) @Before fun setUp() { context.orCreateTestableResources.apply { addOverride(com.android.internal.R.drawable.ic_zen_mode_type_bedtime, BEDTIME_DRAWABLE) addOverride(com.android.internal.R.drawable.ic_zen_mode_type_driving, DRIVING_DRAWABLE) } } @EnableFlags(Flags.FLAG_MODES_UI) @Test Loading Loading @@ -110,8 +130,62 @@ class ModesTileDataInteractorTest : SysuiTestCase() { assertThat(dataList.map { it.activeModes }.last()).isEmpty() } private companion object { @Test @EnableFlags(Flags.FLAG_MODES_UI, Flags.FLAG_MODES_UI_ICONS) fun changesIconWhenActiveModesChange() = testScope.runTest { val dataList: List<ModesTileModel> by collectValues( underTest.tileData(TEST_USER, flowOf(DataUpdateTrigger.InitialRequest)) ) runCurrent() assertThat(dataList.map { it.icon }).containsExactly(null).inOrder() // Add an inactive mode: state hasn't changed, so this shouldn't cause another emission zenModeRepository.addMode(id = "Mode", active = false) runCurrent() assertThat(dataList.map { it.icon }).containsExactly(null).inOrder() // Add an active mode: icon should be the mode icon zenModeRepository.addMode( id = "Bedtime", type = AutomaticZenRule.TYPE_BEDTIME, active = true ) runCurrent() assertThat(dataList.map { it.icon }).containsExactly(null, BEDTIME_ICON).inOrder() // Add another, less-prioritized mode: icon should remain the first mode icon zenModeRepository.addMode( id = "Driving", type = AutomaticZenRule.TYPE_DRIVING, active = true ) runCurrent() assertThat(dataList.map { it.icon }) .containsExactly(null, BEDTIME_ICON, BEDTIME_ICON) .inOrder() // Deactivate more important mode: icon should be the less important, still active mode. zenModeRepository.deactivateMode("Bedtime") runCurrent() assertThat(dataList.map { it.icon }) .containsExactly(null, BEDTIME_ICON, BEDTIME_ICON, DRIVING_ICON) .inOrder() // Deactivate remaining mode: no icon zenModeRepository.deactivateMode("Driving") runCurrent() assertThat(dataList.map { it.icon }) .containsExactly(null, BEDTIME_ICON, BEDTIME_ICON, DRIVING_ICON, null) .inOrder() } private companion object { val TEST_USER = UserHandle.of(1)!! val BEDTIME_DRAWABLE = TestStubDrawable("bedtime") val DRIVING_DRAWABLE = TestStubDrawable("driving") val BEDTIME_ICON = BEDTIME_DRAWABLE.asIcon() val DRIVING_ICON = DRIVING_DRAWABLE.asIcon() } }
packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/ui/ModesTileMapperTest.kt +16 −0 Original line number Diff line number Diff line Loading @@ -16,10 +16,13 @@ package com.android.systemui.qs.tiles.impl.modes.ui import android.app.Flags import android.graphics.drawable.TestStubDrawable 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.common.shared.model.Icon import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesTileModel import com.android.systemui.qs.tiles.viewmodel.QSTileConfigTestBuilder import com.android.systemui.qs.tiles.viewmodel.QSTileState Loading @@ -31,6 +34,7 @@ import org.junit.runner.RunWith @SmallTest @RunWith(AndroidJUnit4::class) @EnableFlags(Flags.FLAG_MODES_UI) class ModesTileMapperTest : SysuiTestCase() { val config = QSTileConfigTestBuilder.build { Loading Loading @@ -85,4 +89,16 @@ class ModesTileMapperTest : SysuiTestCase() { assertThat(state.iconRes).isEqualTo(R.drawable.qs_dnd_icon_on) assertThat(state.secondaryLabel).isEqualTo("3 modes are active") } @Test @EnableFlags(Flags.FLAG_MODES_UI_ICONS) fun activeState_withIcon() { val icon = Icon.Resource(1234, contentDescription = null) val model = ModesTileModel(isActivated = true, activeModes = listOf("DND"), icon = icon) val state = underTest.map(config, model) assertThat(state.iconRes).isNull() assertThat(state.icon()).isEqualTo(icon) } }