diff --git a/packages/react-native/Libraries/Components/AccessibilityInfo/AccessibilityInfo.js b/packages/react-native/Libraries/Components/AccessibilityInfo/AccessibilityInfo.js index 017c1d3c842e..2845263e8f8a 100644 --- a/packages/react-native/Libraries/Components/AccessibilityInfo/AccessibilityInfo.js +++ b/packages/react-native/Libraries/Components/AccessibilityInfo/AccessibilityInfo.js @@ -528,10 +528,15 @@ const AccessibilityInfo = { }, /** - * Get the recommended timeout in milliseconds the user needs, as specified - * in the device's Accessibility settings. + * Get the recommended timeout in milliseconds the user needs, given the + * timeout the app would otherwise use. * - * @platform android + * On Android 10 (API 29) and later, this follows the "Time to take action" + * accessibility setting; earlier versions resolve to `originalTimeout`. + * iOS has no such setting, so React Native allows three times + * `originalTimeout` while Switch Control is running, because moving between + * elements one switch press at a time is slow, and `originalTimeout` + * otherwise. */ getRecommendedTimeoutMillis(originalTimeout: number): Promise { if (Platform.OS === 'android') { @@ -548,7 +553,20 @@ const AccessibilityInfo = { } }); } else { - return Promise.resolve(originalTimeout); + return new Promise(resolve => { + if ( + NativeAccessibilityManagerIOS?.getRecommendedTimeoutMillis != null + ) { + NativeAccessibilityManagerIOS.getRecommendedTimeoutMillis( + originalTimeout, + resolve, + ); + } else { + // An existing API, so new JS on an older binary keeps resolving the + // value it always did on iOS rather than rejecting. + resolve(originalTimeout); + } + }); } }, }; diff --git a/packages/react-native/Libraries/Components/AccessibilityInfo/__tests__/AccessibilityInfo-test.js b/packages/react-native/Libraries/Components/AccessibilityInfo/__tests__/AccessibilityInfo-test.js index 380be9fdd394..02e52643ebf9 100644 --- a/packages/react-native/Libraries/Components/AccessibilityInfo/__tests__/AccessibilityInfo-test.js +++ b/packages/react-native/Libraries/Components/AccessibilityInfo/__tests__/AccessibilityInfo-test.js @@ -22,6 +22,10 @@ const mockGetCurrentShowBordersState = jest.fn((onSuccess, onError) => const mockGetCurrentBoldTextState = jest.fn((onSuccess, onError) => onSuccess(true), ); +const IOS_RECOMMENDED_TIMEOUT = 15000; +const mockGetRecommendedTimeoutMillisIOS = jest.fn( + (originalTimeout, onSuccess) => onSuccess(IOS_RECOMMENDED_TIMEOUT), +); const mockGetCurrentGrayscaleState = jest.fn((onSuccess, onError) => onSuccess(true), ); @@ -38,6 +42,10 @@ const mockGetCurrentVoiceOverState = jest.fn((onSuccess, onError) => onSuccess(true), ); let mockNativeAccessibilityManagerIOS: { + getRecommendedTimeoutMillis: JestMockFn< + [originalTimeout: number, onSuccess: (timeout: number) => void], + void, + > | null, getCurrentShowBordersState: JestMockFn< [ onSuccess: (isShowBordersEnabled: boolean) => void, @@ -102,6 +110,7 @@ let mockNativeAccessibilityManagerIOS: { void, > | null, } = { + getRecommendedTimeoutMillis: mockGetRecommendedTimeoutMillisIOS, getCurrentShowBordersState: mockGetCurrentShowBordersState, getCurrentPrefersCrossFadeTransitionsState: mockGetCurrentPrefersCrossFadeTransitionsState, @@ -831,20 +840,63 @@ describe('AccessibilityInfo', () => { }); describe('iOS', () => { - it('should return originalTimeout', async () => { + it('should return the native recommended timeout', async () => { /* $FlowFixMe[incompatible-type] */ Platform.OS = 'ios'; + const recommendedTimeoutMillis = + await AccessibilityInfo.getRecommendedTimeoutMillis(5000); + + expect(mockGetRecommendedTimeoutMillisIOS).toHaveBeenCalledWith( + 5000, + expect.any(Function), + ); + expect(recommendedTimeoutMillis).toBe(IOS_RECOMMENDED_TIMEOUT); + }); + + it('should return originalTimeout if getRecommendedTimeoutMillis is not available', async () => { + /* $FlowFixMe[incompatible-type] */ + Platform.OS = 'ios'; + + mockNativeAccessibilityManagerIOS.getRecommendedTimeoutMillis = null; + const recommendedTimeoutMillis = await AccessibilityInfo.getRecommendedTimeoutMillis(5000); expect(recommendedTimeoutMillis).toBe(5000); }); + + it('should return originalTimeout if NativeAccessibilityManagerIOS is not available', async () => { + /* $FlowFixMe[incompatible-type] */ + Platform.OS = 'ios'; + + const nativeAccessibilityManagerModule = jest.requireMock( + '../NativeAccessibilityManager', + ); + const originalModule = nativeAccessibilityManagerModule.default; + // The native method is present, so only the missing module can make + // getRecommendedTimeoutMillis skip it. + expect(originalModule.getRecommendedTimeoutMillis).toBe( + mockGetRecommendedTimeoutMillisIOS, + ); + nativeAccessibilityManagerModule.default = null; + + try { + const recommendedTimeoutMillis = + await AccessibilityInfo.getRecommendedTimeoutMillis(5000); + + expect(mockGetRecommendedTimeoutMillisIOS).not.toHaveBeenCalled(); + expect(recommendedTimeoutMillis).toBe(5000); + } finally { + nativeAccessibilityManagerModule.default = originalModule; + } + }); }); }); afterEach(() => { mockNativeAccessibilityManagerIOS = { + getRecommendedTimeoutMillis: mockGetRecommendedTimeoutMillisIOS, getCurrentShowBordersState: mockGetCurrentShowBordersState, getCurrentPrefersCrossFadeTransitionsState: mockGetCurrentPrefersCrossFadeTransitionsState, diff --git a/packages/react-native/React/CoreModules/RCTAccessibilityManager+Internal.h b/packages/react-native/React/CoreModules/RCTAccessibilityManager+Internal.h index 6e180007fdca..d5c0efd4ed96 100644 --- a/packages/react-native/React/CoreModules/RCTAccessibilityManager+Internal.h +++ b/packages/react-native/React/CoreModules/RCTAccessibilityManager+Internal.h @@ -19,6 +19,15 @@ void RCTAccessibilityManagerSetIsVoiceOverEnabled( RCTAccessibilityManager *accessibilityManager, BOOL isVoiceOverEnabled); +// Returns whether Switch Control is running. +typedef BOOL (^RCTSwitchControlReader)(void); + +// Replaces how this module reads whether Switch Control is running, for +// getRecommendedTimeoutMillis. Pass nil to read the system again. +void RCTAccessibilityManagerSetSwitchControlReader( + RCTAccessibilityManager *accessibilityManager, + RCTSwitchControlReader _Nullable switchControlReader); + RCT_EXTERN_C_END NS_ASSUME_NONNULL_END diff --git a/packages/react-native/React/CoreModules/RCTAccessibilityManager.mm b/packages/react-native/React/CoreModules/RCTAccessibilityManager.mm index dee5e643c758..1038d5d6ba6b 100644 --- a/packages/react-native/React/CoreModules/RCTAccessibilityManager.mm +++ b/packages/react-native/React/CoreModules/RCTAccessibilityManager.mm @@ -56,7 +56,10 @@ static NSNotificationName RCTShowBordersStatusDidChangeNotification() #pragma clang diagnostic pop } -@implementation RCTAccessibilityManager +@implementation RCTAccessibilityManager { + // Replaced in tests through RCTAccessibilityManagerSetSwitchControlReader. + RCTSwitchControlReader _switchControlReader; +} @synthesize viewRegistry_DEPRECATED = _viewRegistry_DEPRECATED; @synthesize moduleRegistry = _moduleRegistry; @@ -469,6 +472,16 @@ - (void)getCurrentVoiceOverState:(RCTResponseSenderBlock)onSuccess onError:(__un onSuccess(@[ @(_isVoiceOverEnabled) ]); } +- (void)getRecommendedTimeoutMillis:(double)mSec onSuccess:(RCTResponseSenderBlock)onSuccess +{ + BOOL isSwitchControlRunning = + _switchControlReader != nil ? _switchControlReader() : UIAccessibilityIsSwitchControlRunning(); + // iOS has no recommended timeout setting. Moving between elements one switch + // press at a time is slow, so allow three times as long while Switch Control + // is running. + onSuccess(@[ @(isSwitchControlRunning ? mSec * 3 : mSec) ]); +} + - (std::shared_ptr)getTurboModule: (const facebook::react::ObjCTurboModule::InitParams &)params { @@ -484,6 +497,13 @@ void RCTAccessibilityManagerSetIsVoiceOverEnabled( [accessibilityManager _setIsVoiceOverEnabled:isVoiceOverEnabled]; } +void RCTAccessibilityManagerSetSwitchControlReader( + RCTAccessibilityManager *accessibilityManager, + RCTSwitchControlReader _Nullable switchControlReader) +{ + accessibilityManager->_switchControlReader = [switchControlReader copy]; +} + @end @implementation RCTBridgeProxy (RCTAccessibilityManager) diff --git a/packages/react-native/__typetests__/index.tsx b/packages/react-native/__typetests__/index.tsx index 75e5dce1634c..4593da40d959 100644 --- a/packages/react-native/__typetests__/index.tsx +++ b/packages/react-native/__typetests__/index.tsx @@ -1470,6 +1470,9 @@ AccessibilityInfo.isShowBordersEnabled().then(isEnabled => AccessibilityInfo.addEventListener('showBordersChanged', isEnabled => console.log(`AccessibilityInfo.showBordersChanged => ${isEnabled}`), ); +AccessibilityInfo.getRecommendedTimeoutMillis(4000).then((timeout: number) => + console.log(`AccessibilityInfo.getRecommendedTimeoutMillis => ${timeout}`), +); AccessibilityInfo.isBoldTextEnabled().then(isEnabled => console.log(`AccessibilityInfo.isBoldTextEnabled => ${isEnabled}`), ); diff --git a/packages/react-native/src/private/specs_DEPRECATED/modules/NativeAccessibilityManager.js b/packages/react-native/src/private/specs_DEPRECATED/modules/NativeAccessibilityManager.js index 0dfb462fe674..2629b1d1c068 100644 --- a/packages/react-native/src/private/specs_DEPRECATED/modules/NativeAccessibilityManager.js +++ b/packages/react-native/src/private/specs_DEPRECATED/modules/NativeAccessibilityManager.js @@ -50,6 +50,10 @@ export interface Spec extends TurboModule { onSuccess: (isScreenReaderEnabled: boolean) => void, onError: (error: UnsafeObject) => void, ) => void; + readonly getRecommendedTimeoutMillis?: ( + mSec: number, + onSuccess: (recommendedTimeoutMillis: number) => void, + ) => void; readonly setAccessibilityContentSizeMultipliers: (JSMultipliers: { readonly extraSmall?: ?number, readonly small?: ?number, diff --git a/packages/react-native/types_DEPRECATED/Libraries/Components/AccessibilityInfo/AccessibilityInfo.d.ts b/packages/react-native/types_DEPRECATED/Libraries/Components/AccessibilityInfo/AccessibilityInfo.d.ts index 6f2ccb478328..db1c0a49ed29 100644 --- a/packages/react-native/types_DEPRECATED/Libraries/Components/AccessibilityInfo/AccessibilityInfo.d.ts +++ b/packages/react-native/types_DEPRECATED/Libraries/Components/AccessibilityInfo/AccessibilityInfo.d.ts @@ -182,10 +182,14 @@ export interface AccessibilityInfoStatic { ): void; /** - * Gets the timeout in millisecond that the user needs. - * This value is set in "Time to take action (Accessibility timeout)" of "Accessibility" settings. + * Gets the timeout in milliseconds that the user needs, given the timeout + * the app would otherwise use. * - * @platform android + * On Android 10 (API 29) and later, this value is set in "Time to take + * action (Accessibility timeout)" of "Accessibility" settings; earlier + * versions resolve to `originalTimeout`. iOS has no such setting, so React + * Native allows three times `originalTimeout` while Switch Control is + * running, and `originalTimeout` otherwise. */ getRecommendedTimeoutMillis: (originalTimeout: number) => Promise; sendAccessibilityEvent: ( diff --git a/packages/rn-tester/RNTesterPods.xcodeproj/project.pbxproj b/packages/rn-tester/RNTesterPods.xcodeproj/project.pbxproj index 1d336b424136..8dab68e46d66 100644 --- a/packages/rn-tester/RNTesterPods.xcodeproj/project.pbxproj +++ b/packages/rn-tester/RNTesterPods.xcodeproj/project.pbxproj @@ -20,6 +20,7 @@ 8145AE06241172D900A3F8DA /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8145AE05241172D900A3F8DA /* LaunchScreen.storyboard */; }; 832F45BB2A8A6E1F0097B4E6 /* SwiftTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 832F45BA2A8A6E1F0097B4E6 /* SwiftTest.swift */; }; A975CA6C2C05EADF0043F72A /* RCTNetworkTaskTests.m in Sources */ = {isa = PBXBuildFile; fileRef = A975CA6B2C05EADE0043F72A /* RCTNetworkTaskTests.m */; }; + A11E0F1D2EA6000100A11E0F /* RCTAccessibilityManagerTimeoutTests.m in Sources */ = {isa = PBXBuildFile; fileRef = A11E0F1C2EA6000100A11E0F /* RCTAccessibilityManagerTimeoutTests.m */; }; C175B6D9ED9336FB66637943 /* libPods-RNTester.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C706D402EE4AF9BE838CBA9 /* libPods-RNTester.a */; }; CD10C7A5290BD4EB0033E1ED /* RCTEventEmitterTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CD10C7A4290BD4EB0033E1ED /* RCTEventEmitterTests.m */; }; E62F11832A5C6580000BF1C8 /* FlexibleSizeExampleView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 27F441E81BEBE5030039B79C /* FlexibleSizeExampleView.mm */; }; @@ -100,6 +101,7 @@ 832F45BA2A8A6E1F0097B4E6 /* SwiftTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = SwiftTest.swift; path = RNTester/SwiftTest.swift; sourceTree = ""; }; 93A243F0D4D5C54911E811C4 /* libPods-RNTesterIntegrationTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNTesterIntegrationTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; A975CA6B2C05EADE0043F72A /* RCTNetworkTaskTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RCTNetworkTaskTests.m; sourceTree = ""; }; + A11E0F1C2EA6000100A11E0F /* RCTAccessibilityManagerTimeoutTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTAccessibilityManagerTimeoutTests.m; sourceTree = ""; }; AC474BFB29BBD4A1002BDAED /* RNTester.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; name = RNTester.xctestplan; path = RNTester/RNTester.xctestplan; sourceTree = ""; }; B0E70A8A05E03E868F8703FE /* Pods-RNTesterIntegrationTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTesterIntegrationTests.release.xcconfig"; path = "Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests.release.xcconfig"; sourceTree = ""; }; CA59C9994B1822826D8983F0 /* Pods-RNTester.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTester.debug.xcconfig"; path = "Target Support Files/Pods-RNTester/Pods-RNTester.debug.xcconfig"; sourceTree = ""; }; @@ -320,6 +322,7 @@ children = ( CD10C7A4290BD4EB0033E1ED /* RCTEventEmitterTests.m */, E7DB20A322B2BA84005AC45F /* Info.plist */, + A11E0F1C2EA6000100A11E0F /* RCTAccessibilityManagerTimeoutTests.m */, E7DB20C622B2BAA5005AC45F /* RCTAllocationTests.m */, E7DB20B222B2BAA4005AC45F /* RCTAnimationUtilsTests.m */, E7DB20AB22B2BAA3005AC45F /* RCTBlobManagerTests.m */, @@ -753,6 +756,7 @@ E7DB20DF22B2BAA6005AC45F /* RCTImageLoaderTests.m in Sources */, E7DB20D522B2BAA6005AC45F /* RCTPerformanceLoggerTests.m in Sources */, E7DB20D922B2BAA6005AC45F /* RCTAnimationUtilsTests.m in Sources */, + A11E0F1D2EA6000100A11E0F /* RCTAccessibilityManagerTimeoutTests.m in Sources */, E7DB20D122B2BAA6005AC45F /* RCTBundleURLProviderTests.m in Sources */, E7DB20EC22B2BAA6005AC45F /* RCTMultipartStreamReaderTests.m in Sources */, E7DB20E022B2BAA6005AC45F /* RCTMethodArgumentTests.m in Sources */, diff --git a/packages/rn-tester/RNTesterUnitTests/RCTAccessibilityManagerTimeoutTests.m b/packages/rn-tester/RNTesterUnitTests/RCTAccessibilityManagerTimeoutTests.m new file mode 100644 index 000000000000..3d17e9984d69 --- /dev/null +++ b/packages/rn-tester/RNTesterUnitTests/RCTAccessibilityManagerTimeoutTests.m @@ -0,0 +1,110 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#import +#import + +#import +#import +#import + +// The native module method JS calls, from the generated spec. +@interface RCTAccessibilityManager (RCTAccessibilityManagerTimeoutTests) + +- (void)getRecommendedTimeoutMillis:(double)mSec onSuccess:(RCTResponseSenderBlock)onSuccess; + +@end + +@interface RCTAccessibilityManagerTimeoutTests : XCTestCase + +@end + +@implementation RCTAccessibilityManagerTimeoutTests + +- (NSNumber *)recommendedTimeoutOf:(RCTAccessibilityManager *)manager for:(double)mSec +{ + __block NSNumber *timeout = nil; + [manager getRecommendedTimeoutMillis:mSec + onSuccess:^(NSArray *response) { + timeout = response.firstObject; + }]; + return timeout; +} + +- (void)testTimeoutIsThreeTimesLongerWhileSwitchControlIsRunning +{ + RCTAccessibilityManager *manager = [RCTAccessibilityManager new]; + XCTAssertNotNil(manager); + RCTAccessibilityManagerSetSwitchControlReader(manager, ^BOOL { + return YES; + }); + + XCTAssertEqualObjects([self recommendedTimeoutOf:manager for:4000], @12000); + XCTAssertEqualObjects([self recommendedTimeoutOf:manager for:0], @0); +} + +- (void)testTimeoutIsUnchangedWhileSwitchControlIsNotRunning +{ + RCTAccessibilityManager *manager = [RCTAccessibilityManager new]; + XCTAssertNotNil(manager); + RCTAccessibilityManagerSetSwitchControlReader(manager, ^BOOL { + return NO; + }); + + XCTAssertEqualObjects([self recommendedTimeoutOf:manager for:4000], @4000); + XCTAssertEqualObjects([self recommendedTimeoutOf:manager for:0], @0); +} + +- (void)testReaderIsReadOnEveryCall +{ + RCTAccessibilityManager *manager = [RCTAccessibilityManager new]; + XCTAssertNotNil(manager); + __block BOOL isSwitchControlRunning = NO; + RCTAccessibilityManagerSetSwitchControlReader(manager, ^BOOL { + return isSwitchControlRunning; + }); + + XCTAssertEqualObjects([self recommendedTimeoutOf:manager for:4000], @4000); + isSwitchControlRunning = YES; + XCTAssertEqualObjects([self recommendedTimeoutOf:manager for:4000], @12000); +} + +- (void)testSeparateInstancesUseTheirOwnReaders +{ + RCTAccessibilityManager *managerA = [RCTAccessibilityManager new]; + RCTAccessibilityManager *managerB = [RCTAccessibilityManager new]; + XCTAssertNotNil(managerA); + XCTAssertNotNil(managerB); + RCTAccessibilityManagerSetSwitchControlReader(managerA, ^BOOL { + return YES; + }); + RCTAccessibilityManagerSetSwitchControlReader(managerB, ^BOOL { + return NO; + }); + + XCTAssertEqualObjects([self recommendedTimeoutOf:managerA for:4000], @12000); + XCTAssertEqualObjects([self recommendedTimeoutOf:managerB for:4000], @4000); +} + +- (void)testWithoutAReaderTheSystemIsRead +{ + RCTAccessibilityManager *manager = [RCTAccessibilityManager new]; + XCTAssertNotNil(manager); + NSNumber *expected = UIAccessibilityIsSwitchControlRunning() ? @12000 : @4000; + + XCTAssertEqualObjects([self recommendedTimeoutOf:manager for:4000], expected); + + RCTAccessibilityManagerSetSwitchControlReader(manager, ^BOOL { + return !UIAccessibilityIsSwitchControlRunning(); + }); + XCTAssertNotEqualObjects([self recommendedTimeoutOf:manager for:4000], expected); + + RCTAccessibilityManagerSetSwitchControlReader(manager, nil); + XCTAssertEqualObjects([self recommendedTimeoutOf:manager for:4000], expected); +} + +@end diff --git a/packages/rn-tester/js/examples/Accessibility/AccessibilityExample.js b/packages/rn-tester/js/examples/Accessibility/AccessibilityExample.js index ff2891104139..476a919d7447 100644 --- a/packages/rn-tester/js/examples/Accessibility/AccessibilityExample.js +++ b/packages/rn-tester/js/examples/Accessibility/AccessibilityExample.js @@ -23,6 +23,7 @@ import {createRef, useEffect, useRef, useState} from 'react'; import { AccessibilityInfo, Alert, + AppState, Button, Image, ImageBackground, @@ -1606,6 +1607,7 @@ class DisplayOptionsStatusExample extends React.Component<{}> { /> )} + ); } @@ -1647,6 +1649,41 @@ function DisplayOptionStatusExample({ ); } +function RecommendedTimeoutStatusExample(): React.Node { + const [recommendedTimeout, setRecommendedTimeout] = useState(null); + useEffect(() => { + let isMounted = true; + // AccessibilityInfo has no event for the recommended timeout, so read it + // again whenever the app becomes active. + const read = () => { + // $FlowFixMe[unused-promise] + AccessibilityInfo.getRecommendedTimeoutMillis(4000).then(timeout => { + if (isMounted) { + setRecommendedTimeout(timeout); + } + }); + }; + read(); + const appStateListener = AppState.addEventListener('change', state => { + if (state === 'active') { + read(); + } + }); + return function cleanup() { + isMounted = false; + appStateListener.remove(); + }; + }, []); + return ( + + + {'Recommended timeout for 4000 ms: '} + {recommendedTimeout == null ? 'loading' : `${recommendedTimeout} ms`}. + + + ); +} + function AccessibilityExpandedExample(): React.Node { const [expand, setExpanded] = useState(false); const expandAction = {name: 'expand'}; diff --git a/scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api b/scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api index 8de2c49759a6..f465bfe67531 100644 --- a/scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api @@ -2152,6 +2152,7 @@ protocol NativeAccessibilityManagerSpec : public NSObjectRCTBridgeModule, public public virtual void getCurrentReduceTransparencyState:onError:(RCTResponseSenderBlock onSuccess, RCTResponseSenderBlock onError); public virtual void getCurrentShowBordersState:onError:(RCTResponseSenderBlock onSuccess, RCTResponseSenderBlock onError); public virtual void getCurrentVoiceOverState:onError:(RCTResponseSenderBlock onSuccess, RCTResponseSenderBlock onError); + public virtual void getRecommendedTimeoutMillis:onSuccess:(double mSec, RCTResponseSenderBlock onSuccess); public virtual void setAccessibilityContentSizeMultipliers:(JS::NativeAccessibilityManager::SpecSetAccessibilityContentSizeMultipliersJSMultipliers& JSMultipliers); public virtual void setAccessibilityFocus:(double reactTag); } diff --git a/scripts/cxx-api/api-snapshots/ReactAppleFrameworksCxx.api b/scripts/cxx-api/api-snapshots/ReactAppleFrameworksCxx.api index 6b5e45141f07..060b6be388d1 100644 --- a/scripts/cxx-api/api-snapshots/ReactAppleFrameworksCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAppleFrameworksCxx.api @@ -2210,6 +2210,7 @@ protocol NativeAccessibilityManagerSpec : public NSObjectRCTBridgeModule, public public virtual void getCurrentReduceTransparencyState:onError:(RCTResponseSenderBlock onSuccess, RCTResponseSenderBlock onError); public virtual void getCurrentShowBordersState:onError:(RCTResponseSenderBlock onSuccess, RCTResponseSenderBlock onError); public virtual void getCurrentVoiceOverState:onError:(RCTResponseSenderBlock onSuccess, RCTResponseSenderBlock onError); + public virtual void getRecommendedTimeoutMillis:onSuccess:(double mSec, RCTResponseSenderBlock onSuccess); public virtual void setAccessibilityContentSizeMultipliers:(JS::NativeAccessibilityManager::SpecSetAccessibilityContentSizeMultipliersJSMultipliers& JSMultipliers); public virtual void setAccessibilityFocus:(double reactTag); } diff --git a/scripts/cxx-api/api-snapshots/ReactAppleNewarchCxx.api b/scripts/cxx-api/api-snapshots/ReactAppleNewarchCxx.api index e8201541b2e1..d133ed1a1ac8 100644 --- a/scripts/cxx-api/api-snapshots/ReactAppleNewarchCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAppleNewarchCxx.api @@ -2145,6 +2145,7 @@ protocol NativeAccessibilityManagerSpec : public NSObjectRCTBridgeModule, public public virtual void getCurrentReduceTransparencyState:onError:(RCTResponseSenderBlock onSuccess, RCTResponseSenderBlock onError); public virtual void getCurrentShowBordersState:onError:(RCTResponseSenderBlock onSuccess, RCTResponseSenderBlock onError); public virtual void getCurrentVoiceOverState:onError:(RCTResponseSenderBlock onSuccess, RCTResponseSenderBlock onError); + public virtual void getRecommendedTimeoutMillis:onSuccess:(double mSec, RCTResponseSenderBlock onSuccess); public virtual void setAccessibilityContentSizeMultipliers:(JS::NativeAccessibilityManager::SpecSetAccessibilityContentSizeMultipliersJSMultipliers& JSMultipliers); public virtual void setAccessibilityFocus:(double reactTag); } diff --git a/scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api b/scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api index d3ff97cc59c6..5f7444a233dc 100644 --- a/scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api @@ -2152,6 +2152,7 @@ protocol NativeAccessibilityManagerSpec : public NSObjectRCTBridgeModule, public public virtual void getCurrentReduceTransparencyState:onError:(RCTResponseSenderBlock onSuccess, RCTResponseSenderBlock onError); public virtual void getCurrentShowBordersState:onError:(RCTResponseSenderBlock onSuccess, RCTResponseSenderBlock onError); public virtual void getCurrentVoiceOverState:onError:(RCTResponseSenderBlock onSuccess, RCTResponseSenderBlock onError); + public virtual void getRecommendedTimeoutMillis:onSuccess:(double mSec, RCTResponseSenderBlock onSuccess); public virtual void setAccessibilityContentSizeMultipliers:(JS::NativeAccessibilityManager::SpecSetAccessibilityContentSizeMultipliersJSMultipliers& JSMultipliers); public virtual void setAccessibilityFocus:(double reactTag); }