diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMessageCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMessageCell.java index b18fd8ac6..6752936ee 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMessageCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMessageCell.java @@ -1027,7 +1027,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate public float getProgress() { if (currentMessageObject.isMusic()) { return seekBar.getProgress(); - } else if (currentMessageObject.isVoice()) { + } else if (currentMessageObject.isVoice() || currentMessageObject.isRoundVideo()) { if (useSeekBarWaweform) { return seekBarWaveform.getProgress(); } else { @@ -1042,7 +1042,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate public void setProgress(float progress) { if (currentMessageObject.isMusic()) { seekBar.setProgress(progress); - } else if (currentMessageObject.isVoice()) { + } else if (currentMessageObject.isVoice() || currentMessageObject.isRoundVideo()) { if (useSeekBarWaweform) { seekBarWaveform.setProgress(progress); } else { @@ -10113,6 +10113,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate } } } + if (currentFocusedVirtualView == -1 && hasFocus()) announceForAccessibility((progress * 100) + "%"); } @Override @@ -10129,6 +10130,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate } } createLoadingProgressLayout(uploadedSize, totalSize); + if (currentFocusedVirtualView == -1 && hasFocus()) announceForAccessibility((progress * 100) + "%"); } private void createLoadingProgressLayout(TLRPC.Document document) { @@ -14576,7 +14578,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate @Override public boolean performAccessibilityAction(int action, Bundle arguments) { - if (action == AccessibilityNodeInfo.ACTION_CLICK) { + if (action == AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS) { + currentFocusedVirtualView = -1; + } else if (action == AccessibilityNodeInfo.ACTION_CLICK) { int icon = getIconForCurrentState(); if (icon != MediaActionDrawable.ICON_NONE && icon != MediaActionDrawable.ICON_FILE) { didPressButton(true, false); @@ -14597,7 +14601,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate } } } - if (currentMessageObject.isVoice() || currentMessageObject.isMusic() && MediaController.getInstance().isPlayingMessage(currentMessageObject)) { + if (currentMessageObject.isVoice() || currentMessageObject.isRoundVideo() || currentMessageObject.isMusic() && MediaController.getInstance().isPlayingMessage(currentMessageObject)) { if (seekBarAccessibilityDelegate.performAccessibilityActionInternal(action, arguments)) { return true; } @@ -14618,7 +14622,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate } @Override - public boolean onHoverEvent(MotionEvent event) { + public boolean dispatchHoverEvent(MotionEvent event) { int x = (int) event.getX(); int y = (int) event.getY(); if (event.getAction() == MotionEvent.ACTION_HOVER_ENTER || event.getAction() == MotionEvent.ACTION_HOVER_MOVE) { @@ -14634,9 +14638,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate } } } else if (event.getAction() == MotionEvent.ACTION_HOVER_EXIT) { - currentFocusedVirtualView = 0; + currentFocusedVirtualView = -1; } - return super.onHoverEvent(event); + return super.dispatchHoverEvent(event); } @Override @@ -15053,9 +15057,13 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate info.addAction(AccessibilityNodeInfo.ACTION_LONG_CLICK); } - if ((currentMessageObject.isVoice() || currentMessageObject.isMusic()) && MediaController.getInstance().isPlayingMessage(currentMessageObject)) { + if ((currentMessageObject.isVoice() || currentMessageObject.isRoundVideo() || currentMessageObject.isMusic()) && MediaController.getInstance().isPlayingMessage(currentMessageObject)) { seekBarAccessibilityDelegate.onInitializeAccessibilityNodeInfoInternal(info); } + //smallest ids should be added at first,because talkback can focus on it not always in correct order + if (forwardedNameLayout[1] != null) { + info.addChild(ChatMessageCell.this, FORWARD); + } int i; if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { @@ -15103,9 +15111,6 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate if (replyNameLayout != null) { info.addChild(ChatMessageCell.this, REPLY); } - if (forwardedNameLayout[0] != null && forwardedNameLayout[1] != null) { - info.addChild(ChatMessageCell.this, FORWARD); - } if (drawSelectionBackground || getBackground() != null) { info.setSelected(true); } @@ -15309,14 +15314,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate info.setClickable(true); } else if (virtualViewId == FORWARD) { info.setEnabled(true); - StringBuilder sb = new StringBuilder(); - if (forwardedNameLayout[0] != null && forwardedNameLayout[1] != null) { - for (int a = 0; a < 2; a++) { - sb.append(forwardedNameLayout[a].getText()); - sb.append(a == 0 ? " " : "\n"); - } - } - info.setContentDescription(sb.toString()); + info.setContentDescription(currentForwardNameString); info.addAction(AccessibilityNodeInfo.ACTION_CLICK); int x = (int) Math.min(forwardNameX - forwardNameOffsetX[0], forwardNameX - forwardNameOffsetX[1]); @@ -15332,7 +15330,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate info.setClassName("android.widget.Button"); info.setEnabled(true); if (commentLayout != null) { - info.setText(commentLayout.getText()); + //commentLayout not give for us text information about number of comments,so we shouldn't use text of layout for viryual node. + int commentCount = getRepliesCount(); + info.setText(isRepliesChat ? LocaleController.getString("ViewInChat", R.string.ViewInChat) : commentCount == 0 ? LocaleController.getString("LeaveAComment", R.string.LeaveAComment) : LocaleController.formatPluralString("CommentsCount", commentCount)); } info.addAction(AccessibilityNodeInfo.ACTION_CLICK); rect.set(commentButtonRect); @@ -15356,6 +15356,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate performAccessibilityAction(action, arguments); } else { if (action == AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS) { + currentFocusedVirtualView = virtualViewId; sendAccessibilityEventForVirtualView(virtualViewId, AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED); } else if (action == AccessibilityNodeInfo.ACTION_CLICK) { if (virtualViewId >= LINK_CAPTION_IDS_START) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/DialogCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/DialogCell.java index 5608f605d..83cdface5 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/DialogCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/DialogCell.java @@ -3322,7 +3322,6 @@ public class DialogCell extends BaseCell { public boolean hasOverlappingRendering() { return false; } - @Override public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { super.onInitializeAccessibilityNodeInfo(info); @@ -3331,83 +3330,79 @@ public class DialogCell extends BaseCell { } else { info.addAction(AccessibilityNodeInfo.ACTION_CLICK); info.addAction(AccessibilityNodeInfo.ACTION_LONG_CLICK); - } - } - - @Override - public void onPopulateAccessibilityEvent(AccessibilityEvent event) { - super.onPopulateAccessibilityEvent(event); - StringBuilder sb = new StringBuilder(); - if (currentDialogFolderId == 1) { - sb.append(LocaleController.getString("ArchivedChats", R.string.ArchivedChats)); - sb.append(". "); - } else { - if (encryptedChat != null) { - sb.append(LocaleController.getString("AccDescrSecretChat", R.string.AccDescrSecretChat)); + if (checkBox != null) info.setSelected(checkBox.isChecked()); + StringBuilder sb = new StringBuilder(); + if (currentDialogFolderId == 1) { + sb.append(LocaleController.getString("ArchivedChats", R.string.ArchivedChats)); sb.append(". "); - } - if (user != null) { - if (UserObject.isReplyUser(user)) { - sb.append(LocaleController.getString("RepliesTitle", R.string.RepliesTitle)); - } else { - if (user.bot) { - sb.append(LocaleController.getString("Bot", R.string.Bot)); - sb.append(". "); - } - if (user.self) { - sb.append(LocaleController.getString("SavedMessages", R.string.SavedMessages)); - } else { - sb.append(ContactsController.formatName(user.first_name, user.last_name)); - } - } - sb.append(". "); - } else if (chat != null) { - if (chat.broadcast) { - sb.append(LocaleController.getString("AccDescrChannel", R.string.AccDescrChannel)); - } else { - sb.append(LocaleController.getString("AccDescrGroup", R.string.AccDescrGroup)); - } - sb.append(". "); - sb.append(chat.title); - sb.append(". "); - } - } - if (unreadCount > 0) { - sb.append(LocaleController.formatPluralString("NewMessages", unreadCount)); - sb.append(". "); - } - if (message == null || currentDialogFolderId != 0) { - event.setContentDescription(sb.toString()); - return; - } - int lastDate = lastMessageDate; - if (lastMessageDate == 0) { - lastDate = message.messageOwner.date; - } - String date = LocaleController.formatDateAudio(lastDate, true); - if (message.isOut()) { - sb.append(LocaleController.formatString("AccDescrSentDate", R.string.AccDescrSentDate, date)); - } else { - sb.append(LocaleController.formatString("AccDescrReceivedDate", R.string.AccDescrReceivedDate, date)); - } - sb.append(". "); - if (chat != null && !message.isOut() && message.isFromUser() && message.messageOwner.action == null) { - TLRPC.User fromUser = MessagesController.getInstance(currentAccount).getUser(message.getSenderId()); - if (fromUser != null) { - sb.append(ContactsController.formatName(fromUser.first_name, fromUser.last_name)); - sb.append(". "); - } - } - if (encryptedChat == null) { - sb.append(message.messageText); - if (!message.isMediaEmpty()) { - if (!TextUtils.isEmpty(message.caption)) { + } else { + if (encryptedChat != null) { + sb.append(LocaleController.getString("AccDescrSecretChat", R.string.AccDescrSecretChat)); + sb.append(". "); + } + if (user != null) { + if (UserObject.isReplyUser(user)) { + sb.append(LocaleController.getString("RepliesTitle", R.string.RepliesTitle)); + } else { + if (user.bot) { + sb.append(LocaleController.getString("Bot", R.string.Bot)); + sb.append(". "); + } + if (user.self) { + sb.append(LocaleController.getString("SavedMessages", R.string.SavedMessages)); + } else { + sb.append(ContactsController.formatName(user.first_name, user.last_name)); + } + } + sb.append(". "); + } else if (chat != null) { + if (chat.broadcast) { + sb.append(LocaleController.getString("AccDescrChannel", R.string.AccDescrChannel)); + } else { + sb.append(LocaleController.getString("AccDescrGroup", R.string.AccDescrGroup)); + } + sb.append(". "); + sb.append(chat.title); sb.append(". "); - sb.append(message.caption); } } + if (unreadCount > 0) { + sb.append(LocaleController.formatPluralString("NewMessages", unreadCount)); + sb.append(". "); + } + if (message == null || currentDialogFolderId != 0) { + info.setContentDescription(sb.toString()); + return; + } + int lastDate = lastMessageDate; + if (lastMessageDate == 0) { + lastDate = message.messageOwner.date; + } + String date = LocaleController.formatDateAudio(lastDate, true); + if (message.isOut()) { + sb.append(LocaleController.formatString("AccDescrSentDate", R.string.AccDescrSentDate, date)); + } else { + sb.append(LocaleController.formatString("AccDescrReceivedDate", R.string.AccDescrReceivedDate, date)); + } + sb.append(". "); + if (chat != null && !message.isOut() && message.isFromUser() && message.messageOwner.action == null) { + TLRPC.User fromUser = MessagesController.getInstance(currentAccount).getUser(message.getSenderId()); + if (fromUser != null) { + sb.append(ContactsController.formatName(fromUser.first_name, fromUser.last_name)); + sb.append(". "); + } + } + if (encryptedChat == null) { + sb.append(message.messageText); + if (!message.isMediaEmpty()) { + if (!TextUtils.isEmpty(message.caption)) { + sb.append(". "); + sb.append(message.caption); + } + } + } + info.setContentDescription(sb.toString()); } - event.setContentDescription(sb.toString()); } public void setClipProgress(float value) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ProfileSearchCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ProfileSearchCell.java index f63375b99..91816123d 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ProfileSearchCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ProfileSearchCell.java @@ -674,6 +674,7 @@ public class ProfileSearchCell extends BaseCell { builder.append(statusLayout.getText()); } info.setText(builder.toString()); + if (checkBox != null) info.setSelected(checkBox.isChecked()); } public long getDialogId() { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/BotCommandsMenuView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/BotCommandsMenuView.java index 99b67b2d0..b11e1ebb6 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/BotCommandsMenuView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/BotCommandsMenuView.java @@ -6,6 +6,7 @@ import android.graphics.Color; import android.graphics.Paint; import android.graphics.RectF; import android.graphics.drawable.Drawable; +import android.os.Build; import android.text.Layout; import android.text.StaticLayout; import android.text.TextPaint; @@ -14,6 +15,7 @@ import android.util.TypedValue; import android.view.Gravity; import android.view.View; import android.view.ViewGroup; +import android.view.accessibility.AccessibilityNodeInfo; import android.widget.LinearLayout; import android.widget.TextView; @@ -73,6 +75,18 @@ public class BotCommandsMenuView extends View { int lastSize; + @Override + public CharSequence getAccessibilityClassName() { + return "android.Widget.Button"; + } + + @Override + public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { + super.onInitializeAccessibilityNodeInfo(info); + info.addAction(isOpened()? AccessibilityNodeInfo.AccessibilityAction.ACTION_COLLAPSE : AccessibilityNodeInfo.AccessibilityAction.ACTION_EXPAND); + info.setContentDescription(LocaleController.getString("AccDescrBotCommands",R.string.AccDescrBotCommands)); + } + @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int size = MeasureSpec.getSize(widthMeasureSpec) + MeasureSpec.getSize(heightMeasureSpec) << 16; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/Bulletin.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/Bulletin.java index 2f3bf0706..f04f8b23f 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/Bulletin.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/Bulletin.java @@ -930,6 +930,12 @@ public class Bulletin { textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15); addView(textView, LayoutHelper.createFrameRelatively(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.START | Gravity.CENTER_VERTICAL, 56, 0, 16, 0)); } + + @Override + protected void onShow() { + super.onShow(); + AndroidUtilities.makeAccessibilityAnnouncement(textView.getText()); + } } @SuppressLint("ViewConstructor") @@ -949,6 +955,12 @@ public class Bulletin { textView.setTypeface(Typeface.SANS_SERIF); addView(textView, LayoutHelper.createFrameRelatively(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.START | Gravity.CENTER_VERTICAL, 56, 0, 16, 0)); } + + @Override + protected void onShow() { + super.onShow(); + AndroidUtilities.makeAccessibilityAnnouncement(textView.getText()); + } } @SuppressLint("ViewConstructor") @@ -984,6 +996,11 @@ public class Bulletin { linearLayout.addView(subtitleTextView); } + @Override + protected void onShow() { + super.onShow(); + AndroidUtilities.makeAccessibilityAnnouncement(titleTextView.getText() + ". " + subtitleTextView.getText()); + } } public static class TwoLineLottieLayout extends ButtonLayout { @@ -1027,6 +1044,7 @@ public class Bulletin { protected void onShow() { super.onShow(); imageView.playAnimation(); + AndroidUtilities.makeAccessibilityAnnouncement(titleTextView.getText() + ". " + subtitleTextView.getText()); } public void setAnimation(int resId, String... layers) { @@ -1082,6 +1100,7 @@ public class Bulletin { protected void onShow() { super.onShow(); imageView.playAnimation(); + AndroidUtilities.makeAccessibilityAnnouncement(textView.getText()); } public void setAnimation(int resId, String... layers) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/voip/AcceptDeclineView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/voip/AcceptDeclineView.java index 5e8396268..9779e2108 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/voip/AcceptDeclineView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/voip/AcceptDeclineView.java @@ -50,7 +50,7 @@ public class AcceptDeclineView extends View { private AcceptDeclineAccessibilityNodeProvider accessibilityNodeProvider; private int buttonWidth; - + private int currentFocusedVirtualViewId = View.NO_ID; float smallRadius; float bigRadius; boolean expandSmallRadius = true; @@ -420,11 +420,17 @@ public class AcceptDeclineView extends View { } @Override - public boolean onHoverEvent(MotionEvent event) { - if (accessibilityNodeProvider != null && accessibilityNodeProvider.onHoverEvent(event)) { + public boolean dispatchHoverEvent(MotionEvent event) { + if (accessibilityNodeProvider != null && accessibilityNodeProvider.dispatchHoverEvent(event)) { return true; } - return super.onHoverEvent(event); + return super.dispatchHoverEvent(event); + } + + @Override + public boolean performAccessibilityAction(int action, Bundle arguments) { + if (action == AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS) currentFocusedVirtualViewId = NO_ID; + return super.performAccessibilityAction(action, arguments); } @Override @@ -494,15 +500,12 @@ public class AcceptDeclineView extends View { this.screenWasWakeup = screenWasWakeup; } - private static abstract class AcceptDeclineAccessibilityNodeProvider extends AccessibilityNodeProvider { + private abstract class AcceptDeclineAccessibilityNodeProvider extends AccessibilityNodeProvider { private final View hostView; private final int virtualViewsCount; private final Rect rect = new Rect(); private final AccessibilityManager accessibilityManager; - - private int currentFocusedVirtualViewId = View.NO_ID; - private AcceptDeclineAccessibilityNodeProvider(View hostView, int virtualViewsCount) { this.hostView = hostView; this.virtualViewsCount = virtualViewsCount; @@ -545,16 +548,16 @@ public class AcceptDeclineView extends View { return hostView.performAccessibilityAction(action, arguments); } else { if (action == AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS) { + currentFocusedVirtualViewId = virtualViewId; sendAccessibilityEventForVirtualView(virtualViewId, AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED); } else if (action == AccessibilityNodeInfo.ACTION_CLICK) { onVirtualViewClick(virtualViewId); - return true; } } - return false; + return true;// For action accessibilityFocus should be return true too,because in other case screenreader will consider,what it's the last node on the screen,and we will hear sound fron it,which announce about it. } - public boolean onHoverEvent(MotionEvent event) { + public boolean dispatchHoverEvent(MotionEvent event) { final int x = (int) event.getX(); final int y = (int) event.getY(); if (event.getAction() == MotionEvent.ACTION_HOVER_ENTER || event.getAction() == MotionEvent.ACTION_HOVER_MOVE) { @@ -569,8 +572,8 @@ public class AcceptDeclineView extends View { } } } else if (event.getAction() == MotionEvent.ACTION_HOVER_EXIT) { - if (currentFocusedVirtualViewId != View.NO_ID) { - currentFocusedVirtualViewId = View.NO_ID; + if (currentFocusedVirtualViewId != -1) { + currentFocusedVirtualViewId = -1; return true; } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/LoginActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/LoginActivity.java index a125c496a..19c61db64 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/LoginActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/LoginActivity.java @@ -607,10 +607,14 @@ public class LoginActivity extends BaseFragment implements NotificationCenter.No menu.setSubMenuOpenSide(1); menu.setBackground(Theme.createSelectorDrawable(Theme.getColor(Theme.key_listSelector))); - menu.addSubItem(menu_proxy, R.drawable.proxy_on, LocaleController.getString("Proxy", R.string.Proxy)); - menu.addSubItem(menu_language, R.drawable.ic_translate, LocaleController.getString("Language", R.string.Language)); - menu.addSubItem(menu_bot_login, R.drawable.list_bot, LocaleController.getString("BotLogin", R.string.BotLogin)); - menu.addSubItem(menu_qr_login, R.drawable.wallet_qr, LocaleController.getString("ImportLogin", R.string.ImportLogin)); + menu.addSubItem(menu_proxy, R.drawable.proxy_on, LocaleController.getString("Proxy", R.string.Proxy)) + .setContentDescription(LocaleController.getString("Proxy", R.string.Proxy)); + menu.addSubItem(menu_language, R.drawable.ic_translate, LocaleController.getString("Language", R.string.Language)) + .setContentDescription(LocaleController.getString("Language", R.string.Language)); + menu.addSubItem(menu_bot_login, R.drawable.list_bot, LocaleController.getString("BotLogin", R.string.BotLogin)) + .setContentDescription(LocaleController.getString("BotLogin", R.string.BotLogin)); + menu.addSubItem(menu_qr_login, R.drawable.wallet_qr, LocaleController.getString("ImportLogin", R.string.ImportLogin)) + .setContentDescription(LocaleController.getString("ImportLogin", R.string.ImportLogin)); // otherItem.addSubItem(menu_custom_api, R.drawable.baseline_vpn_key_24, LocaleController.getString("CustomApi", R.string.CustomApi)); // menu.addSubItem(menu_custom_dc, R.drawable.baseline_sync_24, LocaleController.getString("CustomBackend", R.string.CustomBackend));