Nullsafe views/scroll module (#44532)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/44532

Changelog: [Internal]

Fix nullsafe errors in the module and add the annotation

Reviewed By: rshest

Differential Revision: D57218666

fbshipit-source-id: 9fc8c6d002bb2c4b53c0874a6d8c38fcf52b9e19
This commit is contained in:
Thomas Nardone
2024-05-14 09:21:15 -07:00
committed by Facebook GitHub Bot
parent 6876775dc7
commit 13dff7cdf2
5 changed files with 31 additions and 28 deletions
@@ -32,6 +32,7 @@ import androidx.annotation.Nullable;
import androidx.core.view.ViewCompat;
import com.facebook.common.logging.FLog;
import com.facebook.infer.annotation.Assertions;
import com.facebook.infer.annotation.Nullsafe;
import com.facebook.react.common.ReactConstants;
import com.facebook.react.common.build.ReactBuildConfig;
import com.facebook.react.modules.i18nmanager.I18nUtil;
@@ -55,6 +56,7 @@ import java.util.ArrayList;
import java.util.List;
/** Similar to {@link ReactScrollView} but only supports horizontal scrolling. */
@Nullsafe(Nullsafe.Mode.LOCAL)
public class ReactHorizontalScrollView extends HorizontalScrollView
implements ReactClippingViewGroup,
ViewGroup.OnHierarchyChangeListener,
@@ -109,7 +111,7 @@ public class ReactHorizontalScrollView extends HorizontalScrollView
private boolean mPagedArrowScrolling = false;
private int pendingContentOffsetX = UNSET_CONTENT_OFFSET;
private int pendingContentOffsetY = UNSET_CONTENT_OFFSET;
private StateWrapper mStateWrapper = null;
private @Nullable StateWrapper mStateWrapper = null;
private final ReactScrollViewScrollState mReactScrollViewScrollState;
private final ValueAnimator DEFAULT_FLING_ANIMATOR = ObjectAnimator.ofInt(this, "scrollX", 0, 0);
private PointerEvents mPointerEvents = PointerEvents.AUTO;
@@ -248,7 +250,7 @@ public class ReactHorizontalScrollView extends HorizontalScrollView
mSnapInterval = snapInterval;
}
public void setSnapOffsets(List<Integer> snapOffsets) {
public void setSnapOffsets(@Nullable List<Integer> snapOffsets) {
mSnapOffsets = snapOffsets;
}
@@ -268,7 +270,7 @@ public class ReactHorizontalScrollView extends HorizontalScrollView
awakenScrollBars();
}
public void setOverflow(String overflow) {
public void setOverflow(@Nullable String overflow) {
mOverflow = overflow;
invalidate();
}
@@ -307,17 +309,10 @@ public class ReactHorizontalScrollView extends HorizontalScrollView
if (DEBUG_MODE) {
FLog.i(TAG, "onDraw[%d]", getId());
}
getDrawingRect(mRect);
switch (mOverflow) {
case ViewProps.VISIBLE:
break;
default:
canvas.clipRect(mRect);
break;
if (!ViewProps.VISIBLE.equals(mOverflow)) {
canvas.clipRect(mRect);
}
super.onDraw(canvas);
}
@@ -839,8 +834,10 @@ public class ReactHorizontalScrollView extends HorizontalScrollView
}
@Override
public void onChildViewRemoved(View parent, View child) {
mContentView.removeOnLayoutChangeListener(this);
public @Nullable void onChildViewRemoved(View parent, View child) {
if (mContentView != null) {
mContentView.removeOnLayoutChangeListener(this);
}
mContentView = null;
}
@@ -11,6 +11,7 @@ import android.graphics.Color;
import android.view.View;
import androidx.annotation.Nullable;
import androidx.core.view.ViewCompat;
import com.facebook.infer.annotation.Nullsafe;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.RetryableMountingLayerException;
@@ -36,6 +37,7 @@ import java.util.List;
* <p>Note that {@link ReactScrollView} and {@link ReactHorizontalScrollView} are exposed to JS as a
* single ScrollView component, configured via the {@code horizontal} boolean property.
*/
@Nullsafe(Nullsafe.Mode.LOCAL)
@ReactModule(name = ReactHorizontalScrollViewManager.REACT_CLASS)
public class ReactHorizontalScrollViewManager extends ViewGroupManager<ReactHorizontalScrollView>
implements ReactScrollViewCommandHelper.ScrollCommandHandler<ReactHorizontalScrollView> {
@@ -67,7 +69,7 @@ public class ReactHorizontalScrollViewManager extends ViewGroupManager<ReactHori
}
@Override
public Object updateState(
public @Nullable Object updateState(
ReactHorizontalScrollView view, ReactStylesDiffMap props, StateWrapper stateWrapper) {
view.setStateWrapper(stateWrapper);
return null;
@@ -33,6 +33,7 @@ import androidx.annotation.Nullable;
import androidx.core.view.ViewCompat;
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.ReadableMap;
import com.facebook.react.common.ReactConstants;
@@ -62,6 +63,7 @@ import java.util.List;
* <p>ReactScrollView only supports vertical scrolling. For horizontal scrolling, use {@link
* ReactHorizontalScrollView}.
*/
@Nullsafe(Nullsafe.Mode.LOCAL)
public class ReactScrollView extends ScrollView
implements ReactClippingViewGroup,
ViewGroup.OnHierarchyChangeListener,
@@ -111,7 +113,7 @@ public class ReactScrollView extends ScrollView
private @Nullable ReadableMap mCurrentContentOffset = null;
private int pendingContentOffsetX = UNSET_CONTENT_OFFSET;
private int pendingContentOffsetY = UNSET_CONTENT_OFFSET;
private StateWrapper mStateWrapper = null;
private @Nullable StateWrapper mStateWrapper = null;
private final ReactScrollViewScrollState mReactScrollViewScrollState =
new ReactScrollViewScrollState(ViewCompat.LAYOUT_DIRECTION_LTR);
private final ValueAnimator DEFAULT_FLING_ANIMATOR = ObjectAnimator.ofInt(this, "scrollY", 0, 0);
@@ -237,7 +239,7 @@ public class ReactScrollView extends ScrollView
mSnapInterval = snapInterval;
}
public void setSnapOffsets(List<Integer> snapOffsets) {
public void setSnapOffsets(@Nullable List<Integer> snapOffsets) {
mSnapOffsets = snapOffsets;
}
@@ -257,7 +259,7 @@ public class ReactScrollView extends ScrollView
awakenScrollBars();
}
public void setOverflow(String overflow) {
public void setOverflow(@Nullable String overflow) {
mOverflow = overflow;
invalidate();
}
@@ -615,7 +617,7 @@ public class ReactScrollView extends ScrollView
}
private int getMaxScrollY() {
int contentHeight = mContentView.getHeight();
int contentHeight = mContentView == null ? 0 : mContentView.getHeight();
int viewportHeight = getHeight() - getPaddingBottom() - getPaddingTop();
return Math.max(0, contentHeight - viewportHeight);
}
@@ -9,6 +9,7 @@ package com.facebook.react.views.scroll;
import androidx.annotation.Nullable;
import com.facebook.infer.annotation.Assertions;
import com.facebook.infer.annotation.Nullsafe;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.common.MapBuilder;
import com.facebook.react.uimanager.PixelUtil;
@@ -18,6 +19,7 @@ import java.util.Map;
* Helper for view managers to handle commands like 'scrollTo'. Shared by {@link
* ReactScrollViewManager} and {@link ReactHorizontalScrollViewManager}.
*/
@Nullsafe(Nullsafe.Mode.LOCAL)
public class ReactScrollViewCommandHelper {
public static final int COMMAND_SCROLL_TO = 1;
@@ -70,16 +72,15 @@ public class ReactScrollViewCommandHelper {
@Nullable ReadableArray args) {
Assertions.assertNotNull(viewManager);
Assertions.assertNotNull(scrollView);
Assertions.assertNotNull(args);
switch (commandType) {
case COMMAND_SCROLL_TO:
{
scrollTo(viewManager, scrollView, args);
scrollTo(viewManager, scrollView, Assertions.assertNotNull(args));
return;
}
case COMMAND_SCROLL_TO_END:
{
scrollToEnd(viewManager, scrollView, args);
scrollToEnd(viewManager, scrollView, Assertions.assertNotNull(args));
return;
}
case COMMAND_FLASH_SCROLL_INDICATORS:
@@ -101,16 +102,15 @@ public class ReactScrollViewCommandHelper {
@Nullable ReadableArray args) {
Assertions.assertNotNull(viewManager);
Assertions.assertNotNull(scrollView);
Assertions.assertNotNull(args);
switch (commandType) {
case "scrollTo":
{
scrollTo(viewManager, scrollView, args);
scrollTo(viewManager, scrollView, Assertions.assertNotNull(args));
return;
}
case "scrollToEnd":
{
scrollToEnd(viewManager, scrollView, args);
scrollToEnd(viewManager, scrollView, Assertions.assertNotNull(args));
return;
}
case "flashScrollIndicators":
@@ -126,7 +126,7 @@ public class ReactScrollViewCommandHelper {
}
private static <T> void scrollTo(
ScrollCommandHandler<T> viewManager, T scrollView, @Nullable ReadableArray args) {
ScrollCommandHandler<T> viewManager, T scrollView, ReadableArray args) {
int destX = Math.round(PixelUtil.toPixelFromDIP(args.getDouble(0)));
int destY = Math.round(PixelUtil.toPixelFromDIP(args.getDouble(1)));
boolean animated = args.getBoolean(2);
@@ -134,7 +134,7 @@ public class ReactScrollViewCommandHelper {
}
private static <T> void scrollToEnd(
ScrollCommandHandler<T> viewManager, T scrollView, @Nullable ReadableArray args) {
ScrollCommandHandler<T> viewManager, T scrollView, ReadableArray args) {
boolean animated = args.getBoolean(0);
viewManager.scrollToEnd(scrollView, new ScrollToEndCommandData(animated));
}
@@ -11,6 +11,7 @@ import android.graphics.Color;
import android.view.View;
import androidx.annotation.Nullable;
import androidx.core.view.ViewCompat;
import com.facebook.infer.annotation.Nullsafe;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.RetryableMountingLayerException;
@@ -39,6 +40,7 @@ import java.util.Map;
* <p>Note that {@link ReactScrollView} and {@link ReactHorizontalScrollView} are exposed to JS as a
* single ScrollView component, configured via the {@code horizontal} boolean property.
*/
@Nullsafe(Nullsafe.Mode.LOCAL)
@ReactModule(name = ReactScrollViewManager.REACT_CLASS)
public class ReactScrollViewManager extends ViewGroupManager<ReactScrollView>
implements ReactScrollViewCommandHelper.ScrollCommandHandler<ReactScrollView> {
@@ -341,7 +343,7 @@ public class ReactScrollViewManager extends ViewGroupManager<ReactScrollView>
}
@Override
public Object updateState(
public @Nullable Object updateState(
ReactScrollView view, ReactStylesDiffMap props, StateWrapper stateWrapper) {
view.setStateWrapper(stateWrapper);
return null;