Skip to content
Open
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 @@ -115,7 +115,7 @@ export default class DecayAnimation extends Animation {
stop(): void {
super.stop();
if (this._animationFrame != null) {
global.cancelAnimationFrame(this._animationFrame);
cancelAnimationFrame(this._animationFrame);
}
this.__notifyAnimationEnd({finished: false});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ export default class SpringAnimation extends Animation {
super.stop();
clearTimeout(this._timeout);
if (this._animationFrame != null) {
global.cancelAnimationFrame(this._animationFrame);
cancelAnimationFrame(this._animationFrame);
}
this.__notifyAnimationEnd({finished: false});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ export default class TimingAnimation extends Animation {
super.stop();
clearTimeout(this._timeout);
if (this._animationFrame != null) {
global.cancelAnimationFrame(this._animationFrame);
cancelAnimationFrame(this._animationFrame);
}
this.__notifyAnimationEnd({finished: false});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@
*/

import * as ReactNativeFeatureFlags from '../../src/private/featureflags/ReactNativeFeatureFlags';
import {isBridgeless} from '../../src/private/runtime/ReactNativeRuntimeGlobals';
import Platform from '../Utilities/Platform';

function shouldUseTurboAnimatedModule(): boolean {
if (ReactNativeFeatureFlags.cxxNativeAnimatedEnabled()) {
return false;
} else {
return Platform.OS === 'ios' && global.RN$Bridgeless === true;
return Platform.OS === 'ios' && isBridgeless;
}
}

Expand Down
24 changes: 12 additions & 12 deletions packages/react-native/Libraries/BatchedBridge/MessageQueue.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@

'use strict';

const {
isBridgeless,
nativeCallSyncHook,
nativeFlushQueueImmediate,
nativeTraceBeginAsyncFlow,
} = require('../../src/private/runtime/ReactNativeRuntimeGlobals');
const Systrace = require('../Performance/Systrace');
const deepFreezeAndThrowOnMutationInDev =
require('../Utilities/deepFreezeAndThrowOnMutationInDev').default;
Expand Down Expand Up @@ -179,15 +185,15 @@ class MessageQueue {
): unknown {
if (__DEV__) {
invariant(
global.nativeCallSyncHook,
nativeCallSyncHook,
'Calling synchronous methods on native ' +
'modules is not supported in Chrome.\n\n Consider providing alternative ' +
'methods to expose this method in debug mode, e.g. by exposing constants ' +
'ahead-of-time.',
);
}
this.processCallbacks(moduleID, methodID, params, onFail, onSucc);
return global.nativeCallSyncHook(moduleID, methodID, params);
return nativeCallSyncHook?.(moduleID, methodID, params);
}

processCallbacks(
Expand Down Expand Up @@ -231,12 +237,7 @@ class MessageQueue {
this._failureCallbacks.set(this._callID, onFail);
}
if (__DEV__) {
global.nativeTraceBeginAsyncFlow &&
global.nativeTraceBeginAsyncFlow(
TRACE_TAG_REACT,
'native',
this._callID,
);
nativeTraceBeginAsyncFlow?.(TRACE_TAG_REACT, 'native', this._callID);
}
this._callID++;
}
Expand Down Expand Up @@ -317,13 +318,13 @@ class MessageQueue {

const now = Date.now();
if (
global.nativeFlushQueueImmediate &&
nativeFlushQueueImmediate != null &&
now - this._lastFlush >= MIN_TIME_BETWEEN_FLUSHES_MS
) {
const queue = this._queue;
this._queue = [[], [], [], this._callID];
this._lastFlush = now;
global.nativeFlushQueueImmediate(queue);
nativeFlushQueueImmediate(queue);
}
Systrace.counterEvent('pending_js_to_native_queue', this._queue[0].length);
if (__DEV__ && this.__spy && isFinite(moduleID)) {
Expand Down Expand Up @@ -422,8 +423,7 @@ class MessageQueue {
const callableModuleNameList = callableModuleNames.join(', ');

// TODO(T122225939): Remove after investigation: Why are we getting to this line in bridgeless mode?
const isBridgelessMode =
global.RN$Bridgeless === true ? 'true' : 'false';
const isBridgelessMode = isBridgeless ? 'true' : 'false';
invariant(
false,
`Failed to call into JavaScript module method ${module}.${method}(). Module has not been registered as callable. Bridgeless Mode: ${isBridgelessMode}. Registered callable JavaScript modules (n = ${n}): ${callableModuleNameList}.
Expand Down
27 changes: 13 additions & 14 deletions packages/react-native/Libraries/BatchedBridge/NativeModules.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,18 @@

'use strict';

import type {ModuleConfig} from '../../src/private/runtime/ReactNativeRuntimeGlobals';
import type {ExtendedError} from '../Core/ExtendedError';

const {
batchedBridgeConfig,
nativeModuleProxy,
nativeRequireModuleConfig,
} = require('../../src/private/runtime/ReactNativeRuntimeGlobals');
const BatchedBridge = require('./BatchedBridge').default;
const invariant = require('invariant');

export type ModuleConfig = [
string /* name */,
?{...} /* constants */,
?ReadonlyArray<string> /* functions */,
?ReadonlyArray<number> /* promise method IDs */,
?ReadonlyArray<number> /* sync method IDs */,
];
export type {ModuleConfig} from '../../src/private/runtime/ReactNativeRuntimeGlobals';

export type MethodType = 'async' | 'promise' | 'sync';

Expand Down Expand Up @@ -88,10 +88,10 @@ global.__fbGenNativeModule = genModule;

function loadModule(name: string, moduleID: number): ?{...} {
invariant(
global.nativeRequireModuleConfig,
nativeRequireModuleConfig,
"Can't lazily create module without nativeRequireModuleConfig",
);
const config = global.nativeRequireModuleConfig(name);
const config = nativeRequireModuleConfig(name);
const info = genModule(config, moduleID);
return info && info.module;
}
Expand Down Expand Up @@ -182,18 +182,17 @@ function updateErrorWithErrorData(

/* $FlowFixMe[unclear-type] unclear type of NativeModules */
let NativeModules: {[moduleName: string]: any, ...} = {};
if (global.nativeModuleProxy) {
NativeModules = global.nativeModuleProxy;
if (nativeModuleProxy) {
NativeModules = nativeModuleProxy;
} else {
const bridgeConfig = global.__fbBatchedBridgeConfig;
invariant(
bridgeConfig,
batchedBridgeConfig,
'__fbBatchedBridgeConfig is not set, cannot invoke native modules',
);

const defineLazyObjectProperty =
require('../Utilities/defineLazyObjectProperty').default;
(bridgeConfig.remoteModuleConfig || []).forEach(
(batchedBridgeConfig.remoteModuleConfig || []).forEach(
(config: ModuleConfig, moduleID: number) => {
// Initially this config will only contain the module name when running in JSC. The actual
// configuration of the module will be lazily loaded.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,24 +205,32 @@ describe('MessageQueue', function () {
});

describe('sync methods', () => {
afterEach(function () {
delete global.nativeCallSyncHook;
});

it('throwing an exception', function () {
global.nativeCallSyncHook = jest.fn(() => {
const mockNativeCallSyncHook = jest.fn(() => {
throw new Error('firstFailure');
});

jest.resetModules();
jest.doMock(
'../../../src/private/runtime/ReactNativeRuntimeGlobals',
() => ({
...jest.requireActual(
'../../../src/private/runtime/ReactNativeRuntimeGlobals',
),
nativeCallSyncHook: mockNativeCallSyncHook,
}),
);
NativeModules = require('../NativeModules').default;

let error;
try {
NativeModules.RemoteModule1.syncMethod('paloAlto', 'menloPark');
} catch (e) {
} catch (e: mixed) {
error = e;
}

expect(global.nativeCallSyncHook).toBeCalledTimes(1);
expect(global.nativeCallSyncHook).toBeCalledWith(
expect(mockNativeCallSyncHook).toHaveBeenCalledTimes(1);
expect(mockNativeCallSyncHook).toHaveBeenCalledWith(
0, // `RemoteModule1`
3, // `syncMethod`
['paloAlto', 'menloPark'],
Expand All @@ -234,14 +242,26 @@ describe('MessageQueue', function () {
});

it('returning a value', function () {
global.nativeCallSyncHook = jest.fn(() => {
const mockNativeCallSyncHook = jest.fn(() => {
return 'secondSucc';
});

jest.resetModules();
jest.doMock(
'../../../src/private/runtime/ReactNativeRuntimeGlobals',
() => ({
...jest.requireActual(
'../../../src/private/runtime/ReactNativeRuntimeGlobals',
),
nativeCallSyncHook: mockNativeCallSyncHook,
}),
);
NativeModules = require('../NativeModules').default;

const result = NativeModules.RemoteModule2.syncMethod('mac', 'windows');

expect(global.nativeCallSyncHook).toBeCalledTimes(1);
expect(global.nativeCallSyncHook).toBeCalledWith(
expect(mockNativeCallSyncHook).toHaveBeenCalledTimes(1);
expect(mockNativeCallSyncHook).toHaveBeenCalledWith(
1, // `RemoteModule2`
3, // `syncMethod`
['mac', 'windows'],
Expand Down
7 changes: 4 additions & 3 deletions packages/react-native/Libraries/Blob/BlobManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import typeof BlobT from './Blob';
import type {BlobCollector, BlobData, BlobOptions} from './BlobTypes';

import {blobCollectorProvider} from '../../src/private/runtime/ReactNativeRuntimeGlobals';
import NativeBlobModule from './NativeBlobModule';
import invariant from 'invariant';

Expand Down Expand Up @@ -40,10 +41,10 @@ function uuidv4(): string {
// that the current bridge infra doesn't allow to track js objects
// deallocation. Ideally the whole Blob object should be a jsi::HostObject.
function createBlobCollector(blobId: string): BlobCollector | null {
if (global.__blobCollectorProvider == null) {
if (blobCollectorProvider == null) {
return null;
} else {
return global.__blobCollectorProvider(blobId);
return blobCollectorProvider(blobId) ?? null;
}
}

Expand Down Expand Up @@ -88,7 +89,7 @@ class BlobManager {
if (curr.type === 'string') {
/* $FlowFixMe[incompatible-type] Natural Inference rollout. See
* https://fburl.com/workplace/6291gfvu */
return acc + global.unescape(encodeURI(curr.data)).length;
return acc + unescape(encodeURI(curr.data)).length;
} else {
/* $FlowFixMe[prop-missing] Natural Inference rollout. See
* https://fburl.com/workplace/6291gfvu */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1261,7 +1261,7 @@ class ScrollView extends React.Component<ScrollViewProps, ScrollViewState> {
* Invoke this from an `onMomentumScrollBegin` event.
*/
_handleMomentumScrollBegin: (e: ScrollEvent) => void = (e: ScrollEvent) => {
this._lastMomentumScrollBeginTime = global.performance.now();
this._lastMomentumScrollBeginTime = performance.now();
this.props.onMomentumScrollBegin && this.props.onMomentumScrollBegin(e);
};

Expand All @@ -1270,7 +1270,7 @@ class ScrollView extends React.Component<ScrollViewProps, ScrollViewState> {
*/
_handleMomentumScrollEnd: (e: ScrollEvent) => void = (e: ScrollEvent) => {
FrameRateLogger.endScroll();
this._lastMomentumScrollEndTime = global.performance.now();
this._lastMomentumScrollEndTime = performance.now();
this.props.onMomentumScrollEnd && this.props.onMomentumScrollEnd(e);
};

Expand Down Expand Up @@ -1319,7 +1319,7 @@ class ScrollView extends React.Component<ScrollViewProps, ScrollViewState> {
* a touch has just started or ended.
*/
_isAnimating: () => boolean = () => {
const now = global.performance.now();
const now = performance.now();
const timeSinceLastMomentumScrollEnd =
now - this._lastMomentumScrollEndTime;
const isAnimating =
Expand Down
21 changes: 14 additions & 7 deletions packages/react-native/Libraries/Core/ExceptionsManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@
import type {ExtendedError} from './ExtendedError';
import type {ExceptionData} from './NativeExceptionsManager';

import {
handleException as nativeHandleException,
hasHandledFatalException as nativeHasHandledFatalException,
inExceptionHandler as nativeInExceptionHandler,
notifyOfFatalException as nativeNotifyOfFatalException,
} from '../../src/private/runtime/ReactNativeRuntimeGlobals';

export class SyntheticError extends Error {
name: string = '';
}
Expand Down Expand Up @@ -124,10 +131,10 @@ function reportException(
require('./NativeExceptionsManager').default;
if (NativeExceptionsManager) {
if (isFatal) {
if (global.RN$hasHandledFatalException?.()) {
if (nativeHasHandledFatalException?.()) {
return;
}
global.RN$notifyOfFatalException?.();
nativeNotifyOfFatalException?.();
}
NativeExceptionsManager.reportException(data);
}
Expand All @@ -152,8 +159,8 @@ function handleException(e: unknown, isFatal: boolean) {
// TODO(T196834299): We should really use a c++ turbomodule for this
const reportToConsole = true;
if (
!global.RN$handleException ||
!global.RN$handleException(e, isFatal, reportToConsole)
!nativeHandleException ||
!nativeHandleException(e, isFatal, reportToConsole)
) {
let error: Error;
if (e instanceof Error) {
Expand Down Expand Up @@ -185,7 +192,7 @@ function reactConsoleErrorHandler(...args) {
if (!console.reportErrorsAsExceptions) {
return;
}
if (inExceptionHandler || global.RN$inExceptionHandler?.()) {
if (inExceptionHandler || nativeInExceptionHandler?.()) {
// The fundamental trick here is that are multiple entry point to logging errors:
// (see D19743075 for more background)
//
Expand Down Expand Up @@ -236,8 +243,8 @@ function reactConsoleErrorHandler(...args) {
const isFatal = false;
const reportToConsole = false;
if (
!global.RN$handleException ||
!global.RN$handleException(error, isFatal, reportToConsole)
!nativeHandleException ||
!nativeHandleException(error, isFatal, reportToConsole)
) {
if (__DEV__) {
// If we're not reporting to the console in reportException,
Expand Down
9 changes: 3 additions & 6 deletions packages/react-native/Libraries/Core/Timers/JSTimers.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,17 +113,14 @@ function _callTimer(timerID: number, frameTime: number, didTimeout: ?boolean) {
) {
callback();
} else if (type === 'requestAnimationFrame') {
callback(global.performance.now());
callback(performance.now());
} else if (type === 'requestIdleCallback') {
callback({
timeRemaining: function () {
// TODO: Optimisation: allow running for longer than one frame if
// there are no pending JS calls on the bridge from native. This
// would require a way to check the bridge queue synchronously.
return Math.max(
0,
FRAME_DURATION - (global.performance.now() - frameTime),
);
return Math.max(0, FRAME_DURATION - (performance.now() - frameTime));
},
didTimeout: !!didTimeout,
});
Expand Down Expand Up @@ -298,7 +295,7 @@ const JSTimers = {
const index: number = requestIdleCallbacks.indexOf(id);
if (index > -1) {
requestIdleCallbacks.splice(index, 1);
_callTimer(id, global.performance.now(), true);
_callTimer(id, performance.now(), true);
}
delete requestIdleCallbackTimeouts[id];
if (requestIdleCallbacks.length === 0) {
Expand Down
Loading
Loading