From d29a7e7a89f4e5e3489e9723979426bb1b6f0674 Mon Sep 17 00:00:00 2001 From: grgr-dkrk Date: Tue, 6 Apr 2021 13:46:51 -0700 Subject: [PATCH] add getRecommendedTimeoutMillis to AccessibilityInfo (#31063) Summary: resolve https://github.com/facebook/react-native/issues/30866 This PR is for using `getRecommendedTimeoutMillis` with React Native, which is available on Android 10 and above. This allows the Android "Time to take action (Accessibility timeout)" setting to be reflected in the app. ## Changelog [Android] [Added] - Add `getRecommendedTimeoutMillis` to AccessibilityInfo Pull Request resolved: https://github.com/facebook/react-native/pull/31063 Test Plan: I couldn't find any tests at the code level, so I tested them on my Android device. --- ### Android 10 (Pixel4a) #### Settings Set the timeout to 1 minute on the settings screen. #### App The baseline timeout is 3000 ms, but the result of `getRecommendedTimeoutMillis` returns 60000 ms. --- ### Android 7, iOS(Simulator) Return the original timeout. Return the original timeout on Android 7. Return the original timeout on iOS simulator. Reviewed By: lunaleaps Differential Revision: D27475370 Pulled By: nadiia fbshipit-source-id: 4cdd9eb5ddb20d89c1d870e640b4b7e3c3c1b14d --- .../AccessibilityInfo.android.js | 23 +++++++++++++++++++ .../AccessibilityInfo.ios.js | 9 ++++++++ .../NativeAccessibilityInfo.js | 4 ++++ .../AccessibilityInfoModule.java | 13 +++++++++++ jest/setup.js | 1 + 5 files changed, 50 insertions(+) diff --git a/Libraries/Components/AccessibilityInfo/AccessibilityInfo.android.js b/Libraries/Components/AccessibilityInfo/AccessibilityInfo.android.js index 75a37587d27725..fab85a0d5c1912 100644 --- a/Libraries/Components/AccessibilityInfo/AccessibilityInfo.android.js +++ b/Libraries/Components/AccessibilityInfo/AccessibilityInfo.android.js @@ -167,6 +167,29 @@ 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, + ): Promise { + return new Promise((resolve, reject) => { + if ( + NativeAccessibilityInfo && + NativeAccessibilityInfo.getRecommendedTimeoutMillis + ) { + NativeAccessibilityInfo.getRecommendedTimeoutMillis( + originalTimeout, + resolve, + ); + } else { + resolve(originalTimeout); + } + }); + }, }; module.exports = AccessibilityInfo; diff --git a/Libraries/Components/AccessibilityInfo/AccessibilityInfo.ios.js b/Libraries/Components/AccessibilityInfo/AccessibilityInfo.ios.js index 0730f808425547..9af89bf250af68 100644 --- a/Libraries/Components/AccessibilityInfo/AccessibilityInfo.ios.js +++ b/Libraries/Components/AccessibilityInfo/AccessibilityInfo.ios.js @@ -275,6 +275,15 @@ const AccessibilityInfo = { // $FlowFixMe[escaped-generic] _subscriptions.delete(handler); }, + + /** + * Android only + */ + getRecommendedTimeoutMillis: function( + originalTimeout: number, + ): Promise { + return Promise.resolve(originalTimeout); + }, }; module.exports = AccessibilityInfo; diff --git a/Libraries/Components/AccessibilityInfo/NativeAccessibilityInfo.js b/Libraries/Components/AccessibilityInfo/NativeAccessibilityInfo.js index 4810127fd7d48b..916667aa5c2c0a 100644 --- a/Libraries/Components/AccessibilityInfo/NativeAccessibilityInfo.js +++ b/Libraries/Components/AccessibilityInfo/NativeAccessibilityInfo.js @@ -20,6 +20,10 @@ export interface Spec extends TurboModule { ) => void; +setAccessibilityFocus: (reactTag: number) => void; +announceForAccessibility: (announcement: string) => void; + +getRecommendedTimeoutMillis?: ( + mSec: number, + onSuccess: (recommendedTimeoutMillis: number) => void, + ) => void; } export default (TurboModuleRegistry.get('AccessibilityInfo'): ?Spec); diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/accessibilityinfo/AccessibilityInfoModule.java b/ReactAndroid/src/main/java/com/facebook/react/modules/accessibilityinfo/AccessibilityInfoModule.java index bc923fed684d63..ad148228cd9bc0 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/accessibilityinfo/AccessibilityInfoModule.java +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/accessibilityinfo/AccessibilityInfoModule.java @@ -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"; @@ -193,4 +194,16 @@ public void announceForAccessibility(String message) { public void setAccessibilityFocus(double reactTag) { // iOS only } + + @Override + public void getRecommendedTimeoutMillis(double originalTimeout, Callback successCallback) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) { + successCallback.invoke((int) originalTimeout); + return; + } + mRecommendedTimeout = + mAccessibilityManager.getRecommendedTimeoutMillis( + (int) originalTimeout, AccessibilityManager.FLAG_CONTENT_CONTROLS); + successCallback.invoke(mRecommendedTimeout); + } } diff --git a/jest/setup.js b/jest/setup.js index 1bb9af5c51b1c9..6eaf71e5ee4cf2 100644 --- a/jest/setup.js +++ b/jest/setup.js @@ -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(