Populating some more accessibility events.

Change-Id: I7813abdd6dcc0979949caec9e31029486be0396d
diff --git a/res/layout/apps_customize_pane.xml b/res/layout/apps_customize_pane.xml
index 8361d16..8b1bd39 100644
--- a/res/layout/apps_customize_pane.xml
+++ b/res/layout/apps_customize_pane.xml
@@ -43,6 +43,7 @@
                 android:layout_gravity="right"
                 android:gravity="center"
                 android:text="@string/market"
+                android:contentDescription="@string/market"
                 android:textColor="@color/workspace_all_apps_and_delete_zone_text_color"
                 android:textSize="18sp"
                 android:shadowColor="@color/workspace_all_apps_and_delete_zone_text_shadow_color"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 2d41791..e7c18bd 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -245,4 +245,16 @@
 
     <!-- Default folder title -->
     <string name="folder_hint_text">Unnamed Folder</string>
+
+    <!-- Accessibility -->
+    <skip />
+
+    <!-- The format string for default page scroll text [CHAR_LIMIT=none] -->
+    <string name="default_scroll_format" translatable="false">Page %1$d of %2$d</string>
+    <!-- The format string for Workspace page scroll text [CHAR_LIMIT=none] -->
+    <string name="workspace_scroll_format" translatable="false">Workspace %1$d of %2$d</string>
+    <!-- The format string for AppsCustomize Apps page scroll text [CHAR_LIMIT=none] -->
+    <string name="apps_customize_apps_scroll_format" translatable="false">Apps page %1$d of %2$d</string>
+    <!-- The format string for AppsCustomize Apps page scroll text [CHAR_LIMIT=none] -->
+    <string name="apps_customize_widgets_scroll_format" translatable="false">Widgets page %1$d of %2$d</string>
 </resources>
diff --git a/src/com/android/launcher2/AppsCustomizePagedView.java b/src/com/android/launcher2/AppsCustomizePagedView.java
index 5696b50..54a2e42 100644
--- a/src/com/android/launcher2/AppsCustomizePagedView.java
+++ b/src/com/android/launcher2/AppsCustomizePagedView.java
@@ -1192,4 +1192,19 @@
         final int count = getChildCount();
         return Math.min(page + 2, count - 1);
     }
+
+    @Override
+    protected String getCurrentPageDescription() {
+        int page = (mNextPage != INVALID_PAGE) ? mNextPage : mCurrentPage;
+        int stringId = R.string.default_scroll_format;
+        switch (mContentType) {
+        case Applications:
+            stringId = R.string.apps_customize_apps_scroll_format;
+            break;
+        case Widgets:
+            stringId = R.string.apps_customize_widgets_scroll_format;
+            break;
+        }
+        return String.format(mContext.getString(stringId), page + 1, getChildCount());
+    }
 }
diff --git a/src/com/android/launcher2/FolderIcon.java b/src/com/android/launcher2/FolderIcon.java
index 0597110..bae2fd7 100644
--- a/src/com/android/launcher2/FolderIcon.java
+++ b/src/com/android/launcher2/FolderIcon.java
@@ -95,6 +95,7 @@
         icon.mFolderName = (BubbleTextView) icon.findViewById(R.id.folder_name);
         icon.mFolderName.setText(folderInfo.title);
         icon.mPreviewBackground = (ImageView) icon.findViewById(R.id.preview_background);
+        icon.mPreviewBackground.setContentDescription(folderInfo.title);
 
         icon.setTag(folderInfo);
         icon.setOnClickListener(launcher);
@@ -383,5 +384,6 @@
 
     public void onTitleChanged(CharSequence title) {
         mFolderName.setText(title.toString());
+        mPreviewBackground.setContentDescription(title.toString());
     }
 }
diff --git a/src/com/android/launcher2/PagedView.java b/src/com/android/launcher2/PagedView.java
index fa6a570..9ca2f90 100644
--- a/src/com/android/launcher2/PagedView.java
+++ b/src/com/android/launcher2/PagedView.java
@@ -16,8 +16,6 @@
 
 package com.android.launcher2;
 
