Merge "Enable Talkback for photo picker" into ub-contactsdialer-a-dev
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(