Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add getRecommendedTimeoutMillis to AccessibilityInfo #31063

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ type AccessibilityEventDefinitions = {

type AccessibilityEventTypes = 'focus';

type AccessibilityUiContentFlagsTypes =
| 'FLAG_CONTENT_ICONS'
| 'FLAG_CONTENT_TEXT'
| 'FLAG_CONTENT_CONTROLS';

const _subscriptions = new Map();

/**
Expand Down Expand Up @@ -175,6 +180,28 @@ const AccessibilityInfo = {
NativeAccessibilityInfo.announceForAccessibility(announcement);
}
},

/**
* Get the recommended timeout for changes to the UI needed by this user.
*
* See https://reactnative.dev/docs/accessibilityinfo.html#getRecommendedTimeoutMillis
*/
getRecommendedTimeoutMillis: function(
originalTimeout: number,
uiContentFlags: AccessibilityUiContentFlagsTypes,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure we should bother to surface this param in the javascript API.

Under the hood it's actually not doing anything, no matter which flag you pass in, the same value comes back. Looking through the Android source, it seems like they originally intended to have two user settings for timings, one for interactive elements, and one for static elements, but at some point this was dropped in favor of a single setting that just sets both values behind the scenes. These flags seem like a vestigial remnant of that original idea, and will likely be removed in a later API version.

@kacieb, does RN generally have a standard for when we should match a platform API strictly versus going with a simpler API if both options have the same end result?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commenting again to request changes.

): Promise<number | null> {
return new Promise((resolve, reject) => {
if (NativeAccessibilityInfo) {
NativeAccessibilityInfo.getRecommendedTimeoutMillis(
originalTimeout,
uiContentFlags,
resolve,
);
} else {
reject(null);
}
});
},
};

module.exports = AccessibilityInfo;
15 changes: 15 additions & 0 deletions Libraries/Components/AccessibilityInfo/AccessibilityInfo.ios.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ type AccessibilityEventDefinitions = {

type AccessibilityEventTypes = 'focus';

type AccessibilityUiContentFlagsTypes =
| 'FLAG_CONTENT_ICONS'
| 'FLAG_CONTENT_TEXT'
| 'FLAG_CONTENT_CONTROLS';

const _subscriptions = new Map();

/**
Expand Down Expand Up @@ -288,6 +293,16 @@ const AccessibilityInfo = {
// $FlowFixMe[escaped-generic]
_subscriptions.delete(handler);
},

/**
* Android only
*/
getRecommendedTimeoutMillis: function(
originalTimeout: number,
uiContentFlags: AccessibilityUiContentFlagsTypes,
): Promise<number> {
return Promise.resolve(originalTimeout);
},
};

module.exports = AccessibilityInfo;
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ export interface Spec extends TurboModule {
) => void;
+setAccessibilityFocus: (reactTag: number) => void;
+announceForAccessibility: (announcement: string) => void;
+getRecommendedTimeoutMillis: (
mSec: number,
uiContentFlags: string,
onSuccess: (recommendedTimeoutMillis: number) => void,
) => void;
}

export default (TurboModuleRegistry.get<Spec>('AccessibilityInfo'): ?Spec);
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ public void onChange(boolean selfChange, Uri uri) {
private final ContentResolver mContentResolver;
private boolean mReduceMotionEnabled = false;
private boolean mTouchExplorationEnabled = false;
private int mRecommendedTimeout;

private static final String REDUCE_MOTION_EVENT_NAME = "reduceMotionDidChange";
private static final String TOUCH_EXPLORATION_EVENT_NAME = "touchExplorationDidChange";
Expand Down Expand Up @@ -189,4 +190,30 @@ public void announceForAccessibility(String message) {
public void setAccessibilityFocus(double reactTag) {
// iOS only
}

@Override
public void getRecommendedTimeoutMillis(
double originalTimeout, String uiContentFlags, Callback successCallback) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
grgr-dkrk marked this conversation as resolved.
Show resolved Hide resolved
successCallback.invoke((int) originalTimeout);
return;
}
int flag = 0;
switch (uiContentFlags) {
case "FLAG_CONTENT_CONTROLS":
flag = AccessibilityManager.FLAG_CONTENT_CONTROLS;
break;
case "FLAG_CONTENT_ICONS":
flag = AccessibilityManager.FLAG_CONTENT_ICONS;
break;
case "FLAG_CONTENT_TEXT":
flag = AccessibilityManager.FLAG_CONTENT_TEXT;
break;
default:
break;
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

google-java-format suggested changes:

@@ -215 +215,2 @@
-    mRecommendedTimeout = mAccessibilityManager.getRecommendedTimeoutMillis((int)originalTimeout, flag);
+    mRecommendedTimeout =
+        mAccessibilityManager.getRecommendedTimeoutMillis((int) originalTimeout, flag);

mRecommendedTimeout =
mAccessibilityManager.getRecommendedTimeoutMillis((int) originalTimeout, flag);
successCallback.invoke(mRecommendedTimeout);
}
}
1 change: 1 addition & 0 deletions jest/setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ jest
removeEventListener: jest.fn(),
setAccessibilityFocus: jest.fn(),
sendAccessibilityEvent_unstable: jest.fn(),
getRecommendedTimeoutMillis: jest.fn(),
}))
.mock('../Libraries/Components/RefreshControl/RefreshControl', () =>
jest.requireActual(
Expand Down