77
88package com .facebook .react .uimanager ;
99
10+ import static com .facebook .infer .annotation .Assertions .assertNotNull ;
11+
1012import android .content .Context ;
1113import android .graphics .Rect ;
1214import android .os .Bundle ;
2527import androidx .core .view .accessibility .AccessibilityNodeInfoCompat .RangeInfoCompat ;
2628import androidx .core .view .accessibility .AccessibilityNodeProviderCompat ;
2729import androidx .customview .widget .ExploreByTouchHelper ;
30+ import com .facebook .infer .annotation .Nullsafe ;
2831import com .facebook .react .R ;
2932import com .facebook .react .bridge .Arguments ;
3033import com .facebook .react .bridge .Dynamic ;
4952 * Utility class that handles the addition of a "role" for accessibility to either a View or
5053 * AccessibilityNodeInfo.
5154 */
55+ @ Nullsafe (Nullsafe .Mode .LOCAL )
5256public class ReactAccessibilityDelegate extends ExploreByTouchHelper {
5357
5458 public static final String TOP_ACCESSIBILITY_ACTION_EVENT = "topAccessibilityAction" ;
@@ -73,12 +77,15 @@ public class ReactAccessibilityDelegate extends ExploreByTouchHelper {
7377 @ Nullable View mAccessibilityLabelledBy ;
7478
7579 static {
76- sActionIdMap .put ("activate" , AccessibilityActionCompat .ACTION_CLICK .getId ());
77- sActionIdMap .put ("longpress" , AccessibilityActionCompat .ACTION_LONG_CLICK .getId ());
78- sActionIdMap .put ("increment" , AccessibilityActionCompat .ACTION_SCROLL_FORWARD .getId ());
79- sActionIdMap .put ("decrement" , AccessibilityActionCompat .ACTION_SCROLL_BACKWARD .getId ());
80- sActionIdMap .put ("expand" , AccessibilityActionCompat .ACTION_EXPAND .getId ());
81- sActionIdMap .put ("collapse" , AccessibilityActionCompat .ACTION_COLLAPSE .getId ());
80+ sActionIdMap .put ("activate" , assertNotNull (AccessibilityActionCompat .ACTION_CLICK ).getId ());
81+ sActionIdMap .put (
82+ "longpress" , assertNotNull (AccessibilityActionCompat .ACTION_LONG_CLICK ).getId ());
83+ sActionIdMap .put (
84+ "increment" , assertNotNull (AccessibilityActionCompat .ACTION_SCROLL_FORWARD ).getId ());
85+ sActionIdMap .put (
86+ "decrement" , assertNotNull (AccessibilityActionCompat .ACTION_SCROLL_BACKWARD ).getId ());
87+ sActionIdMap .put ("expand" , assertNotNull (AccessibilityActionCompat .ACTION_EXPAND ).getId ());
88+ sActionIdMap .put ("collapse" , assertNotNull (AccessibilityActionCompat .ACTION_COLLAPSE ).getId ());
8289 }
8390
8491 public ReactAccessibilityDelegate (
@@ -91,7 +98,9 @@ public ReactAccessibilityDelegate(
9198 @ Override
9299 public void handleMessage (Message msg ) {
93100 View host = (View ) msg .obj ;
94- host .sendAccessibilityEvent (AccessibilityEvent .TYPE_VIEW_SELECTED );
101+ if (host != null ) {
102+ host .sendAccessibilityEvent (AccessibilityEvent .TYPE_VIEW_SELECTED );
103+ }
95104 }
96105 };
97106
@@ -190,13 +199,14 @@ public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfoCo
190199
191200 if (accessibilityActions != null ) {
192201 for (int i = 0 ; i < accessibilityActions .size (); i ++) {
193- final ReadableMap action = accessibilityActions .getMap (i );
194- if (!action .hasKey ("name" )) {
202+ @ Nullable final ReadableMap action = accessibilityActions .getMap (i );
203+ if (action == null || !action .hasKey ("name" )) {
195204 throw new IllegalArgumentException ("Unknown accessibility action." );
196205 }
197206
198207 String actionName = action .getString ("name" );
199- String actionLabel = action .hasKey ("label" ) ? action .getString ("label" ) : null ;
208+ // AccessibilityActionCompat actionLabel must be non-null
209+ String actionLabel = action .hasKey ("label" ) ? assertNotNull (action .getString ("label" )) : "" ;
200210 int actionId ;
201211
202212 if (sActionIdMap .containsKey (actionName )) {
@@ -336,8 +346,9 @@ public WritableMap getEventData() {
336346 (AccessibilityRole ) host .getTag (R .id .accessibility_role );
337347 final ReadableMap accessibilityValue = (ReadableMap ) host .getTag (R .id .accessibility_value );
338348 if (accessibilityRole == AccessibilityRole .ADJUSTABLE
339- && (action == AccessibilityActionCompat .ACTION_SCROLL_FORWARD .getId ()
340- || action == AccessibilityActionCompat .ACTION_SCROLL_BACKWARD .getId ())) {
349+ && (action == assertNotNull (AccessibilityActionCompat .ACTION_SCROLL_FORWARD ).getId ()
350+ || action
351+ == assertNotNull (AccessibilityActionCompat .ACTION_SCROLL_BACKWARD ).getId ())) {
341352 if (accessibilityValue != null && !accessibilityValue .hasKey ("text" )) {
342353 scheduleAccessibilityEventSender (host );
343354 }
@@ -631,7 +642,8 @@ public static boolean isActionableForAccessibility(@Nullable AccessibilityNodeIn
631642 return true ;
632643 }
633644
634- final List actionList = node .getActionList ();
645+ final List <AccessibilityNodeInfoCompat .AccessibilityActionCompat > actionList =
646+ assertNotNull (node .getActionList ());
635647 return actionList .contains (AccessibilityNodeInfoCompat .ACTION_CLICK )
636648 || actionList .contains (AccessibilityNodeInfoCompat .ACTION_LONG_CLICK )
637649 || actionList .contains (AccessibilityNodeInfoCompat .ACTION_FOCUS );
0 commit comments