From 3900e0f4e690a507a6cc04a68dcc5c5ce05a9154 Mon Sep 17 00:00:00 2001 From: Andrey Yepin Date: Thu, 6 Feb 2025 13:06:48 -0800 Subject: Shareousel: add item position to item content description. Add known item cursor position to the item content description annotation when showing more than one item. This works well when the data provided by the app is consistent (the expected majority of the cases). The position annotation will be ommited in cases when we show the initially shared items before the cursor is loaded and for the initially shared items that were missing in the cursor. Fix: 379032721 Test: manual testing Flag: com.android.intentresolver.announce_shareousel_item_list_position Change-Id: Ie669db3897961d2cf09a30ef229e10badb501566 --- .../ui/composable/ShareouselComposable.kt | 34 ++++++++++++++++++---- .../ui/viewmodel/ShareouselPreviewViewModel.kt | 1 + .../ui/viewmodel/ShareouselViewModel.kt | 2 ++ 3 files changed, 31 insertions(+), 6 deletions(-) (limited to 'java/src/com') diff --git a/java/src/com/android/intentresolver/contentpreview/payloadtoggle/ui/composable/ShareouselComposable.kt b/java/src/com/android/intentresolver/contentpreview/payloadtoggle/ui/composable/ShareouselComposable.kt index 9bc8d3e2..a19398fc 100644 --- a/java/src/com/android/intentresolver/contentpreview/payloadtoggle/ui/composable/ShareouselComposable.kt +++ b/java/src/com/android/intentresolver/contentpreview/payloadtoggle/ui/composable/ShareouselComposable.kt @@ -70,6 +70,7 @@ import androidx.compose.ui.semantics.semantics import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle +import com.android.intentresolver.Flags.announceShareouselItemListPosition import com.android.intentresolver.Flags.shareouselScrollOffscreenSelections import com.android.intentresolver.Flags.shareouselSelectionShrink import com.android.intentresolver.Flags.unselectFinalItem @@ -233,6 +234,7 @@ private fun PreviewCarousel(previews: PreviewsModel, viewModel: ShareouselViewMo ShareouselCard( viewModel = previewModel, aspectRatio = measurements.coerceAspectRatio(previewModel.aspectRatio), + annotateWithPosition = previews.previewModels.size > 1, ) } } @@ -240,17 +242,37 @@ private fun PreviewCarousel(previews: PreviewsModel, viewModel: ShareouselViewMo } @Composable -private fun ShareouselCard(viewModel: ShareouselPreviewViewModel, aspectRatio: Float) { +private fun ShareouselCard( + viewModel: ShareouselPreviewViewModel, + aspectRatio: Float, + annotateWithPosition: Boolean, +) { val bitmapLoadState by viewModel.bitmapLoadState.collectAsStateWithLifecycle() val selected by viewModel.isSelected.collectAsStateWithLifecycle(initialValue = false) val borderColor = MaterialTheme.colorScheme.primary val scope = rememberCoroutineScope() - val contentDescription = - when (viewModel.contentType) { - ContentType.Image -> stringResource(R.string.selectable_image) - ContentType.Video -> stringResource(R.string.selectable_video) - else -> stringResource(R.string.selectable_item) + val contentDescription = buildString { + if ( + announceShareouselItemListPosition() && + annotateWithPosition && + viewModel.cursorPosition >= 0 + ) { + // If item cursor position is not known, do not announce item position. + // We can have items with an unknown cursor position only when: + // * when we haven't got the cursor and showing the initially shared items; + // * when we've got an inconsistent data from the app (some initially shared items + // are missing in the cursor); + append(stringResource(R.string.item_position_label, viewModel.cursorPosition + 1)) + append(", ") } + append( + when (viewModel.contentType) { + ContentType.Image -> stringResource(R.string.selectable_image) + ContentType.Video -> stringResource(R.string.selectable_video) + else -> stringResource(R.string.selectable_item) + } + ) + } Box( modifier = Modifier.fillMaxHeight().aspectRatio(aspectRatio), contentAlignment = Alignment.Center, diff --git a/java/src/com/android/intentresolver/contentpreview/payloadtoggle/ui/viewmodel/ShareouselPreviewViewModel.kt b/java/src/com/android/intentresolver/contentpreview/payloadtoggle/ui/viewmodel/ShareouselPreviewViewModel.kt index de435290..b56aa365 100644 --- a/java/src/com/android/intentresolver/contentpreview/payloadtoggle/ui/viewmodel/ShareouselPreviewViewModel.kt +++ b/java/src/com/android/intentresolver/contentpreview/payloadtoggle/ui/viewmodel/ShareouselPreviewViewModel.kt @@ -33,4 +33,5 @@ data class ShareouselPreviewViewModel( /** Sets whether this preview has been selected by the user. */ val setSelected: suspend (Boolean) -> Unit, val aspectRatio: Float, + val cursorPosition: Int, ) diff --git a/java/src/com/android/intentresolver/contentpreview/payloadtoggle/ui/viewmodel/ShareouselViewModel.kt b/java/src/com/android/intentresolver/contentpreview/payloadtoggle/ui/viewmodel/ShareouselViewModel.kt index 6baf5935..99053e0f 100644 --- a/java/src/com/android/intentresolver/contentpreview/payloadtoggle/ui/viewmodel/ShareouselViewModel.kt +++ b/java/src/com/android/intentresolver/contentpreview/payloadtoggle/ui/viewmodel/ShareouselViewModel.kt @@ -152,6 +152,8 @@ object ShareouselViewModelModule { isSelected = previewInteractor.isSelected, setSelected = previewInteractor::setSelected, aspectRatio = key.aspectRatio, + // only items with a final key has a known cursor position + cursorPosition = if (key.key.isFinal) key.order else -1, ) }, ) -- cgit v1.2.3-59-g8ed1b