From 0b8db7e5e814cfbf9974cc5b6ceb64e8006d8a3c Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Wed, 28 May 2025 15:29:19 -0700 Subject: [PATCH] Mitigate device info main queue modules crash (#51662) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/51662 ## Changes DeviceInfo: Deafult fontScale to 1 when accessibility manager isn't available # Analysis **The problem:** For reasons that we don't understand, accessibility manager is sometimes nil, when deviceinfo needs it. This is a long-standing issue in react native. ``` _constants = @{ @"Dimensions" : [self _exportedDimensions], // Note: // This prop is deprecated and will be removed in a future release. // Please use this only for a quick and temporary solution. // Use instead. @"isIPhoneX_deprecated" : @(RCTIsIPhoneNotched()), }; ``` ``` - (NSDictionary *)_exportedDimensions { RCTAssert(!_invalidated, @"Failed to get exported dimensions: RCTDeviceInfo has been invalidated"); RCTAssert(_moduleRegistry, @"Failed to get exported dimensions: RCTModuleRegistry is nil"); RCTAccessibilityManager *accessibilityManager = (RCTAccessibilityManager *)[_moduleRegistry moduleForName:"AccessibilityManager"]; if (!accessibilityManager) { return nil; } CGFloat fontScale = accessibilityManager ? accessibilityManager.multiplier : 1.0; return RCTExportedDimensions(fontScale); } ``` **The crash:** When accessibility manager is nil, device info tries to insert nil into an NSDictionary, and crashes. We found a possible repro of this issue: [launch facebook, log out, and log back in](https://www.internalfb.com/diff/D72020801?transaction_fbid=982516293994114). **Why this surged now:** Recently, we started initializing device info during react native init. That means this code-path just runs much more often. # Mitigation Remove the return nil in `[self _exportedDimensions]`. Instead, just default the fontScale to 1 when the accessibility manager isn't available. **This should be safe:** If we assume that accessibility manager eventually becomes available, the fontScale will eventually become correct. Device info will send the updated fontScale to js when it becomes available: [native](https://www.internalfb.com/code/fbsource/[ec6fd664a9cd]/xplat/js/react-native-github/packages/react-native/React/CoreModules/RCTDeviceInfo.mm?lines=231-232), [js](https://www.internalfb.com/code/fbsource/[ec6fd664a9cd]/xplat/js/react-native-github/packages/react-native/Libraries/Utilities/Dimensions.js?lines=120-125). # Long-term fix Understand why accessibility manager is nil. Changelog: [Internal] Reviewed By: fkgozali Differential Revision: D75537894 fbshipit-source-id: 921cc573fdfd7e5c340ac3a4ada268caadb9e382 --- packages/react-native/React/CoreModules/RCTDeviceInfo.mm | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/react-native/React/CoreModules/RCTDeviceInfo.mm b/packages/react-native/React/CoreModules/RCTDeviceInfo.mm index 4e3f47d2e72..e1efd2f7342 100644 --- a/packages/react-native/React/CoreModules/RCTDeviceInfo.mm +++ b/packages/react-native/React/CoreModules/RCTDeviceInfo.mm @@ -203,9 +203,10 @@ static NSDictionary *RCTExportedDimensions(CGFloat fontScale) RCTAssert(_moduleRegistry, @"Failed to get exported dimensions: RCTModuleRegistry is nil"); RCTAccessibilityManager *accessibilityManager = (RCTAccessibilityManager *)[_moduleRegistry moduleForName:"AccessibilityManager"]; - if (!accessibilityManager) { - return nil; - } + // TOOD(T225745315): For some reason, accessibilityManager is nil in some cases. + // We default the fontScale to 1.0 in this case. This should be okay: if we assume + // that accessibilityManager will eventually become available, js will eventually + // be updated with the correct fontScale. CGFloat fontScale = accessibilityManager ? accessibilityManager.multiplier : 1.0; return RCTExportedDimensions(fontScale); }