Files
react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/AccessibilityDelegateUtil.java
T
Andrew Chen (Eng) 1f96ff62cf Fix accessibilityRole value lookup
Summary:
Accessibility roles are enums that are looked up by matching a string accessibility role from JS to the enum's name using .toUpperCase(). .toUpperCase() causes issues in certain languages such as Turkish because the "i"s translate to "?".

D9402330 tried to address this by forcing the .toUpperCase to use Locale.US, but now it sometimes translates to "?"

Use .equalsIgnoreCase() instead to avoid translations.

Reviewed By: mdvacca, mmmulani

Differential Revision: D9497494

fbshipit-source-id: 0f8b7f2071b08ccb86655fee7bfd2d009ddde8eb
2018-08-24 13:21:21 -07:00

130 lines
4.5 KiB
Java

// Copyright (c) 2004-present, Facebook, Inc.
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
package com.facebook.react.uimanager;
import android.content.Context;
import android.support.v4.view.AccessibilityDelegateCompat;
import android.support.v4.view.ViewCompat;
import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
import android.view.View;
import com.facebook.react.R;
import java.util.Locale;
import javax.annotation.Nullable;
/**
* Utility class that handles the addition of a "role" for accessibility to either a View or
* AccessibilityNodeInfo.
*/
public class AccessibilityDelegateUtil {
/**
* These roles are defined by Google's TalkBack screen reader, and this list should be kept up to
* date with their implementation. Details can be seen in their source code here:
*
* <p>https://github.com/google/talkback/blob/master/utils/src/main/java/Role.java
*/
public enum AccessibilityRole {
NONE(null),
BUTTON("android.widget.Button"),
LINK("android.widget.ViewGroup"),
SEARCH("android.widget.EditText"),
IMAGE("android.widget.ImageView"),
IMAGEBUTTON("android.widget.ImageView"),
KEYBOARDKEY("android.inputmethodservice.Keyboard$Key"),
TEXT("android.widget.ViewGroup"),
ADJUSTABLE("android.widget.SeekBar"),
SUMMARY("android.widget.ViewGroup"),
HEADER("android.widget.ViewGroup");
@Nullable private final String mValue;
AccessibilityRole(String type) {
mValue = type;
}
@Nullable
public String getValue() {
return mValue;
}
public static AccessibilityRole fromValue(String value) {
for (AccessibilityRole role : AccessibilityRole.values()) {
if (role.name().equalsIgnoreCase(value)) {
return role;
}
}
throw new IllegalArgumentException("Invalid accessibility role value: " + value);
}
}
private AccessibilityDelegateUtil() {
// No instances
}
public static void setDelegate(final View view) {
// if a view already has an accessibility delegate, replacing it could cause problems,
// so leave it alone.
if (!ViewCompat.hasAccessibilityDelegate(view)) {
ViewCompat.setAccessibilityDelegate(
view,
new AccessibilityDelegateCompat() {
@Override
public void onInitializeAccessibilityNodeInfo(
View host, AccessibilityNodeInfoCompat info) {
super.onInitializeAccessibilityNodeInfo(host, info);
String accessibilityHint = (String) view.getTag(R.id.accessibility_hint);
AccessibilityRole accessibilityRole = (AccessibilityRole) view.getTag(R.id.accessibility_role);
if (accessibilityRole == null) {
accessibilityRole = AccessibilityRole.NONE;
}
setRole(info, accessibilityRole, view.getContext());
if (!(accessibilityHint == null)) {
String contentDescription=(String)info.getContentDescription();
if (contentDescription != null) {
contentDescription = contentDescription + ", " + accessibilityHint;
info.setContentDescription(contentDescription);
} else {
info.setContentDescription(accessibilityHint);
}
}
}
});
}
}
/**
* Strings for setting the Role Description in english
*/
//TODO: Eventually support for other languages on talkback
public static void setRole(AccessibilityNodeInfoCompat nodeInfo, final AccessibilityRole role, final Context context) {
nodeInfo.setClassName(role.getValue());
if (Locale.getDefault().getLanguage().equals(new Locale("en").getLanguage())) {
if (role.equals(AccessibilityRole.LINK)) {
nodeInfo.setRoleDescription(context.getString(R.string.link_description));
}
if (role.equals(AccessibilityRole.SEARCH)) {
nodeInfo.setRoleDescription(context.getString(R.string.search_description));
}
if (role.equals(AccessibilityRole.IMAGE)) {
nodeInfo.setRoleDescription(context.getString(R.string.image_description));
}
if (role.equals(AccessibilityRole.IMAGEBUTTON)) {
nodeInfo.setRoleDescription(context.getString(R.string.image_button_description));
}
if (role.equals(AccessibilityRole.ADJUSTABLE)) {
nodeInfo.setRoleDescription(context.getString(R.string.adjustable_description));
}
}
if (role.equals(AccessibilityRole.IMAGEBUTTON)) {
nodeInfo.setClickable(true);
}
}
}