Touch exploration separate setting and API to poll the latter state.

1. Seperated touch exploration to be a seperate setting rather being
   magically enabled by the system of accessiiblity is on the there
   is at leas one accessibility service that speaks enabled. Now
   there is a setting for requesting touch exploration but still the
   system will enabled it only if that makes sense i.e. accessibility
   is on and one accessibility service that speaks is enabled.

2. Added public API for checking of touch exploration is enabled.

3. Added description attribute in accessibility service declaration
   which will be shown to the user before enabling the service.

4. Added API for quick cloning of AccessibilityNodeInfo.

5. Added clone functionality to SparseArray, SparseIntArray, and
   SparseBooleanArray.

bug:5034010
bug:5033928

Change-Id: Ia442edbe55c20309244061cd9d24e0545c01b54f
diff --git a/core/java/android/util/SparseArray.java b/core/java/android/util/SparseArray.java
index 7fc43b9..7cf4579 100644
--- a/core/java/android/util/SparseArray.java
+++ b/core/java/android/util/SparseArray.java
@@ -23,10 +23,14 @@
  * there can be gaps in the indices.  It is intended to be more efficient
  * than using a HashMap to map Integers to Objects.
  */
-public class SparseArray<E> {
+public class SparseArray<E> implements Cloneable {
     private static final Object DELETED = new Object();
     private boolean mGarbage = false;
 
+    private int[] mKeys;
+    private Object[] mValues;
+    private int mSize;
+
     /**
      * Creates a new SparseArray containing no mappings.
      */
@@ -47,6 +51,20 @@
         mSize = 0;
     }
 
+    @Override
+    @SuppressWarnings("unchecked")
+    public SparseArray<E> clone() {
+        SparseArray<E> clone = null;
+        try {
+            clone = (SparseArray<E>) super.clone();
+            clone.mKeys = mKeys.clone();
+            clone.mValues = mValues.clone();
+        } catch (CloneNotSupportedException cnse) {
+            /* ignore */
+        }
+        return clone;
+    }
+
     /**
      * Gets the Object mapped from the specified key, or <code>null</code>
      * if no such mapping has been made.
@@ -59,6 +77,7 @@
      * Gets the Object mapped from the specified key, or the specified Object
      * if no such mapping has been made.
      */
+    @SuppressWarnings("unchecked")
     public E get(int key, E valueIfKeyNotFound) {
         int i = binarySearch(mKeys, 0, mSize, key);
 
@@ -209,6 +228,7 @@
      * the value from the <code>index</code>th key-value mapping that this
      * SparseArray stores.  
      */
+    @SuppressWarnings("unchecked")
     public E valueAt(int index) {
         if (mGarbage) {
             gc();
@@ -331,20 +351,4 @@
         else
             return ~high;
     }
-
-    private void checkIntegrity() {
-        for (int i = 1; i < mSize; i++) {
-            if (mKeys[i] <= mKeys[i - 1]) {
-                for (int j = 0; j < mSize; j++) {
-                    Log.e("FAIL", j + ": " + mKeys[j] + " -> " + mValues[j]);
-                }
-
-                throw new RuntimeException();
-            }
-        }
-    }
-
-    private int[] mKeys;
-    private Object[] mValues;
-    private int mSize;
 }