Enable Talkback for photo picker
- When pressing a button, Talkback speaks the button text.
- When pressing a photo, Talkback speaks photo's account type,
user name, and whether the photo is checked or not.
- When double tapping a photo, Talkback speaks the account type,
user name, and that the photo is checked.
Bug: 25498370
Change-Id: Id43a220a4d5625470ff0ad1ff40a840d9c6bcd84
diff --git a/res/values/strings.xml b/res/values/strings.xml
index bacf641..cf5f798 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -890,4 +890,12 @@
type. For example: Delete Website, Delete SIP, etc [CHAR LIMIT=30]-->
<string name="editor_delete_view_description_short">Delete <xliff:g id="data_kind">%s</xliff:g></string>
+ <!-- Content description of photo in photo picker indicating a photo from a specific account is *not* selected.
+ For example: Photo from Google abc@gmail.com not checked. [CHAR LIMIT=30]-->
+ <string name="photo_view_description_not_checked">Photo from <xliff:g id="account_type">%s </xliff:g><xliff:g id="user_name">%s </xliff:g>not checked</string>
+
+ <!-- Content description of photo in photo picker indicating a photo from a specific account is selected.
+ For example: Photo from Google abc@gmail.com checked. [CHAR LIMIT=30]-->
+ <string name="photo_view_description_checked">Photo from <xliff:g id="account_type">%s </xliff:g><xliff:g id="user_name">%s </xliff:g>checked</string>
+
</resources>
diff --git a/src/com/android/contacts/editor/CompactPhotoSelectionFragment.java b/src/com/android/contacts/editor/CompactPhotoSelectionFragment.java
index 060d64d..0ce6ae7 100644
--- a/src/com/android/contacts/editor/CompactPhotoSelectionFragment.java
+++ b/src/com/android/contacts/editor/CompactPhotoSelectionFragment.java
@@ -34,6 +34,7 @@
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityEvent;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.GridView;
@@ -94,6 +95,9 @@
public int titleRes;
public int iconRes;
public String syncAdapterPackageName;
+ // Account type and user name of a photo
+ public String accountType;
+ public String accountName;
public ValuesDelta valuesDelta;
@@ -248,6 +252,12 @@
final ImageView checkImageView = (ImageView) photoItemView.findViewById(R.id.check);
checkImageView.setVisibility(photo.primary ? View.VISIBLE : View.GONE);
+ final String contentDescription = getString(photo.primary ?
+ R.string.photo_view_description_checked :
+ R.string.photo_view_description_not_checked,
+ photo.accountType, photo.accountName);
+ photoItemView.setContentDescription(contentDescription);
+
return photoItemView;
}
}
@@ -255,6 +265,7 @@
private ArrayList<Photo> mPhotos;
private int mPhotoMode;
private Listener mListener;
+ private GridView mGridView;
public void setListener(Listener listener) {
mListener = listener;
@@ -263,6 +274,7 @@
public void setPhotos(ArrayList<Photo> photos, int photoMode) {
mPhotos = photos;
mPhotoMode = photoMode;
+ mGridView.setAccessibilityDelegate(new View.AccessibilityDelegate() {});
}
@Override
@@ -282,9 +294,9 @@
final View view = inflater.inflate(R.layout.compact_photo_selection_fragment,
container, false);
- final GridView gridView = (GridView) view.findViewById(R.id.grid_view);
- gridView.setAdapter(photoAdapter);
- gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+ mGridView = (GridView) view.findViewById(R.id.grid_view);
+ mGridView.setAdapter(photoAdapter);
+ mGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
final PhotoSourceDialogFragment.Listener listener = (PhotoSourceDialogFragment.Listener)
getActivity();
@@ -298,6 +310,7 @@
if (mListener != null) {
mListener.onPhotoSelected(photo);
}
+ handleAccessibility(photo, position);
}
}
});
@@ -314,11 +327,30 @@
float density = getResources().getDisplayMetrics().density;
float dpColumnWidth = (outMetrics.widthPixels - paddingWidth * (mNumberOfColumns - 1) *
density) / mNumberOfColumns;
- gridView.setColumnWidth((int) dpColumnWidth);
+ mGridView.setColumnWidth((int) dpColumnWidth);
return view;
}
+ private void handleAccessibility(Photo photo, int position) {
+ // Use custom AccessibilityDelegate when closing this fragment to suppress event.
+ mGridView.setAccessibilityDelegate(new View.AccessibilityDelegate() {
+ @Override
+ public boolean onRequestSendAccessibilityEvent(
+ ViewGroup host, View child,AccessibilityEvent event) {
+ if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED) {
+ return false;
+ }
+ return super.onRequestSendAccessibilityEvent(host, child, event);
+ }
+ });
+ final ViewGroup clickedView = (ViewGroup) mGridView.getChildAt(position);
+ final String contentDescription = getString(
+ R.string.photo_view_description_checked,
+ photo.accountType, photo.accountName);
+ clickedView.announceForAccessibility(contentDescription);
+ }
+
@Override
public void onSaveInstanceState(Bundle outState) {
outState.putParcelableArrayList(STATE_PHOTOS, mPhotos);
diff --git a/src/com/android/contacts/editor/CompactRawContactsEditorView.java b/src/com/android/contacts/editor/CompactRawContactsEditorView.java
index 52b2ba6..d4d991b 100644
--- a/src/com/android/contacts/editor/CompactRawContactsEditorView.java
+++ b/src/com/android/contacts/editor/CompactRawContactsEditorView.java
@@ -548,6 +548,8 @@
photo.primary = valuesDelta.isSuperPrimary();
photo.kindSectionDataListIndex = i;
photo.valuesDeltaListIndex = j;
+ photo.accountType = accountType.getDisplayLabel(getContext()).toString();
+ photo.accountName = kindSectionData.getRawContactDelta().getAccountName();
if (updatedPhotos != null) {
photo.updatedPhotoUri = (Uri) updatedPhotos.get(String.valueOf(