Skip to content

Commit 4503068

Browse files
Abbondanzofacebook-github-bot
authored andcommitted
Make ReactAccessibilityDelegate nullsafe (#53068)
Summary: Pull Request resolved: #53068 Adds some assertion annotations and small null checks to `ReactAccessibilityDelegate` to comply with FB's Nullsafe annotation Changelog: [Internal] Reviewed By: arushikesarwani94 Differential Revision: D79645332 fbshipit-source-id: 707e4e6d4a5f09232af168c2f7c57c2fdbb1f08d
1 parent af1bcb6 commit 4503068

1 file changed

Lines changed: 25 additions & 13 deletions

File tree

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactAccessibilityDelegate.java

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
package com.facebook.react.uimanager;
99

10+
import static com.facebook.infer.annotation.Assertions.assertNotNull;
11+
1012
import android.content.Context;
1113
import android.graphics.Rect;
1214
import android.os.Bundle;
@@ -25,6 +27,7 @@
2527
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.RangeInfoCompat;
2628
import androidx.core.view.accessibility.AccessibilityNodeProviderCompat;
2729
import androidx.customview.widget.ExploreByTouchHelper;
30+
import com.facebook.infer.annotation.Nullsafe;
2831
import com.facebook.react.R;
2932
import com.facebook.react.bridge.Arguments;
3033
import com.facebook.react.bridge.Dynamic;
@@ -49,6 +52,7 @@
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)
5256
public 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

Comments
 (0)