diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewGroupDrawingOrderHelper.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewGroupDrawingOrderHelper.java index 99356c260c311f..f80e455505676d 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewGroupDrawingOrderHelper.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewGroupDrawingOrderHelper.java @@ -47,7 +47,7 @@ public void handleAddView(View view) { * * @param view The view that is being removed. */ - public void handleRemoveView(View view) { + public void handleRemoveView(@Nullable View view) { if (ViewGroupManager.getViewZIndex(view) != null) { mNumberOfChildrenWithZIndex--; } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewGroupManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewGroupManager.java index c38b4285a509aa..49457129f44838 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewGroupManager.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewGroupManager.java @@ -68,7 +68,7 @@ public static void setViewZIndex(View view, int zIndex) { mZIndexHash.put(view, zIndex); } - public static @Nullable Integer getViewZIndex(View view) { + public static @Nullable Integer getViewZIndex(@Nullable View view) { return mZIndexHash.get(view); } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostView.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostView.kt index 0384a28d4cafa7..316efcd44b177f 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostView.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostView.kt @@ -375,7 +375,7 @@ public class ReactModalHostView(context: ThemedReactContext) : * styleHeight on the LayoutShadowNode to be the window size. This is done through the * UIManagerModule, and will then cause the children to layout as if they can fill the window. */ - public class DialogRootViewGroup internal constructor(context: Context?) : + public class DialogRootViewGroup internal constructor(context: Context) : ReactViewGroup(context), RootView { internal var stateWrapper: StateWrapper? = null internal var eventDispatcher: EventDispatcher? = null diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactDrawableHelper.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactDrawableHelper.java index e67e2f74d21f77..af3b25867aa1b8 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactDrawableHelper.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactDrawableHelper.java @@ -15,9 +15,9 @@ import android.graphics.drawable.RippleDrawable; import android.util.TypedValue; import androidx.annotation.Nullable; +import com.facebook.infer.annotation.Nullsafe; import com.facebook.react.bridge.JSApplicationIllegalArgumentException; import com.facebook.react.bridge.ReadableMap; -import com.facebook.react.bridge.SoftAssertions; import com.facebook.react.uimanager.PixelUtil; import com.facebook.react.uimanager.ViewProps; @@ -25,15 +25,19 @@ * Utility class that helps with converting android drawable description used in JS to an actual * instance of {@link Drawable}. */ +@Nullsafe(Nullsafe.Mode.LOCAL) public class ReactDrawableHelper { private static final TypedValue sResolveOutValue = new TypedValue(); - public static Drawable createDrawableFromJSDescription( + public static @Nullable Drawable createDrawableFromJSDescription( Context context, ReadableMap drawableDescriptionDict) { String type = drawableDescriptionDict.getString("type"); if ("ThemeAttrAndroid".equals(type)) { String attr = drawableDescriptionDict.getString("attribute"); + if (attr == null) { + throw new JSApplicationIllegalArgumentException("JS description missing 'attribute' field"); + } int attrId = getAttrId(context, attr); if (!context.getTheme().resolveAttribute(attrId, sResolveOutValue, true)) { throw new JSApplicationIllegalArgumentException( @@ -50,7 +54,6 @@ public static Drawable createDrawableFromJSDescription( } private static int getAttrId(Context context, String attr) { - SoftAssertions.assertNotNull(attr); if ("selectableItemBackground".equals(attr)) { return android.R.attr.selectableItemBackground; } else if ("selectableItemBackgroundBorderless".equals(attr)) { @@ -60,7 +63,7 @@ private static int getAttrId(Context context, String attr) { } } - private static Drawable getDefaultThemeDrawable(Context context) { + private static @Nullable Drawable getDefaultThemeDrawable(Context context) { return context.getResources().getDrawable(sResolveOutValue.resourceId, context.getTheme()); } @@ -74,7 +77,8 @@ private static RippleDrawable getRippleDrawable( return new RippleDrawable(colorStateList, null, mask); } - private static Drawable setRadius(ReadableMap drawableDescriptionDict, Drawable drawable) { + private static @Nullable Drawable setRadius( + ReadableMap drawableDescriptionDict, @Nullable Drawable drawable) { if (drawableDescriptionDict.hasKey("rippleRadius") && drawable instanceof RippleDrawable) { RippleDrawable rippleDrawable = (RippleDrawable) drawable; double rippleRadius = drawableDescriptionDict.getDouble("rippleRadius"); diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java index c3dc2964c9fae3..7f7a799c02e9b1 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java @@ -7,6 +7,7 @@ package com.facebook.react.views.view; +import static com.facebook.infer.annotation.Assertions.nullsafeFIXME; import static com.facebook.react.common.ReactConstants.TAG; import android.annotation.SuppressLint; @@ -28,6 +29,7 @@ import androidx.annotation.Nullable; import com.facebook.common.logging.FLog; import com.facebook.infer.annotation.Assertions; +import com.facebook.infer.annotation.Nullsafe; import com.facebook.react.R; import com.facebook.react.bridge.ReactNoCrashSoftException; import com.facebook.react.bridge.ReactSoftExceptionLogger; @@ -63,6 +65,7 @@ * Backing for a React View. Has support for borders, but since borders aren't common, lazy * initializes most of the storage needed for them. */ +@Nullsafe(Nullsafe.Mode.LOCAL) public class ReactViewGroup extends ViewGroup implements ReactInterceptingViewGroup, ReactClippingViewGroup, @@ -381,7 +384,7 @@ public boolean getRemoveClippedSubviews() { @Override public void getClippingRect(Rect outClippingRect) { - outClippingRect.set(mClippingRect); + outClippingRect.set(nullsafeFIXME(mClippingRect, "Fix in Kotlin")); } @Override @@ -522,7 +525,7 @@ private void handleAddView(View view) { } } - private void handleRemoveView(View view) { + private void handleRemoveView(@Nullable View view) { UiThreadUtil.assertOnUiThread(); if (!customDrawOrderDisabled()) { @@ -546,7 +549,7 @@ private void handleRemoveViews(int start, int count) { } @Override - public void addView(View child, int index, ViewGroup.LayoutParams params) { + public void addView(View child, int index, @Nullable ViewGroup.LayoutParams params) { // This will get called for every overload of addView so there is not need to override every // method. handleAddView(child); @@ -561,7 +564,7 @@ protected boolean addViewInLayout( } @Override - public void removeView(View view) { + public void removeView(@Nullable View view) { handleRemoveView(view); super.removeView(view); }