summaryrefslogtreecommitdiffstats
path: root/core/java/android/view
diff options
context:
space:
mode:
authorDianne Hackborn <hackbod@google.com>2015-08-05 18:07:31 -0700
committerDianne Hackborn <hackbod@google.com>2015-08-06 22:54:46 -0700
commit6ff55fcb8553857c9e2b0c0ddaee8a40cdbc6c47 (patch)
treec6cc5b248f0be36cc2d9dc412fc3ea625013a5bd /core/java/android/view
parent6bdc4637d7ac1df86e9d745ac483987107a71282 (diff)
downloadframeworks_base-6ff55fcb8553857c9e2b0c0ddaee8a40cdbc6c47.zip
frameworks_base-6ff55fcb8553857c9e2b0c0ddaee8a40cdbc6c47.tar.gz
frameworks_base-6ff55fcb8553857c9e2b0c0ddaee8a40cdbc6c47.tar.bz2
Fix issue #22846750: Starting Screenie Now On Tap crashes USA Today
Try to deal well with badly behaving old apps. Change-Id: Ibc41e5867869463fbf91f3e411c69677909fedad
Diffstat (limited to 'core/java/android/view')
-rw-r--r--core/java/android/view/ViewGroup.java54
1 files changed, 50 insertions, 4 deletions
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index fab81a4..52d6cbe 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -43,6 +43,7 @@ import android.util.AttributeSet;
import android.util.Log;
import android.util.Pools.SynchronizedPool;
import android.util.SparseArray;
+import android.util.SparseBooleanArray;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.animation.Animation;
@@ -2902,13 +2903,58 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
final int childrenCount = getChildCount();
if (childrenCount > 0) {
structure.setChildCount(childrenCount);
- final ArrayList<View> preorderedList = buildOrderedChildList();
- final boolean customOrder = preorderedList == null
+ ArrayList<View> preorderedList = buildOrderedChildList();
+ boolean customOrder = preorderedList == null
&& isChildrenDrawingOrderEnabled();
final View[] children = mChildren;
for (int i=0; i<childrenCount; i++) {
- final int childIndex = customOrder
- ? getChildDrawingOrder(childrenCount, i) : i;
+ int childIndex;
+ try {
+ childIndex = customOrder ? getChildDrawingOrder(childrenCount, i) : i;
+ } catch (IndexOutOfBoundsException e) {
+ childIndex = i;
+ if (mContext.getApplicationInfo().targetSdkVersion
+ < Build.VERSION_CODES.M) {
+ Log.w(TAG, "Bad getChildDrawingOrder while collecting assist @ "
+ + i + " of " + childrenCount, e);
+ // At least one app is failing when we call getChildDrawingOrder
+ // at this point, so deal semi-gracefully with it by falling back
+ // on the basic order.
+ customOrder = false;
+ if (i > 0) {
+ // If we failed at the first index, there really isn't
+ // anything to do -- we will just proceed with the simple
+ // sequence order.
+ // Otherwise, we failed in the middle, so need to come up
+ // with an order for the remaining indices and use that.
+ // Failed at the first one, easy peasy.
+ int[] permutation = new int[childrenCount];
+ SparseBooleanArray usedIndices = new SparseBooleanArray();
+ // Go back and collected the indices we have done so far.
+ for (int j=0; j<i; j++) {
+ permutation[j] = getChildDrawingOrder(childrenCount, j);
+ usedIndices.put(permutation[j], true);
+ }
+ // Fill in the remaining indices with indices that have not
+ // yet been used.
+ int nextIndex = 0;
+ for (int j=i; j<childrenCount; j++) {
+ while (usedIndices.get(nextIndex, false)) {
+ nextIndex++;
+ }
+ permutation[j] = nextIndex;
+ nextIndex++;
+ }
+ // Build the final view list.
+ preorderedList = new ArrayList<>(childrenCount);
+ for (int j=0; j<childrenCount; j++) {
+ preorderedList.add(children[permutation[j]]);
+ }
+ }
+ } else {
+ throw e;
+ }
+ }
final View child = (preorderedList == null)
? children[childIndex] : preorderedList.get(childIndex);
ViewStructure cstructure = structure.newChild(i);