diff options
author | Dianne Hackborn <hackbod@google.com> | 2015-08-05 18:07:31 -0700 |
---|---|---|
committer | Dianne Hackborn <hackbod@google.com> | 2015-08-06 22:54:46 -0700 |
commit | 6ff55fcb8553857c9e2b0c0ddaee8a40cdbc6c47 (patch) | |
tree | c6cc5b248f0be36cc2d9dc412fc3ea625013a5bd /core/java/android/view | |
parent | 6bdc4637d7ac1df86e9d745ac483987107a71282 (diff) | |
download | frameworks_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.java | 54 |
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); |