Skip to content

Commit ea2fbd4

Browse files
javachefacebook-github-bot
authored andcommitted
fix nullsafe FIXMEs for FabicUIManager.java and mark nullsafe (#50365)
Summary: Pull Request resolved: #50365 Gone trough all the FIXMEs added in the previous diff by the nullsafe tool, marked the class as nullsafe and ensured no remaining violations. Changelog: [Android][Fixed] Made FabricUIManager.java nullsafe Reviewed By: GijsWeterings Differential Revision: D71979601 fbshipit-source-id: 599d87f0783a566c837aa70975a62f5f908a2294
1 parent dc5b840 commit ea2fbd4

File tree

5 files changed

+61
-64
lines changed

5 files changed

+61
-64
lines changed

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/UIManager.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public interface UIManager : PerformanceCounter {
2020
@UiThread
2121
@ThreadConfined(ThreadConfined.UI)
2222
@Deprecated("")
23-
public fun <T : View?> addRootView(rootView: T, initialProps: WritableMap?): Int
23+
public fun <T : View> addRootView(rootView: T, initialProps: WritableMap?): Int
2424

2525
/** Registers a new root view with width and height. */
2626
@AnyThread
@@ -92,7 +92,7 @@ public interface UIManager : PerformanceCounter {
9292
*/
9393
@UiThread
9494
@ThreadConfined(ThreadConfined.UI)
95-
public fun synchronouslyUpdateViewOnUIThread(reactTag: Int, props: ReadableMap?)
95+
public fun synchronouslyUpdateViewOnUIThread(reactTag: Int, props: ReadableMap)
9696

9797
/**
9898
* Dispatch an accessibility event to a view asynchronously.
@@ -109,14 +109,14 @@ public interface UIManager : PerformanceCounter {
109109
*
110110
* @param listener
111111
*/
112-
public fun addUIManagerEventListener(listener: UIManagerListener?)
112+
public fun addUIManagerEventListener(listener: UIManagerListener)
113113

114114
/**
115115
* Unregister a [UIManagerListener] from this UIManager to stop receiving lifecycle callbacks.
116116
*
117117
* @param listener
118118
*/
119-
public fun removeUIManagerEventListener(listener: UIManagerListener?)
119+
public fun removeUIManagerEventListener(listener: UIManagerListener)
120120

121121
/**
122122
* Resolves a view based on its reactTag. Do not mutate properties on this view that are already

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java

Lines changed: 45 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,11 @@
2525
import android.view.View;
2626
import android.view.accessibility.AccessibilityEvent;
2727
import androidx.annotation.AnyThread;
28-
import androidx.annotation.NonNull;
2928
import androidx.annotation.Nullable;
3029
import androidx.annotation.UiThread;
3130
import com.facebook.common.logging.FLog;
31+
import com.facebook.infer.annotation.Assertions;
32+
import com.facebook.infer.annotation.Nullsafe;
3233
import com.facebook.infer.annotation.ThreadConfined;
3334
import com.facebook.proguard.annotations.DoNotStripAny;
3435
import com.facebook.react.bridge.ColorPropConverter;
@@ -98,6 +99,7 @@
9899
* We instruct ProGuard not to strip out any fields or methods, because many of these methods are
99100
* only called through the JNI from Cxx so it appears that most of this class is "unused".
100101
*/
102+
@Nullsafe(Nullsafe.Mode.LOCAL)
101103
@SuppressLint("MissingNativeLoadLibrary")
102104
@DoNotStripAny
103105
public class FabricUIManager
@@ -107,8 +109,7 @@ public class FabricUIManager
107109
// The IS_DEVELOPMENT_ENVIRONMENT variable is used to log extra data when running fabric in a
108110
// development environment. DO NOT ENABLE THIS ON PRODUCTION OR YOU WILL BE FIRED!
109111
public static final boolean IS_DEVELOPMENT_ENVIRONMENT = false && ReactBuildConfig.DEBUG;
110-
// NULLSAFE_FIXME[Field Not Initialized]
111-
public DevToolsReactPerfLogger mDevToolsReactPerfLogger;
112+
public @Nullable DevToolsReactPerfLogger mDevToolsReactPerfLogger;
112113

113114
private static final DevToolsReactPerfLogger.DevToolsReactPerfLoggerListener FABRIC_PERF_LOGGER =
114115
commitPoint -> {
@@ -161,27 +162,24 @@ public class FabricUIManager
161162
}
162163

163164
@Nullable private FabricUIManagerBinding mBinding;
164-
@NonNull private final ReactApplicationContext mReactApplicationContext;
165-
@NonNull private final MountingManager mMountingManager;
166-
@NonNull private final FabricEventDispatcher mEventDispatcher;
167-
@NonNull private final MountItemDispatcher mMountItemDispatcher;
168-
@NonNull private final ViewManagerRegistry mViewManagerRegistry;
165+
private final ReactApplicationContext mReactApplicationContext;
166+
private final MountingManager mMountingManager;
167+
private final FabricEventDispatcher mEventDispatcher;
168+
private final MountItemDispatcher mMountItemDispatcher;
169+
private final ViewManagerRegistry mViewManagerRegistry;
169170

170-
@NonNull private final BatchEventDispatchedListener mBatchEventDispatchedListener;
171+
private final BatchEventDispatchedListener mBatchEventDispatchedListener;
171172

172-
@NonNull
173173
private final CopyOnWriteArrayList<UIManagerListener> mListeners = new CopyOnWriteArrayList<>();
174174

175175
private boolean mMountNotificationScheduled = false;
176176
private List<Integer> mSurfaceIdsWithPendingMountNotification = new ArrayList<>();
177177

178178
@ThreadConfined(UI)
179-
@NonNull
180179
private final DispatchUIFrameCallback mDispatchUIFrameCallback;
181180

182181
/** Set of events sent synchronously during the current frame render. Cleared after each frame. */
183182
@ThreadConfined(UI)
184-
@NonNull
185183
private final Set<SynchronousEvent> mSynchronousEvents = new HashSet<>();
186184

187185
/**
@@ -219,9 +217,9 @@ public void executeItems(Queue<MountItem> items) {
219217
@Nullable private InteropUIBlockListener mInteropUIBlockListener;
220218

221219
public FabricUIManager(
222-
@NonNull ReactApplicationContext reactContext,
223-
@NonNull ViewManagerRegistry viewManagerRegistry,
224-
@NonNull BatchEventDispatchedListener batchEventDispatchedListener) {
220+
ReactApplicationContext reactContext,
221+
ViewManagerRegistry viewManagerRegistry,
222+
BatchEventDispatchedListener batchEventDispatchedListener) {
225223
mDispatchUIFrameCallback = new DispatchUIFrameCallback(reactContext);
226224
mReactApplicationContext = reactContext;
227225
mMountingManager = new MountingManager(viewManagerRegistry, mMountItemExecutor);
@@ -239,8 +237,8 @@ public FabricUIManager(
239237
@UiThread
240238
@ThreadConfined(UI)
241239
@Deprecated
242-
// NULLSAFE_FIXME[Inconsistent Subclass Parameter Annotation]
243-
public <T extends View> int addRootView(final T rootView, final WritableMap initialProps) {
240+
public <T extends View> int addRootView(
241+
final T rootView, final @Nullable WritableMap initialProps) {
244242
ReactSoftExceptionLogger.logSoftException(
245243
TAG,
246244
new IllegalViewOperationException(
@@ -257,19 +255,18 @@ public <T extends View> int addRootView(final T rootView, final WritableMap init
257255
if (ReactNativeFeatureFlags.enableFabricLogs()) {
258256
FLog.d(TAG, "Starting surface for module: %s and reactTag: %d", moduleName, rootTag);
259257
}
260-
// NULLSAFE_FIXME[Nullable Dereference]
258+
Assertions.assertNotNull(mBinding, "Binding in FabricUIManager is null");
261259
mBinding.startSurface(rootTag, moduleName, (NativeMap) initialProps);
262260
return rootTag;
263261
}
264262

265263
@Override
266264
@AnyThread
267265
@ThreadConfined(ANY)
268-
// NULLSAFE_FIXME[Inconsistent Subclass Parameter Annotation]
269266
public <T extends View> int startSurface(
270267
final T rootView,
271268
final String moduleName,
272-
final WritableMap initialProps,
269+
final @Nullable WritableMap initialProps,
273270
int widthMeasureSpec,
274271
int heightMeasureSpec) {
275272
final int rootTag = ((ReactRoot) rootView).getRootViewTag();
@@ -288,7 +285,7 @@ public <T extends View> int startSurface(
288285
Point viewportOffset =
289286
UiThreadUtil.isOnUiThread() ? RootViewUtil.getViewportOffset(rootView) : new Point(0, 0);
290287

291-
// NULLSAFE_FIXME[Nullable Dereference]
288+
Assertions.assertNotNull(mBinding, "Binding in FabricUIManager is null");
292289
mBinding.startSurfaceWithConstraints(
293290
rootTag,
294291
moduleName,
@@ -314,7 +311,7 @@ public void startSurface(
314311
new ThemedReactContext(
315312
mReactApplicationContext, context, surfaceHandler.getModuleName(), rootTag);
316313
mMountingManager.startSurface(rootTag, reactContext, rootView);
317-
// NULLSAFE_FIXME[Nullable Dereference]
314+
Assertions.assertNotNull(mBinding, "Binding in FabricUIManager is null");
318315
mBinding.startSurfaceWithSurfaceHandler(rootTag, surfaceHandler, rootView != null);
319316
}
320317

@@ -339,7 +336,7 @@ public void stopSurface(final SurfaceHandlerBinding surfaceHandler) {
339336
}
340337

341338
mMountingManager.stopSurface(surfaceHandler.getSurfaceId());
342-
// NULLSAFE_FIXME[Nullable Dereference]
339+
Assertions.assertNotNull(mBinding, "Binding in FabricUIManager is null");
343340
mBinding.stopSurfaceWithSurfaceHandler(surfaceHandler);
344341
}
345342

@@ -359,7 +356,7 @@ public void stopSurface(final int surfaceID) {
359356
// Communicate stopSurface to Cxx - causes an empty ShadowTree to be committed,
360357
// but all mounting instructions will be ignored because stopSurface was called
361358
// on the MountingManager
362-
// NULLSAFE_FIXME[Nullable Dereference]
359+
Assertions.assertNotNull(mBinding, "Binding in FabricUIManager is null");
363360
mBinding.stopSurface(surfaceID);
364361
}
365362

@@ -410,8 +407,9 @@ public void invalidate() {
410407
mReactApplicationContext.removeLifecycleEventListener(this);
411408
onHostPause();
412409

413-
// NULLSAFE_FIXME[Nullable Dereference]
414-
mBinding.unregister();
410+
if (mBinding != null) {
411+
mBinding.unregister();
412+
}
415413
mBinding = null;
416414

417415
ViewManagerPropertyUpdater.clear();
@@ -455,7 +453,6 @@ public void prependUIBlock(UIBlock block) {
455453
}
456454
}
457455

458-
@NonNull
459456
private InteropUIBlockListener getInteropUIBlockListener() {
460457
if (mInteropUIBlockListener == null) {
461458
mInteropUIBlockListener = new InteropUIBlockListener();
@@ -542,12 +539,13 @@ private long measure(
542539
return 0;
543540
}
544541
context = surfaceMountingManager.getContext();
542+
Assertions.assertNotNull(
543+
context, "Context in SurfaceMountingManager is null. surfaceId: " + surfaceId);
545544
} else {
546545
context = mReactApplicationContext;
547546
}
548547

549548
return mMountingManager.measure(
550-
// NULLSAFE_FIXME[Parameter Not Nullable]
551549
context,
552550
componentName,
553551
localData,
@@ -581,13 +579,14 @@ private long measureMapBuffer(
581579
return 0;
582580
}
583581
context = surfaceMountingManager.getContext();
582+
Assertions.assertNotNull(
583+
context, "Context in SurfaceMountingManager is null. surfaceId: " + surfaceId);
584584
} else {
585585
context = mReactApplicationContext;
586586
}
587587

588588
// TODO: replace ReadableNativeMap -> ReadableMapBuffer
589589
return mMountingManager.measureMapBuffer(
590-
// NULLSAFE_FIXME[Parameter Not Nullable]
591590
context,
592591
componentName,
593592
localData,
@@ -624,13 +623,11 @@ public boolean getThemeData(int surfaceId, float[] defaultTextInputPadding) {
624623
}
625624

626625
@Override
627-
// NULLSAFE_FIXME[Inconsistent Subclass Parameter Annotation]
628626
public void addUIManagerEventListener(UIManagerListener listener) {
629627
mListeners.add(listener);
630628
}
631629

632630
@Override
633-
// NULLSAFE_FIXME[Inconsistent Subclass Parameter Annotation]
634631
public void removeUIManagerEventListener(UIManagerListener listener) {
635632
mListeners.remove(listener);
636633
}
@@ -645,9 +642,7 @@ public void synchronouslyUpdateViewOnUIThread(
645642
@Override
646643
@UiThread
647644
@ThreadConfined(UI)
648-
// NULLSAFE_FIXME[Inconsistent Subclass Parameter Annotation]
649-
public void synchronouslyUpdateViewOnUIThread(
650-
final int reactTag, @NonNull final ReadableMap props) {
645+
public void synchronouslyUpdateViewOnUIThread(final int reactTag, final ReadableMap props) {
651646
UiThreadUtil.assertOnUiThread();
652647

653648
int commitNumber = mCurrentSynchronousCommitNumber++;
@@ -678,7 +673,7 @@ public void synchronouslyUpdateViewOnUIThread(
678673
MountItem synchronousMountItem =
679674
new MountItem() {
680675
@Override
681-
public void execute(@NonNull MountingManager mountingManager) {
676+
public void execute(MountingManager mountingManager) {
682677
try {
683678
mountingManager.updateProps(reactTag, props);
684679
} catch (Exception ex) {
@@ -696,7 +691,6 @@ public int getSurfaceId() {
696691
return View.NO_ID;
697692
}
698693

699-
@NonNull
700694
@Override
701695
public String toString() {
702696
String propsString =
@@ -801,11 +795,14 @@ private void scheduleMountItem(
801795
// calls scheduleMountItems with a BatchMountItem.
802796
long scheduleMountItemStartTime = SystemClock.uptimeMillis();
803797
boolean isBatchMountItem = mountItem instanceof BatchMountItem;
804-
boolean shouldSchedule =
805-
// NULLSAFE_FIXME[Nullable Dereference]
806-
(isBatchMountItem && !((BatchMountItem) mountItem).isBatchEmpty())
807-
|| (!isBatchMountItem && mountItem != null);
808-
798+
boolean shouldSchedule = false;
799+
if (isBatchMountItem) {
800+
BatchMountItem batchMountItem = (BatchMountItem) mountItem;
801+
Assertions.assertNotNull(batchMountItem, "BatchMountItem is null");
802+
shouldSchedule = !batchMountItem.isBatchEmpty();
803+
} else {
804+
shouldSchedule = mountItem != null;
805+
}
809806
// In case of sync rendering, this could be called on the UI thread. Otherwise,
810807
// it should ~always be called on the JS thread.
811808
for (UIManagerListener listener : mListeners) {
@@ -821,7 +818,7 @@ private void scheduleMountItem(
821818
}
822819

823820
if (shouldSchedule) {
824-
// NULLSAFE_FIXME[Parameter Not Nullable]
821+
Assertions.assertNotNull(mountItem, "MountItem is null");
825822
mMountItemDispatcher.addMountItem(mountItem);
826823
Runnable runnable =
827824
new GuardedRunnable(mReactApplicationContext) {
@@ -918,7 +915,7 @@ public void updateRootLayoutSpecs(
918915
doLeftAndRightSwapInRTL = I18nUtil.getInstance().doLeftAndRightSwapInRTL(context);
919916
}
920917

921-
// NULLSAFE_FIXME[Nullable Dereference]
918+
Assertions.assertNotNull(mBinding, "Binding in FabricUIManager is null");
922919
mBinding.setConstraints(
923920
surfaceId,
924921
getMinSize(widthMeasureSpec),
@@ -932,11 +929,10 @@ public void updateRootLayoutSpecs(
932929
}
933930

934931
@Override
935-
public View resolveView(int reactTag) {
932+
public @Nullable View resolveView(int reactTag) {
936933
UiThreadUtil.assertOnUiThread();
937934

938935
SurfaceMountingManager surfaceManager = mMountingManager.getSurfaceManagerForView(reactTag);
939-
// NULLSAFE_FIXME[Return Not Nullable]
940936
return surfaceManager == null ? null : surfaceManager.getView(reactTag);
941937
}
942938

@@ -979,7 +975,7 @@ public void receiveEvent(
979975
public void receiveEvent(
980976
int surfaceId,
981977
int reactTag,
982-
@NonNull String eventName,
978+
String eventName,
983979
boolean canCoalesceEvent,
984980
@Nullable WritableMap params,
985981
@EventCategoryDef int eventCategory,
@@ -1032,7 +1028,6 @@ public void onHostResume() {
10321028
}
10331029

10341030
@Override
1035-
@NonNull
10361031
public EventDispatcher getEventDispatcher() {
10371032
return mEventDispatcher;
10381033
}
@@ -1145,7 +1140,7 @@ public void setJSResponder(
11451140
mMountItemDispatcher.addMountItem(
11461141
new MountItem() {
11471142
@Override
1148-
public void execute(@NonNull MountingManager mountingManager) {
1143+
public void execute(MountingManager mountingManager) {
11491144
SurfaceMountingManager surfaceMountingManager =
11501145
mountingManager.getSurfaceManager(surfaceId);
11511146
if (surfaceMountingManager != null) {
@@ -1162,7 +1157,6 @@ public int getSurfaceId() {
11621157
return surfaceId;
11631158
}
11641159

1165-
@NonNull
11661160
@SuppressLint("DefaultLocale")
11671161
@Override
11681162
public String toString() {
@@ -1179,7 +1173,7 @@ public void clearJSResponder() {
11791173
mMountItemDispatcher.addMountItem(
11801174
new MountItem() {
11811175
@Override
1182-
public void execute(@NonNull MountingManager mountingManager) {
1176+
public void execute(MountingManager mountingManager) {
11831177
mountingManager.clearJSResponder();
11841178
}
11851179

@@ -1188,7 +1182,6 @@ public int getSurfaceId() {
11881182
return View.NO_ID;
11891183
}
11901184

1191-
@NonNull
11921185
@Override
11931186
public String toString() {
11941187
return "CLEAR_JS_RESPONDER";
@@ -1337,7 +1330,7 @@ private class DispatchUIFrameCallback extends GuardedFrameCallback {
13371330
@ThreadConfined(UI)
13381331
private boolean mIsScheduled = false;
13391332

1340-
private DispatchUIFrameCallback(@NonNull ReactContext reactContext) {
1333+
private DispatchUIFrameCallback(ReactContext reactContext) {
13411334
super(reactContext);
13421335
}
13431336

0 commit comments

Comments
 (0)