Improve compose TalkBack screen-entry announcements#6467
Conversation
|
@CodeRabbit review |
PR checklist ✅All required conditions are satisfied:
🎉 Great job! This PR is ready for review. |
✅ Actions performedReview triggered.
|
WalkthroughThis PR adds Compose accessibility semantics ( ChangesAccessibility Pane Title Support
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
SDK Size Comparison 📏
|
TalkBack announces android:label on Activity entry. Without per-activity labels, every screen was announced as 'Chat Sample Compose'. Each non-routing activity now has a screen-specific label, reusing existing sample/SDK strings where they fit; only 'channel_title' and 'user_profile_title' are new keys.
paneTitle is the Compose semantic that drives TalkBack's pane-change announcement (TYPE_WINDOW_STATE_CHANGED) when a screen appears via FullscreenDialog, adaptive-layout pane swap, or Compose Navigation route change inside an existing Activity. Without it, TalkBack only announces the host Activity's android:label on entry and stays silent on subsequent in-Activity pane changes. - AddMembersScreen, GroupChannelEditScreen: announce 'Add Members' / 'Edit' when shown via FullscreenDialog from GroupChannelInfoScreen. - DirectChannelInfoScreen, GroupChannelInfoScreen, ChannelsScreen, ChatsScreen, ThreadsScreen: announce their title when used as a pane in an adaptive layout or routed-to via Compose Navigation. All reuse existing strings or the screen's existing title parameter; no new public API.
ChannelsScreen, ChatsScreen, and ThreadsScreen route their title parameter into Modifier.semantics { paneTitle = ... } on the screen root. The @param title KDoc now states that contract so integrators know the value is announced by TalkBack when the screen appears as a pane.
ThreadsScreenTest is a new Robolectric Compose UI test class that follows the ChannelsScreenTest / ChatsScreenTest pattern: mocks the chat client + state, renders the screen with default and custom titles, asserts the header text. ChatsScreenTest gains an equivalent custom-title case so the new remember(listContentMode, title) key path is exercised.
4431862 to
3f5094e
Compare
|
* Add android:label to compose sample activities for TalkBack
TalkBack announces android:label on Activity entry. Without per-activity labels, every screen was announced as 'Chat Sample Compose'. Each non-routing activity now has a screen-specific label, reusing existing sample/SDK strings where they fit; only 'channel_title' and 'user_profile_title' are new keys.
* Add paneTitle to compose SDK screens for TalkBack pane announcements
paneTitle is the Compose semantic that drives TalkBack's pane-change announcement (TYPE_WINDOW_STATE_CHANGED) when a screen appears via FullscreenDialog, adaptive-layout pane swap, or Compose Navigation route change inside an existing Activity. Without it, TalkBack only announces the host Activity's android:label on entry and stays silent on subsequent in-Activity pane changes.
- AddMembersScreen, GroupChannelEditScreen: announce 'Add Members' / 'Edit' when shown via FullscreenDialog from GroupChannelInfoScreen.
- DirectChannelInfoScreen, GroupChannelInfoScreen, ChannelsScreen, ChatsScreen, ThreadsScreen: announce their title when used as a pane in an adaptive layout or routed-to via Compose Navigation. All reuse existing strings or the screen's existing title parameter; no new public API.
* Document paneTitle behavior on title @param of public screen composables
ChannelsScreen, ChatsScreen, and ThreadsScreen route their title parameter into Modifier.semantics { paneTitle = ... } on the screen root. The @param title KDoc now states that contract so integrators know the value is announced by TalkBack when the screen appears as a pane.



AND-1180
Goal
TalkBack was reading the wrong thing whenever a user navigated between screens in the Compose sample, and was silent when sub-screens appeared inside an existing Activity:
android:label. The user couldn't tell which screen they had just landed on.FullscreenDialog(e.g.AddMembersScreen,GroupChannelEditScreenreached fromGroupChannelInfoScreen) had noModifier.semantics { paneTitle = ... }, so TalkBack made no pane-change announcement on dialog open. The user heard only the back-button focus, with no indication of which dialog had appeared.ChannelsScreen,ChatsScreen,ThreadsScreen,DirectChannelInfoScreen,GroupChannelInfoScreen) had nopaneTitleeither. When used as a pane in an adaptive layout or shown via a Compose Navigation route inside an existing Activity, pane changes were silent.The two mechanisms are independent and not interchangeable.
android:labelis the only thing TalkBack announces on Activity entry.paneTitleis the only thing TalkBack announces on in-Activity pane / dialog changes. Empirically verified: removingandroid:labelwhile settingpaneTitlealone onPinnedMessagesActivityproduced "Chat Sample Compose, Back, button…" —paneTitledoes not fire on initial Activity entry. Confirmed by the official Compose semantics docs: "Window-like custom components, similar toModalBottomSheet, need additional signals to differentiate them from surrounding content. For this, you can usepaneTitlesemantics, so that any relevant window or pane changes may be represented appropriately by the accessibility services."Implementation
Compose sample app — per-Activity
android:labelAdded
android:labelto 13 activities instream-chat-android-compose-sample/src/main/AndroidManifest.xmlthat previously had none (two attachment activities — Files, Media — already carried a label).StartupActivityis deliberately skipped because it routes to another Activity inonCreateand never gains stable focus. Labels reuse existing sample strings (pinned_messages_title,reminders_title,add_channel_title, etc.) or SDK ui-common strings (stream_ui_channel_info_contact_title,stream_ui_channel_info_group_title) where they fit. Only two net-new sample strings were needed (channel_title,user_profile_title) for screens whose top bar is dynamic or empty.Compose SDK —
paneTitleon Screen composablesAdded
Modifier.semantics { paneTitle = ... }to seven SDK Screen composables. All reuse existing strings or the screen's existingtitleparameter — no new public API:paneTitlesourceAddMembersScreenR.string.stream_compose_add_members_titleGroupChannelEditScreenUiCommonR.string.stream_ui_channel_info_edit_titleDirectChannelInfoScreenUiCommonR.string.stream_ui_channel_info_contact_titleGroupChannelInfoScreenUiCommonR.string.stream_ui_channel_info_group_titleChannelsScreentitleparameterChatsScreentitleparameter (applied on the list-pane Scaffold)ThreadsScreentitleparameterChannelScreen(dynamic channel-name title) andMediaGalleryPreviewScreen(complex dual-overload structure) are deferred to follow-up PRs — each needs its own design decision.ChannelsScreen,ChatsScreen, andThreadsScreenalso have their@param titleKDoc updated to state that the value drives thepaneTitlesemantic.No visual changes; only accessibility semantics and manifest labels.
Testing
paneTitlefor FullscreenDialog content. Open a group channel's info screen, tap Add Members → TalkBack should announce "Add Members" when the dialog appears. From the same screen, tap the edit action → TalkBack should announce "Edit".Summary by CodeRabbit