14
14
import android .view .ViewGroup ;
15
15
import android .view .ViewParent ;
16
16
import androidx .annotation .AnyThread ;
17
- import androidx .annotation .NonNull ;
18
17
import androidx .annotation .Nullable ;
19
18
import androidx .annotation .UiThread ;
20
19
import androidx .collection .SparseArrayCompat ;
21
20
import com .facebook .common .logging .FLog ;
22
21
import com .facebook .infer .annotation .Assertions ;
22
+ import com .facebook .infer .annotation .Nullsafe ;
23
23
import com .facebook .infer .annotation .ThreadConfined ;
24
24
import com .facebook .react .bridge .ReactNoCrashSoftException ;
25
25
import com .facebook .react .bridge .ReactSoftExceptionLogger ;
56
56
import java .util .Set ;
57
57
import java .util .concurrent .ConcurrentHashMap ;
58
58
59
+ @ Nullsafe (Nullsafe .Mode .LOCAL )
59
60
public class SurfaceMountingManager {
60
61
public static final String TAG = SurfaceMountingManager .class .getSimpleName ();
61
62
@@ -66,14 +67,15 @@ public class SurfaceMountingManager {
66
67
67
68
@ Nullable private ThemedReactContext mThemedReactContext ;
68
69
69
- // These are all non-null, until StopSurface is called
70
- private ConcurrentHashMap <Integer , ViewState > mTagToViewState =
70
+ private final ConcurrentHashMap <Integer , ViewState > mTagToViewState =
71
71
new ConcurrentHashMap <>(); // any thread
72
- private Queue <MountItem > mOnViewAttachMountItems = new ArrayDeque <>();
72
+ private final Queue <MountItem > mOnViewAttachMountItems = new ArrayDeque <>();
73
73
private JSResponderHandler mJSResponderHandler ;
74
74
private ViewManagerRegistry mViewManagerRegistry ;
75
- private RootViewManager mRootViewManager ;
76
- private MountItemExecutor mMountItemExecutor ;
75
+
76
+ // These are non-null, until StopSurface is called
77
+ private @ Nullable RootViewManager mRootViewManager ;
78
+ private @ Nullable MountItemExecutor mMountItemExecutor ;
77
79
78
80
@ ThreadConfined (UI )
79
81
private final Set <Integer > mErroneouslyReaddedReactTags = new HashSet <>();
@@ -90,18 +92,17 @@ public class SurfaceMountingManager {
90
92
private final Set <Integer > mViewsToDeleteAfterTouchFinishes = new HashSet <>();
91
93
92
94
// This is null *until* StopSurface is called.
93
- // NULLSAFE_FIXME[Field Not Initialized]
94
- private SparseArrayCompat <Object > mTagSetForStoppedSurface ;
95
+ private @ Nullable SparseArrayCompat <Object > mTagSetForStoppedSurface ;
95
96
96
97
private final int mSurfaceId ;
97
98
98
99
public SurfaceMountingManager (
99
100
int surfaceId ,
100
- @ NonNull JSResponderHandler jsResponderHandler ,
101
- @ NonNull ViewManagerRegistry viewManagerRegistry ,
102
- @ NonNull RootViewManager rootViewManager ,
103
- @ NonNull MountItemExecutor mountItemExecutor ,
104
- @ NonNull ThemedReactContext reactContext ) {
101
+ JSResponderHandler jsResponderHandler ,
102
+ ViewManagerRegistry viewManagerRegistry ,
103
+ RootViewManager rootViewManager ,
104
+ MountItemExecutor mountItemExecutor ,
105
+ ThemedReactContext reactContext ) {
105
106
mSurfaceId = surfaceId ;
106
107
mJSResponderHandler = jsResponderHandler ;
107
108
mViewManagerRegistry = viewManagerRegistry ;
@@ -182,11 +183,13 @@ public void scheduleMountItemOnViewAttach(MountItem item) {
182
183
}
183
184
184
185
@ AnyThread
185
- private void addRootView (@ NonNull final View rootView ) {
186
+ private void addRootView (final View rootView ) {
186
187
if (isStopped ()) {
187
188
return ;
188
189
}
189
-
190
+ // mRootViewManager is non-null until StopSurface is called, which we know hasn't happened yet
191
+ // due to the isStopped() check above
192
+ Assertions .assertNotNull (mRootViewManager );
190
193
mTagToViewState .put (mSurfaceId , new ViewState (mSurfaceId , rootView , mRootViewManager , true ));
191
194
192
195
Runnable runnable =
@@ -253,6 +256,10 @@ private void addRootView(@NonNull final View rootView) {
253
256
@ UiThread
254
257
@ ThreadConfined (UI )
255
258
private void executeMountItemsOnViewAttach () {
259
+ Assertions .assertNotNull (
260
+ mMountItemExecutor ,
261
+ "executeMountItemsOnViewAttach was called after StopSurface, and this wasn't checked by the"
262
+ + " caller with isStopped()." );
256
263
mMountItemExecutor .executeItems (mOnViewAttachMountItems );
257
264
}
258
265
@@ -315,15 +322,12 @@ public void stopSurface() {
315
322
}
316
323
317
324
// Evict all views from cache and memory
318
- // TODO: clear instead of nulling out to simplify null-safety in this class
319
- // NULLSAFE_FIXME[Field Not Nullable]
320
- mTagToViewState = null ;
321
- // NULLSAFE_FIXME[Field Not Nullable]
322
- mJSResponderHandler = null ;
323
- // NULLSAFE_FIXME[Field Not Nullable]
325
+ mTagToViewState .clear ();
326
+ mJSResponderHandler .clearJSResponder ();
327
+
324
328
mRootViewManager = null ;
325
- // NULLSAFE_FIXME[Field Not Nullable]
326
329
mMountItemExecutor = null ;
330
+
327
331
mThemedReactContext = null ;
328
332
mOnViewAttachMountItems .clear ();
329
333
@@ -616,9 +620,9 @@ public void run() {
616
620
617
621
@ UiThread
618
622
public void createView (
619
- @ NonNull String componentName ,
623
+ String componentName ,
620
624
int reactTag ,
621
- @ Nullable ReadableMap props ,
625
+ ReadableMap props ,
622
626
@ Nullable StateWrapper stateWrapper ,
623
627
@ Nullable EventEmitterWrapper eventEmitterWrapper ,
624
628
boolean isLayoutable ) {
@@ -654,17 +658,16 @@ public void createView(
654
658
*/
655
659
@ UiThread
656
660
public void createViewUnsafe (
657
- @ NonNull String componentName ,
661
+ String componentName ,
658
662
int reactTag ,
659
- @ Nullable ReadableMap props ,
663
+ ReadableMap props ,
660
664
@ Nullable StateWrapper stateWrapper ,
661
665
@ Nullable EventEmitterWrapper eventEmitterWrapper ,
662
666
boolean isLayoutable ) {
663
667
Systrace .beginSection (
664
668
Systrace .TRACE_TAG_REACT_JAVA_BRIDGE ,
665
669
"SurfaceMountingManager::createViewUnsafe(" + componentName + ")" );
666
670
try {
667
- // NULLSAFE_FIXME[Parameter Not Nullable]
668
671
ReactStylesDiffMap propMap = new ReactStylesDiffMap (props );
669
672
670
673
ViewState viewState = new ViewState (reactTag );
@@ -675,10 +678,16 @@ public void createViewUnsafe(
675
678
676
679
if (isLayoutable ) {
677
680
ViewManager viewManager = mViewManagerRegistry .get (componentName );
681
+ if (mThemedReactContext == null ) {
682
+ throw new IllegalStateException (
683
+ "Unable to create view for tag ["
684
+ + reactTag
685
+ + "], mThemedReactContext is null. This can happen if you are creating a view"
686
+ + " after the surface has been stopped." );
687
+ }
678
688
// View Managers are responsible for dealing with inital state and props.
679
689
viewState .mView =
680
690
viewManager .createView (
681
- // NULLSAFE_FIXME[Parameter Not Nullable]
682
691
reactTag , mThemedReactContext , propMap , stateWrapper , mJSResponderHandler );
683
692
viewState .mViewManager = viewManager ;
684
693
}
@@ -733,8 +742,7 @@ public void receiveCommand(int reactTag, int commandId, @Nullable ReadableArray
733
742
viewState .mViewManager .receiveCommand (viewState .mView , commandId , commandArgs );
734
743
}
735
744
736
- public void receiveCommand (
737
- int reactTag , @ NonNull String commandId , @ Nullable ReadableArray commandArgs ) {
745
+ public void receiveCommand (int reactTag , String commandId , @ Nullable ReadableArray commandArgs ) {
738
746
if (isStopped ()) {
739
747
return ;
740
748
}
@@ -936,12 +944,12 @@ public void updateState(final int reactTag, @Nullable StateWrapper stateWrapper)
936
944
if (viewManager == null ) {
937
945
throw new IllegalStateException ("Unable to find ViewManager for tag: " + reactTag );
938
946
}
939
- Object extraData =
940
- // NULLSAFE_FIXME[Parameter Not Nullable]
941
- viewManager .updateState (viewState .mView , viewState .mCurrentProps , stateWrapper );
942
- if (extraData != null ) {
943
- // NULLSAFE_FIXME[Parameter Not Nullable]
944
- viewManager . updateExtraData ( viewState . mView , extraData );
947
+ if ( viewState . mView != null && viewState . mCurrentProps != null && stateWrapper != null ) {
948
+ Object extraData =
949
+ viewManager .updateState (viewState .mView , viewState .mCurrentProps , stateWrapper );
950
+ if (extraData != null ) {
951
+ viewManager . updateExtraData ( viewState . mView , extraData );
952
+ }
945
953
}
946
954
947
955
// Immediately clear native side of previous state wrapper. This causes the State object in C++
@@ -953,7 +961,7 @@ public void updateState(final int reactTag, @Nullable StateWrapper stateWrapper)
953
961
954
962
/** We update the event emitter from the main thread when the view is mounted. */
955
963
@ UiThread
956
- public void updateEventEmitter (int reactTag , @ NonNull EventEmitterWrapper eventEmitter ) {
964
+ public void updateEventEmitter (int reactTag , EventEmitterWrapper eventEmitter ) {
957
965
UiThreadUtil .assertOnUiThread ();
958
966
if (isStopped ()) {
959
967
return ;
@@ -1034,8 +1042,7 @@ private void onViewStateDeleted(ViewState viewState) {
1034
1042
1035
1043
// For non-root views we notify viewmanager with {@link ViewManager#onDropInstance}
1036
1044
ViewManager viewManager = viewState .mViewManager ;
1037
- if (!viewState .mIsRoot && viewManager != null ) {
1038
- // NULLSAFE_FIXME[Parameter Not Nullable]
1045
+ if (!viewState .mIsRoot && viewManager != null && viewState .mView != null ) {
1039
1046
viewManager .onDropViewInstance (viewState .mView );
1040
1047
}
1041
1048
}
@@ -1076,9 +1083,9 @@ public void deleteView(int reactTag) {
1076
1083
1077
1084
@ UiThread
1078
1085
public void preallocateView (
1079
- @ NonNull String componentName ,
1086
+ String componentName ,
1080
1087
int reactTag ,
1081
- @ Nullable ReadableMap props ,
1088
+ ReadableMap props ,
1082
1089
@ Nullable StateWrapper stateWrapper ,
1083
1090
boolean isLayoutable ) {
1084
1091
UiThreadUtil .assertOnUiThread ();
@@ -1113,7 +1120,7 @@ public View getView(int reactTag) {
1113
1120
return view ;
1114
1121
}
1115
1122
1116
- private @ NonNull ViewState getViewState (int tag ) {
1123
+ private ViewState getViewState (int tag ) {
1117
1124
ViewState viewState = mTagToViewState .get (tag );
1118
1125
if (viewState == null ) {
1119
1126
throw new RetryableMountingLayerException (
@@ -1131,8 +1138,7 @@ public View getView(int reactTag) {
1131
1138
}
1132
1139
1133
1140
@ SuppressWarnings ("unchecked" ) // prevents unchecked conversion warn of the <ViewGroup> type
1134
- private static @ NonNull IViewGroupManager <ViewGroup > getViewGroupManager (
1135
- @ NonNull ViewState viewState ) {
1141
+ private static IViewGroupManager <ViewGroup > getViewGroupManager (ViewState viewState ) {
1136
1142
if (viewState .mViewManager == null ) {
1137
1143
throw new IllegalStateException ("Unable to find ViewManager for view: " + viewState );
1138
1144
}
@@ -1237,7 +1243,6 @@ private ViewState(
1237
1243
mViewManager = viewManager ;
1238
1244
}
1239
1245
1240
- @ NonNull
1241
1246
@ Override
1242
1247
public String toString () {
1243
1248
boolean isLayoutOnly = mViewManager == null ;
0 commit comments