-import java.util.ArrayList;
-
 import android.animation.Animator;
 import android.animation.AnimatorInflater;
 import android.animation.AnimatorListenerAdapter;
@@ -39,6 +37,8 @@
 import android.view.ViewConfiguration;
 import android.view.ViewGroup;
 import android.view.ViewParent;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.animation.Interpolator;
 import android.widget.Checkable;
 import android.widget.ImageView;
@@ -46,6 +46,8 @@
 
 import com.android.launcher.R;
 
+import java.util.ArrayList;
+
 /**
  * An abstraction of the original Workspace which supports browsing through a
  * sequential list of "pages"
@@ -1699,4 +1701,49 @@
         int indicatorPos = (int) (offset * pageWidth) + pageOffset + indicatorCenterOffset;
         mScrollIndicator.setTranslationX(indicatorPos);
     }
+
+    /* Accessibility */
+    @Override
+    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+        super.onInitializeAccessibilityNodeInfo(info);
+        info.setScrollable(true);
+    }
+
+    @Override
+    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
+        super.onInitializeAccessibilityEvent(event);
+        event.setScrollable(true);
+        if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_SCROLLED) {
+            event.setFromIndex(mCurrentPage);
+            event.setToIndex(mCurrentPage);
+            event.setItemCount(getChildCount());
+        }
+    }
+
+    @Override
+    public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
+        // Do not append text content to scroll events they are fired frequently
+        // and the client has already received another event type with the text.
+        if (event.getEventType() != AccessibilityEvent.TYPE_VIEW_SCROLLED) {
+            super.dispatchPopulateAccessibilityEvent(event);
+        }
+
+        onPopulateAccessibilityEvent(event);
+        return false;
+    }
+
+    @Override
+    public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
+        super.onPopulateAccessibilityEvent(event);
+
+        if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_SCROLLED) {
+            event.getText().add(getCurrentPageDescription());
+        }
+    }
+
+    protected String getCurrentPageDescription() {
+        int page = (mNextPage != INVALID_PAGE) ? mNextPage : mCurrentPage;
+        return String.format(mContext.getString(R.string.default_scroll_format),
+                page + 1, getChildCount());
+    }
 }
diff --git a/src/com/android/launcher2/PagedViewWidget.java b/src/com/android/launcher2/PagedViewWidget.java
index 365965d..d9c2a84 100644
--- a/src/com/android/launcher2/PagedViewWidget.java
+++ b/src/com/android/launcher2/PagedViewWidget.java
@@ -105,6 +105,7 @@
             image.setMaxWidth(maxWidth);
         }
         image.setImageDrawable(preview);
+        image.setContentDescription(info.label);
         mPreviewImageView = image;
         final TextView name = (TextView) findViewById(R.id.widget_name);
         name.setText(info.label);
@@ -117,11 +118,13 @@
     public void applyFromResolveInfo(PackageManager pm, ResolveInfo info,
             FastBitmapDrawable preview, HolographicOutlineHelper holoOutlineHelper) {
         mHolographicOutlineHelper = holoOutlineHelper;
+        CharSequence label = info.loadLabel(pm);
         final ImageView image = (ImageView) findViewById(R.id.widget_preview);
         image.setImageDrawable(preview);
+        image.setContentDescription(label);
         mPreviewImageView = image;
         final TextView name = (TextView) findViewById(R.id.widget_name);
-        name.setText(info.loadLabel(pm));
+        name.setText(label);
         name.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
         final TextView dims = (TextView) findViewById(R.id.widget_dims);
         if (dims != null) {
diff --git a/src/com/android/launcher2/Workspace.java b/src/com/android/launcher2/Workspace.java
index 4eea5c3..e53768d 100644
--- a/src/com/android/launcher2/Workspace.java
+++ b/src/com/android/launcher2/Workspace.java
@@ -3477,4 +3477,11 @@
     @Override
     public void syncPageItems(int page) {
     }
+
+    @Override
+    protected String getCurrentPageDescription() {
+        int page = (mNextPage != INVALID_PAGE) ? mNextPage : mCurrentPage;
+        return String.format(mContext.getString(R.string.workspace_scroll_format),
+                page + 1, getChildCount());
+    }
 }