Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -26451,6 +26451,19 @@ public AccessibilityNodeProvider getAccessibilityNodeProvider() {
return new MessageAccessibilityNodeProvider();
}

// the buttons of a message are reported in the order they are added to it: keeping that
// order lets each of them say which one comes before it, which is what a screen reader
// walks back through
private final java.util.ArrayList<Integer> reportedVirtualViewIds = new java.util.ArrayList<>();

private int previousVirtualViewId(int virtualViewId) {
final int at = reportedVirtualViewIds.indexOf(virtualViewId);
if (at <= 0) {
return Integer.MIN_VALUE;
}
return reportedVirtualViewIds.get(at - 1);
}

private void sendAccessibilityEventForVirtualView(int viewId, int eventType) {
sendAccessibilityEventForVirtualView(viewId, eventType, null);
}
Expand Down Expand Up @@ -27157,19 +27170,23 @@ public void onClick(View view) {

if (useTranscribeButton && transcribeButton != null) {
info.addChild(ChatMessageCell.this, TRANSCRIBE);
reportedVirtualViewIds.add(TRANSCRIBE);
}

reportedVirtualViewIds.clear();
int i;
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
if (isChat && currentUser != null && !currentMessageObject.isOut()) {
info.addChild(ChatMessageCell.this, PROFILE);
reportedVirtualViewIds.add(PROFILE);
}
if (currentMessageObject.messageText instanceof Spannable) {
Spannable buffer = (Spannable) currentMessageObject.messageText;
CharacterStyle[] links = buffer.getSpans(0, buffer.length(), ClickableSpan.class);
i = 0;
for (CharacterStyle link : links) {
info.addChild(ChatMessageCell.this, LINK_IDS_START + i);
reportedVirtualViewIds.add(LINK_IDS_START + i);
i++;
}
}
Expand All @@ -27179,50 +27196,62 @@ public void onClick(View view) {
i = 0;
for (CharacterStyle link : links) {
info.addChild(ChatMessageCell.this, LINK_CAPTION_IDS_START + i);
reportedVirtualViewIds.add(LINK_CAPTION_IDS_START + i);
i++;
}
}
}
i = 0;
for (BotButton button : botButtons) {
info.addChild(ChatMessageCell.this, BOT_BUTTONS_START + i);
reportedVirtualViewIds.add(BOT_BUTTONS_START + i);
i++;
}
if (hintButtonVisible && pollHintX != -1 && currentMessageObject.isPoll()) {
info.addChild(ChatMessageCell.this, POLL_HINT);
reportedVirtualViewIds.add(POLL_HINT);
}
i = 0;
for (PollButton button : pollButtons) {
info.addChild(ChatMessageCell.this, POLL_BUTTONS_START + i);
reportedVirtualViewIds.add(POLL_BUTTONS_START + i);
i++;
}
if (drawInstantView && !instantButtonRect.isEmpty()) {
info.addChild(ChatMessageCell.this, INSTANT_VIEW);
reportedVirtualViewIds.add(INSTANT_VIEW);
}
if (drawContact && contactRect != null && !contactRect.isEmpty()) {
info.addChild(ChatMessageCell.this, CONTACT);
reportedVirtualViewIds.add(CONTACT);
if (contactButtons != null && contactButtons.size() > 1) {
for (InstantViewButton instantViewButton : contactButtons) {
if (drawContactView && instantViewButton.type == INSTANT_BUTTON_TYPE_CONTACT_VIEW && !instantViewButton.rect.isEmpty()) {
info.addChild(ChatMessageCell.this, CONTACT_VIEW);
reportedVirtualViewIds.add(CONTACT_VIEW);
}
if (drawContactAdd && instantViewButton.type == INSTANT_BUTTON_TYPE_CONTACT_ADD && !instantViewButton.rect.isEmpty()) {
info.addChild(ChatMessageCell.this, CONTACT_ADD);
reportedVirtualViewIds.add(CONTACT_ADD);
}
if (drawContactSendMessage && instantViewButton.type == INSTANT_BUTTON_TYPE_CONTACT_SEND_MESSAGE && !instantViewButton.rect.isEmpty()) {
info.addChild(ChatMessageCell.this, CONTACT_MESSAGE);
reportedVirtualViewIds.add(CONTACT_MESSAGE);
}
}
}
}
if (commentLayout != null) {
info.addChild(ChatMessageCell.this, COMMENT);
reportedVirtualViewIds.add(COMMENT);
}
if (drawSideButton == 1 || drawSideButton == 2) {
info.addChild(ChatMessageCell.this, SHARE);
reportedVirtualViewIds.add(SHARE);
}
if (replyNameLayout != null) {
info.addChild(ChatMessageCell.this, REPLY);
reportedVirtualViewIds.add(REPLY);
}
if (currentMessageObject != null && currentMessageObject.richLayout != null) {
final RichMessageLayout richLayout = currentMessageObject.richLayout;
Expand All @@ -27235,6 +27264,7 @@ public void onClick(View view) {
final int count = block.getAccessibilityElementCount();
for (int e = 0; e < count; e++) {
info.addChild(ChatMessageCell.this, RICH_MEDIA_START + acc + e);
reportedVirtualViewIds.add(RICH_MEDIA_START + acc + e);
}
acc += count;
}
Expand Down Expand Up @@ -27614,6 +27644,22 @@ public void onClick(View view) {
info.setBoundsInScreen(rect);
info.setClickable(true);
}
// a message that is not laid out yet, or is being held for reuse, has buttons with
// no place on the screen: reporting them leaves empty stops that a screen reader
// lands on and that get in the way of going back through the messages
info.getBoundsInScreen(rect);
if (rect.isEmpty()) {
return null;
}
// and the ones that do have a place are tied to the one before them, so going
// back through them follows the same path as going forward, whichever screen
// reader is doing the walking
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
final int previous = previousVirtualViewId(virtualViewId);
if (previous != Integer.MIN_VALUE) {
info.setTraversalAfter(ChatMessageCell.this, previous);
}
}
info.setFocusable(true);
info.setVisibleToUser(true);
return info;
Expand Down