Skip to content

Commit 9640cb6

Browse files
javachefacebook-github-bot
authored andcommitted
Add more diagnostics for subview clipping crash (facebook#47937)
Summary: Changelog: [Internal] Reviewed By: tdn120 Differential Revision: D66469161
1 parent 2a2f58a commit 9640cb6

File tree

1 file changed

+25
-3
lines changed
  • packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view

1 file changed

+25
-3
lines changed

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import android.view.MotionEvent;
2323
import android.view.View;
2424
import android.view.ViewGroup;
25+
import android.view.ViewParent;
2526
import android.view.ViewStructure;
2627
import android.view.animation.Animation;
2728
import androidx.annotation.Nullable;
@@ -56,6 +57,8 @@
5657
import com.facebook.react.uimanager.style.BorderStyle;
5758
import com.facebook.react.uimanager.style.LogicalEdge;
5859
import com.facebook.react.uimanager.style.Overflow;
60+
import java.util.HashSet;
61+
import java.util.Set;
5962

6063
/**
6164
* Backing for a React View. Has support for borders, but since borders aren't common, lazy
@@ -409,6 +412,13 @@ private void updateClippingToRect(Rect clippingRect) {
409412
try {
410413
updateSubviewClipStatus(clippingRect, i, clippedSoFar);
411414
} catch (IndexOutOfBoundsException e) {
415+
int realClippedSoFar = 0;
416+
Set<View> uniqueViews = new HashSet<>();
417+
for (int j = 0; j < i; j++) {
418+
realClippedSoFar += isViewClipped(mAllChildren[j]) ? 1 : 0;
419+
uniqueViews.add(mAllChildren[j]);
420+
}
421+
412422
throw new IllegalStateException(
413423
"Invalid clipping state. i="
414424
+ i
@@ -419,7 +429,11 @@ private void updateClippingToRect(Rect clippingRect) {
419429
+ " allChildrenCount="
420430
+ mAllChildrenCount
421431
+ " recycleCount="
422-
+ mRecycleCount,
432+
+ mRecycleCount
433+
+ " realClippedSoFar="
434+
+ realClippedSoFar
435+
+ " uniqueViewsCount="
436+
+ uniqueViews.size(),
423437
e);
424438
}
425439
if (isViewClipped(mAllChildren[i])) {
@@ -450,7 +464,9 @@ private void updateSubviewClipStatus(Rect clippingRect, int idx, int clippedSoFa
450464
removeViewInLayout(child);
451465
needUpdateClippingRecursive = true;
452466
} else if (intersects && isViewClipped(child)) {
453-
addViewInLayout(child, idx - clippedSoFar, sDefaultLayoutParam, true);
467+
int adjustedIdx = idx - clippedSoFar;
468+
Assertions.assertCondition(adjustedIdx >= 0);
469+
addViewInLayout(child, adjustedIdx, sDefaultLayoutParam, true);
454470
invalidate();
455471
needUpdateClippingRecursive = true;
456472
} else if (intersects) {
@@ -694,7 +710,13 @@ public void run() {
694710
* @return {@code true} if the view has been removed from the ViewGroup.
695711
*/
696712
private boolean isViewClipped(View view) {
697-
return view.getParent() == null;
713+
ViewParent parent = view.getParent();
714+
if (parent == null) {
715+
return true;
716+
} else {
717+
Assertions.assertCondition(parent == this);
718+
return false;
719+
}
698720
}
699721

700722
private int indexOfChildInAllChildren(View child) {

0 commit comments

Comments
 (0)