From 8282992151fc024b52501f7951d9a130a736f73d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20V=C3=A1gner?= Date: Fri, 6 Sep 2024 01:43:57 +0200 Subject: [PATCH] a11y: Improvements to message list presentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Improved screen reader accessibility of message list in regard to up to date features since this has been looked into last time. It includes these changes: * Explicitly set contentDescription of image buttons and image views to @null rather than setting it into textual values where these are not used. * Some 3rd party screen reader apps don't disable their contentDescription calculation from child widgets while the parent has a custom actions and overridden contentDescriptions so use setImportantForAccessibility on all the widgets contentDescription is populated from. This avoids speaking some texts multiple times on non default accessibility service setups. * Added missing details to the contentDescription such as signed, notes, labels, keywords. * Change it so visibility of the individual widgets is respected where possible. Signed-off-by: Peter Vágner --- .../eu/faircode/email/AdapterMessage.java | 133 ++++++++++++++---- .../res/layout/include_message_compact.xml | 30 ++-- .../res/layout/include_message_normal.xml | 30 ++-- app/src/main/res/values/strings.xml | 1 + 4 files changed, 151 insertions(+), 43 deletions(-) diff --git a/app/src/main/java/eu/faircode/email/AdapterMessage.java b/app/src/main/java/eu/faircode/email/AdapterMessage.java index b34472cfcc..65f0c6e578 100644 --- a/app/src/main/java/eu/faircode/email/AdapterMessage.java +++ b/app/src/main/java/eu/faircode/email/AdapterMessage.java @@ -5074,14 +5074,22 @@ public class AdapterMessage extends RecyclerView.Adapter 0) + ToastEx.makeText(context, resid, Toast.LENGTH_LONG).show(); + } + + private int getSensitivity(TupleMessageEx message) { int resid = -1; if (EntityMessage.SENSITIVITY_PERSONAL.equals(message.sensitivity)) resid = R.string.title_legend_sensitivity_personal; @@ -5089,26 +5097,41 @@ public class AdapterMessage extends RecyclerView.Adapter 0) ToastEx.makeText(context, resid, Toast.LENGTH_LONG).show(); } - private void onShowSigned(TupleMessageEx message) { + private int getSigned(TupleMessageEx message) { int resid = -1; if (EntityMessage.PGP_SIGNONLY.equals(message.ui_encrypt)) resid = R.string.title_advanced_caption_pgp; else if (EntityMessage.SMIME_SIGNONLY.equals(message.ui_encrypt)) resid = R.string.title_advanced_caption_smime; + return resid; + } + + private void onShowSigned(TupleMessageEx message) { + int resid = getSigned(message); if (resid > 0) ToastEx.makeText(context, resid, Toast.LENGTH_LONG).show(); } - private void onShowEncrypted(TupleMessageEx message) { + private int getEncrypted(TupleMessageEx message) { int resid = -1; if (EntityMessage.PGP_SIGNENCRYPT.equals(message.ui_encrypt)) resid = R.string.title_advanced_caption_pgp; else if (EntityMessage.SMIME_SIGNENCRYPT.equals(message.ui_encrypt)) resid = R.string.title_advanced_caption_smime; + return resid; + } + + private void onShowEncrypted(TupleMessageEx message) { + int resid = getEncrypted(message); if (resid > 0) ToastEx.makeText(context, resid, Toast.LENGTH_LONG).show(); } @@ -8107,19 +8130,30 @@ public class AdapterMessage extends RecyclerView.Adapter 0 ? R.string.title_accessibility_unseen : R.string.title_accessibility_seen)); - if (tvCount.getVisibility() == View.VISIBLE) + if (tvCount.getVisibility() == View.VISIBLE) { result.add(context.getResources().getQuantityString( R.plurals.title_accessibility_messages, message.visible, message.visible)); + tvCount.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO); + } - if (ibExpander.getVisibility() == View.VISIBLE) + if (ibExpander.getVisibility() == View.VISIBLE) { result.add(context.getString( expanded ? R.string.title_accessibility_expanded : R.string.title_accessibility_collapsed)); + ibExpander.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO); + } if (message.drafts > 0) result.add(context.getString(R.string.title_legend_draft)); - if (message.ui_answered) + if (ivAnswered.getVisibility() == View.VISIBLE) { result.add(context.getString(R.string.title_accessibility_answered)); + ivAnswered.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO); + } + + if (ivForwarded.getVisibility() == View.VISIBLE) { + result.add(context.getString(R.string.title_accessibility_forwarded)); + ivForwarded.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO); + } if (ibFlagged.getVisibility() == View.VISIBLE && ibFlagged.isEnabled()) { int flagged = (message.count - message.unflagged); @@ -8127,13 +8161,25 @@ public class AdapterMessage extends RecyclerView.Adapter 0) + if (ivAttachments.getVisibility() == View.VISIBLE) { result.add(context.getString(R.string.title_accessibility_attachment)); + ivAttachments.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO); + } + + if (tvNotes.getVisibility() == View.VISIBLE) { + result.add(tvNotes.getText().toString()); + tvNotes.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO); + } boolean outgoing = isOutgoing(message); Address[] addresses = (EntityFolder.isOutgoing(message.folderType) && @@ -8151,20 +8197,34 @@ public class AdapterMessage extends RecyclerView.Adapter @@ -17,6 +18,7 @@ android:layout_width="6dp" android:layout_height="0dp" android:background="?attr/colorAccent" + android:contentDescription="@null" app:layout_constraintBottom_toBottomOf="@+id/paddingBottom" app:layout_constraintStart_toEndOf="@+id/ivBadge" app:layout_constraintTop_toTopOf="parent" /> @@ -37,6 +39,7 @@ android:layout_gravity="center_vertical|center_horizontal" android:layout_marginStart="6dp" android:background="?android:attr/selectableItemBackgroundBorderless" + android:contentDescription="@null" android:visibility="visible" app:layout_constraintBottom_toBottomOf="@+id/paddingBottom" app:layout_constraintStart_toEndOf="@id/vwColor" @@ -57,7 +60,7 @@ android:layout_height="0dp" android:layout_marginStart="6dp" android:background="?android:attr/selectableItemBackgroundBorderless" - android:contentDescription="@string/title_legend_avatar" + android:contentDescription="@null" android:scaleType="centerCrop" app:layout_constraintBottom_toBottomOf="@+id/tvFolder" app:layout_constraintDimensionRatio="1:1" @@ -71,6 +74,7 @@ android:layout_height="21dp" android:layout_marginStart="6dp" android:background="?android:attr/selectableItemBackgroundBorderless" + android:contentDescription="@null" app:layout_constraintBottom_toBottomOf="@+id/tvFrom" app:layout_constraintStart_toEndOf="@id/ibAvatar" app:layout_constraintTop_toTopOf="@+id/tvFrom" @@ -83,7 +87,7 @@ android:layout_height="21dp" android:layout_marginStart="6dp" android:background="?android:attr/selectableItemBackgroundBorderless" - android:contentDescription="@string/title_legend_auth" + android:contentDescription="@null" app:layout_constraintBottom_toBottomOf="@+id/tvFrom" app:layout_constraintStart_toEndOf="@id/ibVerified" app:layout_constraintTop_toTopOf="@+id/tvFrom" @@ -96,6 +100,7 @@ android:layout_height="21dp" android:layout_marginStart="6dp" android:background="?android:attr/selectableItemBackgroundBorderless" + android:contentDescription="@null" app:layout_constraintBottom_toBottomOf="@+id/tvFrom" app:layout_constraintStart_toEndOf="@id/ibAuth" app:layout_constraintTop_toTopOf="@+id/tvFrom" @@ -108,6 +113,7 @@ android:layout_height="21dp" android:layout_marginStart="6dp" android:background="?android:attr/selectableItemBackgroundBorderless" + android:contentDescription="@null" app:layout_constraintBottom_toBottomOf="@+id/tvFrom" app:layout_constraintStart_toEndOf="@id/ibPriority" app:layout_constraintTop_toTopOf="@+id/tvFrom" @@ -119,6 +125,7 @@ android:layout_width="21dp" android:layout_height="21dp" android:layout_marginStart="6dp" + android:contentDescription="@null" app:layout_constraintBottom_toBottomOf="@+id/tvFrom" app:layout_constraintStart_toEndOf="@id/ibSensitivity" app:layout_constraintTop_toTopOf="@+id/tvFrom" @@ -131,7 +138,7 @@ android:layout_height="21dp" android:layout_marginStart="6dp" android:background="?android:attr/selectableItemBackgroundBorderless" - android:contentDescription="@string/title_legend_signed" + android:contentDescription="@null" app:layout_constraintBottom_toBottomOf="@+id/tvFrom" app:layout_constraintStart_toEndOf="@id/ivImportance" app:layout_constraintTop_toTopOf="@+id/tvFrom" @@ -143,7 +150,7 @@ android:layout_height="21dp" android:layout_marginStart="6dp" android:background="?android:attr/selectableItemBackgroundBorderless" - android:contentDescription="@string/title_legend_encrypted" + android:contentDescription="@null" app:layout_constraintBottom_toBottomOf="@+id/tvFrom" app:layout_constraintStart_toEndOf="@id/ibSigned" app:layout_constraintTop_toTopOf="@+id/tvFrom" @@ -197,6 +204,7 @@ android:layout_width="21dp" android:layout_height="21dp" android:layout_marginStart="6dp" + android:contentDescription="@null" app:layout_constraintBottom_toBottomOf="@+id/tvSubject" app:layout_constraintStart_toEndOf="@id/ibAvatar" app:layout_constraintTop_toTopOf="@+id/tvSubject" @@ -207,7 +215,7 @@ android:layout_width="21dp" android:layout_height="21dp" android:layout_marginStart="6dp" - android:contentDescription="@string/title_legend_found" + android:contentDescription="@null" app:layout_constraintBottom_toBottomOf="@+id/tvSubject" app:layout_constraintStart_toEndOf="@id/ivType" app:layout_constraintTop_toTopOf="@+id/tvSubject" @@ -219,7 +227,7 @@ android:layout_height="21dp" android:layout_marginStart="6dp" android:background="?android:attr/selectableItemBackgroundBorderless" - android:contentDescription="@string/title_legend_snoozed" + android:contentDescription="@null" app:layout_constraintBottom_toBottomOf="@+id/tvSubject" app:layout_constraintStart_toEndOf="@id/ivFound" app:layout_constraintTop_toTopOf="@+id/tvSubject" @@ -230,7 +238,7 @@ android:layout_width="21dp" android:layout_height="21dp" android:layout_marginStart="6dp" - android:contentDescription="@string/title_legend_classified" + android:contentDescription="@null" app:layout_constraintBottom_toBottomOf="@+id/tvSubject" app:layout_constraintStart_toEndOf="@id/ibSnoozed" app:layout_constraintTop_toTopOf="@+id/tvSubject" @@ -241,7 +249,7 @@ android:layout_width="21dp" android:layout_height="21dp" android:layout_marginStart="6dp" - android:contentDescription="@string/title_legend_answered" + android:contentDescription="@null" app:layout_constraintBottom_toBottomOf="@+id/tvSubject" app:layout_constraintStart_toEndOf="@id/ivClassified" app:layout_constraintTop_toTopOf="@+id/tvSubject" @@ -252,7 +260,7 @@ android:layout_width="21dp" android:layout_height="21dp" android:layout_marginStart="6dp" - android:contentDescription="@string/title_legend_answered" + android:contentDescription="@null" app:layout_constraintBottom_toBottomOf="@+id/tvSubject" app:layout_constraintStart_toEndOf="@id/ivAnswered" app:layout_constraintTop_toTopOf="@+id/tvSubject" @@ -263,6 +271,7 @@ android:layout_width="21dp" android:layout_height="21dp" android:layout_marginStart="6dp" + android:contentDescription="@null" app:layout_constraintBottom_toBottomOf="@+id/tvSubject" app:layout_constraintStart_toEndOf="@id/ivForwarded" app:layout_constraintTop_toTopOf="@+id/tvSubject" @@ -303,6 +312,7 @@ android:layout_width="15dp" android:layout_height="15dp" android:layout_marginEnd="6dp" + android:contentDescription="@null" app:layout_constraintBottom_toBottomOf="@id/tvSubject" app:layout_constraintEnd_toStartOf="@+id/ibFlagged" app:layout_constraintTop_toTopOf="@+id/tvSubject" @@ -314,6 +324,7 @@ android:layout_height="36dp" android:layout_marginEnd="6dp" android:background="?android:attr/selectableItemBackgroundBorderless" + android:contentDescription="@null" android:paddingTop="6dp" android:paddingBottom="6dp" android:visibility="visible" @@ -427,6 +438,7 @@ android:layout_height="27dp" android:layout_marginEnd="6dp" android:background="?android:attr/selectableItemBackgroundBorderless" + android:contentDescription="@null" android:scaleType="fitCenter" app:layout_constraintBottom_toBottomOf="@+id/tvError" app:layout_constraintEnd_toStartOf="@+id/paddingEnd" diff --git a/app/src/main/res/layout/include_message_normal.xml b/app/src/main/res/layout/include_message_normal.xml index 88605830af..11e5761f56 100644 --- a/app/src/main/res/layout/include_message_normal.xml +++ b/app/src/main/res/layout/include_message_normal.xml @@ -7,6 +7,7 @@ android:id="@+id/ivBadge" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:contentDescription="@null" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:srcCompat="@drawable/badge" /> @@ -16,6 +17,7 @@ android:layout_width="6dp" android:layout_height="0dp" android:background="?attr/colorAccent" + android:contentDescription="@null" app:layout_constraintBottom_toBottomOf="@+id/paddingBottom" app:layout_constraintStart_toEndOf="@+id/ivBadge" app:layout_constraintTop_toTopOf="parent" /> @@ -36,6 +38,7 @@ android:layout_marginStart="6dp" android:background="?android:attr/selectableItemBackgroundBorderless" android:visibility="visible" + android:contentDescription="@null" app:layout_constraintBottom_toBottomOf="@+id/paddingBottom" app:layout_constraintStart_toEndOf="@id/vwColor" app:layout_constraintTop_toTopOf="@id/paddingTop" @@ -54,7 +57,7 @@ android:layout_width="0dp" android:layout_height="0dp" android:background="?android:attr/selectableItemBackgroundBorderless" - android:contentDescription="@string/title_legend_avatar" + android:contentDescription="@null" android:paddingStart="6dp" android:paddingEnd="6dp" android:scaleType="centerCrop" @@ -70,6 +73,7 @@ android:layout_height="21dp" android:layout_marginStart="6dp" android:background="?android:attr/selectableItemBackgroundBorderless" + android:contentDescription="@null" app:layout_constraintBottom_toBottomOf="@+id/tvFrom" app:layout_constraintStart_toEndOf="@id/ibAvatar" app:layout_constraintTop_toTopOf="@+id/tvFrom" @@ -82,7 +86,7 @@ android:layout_height="21dp" android:layout_marginStart="6dp" android:background="?android:attr/selectableItemBackgroundBorderless" - android:contentDescription="@string/title_legend_auth" + android:contentDescription="@null" app:layout_constraintBottom_toBottomOf="@+id/tvFrom" app:layout_constraintStart_toEndOf="@id/ibVerified" app:layout_constraintTop_toTopOf="@+id/tvFrom" @@ -95,6 +99,7 @@ android:layout_height="21dp" android:layout_marginStart="6dp" android:background="?android:attr/selectableItemBackgroundBorderless" + android:contentDescription="@null" app:layout_constraintBottom_toBottomOf="@+id/tvFrom" app:layout_constraintStart_toEndOf="@id/ibAuth" app:layout_constraintTop_toTopOf="@+id/tvFrom" @@ -107,6 +112,7 @@ android:layout_height="21dp" android:layout_marginStart="6dp" android:background="?android:attr/selectableItemBackgroundBorderless" + android:contentDescription="@null" app:layout_constraintBottom_toBottomOf="@+id/tvFrom" app:layout_constraintStart_toEndOf="@id/ibPriority" app:layout_constraintTop_toTopOf="@+id/tvFrom" @@ -118,6 +124,7 @@ android:layout_width="21dp" android:layout_height="21dp" android:layout_marginStart="6dp" + android:contentDescription="@null" app:layout_constraintBottom_toBottomOf="@+id/tvFrom" app:layout_constraintStart_toEndOf="@id/ibSensitivity" app:layout_constraintTop_toTopOf="@+id/tvFrom" @@ -130,7 +137,7 @@ android:layout_height="21dp" android:layout_marginStart="6dp" android:background="?android:attr/selectableItemBackgroundBorderless" - android:contentDescription="@string/title_legend_signed" + android:contentDescription="@null" app:layout_constraintBottom_toBottomOf="@+id/tvFrom" app:layout_constraintStart_toEndOf="@id/ivImportance" app:layout_constraintTop_toTopOf="@+id/tvFrom" @@ -142,7 +149,7 @@ android:layout_height="21dp" android:layout_marginStart="6dp" android:background="?android:attr/selectableItemBackgroundBorderless" - android:contentDescription="@string/title_legend_encrypted" + android:contentDescription="@null" app:layout_constraintBottom_toBottomOf="@+id/tvFrom" app:layout_constraintStart_toEndOf="@id/ibSigned" app:layout_constraintTop_toTopOf="@+id/tvFrom" @@ -226,6 +233,7 @@ android:layout_height="42dp" android:background="?android:attr/selectableItemBackgroundBorderless" android:padding="6dp" + android:contentDescription="@null" android:visibility="visible" app:layout_constraintBottom_toBottomOf="@+id/tvFolder" app:layout_constraintEnd_toStartOf="@id/paddingEnd" @@ -237,6 +245,7 @@ android:layout_width="21dp" android:layout_height="21dp" android:layout_marginStart="6dp" + android:contentDescription="@null" app:layout_constraintBottom_toBottomOf="@+id/tvFolder" app:layout_constraintStart_toEndOf="@id/ibAvatar" app:layout_constraintTop_toTopOf="@+id/tvFolder" @@ -247,7 +256,7 @@ android:layout_width="21dp" android:layout_height="21dp" android:layout_marginStart="6dp" - android:contentDescription="@string/title_legend_found" + android:contentDescription="@null" app:layout_constraintBottom_toBottomOf="@+id/tvFolder" app:layout_constraintStart_toEndOf="@id/ivType" app:layout_constraintTop_toTopOf="@+id/tvFolder" @@ -259,7 +268,7 @@ android:layout_height="21dp" android:layout_marginStart="6dp" android:background="?android:attr/selectableItemBackgroundBorderless" - android:contentDescription="@string/title_legend_snoozed" + android:contentDescription="@null" app:layout_constraintBottom_toBottomOf="@+id/tvFolder" app:layout_constraintStart_toEndOf="@id/ivFound" app:layout_constraintTop_toTopOf="@+id/tvFolder" @@ -270,7 +279,7 @@ android:layout_width="21dp" android:layout_height="21dp" android:layout_marginStart="6dp" - android:contentDescription="@string/title_legend_classified" + android:contentDescription="@null" app:layout_constraintBottom_toBottomOf="@+id/tvFolder" app:layout_constraintStart_toEndOf="@id/ibSnoozed" app:layout_constraintTop_toTopOf="@+id/tvFolder" @@ -281,7 +290,7 @@ android:layout_width="21dp" android:layout_height="21dp" android:layout_marginStart="6dp" - android:contentDescription="@string/title_legend_answered" + android:contentDescription="@null" app:layout_constraintBottom_toBottomOf="@+id/tvFolder" app:layout_constraintStart_toEndOf="@id/ivClassified" app:layout_constraintTop_toTopOf="@+id/tvFolder" @@ -292,7 +301,7 @@ android:layout_width="21dp" android:layout_height="21dp" android:layout_marginStart="6dp" - android:contentDescription="@string/title_legend_answered" + android:contentDescription="@null" app:layout_constraintBottom_toBottomOf="@+id/tvFolder" app:layout_constraintStart_toEndOf="@id/ivAnswered" app:layout_constraintTop_toTopOf="@+id/tvFolder" @@ -303,6 +312,7 @@ android:layout_width="21dp" android:layout_height="21dp" android:layout_marginStart="6dp" + android:contentDescription="@null" app:layout_constraintBottom_toBottomOf="@+id/tvFolder" app:layout_constraintStart_toEndOf="@id/ivForwarded" app:layout_constraintTop_toTopOf="@+id/tvFolder" @@ -343,6 +353,7 @@ android:layout_width="15dp" android:layout_height="15dp" android:layout_marginEnd="6dp" + android:contentDescription="@null" app:layout_constraintBottom_toBottomOf="@+id/tvFolder" app:layout_constraintEnd_toStartOf="@+id/ibFlagged" app:layout_constraintTop_toTopOf="@+id/tvFolder" @@ -427,6 +438,7 @@ android:layout_height="27dp" android:layout_marginEnd="6dp" android:background="?android:attr/selectableItemBackgroundBorderless" + android:contentDescription="@null" android:scaleType="fitCenter" app:layout_constraintBottom_toBottomOf="@+id/tvError" app:layout_constraintEnd_toStartOf="@+id/paddingEnd" diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index dd39425047..8628c4adda 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -2541,6 +2541,7 @@ View help Selected Replied + Forwarded Scroll down Scroll up Toggle read messages filter