Merge "Try to mitigate issue #31016187: system_server crash in ArraySet." into nyc-dev
diff --git a/core/java/android/util/ArraySet.java b/core/java/android/util/ArraySet.java
index 1e765b6..a02c070 100644
--- a/core/java/android/util/ArraySet.java
+++ b/core/java/android/util/ArraySet.java
@@ -156,28 +156,46 @@
             synchronized (ArraySet.class) {
                 if (mTwiceBaseCache != null) {
                     final Object[] array = mTwiceBaseCache;
-                    mArray = array;
-                    mTwiceBaseCache = (Object[])array[0];
-                    mHashes = (int[])array[1];
-                    array[0] = array[1] = null;
-                    mTwiceBaseCacheSize--;
-                    if (DEBUG) Log.d(TAG, "Retrieving 2x cache " + mHashes
-                            + " now have " + mTwiceBaseCacheSize + " entries");
-                    return;
+                    try {
+                        mArray = array;
+                        mTwiceBaseCache = (Object[]) array[0];
+                        mHashes = (int[]) array[1];
+                        array[0] = array[1] = null;
+                        mTwiceBaseCacheSize--;
+                        if (DEBUG) Log.d(TAG, "Retrieving 2x cache " + mHashes
+                                + " now have " + mTwiceBaseCacheSize + " entries");
+                        return;
+                    } catch (ClassCastException e) {
+                    }
+                    // Whoops!  Someone trampled the array (probably due to not protecting
+                    // their access with a lock).  Our cache is corrupt; report and give up.
+                    Slog.wtf(TAG, "Found corrupt ArraySet cache: [0]=" + array[0]
+                            + " [1]=" + array[1]);
+                    mTwiceBaseCache = null;
+                    mTwiceBaseCacheSize = 0;
                 }
             }
         } else if (size == BASE_SIZE) {
             synchronized (ArraySet.class) {
                 if (mBaseCache != null) {
                     final Object[] array = mBaseCache;
-                    mArray = array;
-                    mBaseCache = (Object[])array[0];
-                    mHashes = (int[])array[1];
-                    array[0] = array[1] = null;
-                    mBaseCacheSize--;
-                    if (DEBUG) Log.d(TAG, "Retrieving 1x cache " + mHashes
-                            + " now have " + mBaseCacheSize + " entries");
-                    return;
+                    try {
+                        mArray = array;
+                        mBaseCache = (Object[]) array[0];
+                        mHashes = (int[]) array[1];
+                        array[0] = array[1] = null;
+                        mBaseCacheSize--;
+                        if (DEBUG) Log.d(TAG, "Retrieving 1x cache " + mHashes
+                                + " now have " + mBaseCacheSize + " entries");
+                        return;
+                    } catch (ClassCastException e) {
+                    }
+                    // Whoops!  Someone trampled the array (probably due to not protecting
+                    // their access with a lock).  Our cache is corrupt; report and give up.
+                    Slog.wtf(TAG, "Found corrupt ArraySet cache: [0]=" + array[0]
+                            + " [1]=" + array[1]);
+                    mBaseCache = null;
+                    mBaseCacheSize = 0;
                 }
             }
         }