Loading packages/SettingsLib/src/com/android/settingslib/notification/data/repository/FakeZenModeRepository.kt +4 −0 Original line number Diff line number Diff line Loading @@ -61,6 +61,10 @@ class FakeZenModeRepository : ZenModeRepository { mutableModesFlow.value += zenModes } fun addMode(mode: ZenMode) { mutableModesFlow.value += mode } fun addMode(id: String, @AutomaticZenRule.Type type: Int = AutomaticZenRule.TYPE_UNKNOWN, active: Boolean = false) { mutableModesFlow.value += newMode(id, type, active) Loading packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileDataInteractorTest.kt +30 −15 Original line number Diff line number Diff line Loading @@ -25,7 +25,9 @@ import android.platform.test.annotations.EnableFlags import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.internal.R import com.android.settingslib.notification.modes.TestModeBuilder import com.android.systemui.SysuiTestCase import com.android.systemui.SysuiTestableContext import com.android.systemui.common.shared.model.asIcon import com.android.systemui.coroutines.collectLastValue import com.android.systemui.coroutines.collectValues Loading Loading @@ -62,7 +64,12 @@ class ModesTileDataInteractorTest : SysuiTestCase() { context.orCreateTestableResources.apply { addOverride(MODES_DRAWABLE_ID, MODES_DRAWABLE) addOverride(R.drawable.ic_zen_mode_type_bedtime, BEDTIME_DRAWABLE) addOverride(R.drawable.ic_zen_mode_type_driving, DRIVING_DRAWABLE) } val customPackageContext = SysuiTestableContext(context) context.prepareCreatePackageContext(CUSTOM_PACKAGE, customPackageContext) customPackageContext.orCreateTestableResources.apply { addOverride(CUSTOM_DRAWABLE_ID, CUSTOM_DRAWABLE) } } Loading Loading @@ -146,35 +153,41 @@ class ModesTileDataInteractorTest : SysuiTestCase() { assertThat(tileData?.icon).isEqualTo(MODES_ICON) assertThat(tileData?.iconResId).isEqualTo(MODES_DRAWABLE_ID) // Add an active mode: icon should be the mode icon. No iconResId, because we don't // really know that it's a system icon. // Add an active mode with a default icon: icon should be the mode icon, and the // iconResId is also populated, because we know it's a system icon. zenModeRepository.addMode( id = "Bedtime", id = "Bedtime with default icon", type = AutomaticZenRule.TYPE_BEDTIME, active = true ) runCurrent() assertThat(tileData?.icon).isEqualTo(BEDTIME_ICON) assertThat(tileData?.iconResId).isNull() assertThat(tileData?.iconResId).isEqualTo(R.drawable.ic_zen_mode_type_bedtime) // Add another, less-prioritized mode: icon should remain the first mode icon // Add another, less-prioritized mode that has a *custom* icon: for now, icon should // remain the first mode icon zenModeRepository.addMode( id = "Driving", type = AutomaticZenRule.TYPE_DRIVING, active = true TestModeBuilder() .setId("Driving with custom icon") .setType(AutomaticZenRule.TYPE_DRIVING) .setPackage(CUSTOM_PACKAGE) .setIconResId(CUSTOM_DRAWABLE_ID) .setActive(true) .build() ) runCurrent() assertThat(tileData?.icon).isEqualTo(BEDTIME_ICON) assertThat(tileData?.iconResId).isNull() assertThat(tileData?.iconResId).isEqualTo(R.drawable.ic_zen_mode_type_bedtime) // Deactivate more important mode: icon should be the less important, still active mode zenModeRepository.deactivateMode("Bedtime") // And because it's a package-provided icon, iconResId is not populated. zenModeRepository.deactivateMode("Bedtime with default icon") runCurrent() assertThat(tileData?.icon).isEqualTo(DRIVING_ICON) assertThat(tileData?.icon).isEqualTo(CUSTOM_ICON) assertThat(tileData?.iconResId).isNull() // Deactivate remaining mode: back to the default modes icon zenModeRepository.deactivateMode("Driving") zenModeRepository.deactivateMode("Driving with custom icon") runCurrent() assertThat(tileData?.icon).isEqualTo(MODES_ICON) assertThat(tileData?.iconResId).isEqualTo(MODES_DRAWABLE_ID) Loading Loading @@ -241,15 +254,17 @@ class ModesTileDataInteractorTest : SysuiTestCase() { private companion object { val TEST_USER = UserHandle.of(1)!! const val CUSTOM_PACKAGE = "com.some.mode.owner.package" val MODES_DRAWABLE_ID = R.drawable.ic_zen_priority_modes const val CUSTOM_DRAWABLE_ID = 12345 val MODES_DRAWABLE = TestStubDrawable("modes_icon") val BEDTIME_DRAWABLE = TestStubDrawable("bedtime") val DRIVING_DRAWABLE = TestStubDrawable("driving") val CUSTOM_DRAWABLE = TestStubDrawable("custom") val MODES_ICON = MODES_DRAWABLE.asIcon() val BEDTIME_ICON = BEDTIME_DRAWABLE.asIcon() val DRIVING_ICON = DRIVING_DRAWABLE.asIcon() val CUSTOM_ICON = CUSTOM_DRAWABLE.asIcon() } } packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/ui/ModesTileMapperTest.kt +1 −21 Original line number Diff line number Diff line Loading @@ -18,7 +18,6 @@ package com.android.systemui.qs.tiles.impl.modes.ui import android.app.Flags import android.graphics.drawable.TestStubDrawable import android.platform.test.annotations.DisableFlags import android.platform.test.annotations.EnableFlags import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest Loading Loading @@ -109,26 +108,7 @@ class ModesTileMapperTest : SysuiTestCase() { } @Test @EnableFlags(Flags.FLAG_MODES_UI_ICONS) fun state_withEnabledFlag_noIconResId() { val icon = TestStubDrawable("res123").asIcon() val model = ModesTileModel( isActivated = false, activeModes = emptyList(), icon = icon, iconResId = 123 // Should not be populated, but is ignored even if present ) val state = underTest.map(config, model) assertThat(state.icon()).isEqualTo(icon) assertThat(state.iconRes).isNull() } @Test @DisableFlags(Flags.FLAG_MODES_UI_ICONS) fun state_withDisabledFlag_includesIconResId() { fun state_modelHasIconResId_includesIconResId() { val icon = TestStubDrawable("res123").asIcon() val model = ModesTileModel( Loading packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileDataInteractor.kt +23 −9 Original line number Diff line number Diff line Loading @@ -20,13 +20,16 @@ import android.app.Flags import android.content.Context import android.os.UserHandle import com.android.app.tracing.coroutines.flow.map import com.android.systemui.common.shared.model.Icon import com.android.systemui.common.shared.model.asIcon import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.qs.tiles.ModesTile import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesTileModel import com.android.systemui.statusbar.policy.domain.interactor.ZenModeInteractor import com.android.systemui.statusbar.policy.domain.model.ActiveZenModes import com.android.systemui.statusbar.policy.domain.model.ZenModeInfo import javax.inject.Inject import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.flow.Flow Loading Loading @@ -61,28 +64,39 @@ constructor( suspend fun getCurrentTileModel() = buildTileData(zenModeInteractor.getActiveModes()) private fun buildTileData(activeModes: ActiveZenModes): ModesTileModel { val modesIconResId = com.android.internal.R.drawable.ic_zen_priority_modes if (usesModeIcons()) { val mainModeDrawable = activeModes.mainMode?.icon?.drawable val iconResId = if (mainModeDrawable == null) modesIconResId else null val tileIcon = getTileIcon(activeModes.mainMode) return ModesTileModel( isActivated = activeModes.isAnyActive(), icon = (mainModeDrawable ?: context.getDrawable(modesIconResId)!!).asIcon(), iconResId = iconResId, icon = tileIcon.icon, iconResId = tileIcon.resId, activeModes = activeModes.modeNames ) } else { return ModesTileModel( isActivated = activeModes.isAnyActive(), icon = context.getDrawable(modesIconResId)!!.asIcon(), iconResId = modesIconResId, icon = context.getDrawable(ModesTile.ICON_RES_ID)!!.asIcon(), iconResId = ModesTile.ICON_RES_ID, activeModes = activeModes.modeNames ) } } private data class TileIcon(val icon: Icon.Loaded, val resId: Int?) private fun getTileIcon(activeMode: ZenModeInfo?): TileIcon { return if (activeMode != null) { // ZenIconKey.resPackage is null if its resId is a system icon. if (activeMode.icon.key.resPackage == null) { TileIcon(activeMode.icon.drawable.asIcon(), activeMode.icon.key.resId) } else { TileIcon(activeMode.icon.drawable.asIcon(), null) } } else { TileIcon(context.getDrawable(ModesTile.ICON_RES_ID)!!.asIcon(), ModesTile.ICON_RES_ID) } } override fun availability(user: UserHandle): Flow<Boolean> = flowOf(Flags.modesUi()) private fun usesModeIcons() = Flags.modesApi() && Flags.modesUi() && Flags.modesUiIcons() Loading packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/ui/ModesTileMapper.kt +1 −3 Original line number Diff line number Diff line Loading @@ -36,9 +36,7 @@ constructor( ) : QSTileDataToStateMapper<ModesTileModel> { override fun map(config: QSTileConfig, data: ModesTileModel): QSTileState = QSTileState.build(resources, theme, config.uiConfig) { if (!android.app.Flags.modesUiIcons()) { iconRes = data.iconResId } icon = { data.icon } activationState = if (data.isActivated) { Loading Loading
packages/SettingsLib/src/com/android/settingslib/notification/data/repository/FakeZenModeRepository.kt +4 −0 Original line number Diff line number Diff line Loading @@ -61,6 +61,10 @@ class FakeZenModeRepository : ZenModeRepository { mutableModesFlow.value += zenModes } fun addMode(mode: ZenMode) { mutableModesFlow.value += mode } fun addMode(id: String, @AutomaticZenRule.Type type: Int = AutomaticZenRule.TYPE_UNKNOWN, active: Boolean = false) { mutableModesFlow.value += newMode(id, type, active) Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileDataInteractorTest.kt +30 −15 Original line number Diff line number Diff line Loading @@ -25,7 +25,9 @@ import android.platform.test.annotations.EnableFlags import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.internal.R import com.android.settingslib.notification.modes.TestModeBuilder import com.android.systemui.SysuiTestCase import com.android.systemui.SysuiTestableContext import com.android.systemui.common.shared.model.asIcon import com.android.systemui.coroutines.collectLastValue import com.android.systemui.coroutines.collectValues Loading Loading @@ -62,7 +64,12 @@ class ModesTileDataInteractorTest : SysuiTestCase() { context.orCreateTestableResources.apply { addOverride(MODES_DRAWABLE_ID, MODES_DRAWABLE) addOverride(R.drawable.ic_zen_mode_type_bedtime, BEDTIME_DRAWABLE) addOverride(R.drawable.ic_zen_mode_type_driving, DRIVING_DRAWABLE) } val customPackageContext = SysuiTestableContext(context) context.prepareCreatePackageContext(CUSTOM_PACKAGE, customPackageContext) customPackageContext.orCreateTestableResources.apply { addOverride(CUSTOM_DRAWABLE_ID, CUSTOM_DRAWABLE) } } Loading Loading @@ -146,35 +153,41 @@ class ModesTileDataInteractorTest : SysuiTestCase() { assertThat(tileData?.icon).isEqualTo(MODES_ICON) assertThat(tileData?.iconResId).isEqualTo(MODES_DRAWABLE_ID) // Add an active mode: icon should be the mode icon. No iconResId, because we don't // really know that it's a system icon. // Add an active mode with a default icon: icon should be the mode icon, and the // iconResId is also populated, because we know it's a system icon. zenModeRepository.addMode( id = "Bedtime", id = "Bedtime with default icon", type = AutomaticZenRule.TYPE_BEDTIME, active = true ) runCurrent() assertThat(tileData?.icon).isEqualTo(BEDTIME_ICON) assertThat(tileData?.iconResId).isNull() assertThat(tileData?.iconResId).isEqualTo(R.drawable.ic_zen_mode_type_bedtime) // Add another, less-prioritized mode: icon should remain the first mode icon // Add another, less-prioritized mode that has a *custom* icon: for now, icon should // remain the first mode icon zenModeRepository.addMode( id = "Driving", type = AutomaticZenRule.TYPE_DRIVING, active = true TestModeBuilder() .setId("Driving with custom icon") .setType(AutomaticZenRule.TYPE_DRIVING) .setPackage(CUSTOM_PACKAGE) .setIconResId(CUSTOM_DRAWABLE_ID) .setActive(true) .build() ) runCurrent() assertThat(tileData?.icon).isEqualTo(BEDTIME_ICON) assertThat(tileData?.iconResId).isNull() assertThat(tileData?.iconResId).isEqualTo(R.drawable.ic_zen_mode_type_bedtime) // Deactivate more important mode: icon should be the less important, still active mode zenModeRepository.deactivateMode("Bedtime") // And because it's a package-provided icon, iconResId is not populated. zenModeRepository.deactivateMode("Bedtime with default icon") runCurrent() assertThat(tileData?.icon).isEqualTo(DRIVING_ICON) assertThat(tileData?.icon).isEqualTo(CUSTOM_ICON) assertThat(tileData?.iconResId).isNull() // Deactivate remaining mode: back to the default modes icon zenModeRepository.deactivateMode("Driving") zenModeRepository.deactivateMode("Driving with custom icon") runCurrent() assertThat(tileData?.icon).isEqualTo(MODES_ICON) assertThat(tileData?.iconResId).isEqualTo(MODES_DRAWABLE_ID) Loading Loading @@ -241,15 +254,17 @@ class ModesTileDataInteractorTest : SysuiTestCase() { private companion object { val TEST_USER = UserHandle.of(1)!! const val CUSTOM_PACKAGE = "com.some.mode.owner.package" val MODES_DRAWABLE_ID = R.drawable.ic_zen_priority_modes const val CUSTOM_DRAWABLE_ID = 12345 val MODES_DRAWABLE = TestStubDrawable("modes_icon") val BEDTIME_DRAWABLE = TestStubDrawable("bedtime") val DRIVING_DRAWABLE = TestStubDrawable("driving") val CUSTOM_DRAWABLE = TestStubDrawable("custom") val MODES_ICON = MODES_DRAWABLE.asIcon() val BEDTIME_ICON = BEDTIME_DRAWABLE.asIcon() val DRIVING_ICON = DRIVING_DRAWABLE.asIcon() val CUSTOM_ICON = CUSTOM_DRAWABLE.asIcon() } }
packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/ui/ModesTileMapperTest.kt +1 −21 Original line number Diff line number Diff line Loading @@ -18,7 +18,6 @@ package com.android.systemui.qs.tiles.impl.modes.ui import android.app.Flags import android.graphics.drawable.TestStubDrawable import android.platform.test.annotations.DisableFlags import android.platform.test.annotations.EnableFlags import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest Loading Loading @@ -109,26 +108,7 @@ class ModesTileMapperTest : SysuiTestCase() { } @Test @EnableFlags(Flags.FLAG_MODES_UI_ICONS) fun state_withEnabledFlag_noIconResId() { val icon = TestStubDrawable("res123").asIcon() val model = ModesTileModel( isActivated = false, activeModes = emptyList(), icon = icon, iconResId = 123 // Should not be populated, but is ignored even if present ) val state = underTest.map(config, model) assertThat(state.icon()).isEqualTo(icon) assertThat(state.iconRes).isNull() } @Test @DisableFlags(Flags.FLAG_MODES_UI_ICONS) fun state_withDisabledFlag_includesIconResId() { fun state_modelHasIconResId_includesIconResId() { val icon = TestStubDrawable("res123").asIcon() val model = ModesTileModel( Loading
packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileDataInteractor.kt +23 −9 Original line number Diff line number Diff line Loading @@ -20,13 +20,16 @@ import android.app.Flags import android.content.Context import android.os.UserHandle import com.android.app.tracing.coroutines.flow.map import com.android.systemui.common.shared.model.Icon import com.android.systemui.common.shared.model.asIcon import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.qs.tiles.ModesTile import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesTileModel import com.android.systemui.statusbar.policy.domain.interactor.ZenModeInteractor import com.android.systemui.statusbar.policy.domain.model.ActiveZenModes import com.android.systemui.statusbar.policy.domain.model.ZenModeInfo import javax.inject.Inject import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.flow.Flow Loading Loading @@ -61,28 +64,39 @@ constructor( suspend fun getCurrentTileModel() = buildTileData(zenModeInteractor.getActiveModes()) private fun buildTileData(activeModes: ActiveZenModes): ModesTileModel { val modesIconResId = com.android.internal.R.drawable.ic_zen_priority_modes if (usesModeIcons()) { val mainModeDrawable = activeModes.mainMode?.icon?.drawable val iconResId = if (mainModeDrawable == null) modesIconResId else null val tileIcon = getTileIcon(activeModes.mainMode) return ModesTileModel( isActivated = activeModes.isAnyActive(), icon = (mainModeDrawable ?: context.getDrawable(modesIconResId)!!).asIcon(), iconResId = iconResId, icon = tileIcon.icon, iconResId = tileIcon.resId, activeModes = activeModes.modeNames ) } else { return ModesTileModel( isActivated = activeModes.isAnyActive(), icon = context.getDrawable(modesIconResId)!!.asIcon(), iconResId = modesIconResId, icon = context.getDrawable(ModesTile.ICON_RES_ID)!!.asIcon(), iconResId = ModesTile.ICON_RES_ID, activeModes = activeModes.modeNames ) } } private data class TileIcon(val icon: Icon.Loaded, val resId: Int?) private fun getTileIcon(activeMode: ZenModeInfo?): TileIcon { return if (activeMode != null) { // ZenIconKey.resPackage is null if its resId is a system icon. if (activeMode.icon.key.resPackage == null) { TileIcon(activeMode.icon.drawable.asIcon(), activeMode.icon.key.resId) } else { TileIcon(activeMode.icon.drawable.asIcon(), null) } } else { TileIcon(context.getDrawable(ModesTile.ICON_RES_ID)!!.asIcon(), ModesTile.ICON_RES_ID) } } override fun availability(user: UserHandle): Flow<Boolean> = flowOf(Flags.modesUi()) private fun usesModeIcons() = Flags.modesApi() && Flags.modesUi() && Flags.modesUiIcons() Loading
packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/ui/ModesTileMapper.kt +1 −3 Original line number Diff line number Diff line Loading @@ -36,9 +36,7 @@ constructor( ) : QSTileDataToStateMapper<ModesTileModel> { override fun map(config: QSTileConfig, data: ModesTileModel): QSTileState = QSTileState.build(resources, theme, config.uiConfig) { if (!android.app.Flags.modesUiIcons()) { iconRes = data.iconResId } icon = { data.icon } activationState = if (data.isActivated) { Loading