Announce new state of modes when toggled in Modes Dialog
By setting the contentDescription at the row level.
Bug: 359845144
Test: atest ModesDialogViewModelTest + manually with TalkBack
Flag: android.app.modes_ui
Change-Id: I67c2d59fc4a23d882f123a944e10ad77e87d4d3c
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/ui/dialog/viewmodel/ModesDialogViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/ui/dialog/viewmodel/ModesDialogViewModelTest.kt
index d2bc54e0..827236c5 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/ui/dialog/viewmodel/ModesDialogViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/ui/dialog/viewmodel/ModesDialogViewModelTest.kt
@@ -330,6 +330,67 @@
}
@Test
+ fun tiles_calculatesContentDescription() =
+ testScope.runTest {
+ val tiles by collectLastValue(underTest.tiles)
+
+ repository.addModes(
+ listOf(
+ TestModeBuilder()
+ .setName("With description, inactive")
+ .setManualInvocationAllowed(true)
+ .setTriggerDescription("When the going gets tough")
+ .setActive(false)
+ .build(),
+ TestModeBuilder()
+ .setName("With description, active")
+ .setManualInvocationAllowed(true)
+ .setTriggerDescription("When in Rome")
+ .setActive(true)
+ .build(),
+ TestModeBuilder()
+ .setName("With description, needs setup")
+ .setManualInvocationAllowed(true)
+ .setTriggerDescription("When you find yourself in a hole")
+ .setEnabled(false, /* byUser= */ false)
+ .build(),
+ TestModeBuilder()
+ .setName("Without description, inactive")
+ .setManualInvocationAllowed(true)
+ .setTriggerDescription(null)
+ .setActive(false)
+ .build(),
+ TestModeBuilder()
+ .setName("Without description, active")
+ .setManualInvocationAllowed(true)
+ .setTriggerDescription(null)
+ .setActive(true)
+ .build(),
+ TestModeBuilder()
+ .setName("Without description, needs setup")
+ .setManualInvocationAllowed(true)
+ .setTriggerDescription(null)
+ .setEnabled(false, /* byUser= */ false)
+ .build(),
+ )
+ )
+ runCurrent()
+
+ assertThat(tiles!!).hasSize(6)
+ assertThat(tiles!![0].contentDescription)
+ .isEqualTo("With description, inactive\nOff\nWhen the going gets tough")
+ assertThat(tiles!![1].contentDescription)
+ .isEqualTo("With description, active\nOn\nWhen in Rome")
+ assertThat(tiles!![2].contentDescription)
+ .isEqualTo("With description, needs setup\nSet up")
+ assertThat(tiles!![3].contentDescription)
+ .isEqualTo("Without description, inactive\nOff")
+ assertThat(tiles!![4].contentDescription).isEqualTo("Without description, active\nOn")
+ assertThat(tiles!![5].contentDescription)
+ .isEqualTo("Without description, needs setup\nSet up")
+ }
+
+ @Test
fun onClick_togglesTileState() =
testScope.runTest {
val tiles by collectLastValue(underTest.tiles)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ui/dialog/composable/ModeTile.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ui/dialog/composable/ModeTile.kt
index 3fffd9f..8b50f84 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ui/dialog/composable/ModeTile.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ui/dialog/composable/ModeTile.kt
@@ -33,6 +33,9 @@
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
+import androidx.compose.ui.semantics.clearAndSetSemantics
+import androidx.compose.ui.semantics.contentDescription
+import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import com.android.systemui.common.ui.compose.Icon
@@ -58,7 +61,9 @@
onClick = viewModel.onClick,
onLongClick = viewModel.onLongClick
)
- .padding(20.dp),
+ .padding(20.dp)
+ .semantics(mergeDescendants = true) {}
+ .clearAndSetSemantics { contentDescription = viewModel.contentDescription },
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement =
Arrangement.spacedBy(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ui/dialog/viewmodel/ModeTileViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ui/dialog/viewmodel/ModeTileViewModel.kt
index 7c1cb6a..921d79b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ui/dialog/viewmodel/ModeTileViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ui/dialog/viewmodel/ModeTileViewModel.kt
@@ -28,6 +28,7 @@
val icon: Icon,
val text: String,
val subtext: String,
+ val contentDescription: String,
val enabled: Boolean,
val onClick: () -> Unit,
val onLongClick: () -> Unit,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ui/dialog/viewmodel/ModesDialogViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ui/dialog/viewmodel/ModesDialogViewModel.kt
index 16c18dd8c..38bade0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ui/dialog/viewmodel/ModesDialogViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ui/dialog/viewmodel/ModesDialogViewModel.kt
@@ -89,8 +89,9 @@
ModeTileViewModel(
id = mode.id,
icon = zenModeInteractor.getModeIcon(mode, context),
- text = mode.rule.name,
+ text = mode.name,
subtext = getTileSubtext(mode),
+ contentDescription = getTileContentDescription(mode),
enabled = mode.isActive,
onClick = {
if (!mode.rule.isEnabled) {
@@ -147,6 +148,25 @@
}
}
+ private fun getTileContentDescription(mode: ZenMode): String {
+ return buildList {
+ add(mode.name)
+ if (!mode.rule.isEnabled) {
+ add(context.getString(R.string.zen_mode_set_up))
+ } else if (!mode.rule.isManualInvocationAllowed && !mode.isActive) {
+ add(context.getString(R.string.zen_mode_no_manual_invocation))
+ } else {
+ add(
+ context.getString(
+ if (mode.isActive) R.string.zen_mode_on else R.string.zen_mode_off
+ )
+ )
+ mode.getDynamicDescription(context)?.let { add(it) }
+ }
+ }
+ .joinToString(separator = "\n")
+ }
+
private fun makeZenModeDialog(): Dialog {
val dialog =
EnableZenModeDialog(