Back out "remove use of RCTUnsafeExecuteOnMainQueueSync and main thread setup from RCTDeviceInfo" (#49681)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/49681

changelog: [internal]

Original commit changeset: e8280d2f5025

Original Phabricator Diff: D69747829

Reviewed By: NickGerleman

Differential Revision: D70200854

fbshipit-source-id: cbdd3746be4d43d320bb0f708cc1a790c010218b
This commit is contained in:
Samuel Susla
2025-02-25 20:39:07 -08:00
committed by Facebook GitHub Bot
parent 0f12f99d6c
commit ca49b512ad
4 changed files with 41 additions and 163 deletions
@@ -7,7 +7,6 @@
#import "RCTInitializeUIKitProxies.h"
#import "RCTInitialAccessibilityValuesProxy.h"
#import "RCTKeyWindowValuesProxy.h"
#import "RCTTraitCollectionProxy.h"
#import "RCTWindowSafeAreaProxy.h"
@@ -18,6 +17,5 @@ void RCTInitializeUIKitProxies(void)
[[RCTWindowSafeAreaProxy sharedInstance] startObservingSafeArea];
[[RCTTraitCollectionProxy sharedInstance] startObservingTraitCollection];
[[RCTInitialAccessibilityValuesProxy sharedInstance] recordAccessibilityValues];
[[RCTKeyWindowValuesProxy sharedInstance] startObservingWindowSizeIfNecessary];
});
}
@@ -1,23 +0,0 @@
/*
* 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 <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface RCTKeyWindowValuesProxy : NSObject
+ (instancetype)sharedInstance;
@property (assign, readonly) CGSize windowSize;
@property (assign, readonly) UIInterfaceOrientation currentInterfaceOrientation;
- (void)startObservingWindowSizeIfNecessary;
@end
NS_ASSUME_NONNULL_END
@@ -1,123 +0,0 @@
/*
* 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 "RCTKeyWindowValuesProxy.h"
#import <React/RCTAssert.h>
#import <React/RCTUtils.h>
#import <mutex>
#import <React/RCTConstants.h>
static NSString *const kFrameKeyPath = @"frame";
@implementation RCTKeyWindowValuesProxy {
BOOL _isObserving;
std::mutex _mutex;
CGSize _currentWindowSize;
UIInterfaceOrientation _currentInterfaceOrientation;
}
+ (instancetype)sharedInstance
{
static RCTKeyWindowValuesProxy *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [RCTKeyWindowValuesProxy new];
});
return sharedInstance;
}
- (instancetype)init
{
self = [super init];
if (self) {
_isObserving = NO;
UIView *mainWindow = RCTKeyWindow();
_currentWindowSize = mainWindow ? mainWindow.bounds.size : UIScreen.mainScreen.bounds.size;
}
return self;
}
- (void)startObservingWindowSizeIfNecessary
{
// Accesing _isObserving must be done under the lock to avoid a race condition.
// We can't hold the lock while calling RCTUnsafeExecuteOnMainQueueSync.
// Therefore, reading/writing _isObserving is kept separate from calling RCTUnsafeExecuteOnMainQueueSync.
{
std::lock_guard<std::mutex> lock(_mutex);
if (_isObserving) {
return;
}
_isObserving = YES;
}
// For backwards compatibility, we register for notifications from the main thread only.
// On the new architecture, we are already on the main thread and RCTUnsafeExecuteOnMainQueueSync will simply call
// the block.
RCTUnsafeExecuteOnMainQueueSync(^{
[RCTKeyWindow() addObserver:self forKeyPath:kFrameKeyPath options:NSKeyValueObservingOptionNew context:nil];
});
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(_interfaceOrientationDidChange)
name:UIApplicationDidBecomeActiveNotification
object:nil];
}
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context
{
if ([keyPath isEqualToString:kFrameKeyPath]) {
[[NSNotificationCenter defaultCenter] postNotificationName:RCTWindowFrameDidChangeNotification object:self];
{
std::lock_guard<std::mutex> lock(_mutex);
_currentWindowSize = RCTKeyWindow().bounds.size;
}
}
}
- (CGSize)windowSize
{
{
std::lock_guard<std::mutex> lock(_mutex);
if (_isObserving) {
return _currentWindowSize;
}
}
__block CGSize size;
RCTUnsafeExecuteOnMainQueueSync(^{
size = RCTKeyWindow().bounds.size;
});
return size;
}
- (UIInterfaceOrientation)currentInterfaceOrientation
{
{
std::lock_guard<std::mutex> lock(_mutex);
if (_isObserving) {
return _currentInterfaceOrientation;
}
}
__block UIInterfaceOrientation interfaceOrientation;
RCTUnsafeExecuteOnMainQueueSync(^{
interfaceOrientation = RCTKeyWindow().windowScene.interfaceOrientation;
});
return interfaceOrientation;
}
- (void)_interfaceOrientationDidChange
{
std::lock_guard<std::mutex> lock(_mutex);
_currentInterfaceOrientation = RCTKeyWindow().windowScene.interfaceOrientation;
}
@end
@@ -14,9 +14,7 @@
#import <React/RCTEventDispatcherProtocol.h>
#import <React/RCTInitializing.h>
#import <React/RCTInvalidating.h>
#import <React/RCTKeyWindowValuesProxy.h>
#import <React/RCTUtils.h>
#import <React/RCTWindowSafeAreaProxy.h>
#import <atomic>
#import "CoreModulesPlugins.h"
@@ -33,6 +31,8 @@ using namespace facebook::react;
std::atomic<BOOL> _invalidated;
}
static NSString *const kFrameKeyPath = @"frame";
@synthesize moduleRegistry = _moduleRegistry;
RCT_EXPORT_MODULE()
@@ -40,14 +40,25 @@ RCT_EXPORT_MODULE()
- (instancetype)init
{
if (self = [super init]) {
[[RCTKeyWindowValuesProxy sharedInstance] startObservingWindowSizeIfNecessary];
[RCTKeyWindow() addObserver:self forKeyPath:kFrameKeyPath options:NSKeyValueObservingOptionNew context:nil];
}
return self;
}
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context
{
if ([keyPath isEqualToString:kFrameKeyPath]) {
[self interfaceFrameDidChange];
[[NSNotificationCenter defaultCenter] postNotificationName:RCTWindowFrameDidChangeNotification object:self];
}
}
+ (BOOL)requiresMainQueueSetup
{
return NO;
return YES;
}
- (dispatch_queue_t)methodQueue
@@ -81,7 +92,7 @@ RCT_EXPORT_MODULE()
#if TARGET_OS_IOS
_currentInterfaceOrientation = [RCTKeyWindowValuesProxy sharedInstance].currentInterfaceOrientation;
_currentInterfaceOrientation = RCTKeyWindow().windowScene.interfaceOrientation;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(interfaceFrameDidChange)
@@ -120,6 +131,8 @@ RCT_EXPORT_MODULE()
[[NSNotificationCenter defaultCenter] removeObserver:self name:RCTBridgeWillInvalidateModulesNotification object:nil];
[RCTKeyWindow() removeObserver:self forKeyPath:kFrameKeyPath];
#if TARGET_OS_IOS
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil];
#endif
@@ -132,8 +145,13 @@ static BOOL RCTIsIPhoneNotched()
#if TARGET_OS_IOS
dispatch_once(&onceToken, ^{
RCTAssertMainQueue();
// 20pt is the top safeArea value in non-notched devices
isIPhoneNotched = [RCTWindowSafeAreaProxy sharedInstance].currentSafeAreaInsets.top > 20;
UIWindow *keyWindow = RCTKeyWindow();
if (keyWindow) {
isIPhoneNotched = keyWindow.safeAreaInsets.top > 20;
}
});
#endif
@@ -142,11 +160,13 @@ static BOOL RCTIsIPhoneNotched()
static NSDictionary *RCTExportedDimensions(CGFloat fontScale)
{
RCTAssertMainQueue();
UIScreen *mainScreen = UIScreen.mainScreen;
CGSize screenSize = mainScreen.bounds.size;
UIView *mainWindow = RCTKeyWindow();
// We fallback to screen size if a key window is not found.
CGSize windowSize = [RCTKeyWindowValuesProxy sharedInstance].windowSize;
CGSize windowSize = mainWindow ? mainWindow.bounds.size : screenSize;
NSDictionary<NSString *, NSNumber *> *dimsWindow = @{
@"width" : @(windowSize.width),
@@ -182,14 +202,20 @@ static NSDictionary *RCTExportedDimensions(CGFloat fontScale)
- (NSDictionary<NSString *, id> *)getConstants
{
return @{
@"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 <SafeAreaView> instead.
@"isIPhoneX_deprecated" : @(RCTIsIPhoneNotched()),
};
__block NSDictionary<NSString *, id> *constants;
__weak __typeof(self) weakSelf = self;
RCTUnsafeExecuteOnMainQueueSync(^{
constants = @{
@"Dimensions" : [weakSelf _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 <SafeAreaView> instead.
@"isIPhoneX_deprecated" : @(RCTIsIPhoneNotched()),
};
});
return constants;
}
- (void)didReceiveNewContentSizeMultiplier