Initial changes to make folders accessible

Change-Id: Id8c9cbc0ef200967c3b966fbccfdfde184d4211c
diff --git a/src/com/android/launcher2/Folder.java b/src/com/android/launcher2/Folder.java
index 019ac70..33b5de1 100644
--- a/src/com/android/launcher2/Folder.java
+++ b/src/com/android/launcher2/Folder.java
@@ -37,6 +37,8 @@
 import android.view.MenuItem;
 import android.view.MotionEvent;
 import android.view.View;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
 import android.view.animation.AccelerateInterpolator;
 import android.view.animation.DecelerateInterpolator;
 import android.view.inputmethod.EditorInfo;
@@ -95,7 +97,6 @@
     private Alarm mReorderAlarm = new Alarm();
     private Alarm mOnExitAlarm = new Alarm();
     private int mFolderNameHeight;
-    private Rect mHitRect = new Rect();
     private Rect mTempRect = new Rect();
     private boolean mDragInProgress = false;
     private boolean mDeleteFolderOnDropCompleted = false;
@@ -240,9 +241,14 @@
         mFolderName.setHint(sHintText);
         // Convert to a string here to ensure that no other state associated with the text field
         // gets saved.
-        mInfo.setTitle(mFolderName.getText().toString());
+        String newTitle = mFolderName.getText().toString();
+        mInfo.setTitle(newTitle);
         LauncherModel.updateItemInDatabase(mLauncher, mInfo);
 
+        if (commit) {
+            sendCustomAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED,
+                    String.format(mContext.getString(R.string.folder_renamed), newTitle));
+        }
         // In order to clear the focus from the text field, we set the focus on ourself. This
         // ensures that every time the field is clicked, focus is gained, giving reliable behavior.
         requestFocus();
@@ -283,6 +289,12 @@
         mFolderIcon = icon;
     }
 
+    @Override
+    public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
+        // When the folder gets focus, we don't want to announce the list of items.
+        return true;
+    }
+
     /**
      * @return the FolderInfo object associated with this folder
      */
@@ -398,6 +410,9 @@
         oa.addListener(new AnimatorListenerAdapter() {
             @Override
             public void onAnimationStart(Animator animation) {
+                sendCustomAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED,
+                        String.format(mContext.getString(R.string.folder_opened),
+                        mContent.getCountX(), mContent.getCountY()));
                 mState = STATE_ANIMATING;
             }
             @Override
@@ -415,6 +430,15 @@
         oa.start();
     }
 
+    private void sendCustomAccessibilityEvent(int type, String text) {
+        if (AccessibilityManager.getInstance(mContext).isEnabled()) {
+            AccessibilityEvent event = AccessibilityEvent.obtain(type);
+            onInitializeAccessibilityEvent(event);
+            event.getText().add(text);
+            AccessibilityManager.getInstance(mContext).sendAccessibilityEvent(event);
+        }
+    }
+
     private void setFocusOnFirstChild() {
         View firstChild = mContent.getChildAt(0, 0);
         if (firstChild != null) {
@@ -460,6 +484,8 @@
             }
             @Override
             public void onAnimationStart(Animator animation) {
+                sendCustomAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED,
+                        mContext.getString(R.string.folder_closed));
                 mState = STATE_ANIMATING;
             }
         });