From 7c84a1a47807bfe209cd45512a78513e61a32b5f Mon Sep 17 00:00:00 2001 From: Mateusz Rajski Date: Mon, 26 Aug 2024 14:05:22 +0200 Subject: [PATCH 01/33] Get more necessary session data from OldDot --- src/components/InitialURLContextProvider.tsx | 16 ++++++++++++++++ src/libs/actions/Session/index.ts | 6 ++++++ 2 files changed, 22 insertions(+) diff --git a/src/components/InitialURLContextProvider.tsx b/src/components/InitialURLContextProvider.tsx index 4aa76edd3e62..be249051494d 100644 --- a/src/components/InitialURLContextProvider.tsx +++ b/src/components/InitialURLContextProvider.tsx @@ -1,6 +1,7 @@ import React, {createContext, useEffect, useState} from 'react'; import type {ReactNode} from 'react'; import {Linking} from 'react-native'; +import {signInWithOldDotData} from '@libs/actions/Session'; import type {Route} from '@src/ROUTES'; /** Initial url that will be opened when NewDot is embedded into Hybrid App. */ @@ -14,14 +15,29 @@ type InitialURLContextProviderProps = { children: ReactNode; }; +function setParamsInOnyx(urlToParse: string) { + const requiredParams = ['email', 'authToken', 'encryptedAuthToken', 'accountID', 'autoGeneratedLogin', 'autoGeneratedPassword']; + const searchParams = new URL(urlToParse).searchParams; + + const params = Object.fromEntries(requiredParams.map((param) => [param, searchParams.get(param)])); + + if (params.email && params.authToken && params.encryptedAuthToken && params.accountID && params.autoGeneratedLogin && params.autoGeneratedPassword) { + signInWithOldDotData(params.email, params.authToken, params.encryptedAuthToken, Number(params.accountID), params.autoGeneratedLogin, params.autoGeneratedPassword); + } +} + function InitialURLContextProvider({children, url}: InitialURLContextProviderProps) { const [initialURL, setInitialURL] = useState(url); useEffect(() => { if (url) { setInitialURL(url); + setParamsInOnyx(url); return; } Linking.getInitialURL().then((initURL) => { + if (initURL) { + setParamsInOnyx(initURL); + } setInitialURL(initURL as Route); }); }, [url]); diff --git a/src/libs/actions/Session/index.ts b/src/libs/actions/Session/index.ts index b687abd61bb9..a4a0c770001e 100644 --- a/src/libs/actions/Session/index.ts +++ b/src/libs/actions/Session/index.ts @@ -459,6 +459,11 @@ function signUpUser() { API.write(WRITE_COMMANDS.SIGN_UP_USER, params, {optimisticData, successData, failureData}); } +function signInWithOldDotData(email: string, authToken: string, encryptedAuthToken: string, accountID: number, autoGeneratedLogin: string, autoGeneratedPassword: string) { + Onyx.set(ONYXKEYS.SESSION, {email, authToken, encryptedAuthToken, accountID}); + Onyx.set(ONYXKEYS.CREDENTIALS, {autoGeneratedLogin, autoGeneratedPassword}); +} + /** * Given an idToken from Sign in with Apple, checks the API to see if an account * exists for that email address and signs the user in if so. @@ -1081,4 +1086,5 @@ export { isSupportAuthToken, hasStashedSession, signUpUser, + signInWithOldDotData, }; From 140a84f152e6f4b98e8db93e608a7e507b1e9669 Mon Sep 17 00:00:00 2001 From: Mateusz Rajski Date: Mon, 26 Aug 2024 16:05:07 +0200 Subject: [PATCH 02/33] Get rid of custom BootSplash logic for HybridApp --- src/Expensify.tsx | 4 +- .../HybridAppMiddleware/index.ios.tsx | 103 +---------------- src/components/HybridAppMiddleware/index.tsx | 104 +----------------- src/components/InitialURLContextProvider.tsx | 10 +- 4 files changed, 12 insertions(+), 209 deletions(-) diff --git a/src/Expensify.tsx b/src/Expensify.tsx index 8a2ef4a2b2f4..b04a0f3ff056 100644 --- a/src/Expensify.tsx +++ b/src/Expensify.tsx @@ -1,7 +1,7 @@ import {Audio} from 'expo-av'; import React, {useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState} from 'react'; import type {NativeEventSubscription} from 'react-native'; -import {AppState, Linking, NativeModules, Platform} from 'react-native'; +import {AppState, Linking, Platform} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; import Onyx, {useOnyx, withOnyx} from 'react-native-onyx'; import ConfirmModal from './components/ConfirmModal'; @@ -303,7 +303,7 @@ function Expensify({ )} {/* HybridApp has own middleware to hide SplashScreen */} - {!NativeModules.HybridAppModule && shouldHideSplash && } + {shouldHideSplash && } ); } diff --git a/src/components/HybridAppMiddleware/index.ios.tsx b/src/components/HybridAppMiddleware/index.ios.tsx index aee837e02dea..494c0a6241fd 100644 --- a/src/components/HybridAppMiddleware/index.ios.tsx +++ b/src/components/HybridAppMiddleware/index.ios.tsx @@ -1,21 +1,13 @@ import type React from 'react'; -import {useContext, useEffect, useRef, useState} from 'react'; +import {useEffect} from 'react'; import {NativeEventEmitter, NativeModules} from 'react-native'; import type {NativeModule} from 'react-native'; import {useOnyx} from 'react-native-onyx'; import type {OnyxEntry} from 'react-native-onyx'; -import {InitialURLContext} from '@components/InitialURLContextProvider'; -import useExitTo from '@hooks/useExitTo'; import useSplashScreen from '@hooks/useSplashScreen'; -import BootSplash from '@libs/BootSplash'; import Log from '@libs/Log'; -import Navigation from '@libs/Navigation/Navigation'; -import * as SessionUtils from '@libs/SessionUtils'; -import * as Welcome from '@userActions/Welcome'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import type {HybridAppRoute, Route} from '@src/ROUTES'; -import ROUTES from '@src/ROUTES'; import type {TryNewDot} from '@src/types/onyx'; type HybridAppMiddlewareProps = { @@ -38,33 +30,10 @@ const onboardingStatusSelector = (tryNewDot: OnyxEntry) => { * It is crucial to make transitions between OldDot and NewDot look smooth. * The middleware assumes that the entry point for HybridApp is the /transition route. */ -function HybridAppMiddleware({children, authenticated}: HybridAppMiddlewareProps) { - const {isSplashHidden, setIsSplashHidden} = useSplashScreen(); - const [startedTransition, setStartedTransition] = useState(false); - const [finishedTransition, setFinishedTransition] = useState(false); - - const initialURL = useContext(InitialURLContext); - const exitToParam = useExitTo(); - const [exitTo, setExitTo] = useState(); - - const [isAccountLoading] = useOnyx(ONYXKEYS.ACCOUNT, {selector: (account) => account?.isLoading ?? false}); - const [sessionEmail] = useOnyx(ONYXKEYS.SESSION, {selector: (session) => session?.email}); +function HybridAppMiddleware({children}: HybridAppMiddlewareProps) { + const {setIsSplashHidden} = useSplashScreen(); const [completedHybridAppOnboarding] = useOnyx(ONYXKEYS.NVP_TRYNEWDOT, {selector: onboardingStatusSelector}); - const maxTimeoutRef = useRef(null); - - // We need to ensure that the BootSplash is always hidden after a certain period. - useEffect(() => { - if (!NativeModules.HybridAppModule) { - return; - } - - maxTimeoutRef.current = setTimeout(() => { - Log.info('[HybridApp] Forcing transition due to unknown problem', true); - setStartedTransition(true); - setExitTo(ROUTES.HOME); - }, 3000); - }, []); /** * This useEffect tracks changes of `nvp_tryNewDot` value. * We propagate it from OldDot to NewDot with native method due to limitations of old app. @@ -95,9 +64,6 @@ function HybridAppMiddleware({children, authenticated}: HybridAppMiddlewareProps const listener = HybridAppEvents.addListener(CONST.EVENTS.ON_RETURN_TO_OLD_DOT, () => { Log.info('[HybridApp] `onReturnToOldDot` event received. Resetting state of HybridAppMiddleware', true); setIsSplashHidden(false); - setStartedTransition(false); - setFinishedTransition(false); - setExitTo(undefined); }); return () => { @@ -105,69 +71,6 @@ function HybridAppMiddleware({children, authenticated}: HybridAppMiddlewareProps }; }, [setIsSplashHidden]); - // Save `exitTo` when we reach /transition route. - // `exitTo` should always exist during OldDot -> NewDot transitions. - useEffect(() => { - if (!NativeModules.HybridAppModule || !exitToParam || exitTo) { - return; - } - - Log.info('[HybridApp] Saving `exitTo` for later', true, {exitTo: exitToParam}); - setExitTo(exitToParam); - - Log.info(`[HybridApp] Started transition`, true); - setStartedTransition(true); - }, [exitTo, exitToParam]); - - useEffect(() => { - if (!startedTransition || finishedTransition) { - return; - } - - const transitionURL = NativeModules.HybridAppModule ? `${CONST.DEEPLINK_BASE_URL}${initialURL ?? ''}` : initialURL; - const isLoggingInAsNewUser = SessionUtils.isLoggingInAsNewUser(transitionURL ?? undefined, sessionEmail); - - // We need to wait with navigating to exitTo until all login-related actions are complete. - if (!authenticated || isLoggingInAsNewUser || isAccountLoading) { - return; - } - - if (exitTo) { - Navigation.isNavigationReady().then(() => { - // We need to remove /transition from route history. - // `useExitTo` returns undefined for routes other than /transition. - if (exitToParam) { - Log.info('[HybridApp] Removing /transition route from history', true); - Navigation.goBack(); - } - - Log.info('[HybridApp] Navigating to `exitTo` route', true, {exitTo}); - Navigation.navigate(Navigation.parseHybridAppUrl(exitTo)); - setExitTo(undefined); - - setTimeout(() => { - Log.info('[HybridApp] Setting `finishedTransition` to true', true); - setFinishedTransition(true); - }, CONST.SCREEN_TRANSITION_END_TIMEOUT); - }); - } - }, [authenticated, exitTo, exitToParam, finishedTransition, initialURL, isAccountLoading, sessionEmail, startedTransition]); - - useEffect(() => { - if (!finishedTransition || isSplashHidden) { - return; - } - - Log.info('[HybridApp] Finished transition, hiding BootSplash', true); - BootSplash.hide().then(() => { - setIsSplashHidden(true); - if (authenticated) { - Log.info('[HybridApp] Handling onboarding flow', true); - Welcome.handleHybridAppOnboarding(); - } - }); - }, [authenticated, finishedTransition, isSplashHidden, setIsSplashHidden]); - return children; } diff --git a/src/components/HybridAppMiddleware/index.tsx b/src/components/HybridAppMiddleware/index.tsx index bb5d7803e52e..1ebe1347df8e 100644 --- a/src/components/HybridAppMiddleware/index.tsx +++ b/src/components/HybridAppMiddleware/index.tsx @@ -1,24 +1,13 @@ import type React from 'react'; -import {useContext, useEffect, useRef, useState} from 'react'; +import {useEffect} from 'react'; import {NativeModules} from 'react-native'; import {useOnyx} from 'react-native-onyx'; import type {OnyxEntry} from 'react-native-onyx'; -import {InitialURLContext} from '@components/InitialURLContextProvider'; -import useExitTo from '@hooks/useExitTo'; -import useSplashScreen from '@hooks/useSplashScreen'; -import BootSplash from '@libs/BootSplash'; import Log from '@libs/Log'; -import Navigation from '@libs/Navigation/Navigation'; -import * as SessionUtils from '@libs/SessionUtils'; -import * as Welcome from '@userActions/Welcome'; -import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import type {HybridAppRoute, Route} from '@src/ROUTES'; -import ROUTES from '@src/ROUTES'; import type {TryNewDot} from '@src/types/onyx'; type HybridAppMiddlewareProps = { - authenticated: boolean; children: React.ReactNode; }; @@ -37,33 +26,9 @@ const onboardingStatusSelector = (tryNewDot: OnyxEntry) => { * It is crucial to make transitions between OldDot and NewDot look smooth. * The middleware assumes that the entry point for HybridApp is the /transition route. */ -function HybridAppMiddleware({children, authenticated}: HybridAppMiddlewareProps) { - const {isSplashHidden, setIsSplashHidden} = useSplashScreen(); - const [startedTransition, setStartedTransition] = useState(false); - const [finishedTransition, setFinishedTransition] = useState(false); - - const initialURL = useContext(InitialURLContext); - const exitToParam = useExitTo(); - const [exitTo, setExitTo] = useState(); - - const [isAccountLoading] = useOnyx(ONYXKEYS.ACCOUNT, {selector: (account) => account?.isLoading ?? false}); - const [sessionEmail] = useOnyx(ONYXKEYS.SESSION, {selector: (session) => session?.email}); +function HybridAppMiddleware({children}: HybridAppMiddlewareProps) { const [completedHybridAppOnboarding] = useOnyx(ONYXKEYS.NVP_TRYNEWDOT, {selector: onboardingStatusSelector}); - const maxTimeoutRef = useRef(null); - - // We need to ensure that the BootSplash is always hidden after a certain period. - useEffect(() => { - if (!NativeModules.HybridAppModule) { - return; - } - - maxTimeoutRef.current = setTimeout(() => { - Log.info('[HybridApp] Forcing transition due to unknown problem', true); - setStartedTransition(true); - setExitTo(ROUTES.HOME); - }, 3000); - }, []); /** * This useEffect tracks changes of `nvp_tryNewDot` value. * We propagate it from OldDot to NewDot with native method due to limitations of old app. @@ -77,71 +42,6 @@ function HybridAppMiddleware({children, authenticated}: HybridAppMiddlewareProps NativeModules.HybridAppModule.completeOnboarding(completedHybridAppOnboarding); }, [completedHybridAppOnboarding]); - // Save `exitTo` when we reach /transition route. - // `exitTo` should always exist during OldDot -> NewDot transitions. - useEffect(() => { - if (!NativeModules.HybridAppModule || !exitToParam || exitTo) { - return; - } - - Log.info('[HybridApp] Saving `exitTo` for later', true, {exitTo: exitToParam}); - setExitTo(exitToParam); - - Log.info(`[HybridApp] Started transition`, true); - setStartedTransition(true); - }, [exitTo, exitToParam]); - - useEffect(() => { - if (!startedTransition || finishedTransition) { - return; - } - - const transitionURL = NativeModules.HybridAppModule ? `${CONST.DEEPLINK_BASE_URL}${initialURL ?? ''}` : initialURL; - const isLoggingInAsNewUser = SessionUtils.isLoggingInAsNewUser(transitionURL ?? undefined, sessionEmail); - - // We need to wait with navigating to exitTo until all login-related actions are complete. - if (!authenticated || isLoggingInAsNewUser || isAccountLoading) { - return; - } - - if (exitTo) { - Navigation.isNavigationReady().then(() => { - // We need to remove /transition from route history. - // `useExitTo` returns undefined for routes other than /transition. - if (exitToParam && Navigation.getActiveRoute().includes(ROUTES.TRANSITION_BETWEEN_APPS)) { - Log.info('[HybridApp] Removing /transition route from history', true); - Navigation.goBack(); - } - - if (exitTo !== ROUTES.HOME) { - Log.info('[HybridApp] Navigating to `exitTo` route', true, {exitTo}); - Navigation.navigate(Navigation.parseHybridAppUrl(exitTo)); - } - setExitTo(undefined); - - setTimeout(() => { - Log.info('[HybridApp] Setting `finishedTransition` to true', true); - setFinishedTransition(true); - }, CONST.SCREEN_TRANSITION_END_TIMEOUT); - }); - } - }, [authenticated, exitTo, exitToParam, finishedTransition, initialURL, isAccountLoading, sessionEmail, startedTransition]); - - useEffect(() => { - if (!finishedTransition || isSplashHidden) { - return; - } - - Log.info('[HybridApp] Finished transition, hiding BootSplash', true); - BootSplash.hide().then(() => { - setIsSplashHidden(true); - if (authenticated) { - Log.info('[HybridApp] Handling onboarding flow', true); - Welcome.handleHybridAppOnboarding(); - } - }); - }, [authenticated, finishedTransition, isSplashHidden, setIsSplashHidden]); - return children; } diff --git a/src/components/InitialURLContextProvider.tsx b/src/components/InitialURLContextProvider.tsx index be249051494d..93b5e7651d10 100644 --- a/src/components/InitialURLContextProvider.tsx +++ b/src/components/InitialURLContextProvider.tsx @@ -2,6 +2,8 @@ import React, {createContext, useEffect, useState} from 'react'; import type {ReactNode} from 'react'; import {Linking} from 'react-native'; import {signInWithOldDotData} from '@libs/actions/Session'; +import Log from '@libs/Log'; +import CONFIG from '@src/CONFIG'; import type {Route} from '@src/ROUTES'; /** Initial url that will be opened when NewDot is embedded into Hybrid App. */ @@ -17,11 +19,12 @@ type InitialURLContextProviderProps = { function setParamsInOnyx(urlToParse: string) { const requiredParams = ['email', 'authToken', 'encryptedAuthToken', 'accountID', 'autoGeneratedLogin', 'autoGeneratedPassword']; - const searchParams = new URL(urlToParse).searchParams; + const searchParams = new URL(urlToParse, CONFIG.EXPENSIFY.EXPENSIFY_URL).searchParams; const params = Object.fromEntries(requiredParams.map((param) => [param, searchParams.get(param)])); if (params.email && params.authToken && params.encryptedAuthToken && params.accountID && params.autoGeneratedLogin && params.autoGeneratedPassword) { + Log.info('[HybridApp] Saving data from transition in Onyx'); signInWithOldDotData(params.email, params.authToken, params.encryptedAuthToken, Number(params.accountID), params.autoGeneratedLogin, params.autoGeneratedPassword); } } @@ -30,14 +33,11 @@ function InitialURLContextProvider({children, url}: InitialURLContextProviderPro const [initialURL, setInitialURL] = useState(url); useEffect(() => { if (url) { - setInitialURL(url); setParamsInOnyx(url); + setInitialURL(url); return; } Linking.getInitialURL().then((initURL) => { - if (initURL) { - setParamsInOnyx(initURL); - } setInitialURL(initURL as Route); }); }, [url]); From 7f1c4e92f030c30d540c4b488f9ffba078486a86 Mon Sep 17 00:00:00 2001 From: Mateusz Rajski Date: Mon, 26 Aug 2024 16:07:04 +0200 Subject: [PATCH 03/33] Remove invalid prop from HybridAppMiddleware --- src/libs/Navigation/NavigationRoot.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/Navigation/NavigationRoot.tsx b/src/libs/Navigation/NavigationRoot.tsx index 152594ba6b3e..8812c2c0f428 100644 --- a/src/libs/Navigation/NavigationRoot.tsx +++ b/src/libs/Navigation/NavigationRoot.tsx @@ -181,7 +181,7 @@ function NavigationRoot({authenticated, lastVisitedPath, initialUrl, onReady, sh }} > {/* HybridAppMiddleware needs to have access to navigation ref and SplashScreenHidden context */} - + From 3173707fd8e82cbe92c32e7d8790ce326218e0d4 Mon Sep 17 00:00:00 2001 From: Mateusz Rajski Date: Fri, 30 Aug 2024 10:29:05 +0200 Subject: [PATCH 04/33] Clean up code --- src/components/InitialURLContextProvider.tsx | 18 ++---------------- src/libs/actions/Session/index.ts | 18 ++++++++++++++---- 2 files changed, 16 insertions(+), 20 deletions(-) diff --git a/src/components/InitialURLContextProvider.tsx b/src/components/InitialURLContextProvider.tsx index 93b5e7651d10..0b497a5d2a3c 100644 --- a/src/components/InitialURLContextProvider.tsx +++ b/src/components/InitialURLContextProvider.tsx @@ -1,9 +1,7 @@ import React, {createContext, useEffect, useState} from 'react'; import type {ReactNode} from 'react'; import {Linking} from 'react-native'; -import {signInWithOldDotData} from '@libs/actions/Session'; -import Log from '@libs/Log'; -import CONFIG from '@src/CONFIG'; +import {signInAfterTransitionFromOldDot} from '@libs/actions/Session'; import type {Route} from '@src/ROUTES'; /** Initial url that will be opened when NewDot is embedded into Hybrid App. */ @@ -17,23 +15,11 @@ type InitialURLContextProviderProps = { children: ReactNode; }; -function setParamsInOnyx(urlToParse: string) { - const requiredParams = ['email', 'authToken', 'encryptedAuthToken', 'accountID', 'autoGeneratedLogin', 'autoGeneratedPassword']; - const searchParams = new URL(urlToParse, CONFIG.EXPENSIFY.EXPENSIFY_URL).searchParams; - - const params = Object.fromEntries(requiredParams.map((param) => [param, searchParams.get(param)])); - - if (params.email && params.authToken && params.encryptedAuthToken && params.accountID && params.autoGeneratedLogin && params.autoGeneratedPassword) { - Log.info('[HybridApp] Saving data from transition in Onyx'); - signInWithOldDotData(params.email, params.authToken, params.encryptedAuthToken, Number(params.accountID), params.autoGeneratedLogin, params.autoGeneratedPassword); - } -} - function InitialURLContextProvider({children, url}: InitialURLContextProviderProps) { const [initialURL, setInitialURL] = useState(url); useEffect(() => { if (url) { - setParamsInOnyx(url); + signInAfterTransitionFromOldDot(url); setInitialURL(url); return; } diff --git a/src/libs/actions/Session/index.ts b/src/libs/actions/Session/index.ts index a4a0c770001e..318c087e03bb 100644 --- a/src/libs/actions/Session/index.ts +++ b/src/libs/actions/Session/index.ts @@ -459,9 +459,19 @@ function signUpUser() { API.write(WRITE_COMMANDS.SIGN_UP_USER, params, {optimisticData, successData, failureData}); } -function signInWithOldDotData(email: string, authToken: string, encryptedAuthToken: string, accountID: number, autoGeneratedLogin: string, autoGeneratedPassword: string) { - Onyx.set(ONYXKEYS.SESSION, {email, authToken, encryptedAuthToken, accountID}); - Onyx.set(ONYXKEYS.CREDENTIALS, {autoGeneratedLogin, autoGeneratedPassword}); +function signInAfterTransitionFromOldDot(transitionURL: string) { + const searchParams = new URL(transitionURL, CONFIG.EXPENSIFY.EXPENSIFY_URL).searchParams; + const searchParamsKeys = Array.from(searchParams.keys()); + + const {email, authToken, encryptedAuthToken, accountID, autoGeneratedLogin, autoGeneratedPassword} = Object.fromEntries( + searchParamsKeys.map((param: string) => [param, searchParams.get(param)]), + ); + + if (email && authToken && encryptedAuthToken && accountID && autoGeneratedLogin && autoGeneratedPassword) { + Log.info('[HybridApp] Saving data from transition in Onyx'); + Onyx.set(ONYXKEYS.SESSION, {email, authToken, encryptedAuthToken, accountID: Number(accountID)}); + Onyx.set(ONYXKEYS.CREDENTIALS, {autoGeneratedLogin, autoGeneratedPassword}); + } } /** @@ -1086,5 +1096,5 @@ export { isSupportAuthToken, hasStashedSession, signUpUser, - signInWithOldDotData, + signInAfterTransitionFromOldDot, }; From a9e3fef8592bbff06f057ceb50dc3981dcfe7184 Mon Sep 17 00:00:00 2001 From: war-in Date: Fri, 30 Aug 2024 11:23:44 +0200 Subject: [PATCH 05/33] clear onyx on new sign in --- src/App.tsx | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 98b5d4afeb1d..026472c730dd 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,8 +1,9 @@ import {PortalProvider} from '@gorhom/portal'; -import React from 'react'; +import React, {useState} from 'react'; import {LogBox} from 'react-native'; import {GestureHandlerRootView} from 'react-native-gesture-handler'; import {KeyboardProvider} from 'react-native-keyboard-controller'; +import Onyx from 'react-native-onyx'; import {PickerStateProvider} from 'react-native-picker-select'; import {SafeAreaProvider} from 'react-native-safe-area-context'; import '../wdyr'; @@ -36,6 +37,7 @@ import CONFIG from './CONFIG'; import Expensify from './Expensify'; import useDefaultDragAndDrop from './hooks/useDefaultDragAndDrop'; import {ReportIDsContextProvider} from './hooks/useReportIDs'; +import {KEYS_TO_PRESERVE} from './libs/actions/App'; import OnyxUpdateManager from './libs/actions/OnyxUpdateManager'; import {ReportAttachmentsProvider} from './pages/home/report/ReportAttachmentsContext'; import type {Route} from './ROUTES'; @@ -43,6 +45,9 @@ import type {Route} from './ROUTES'; type AppProps = { /** URL passed to our top-level React Native component by HybridApp. Will always be undefined in "pure" NewDot builds. */ url?: Route; + + /** Boolean passed to our top-level React Native component by HybridApp. Will always be undefined in "pure" NewDot builds. */ + newSignIn?: boolean; }; LogBox.ignoreLogs([ @@ -56,10 +61,16 @@ const fill = {flex: 1}; const StrictModeWrapper = CONFIG.USE_REACT_STRICT_MODE ? React.StrictMode : ({children}: {children: React.ReactElement}) => children; -function App({url}: AppProps) { +function App({url, newSignIn}: AppProps) { useDefaultDragAndDrop(); OnyxUpdateManager(); + const [shouldClearOnyx, setShouldClearOnyx] = useState(!!newSignIn); + if (shouldClearOnyx) { + setShouldClearOnyx(false); + Onyx.clear(KEYS_TO_PRESERVE); + } + return ( From 8dbf093e1833e91efd8abd430960638598e81f09 Mon Sep 17 00:00:00 2001 From: Mateusz Rajski Date: Fri, 30 Aug 2024 12:22:43 +0200 Subject: [PATCH 06/33] Refactor code and temporary do not propagate encryptedAuthToken --- src/libs/actions/Session/index.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/libs/actions/Session/index.ts b/src/libs/actions/Session/index.ts index 318c087e03bb..e33bef477855 100644 --- a/src/libs/actions/Session/index.ts +++ b/src/libs/actions/Session/index.ts @@ -460,16 +460,18 @@ function signUpUser() { } function signInAfterTransitionFromOldDot(transitionURL: string) { - const searchParams = new URL(transitionURL, CONFIG.EXPENSIFY.EXPENSIFY_URL).searchParams; - const searchParamsKeys = Array.from(searchParams.keys()); + const queryParams = transitionURL.split('?')[1]; - const {email, authToken, encryptedAuthToken, accountID, autoGeneratedLogin, autoGeneratedPassword} = Object.fromEntries( - searchParamsKeys.map((param: string) => [param, searchParams.get(param)]), + const {email, authToken, accountID, autoGeneratedLogin, autoGeneratedPassword} = Object.fromEntries( + queryParams.split('&').map((param) => { + const [key, value] = param.split('='); + return [key, value]; + }), ); - if (email && authToken && encryptedAuthToken && accountID && autoGeneratedLogin && autoGeneratedPassword) { + if (email && authToken && accountID && autoGeneratedLogin && autoGeneratedPassword) { Log.info('[HybridApp] Saving data from transition in Onyx'); - Onyx.set(ONYXKEYS.SESSION, {email, authToken, encryptedAuthToken, accountID: Number(accountID)}); + Onyx.set(ONYXKEYS.SESSION, {email, authToken, accountID: Number(accountID)}); Onyx.set(ONYXKEYS.CREDENTIALS, {autoGeneratedLogin, autoGeneratedPassword}); } } From fd8d79ed436487951e53162490d5bc68632fcf05 Mon Sep 17 00:00:00 2001 From: war-in Date: Fri, 30 Aug 2024 13:36:02 +0200 Subject: [PATCH 07/33] pass shouldClearOnyxOnStart in url --- src/App.tsx | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 026472c730dd..fa2b0c3d9882 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,5 +1,5 @@ import {PortalProvider} from '@gorhom/portal'; -import React, {useState} from 'react'; +import React, {useEffect} from 'react'; import {LogBox} from 'react-native'; import {GestureHandlerRootView} from 'react-native-gesture-handler'; import {KeyboardProvider} from 'react-native-keyboard-controller'; @@ -45,9 +45,6 @@ import type {Route} from './ROUTES'; type AppProps = { /** URL passed to our top-level React Native component by HybridApp. Will always be undefined in "pure" NewDot builds. */ url?: Route; - - /** Boolean passed to our top-level React Native component by HybridApp. Will always be undefined in "pure" NewDot builds. */ - newSignIn?: boolean; }; LogBox.ignoreLogs([ @@ -61,15 +58,18 @@ const fill = {flex: 1}; const StrictModeWrapper = CONFIG.USE_REACT_STRICT_MODE ? React.StrictMode : ({children}: {children: React.ReactElement}) => children; -function App({url, newSignIn}: AppProps) { +function App({url}: AppProps) { useDefaultDragAndDrop(); OnyxUpdateManager(); - const [shouldClearOnyx, setShouldClearOnyx] = useState(!!newSignIn); - if (shouldClearOnyx) { - setShouldClearOnyx(false); - Onyx.clear(KEYS_TO_PRESERVE); - } + useEffect(() => { + const params = new URLSearchParams(url); + const shouldClearOnyxOnStartParam = params.get('shouldClearOnyxOnStart'); + + if (shouldClearOnyxOnStartParam === 'true') { + Onyx.clear(KEYS_TO_PRESERVE); + } + }, [url]); return ( From 938b2b72163e63446599b6519dcb8c298a293c1d Mon Sep 17 00:00:00 2001 From: Mateusz Rajski Date: Fri, 30 Aug 2024 13:52:12 +0200 Subject: [PATCH 08/33] Change HybridApp BootSplash condition --- src/Expensify.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Expensify.tsx b/src/Expensify.tsx index b04a0f3ff056..0ead3ccf3e8e 100644 --- a/src/Expensify.tsx +++ b/src/Expensify.tsx @@ -1,7 +1,7 @@ import {Audio} from 'expo-av'; import React, {useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState} from 'react'; import type {NativeEventSubscription} from 'react-native'; -import {AppState, Linking, Platform} from 'react-native'; +import {AppState, Linking, NativeModules, Platform} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; import Onyx, {useOnyx, withOnyx} from 'react-native-onyx'; import ConfirmModal from './components/ConfirmModal'; @@ -302,8 +302,9 @@ function Expensify({ /> )} - {/* HybridApp has own middleware to hide SplashScreen */} - {shouldHideSplash && } + {!NativeModules.HybridAppModule && shouldHideSplash && } + {/* On HybridApp we want to hide BootSplash once we're authenticated */} + {NativeModules.HybridAppModule && isAuthenticated && shouldHideSplash && } ); } From 09ac53249b88ee316415b2a9e23dc100418dd1f2 Mon Sep 17 00:00:00 2001 From: war-in Date: Fri, 30 Aug 2024 14:29:21 +0200 Subject: [PATCH 09/33] fix signout button --- src/libs/actions/Session/index.ts | 2 +- src/pages/settings/ExitSurvey/ExitSurveyConfirmPage.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/actions/Session/index.ts b/src/libs/actions/Session/index.ts index b687abd61bb9..32809b2f7500 100644 --- a/src/libs/actions/Session/index.ts +++ b/src/libs/actions/Session/index.ts @@ -206,7 +206,7 @@ function signOutAndRedirectToSignIn(shouldResetToHome?: boolean, shouldStashSess if (!isAnonymousUser()) { // In the HybridApp, we want the Old Dot to handle the sign out process if (NativeModules.HybridAppModule && killHybridApp) { - NativeModules.HybridAppModule.closeReactNativeApp(true); + NativeModules.HybridAppModule.closeReactNativeApp(true, false); return; } // We'll only call signOut if we're not stashing the session and this is not a supportal session, diff --git a/src/pages/settings/ExitSurvey/ExitSurveyConfirmPage.tsx b/src/pages/settings/ExitSurvey/ExitSurveyConfirmPage.tsx index 2c9fa879dcfc..f6adfb9dc144 100644 --- a/src/pages/settings/ExitSurvey/ExitSurveyConfirmPage.tsx +++ b/src/pages/settings/ExitSurvey/ExitSurveyConfirmPage.tsx @@ -88,7 +88,7 @@ function ExitSurveyConfirmPage({exitReason, isLoading, route, navigation}: ExitS if (NativeModules.HybridAppModule) { promise.then(() => { Navigation.resetToHome(); - NativeModules.HybridAppModule.closeReactNativeApp(false); + NativeModules.HybridAppModule.closeReactNativeApp(false, true); }); return; } From e68f0074f34c8dbe03fa42a601399ad826e173a8 Mon Sep 17 00:00:00 2001 From: Mateusz Rajski Date: Fri, 30 Aug 2024 15:40:23 +0200 Subject: [PATCH 10/33] Use App.openApp on transition --- src/components/InitialURLContextProvider.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/components/InitialURLContextProvider.tsx b/src/components/InitialURLContextProvider.tsx index 0b497a5d2a3c..d58fae61d79d 100644 --- a/src/components/InitialURLContextProvider.tsx +++ b/src/components/InitialURLContextProvider.tsx @@ -2,6 +2,7 @@ import React, {createContext, useEffect, useState} from 'react'; import type {ReactNode} from 'react'; import {Linking} from 'react-native'; import {signInAfterTransitionFromOldDot} from '@libs/actions/Session'; +import * as App from '@userActions/App'; import type {Route} from '@src/ROUTES'; /** Initial url that will be opened when NewDot is embedded into Hybrid App. */ @@ -21,6 +22,7 @@ function InitialURLContextProvider({children, url}: InitialURLContextProviderPro if (url) { signInAfterTransitionFromOldDot(url); setInitialURL(url); + App.openApp(); return; } Linking.getInitialURL().then((initURL) => { From 4c305a6f2a868b6833689841ca0c6769ed693058 Mon Sep 17 00:00:00 2001 From: Mateusz Rajski Date: Fri, 30 Aug 2024 15:49:45 +0200 Subject: [PATCH 11/33] Fix openApp --- src/App.tsx | 12 ------------ src/components/InitialURLContextProvider.tsx | 2 -- src/libs/actions/Session/index.ts | 11 ++++++++++- 3 files changed, 10 insertions(+), 15 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index fa2b0c3d9882..cfedba110b2e 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,9 +1,7 @@ import {PortalProvider} from '@gorhom/portal'; -import React, {useEffect} from 'react'; import {LogBox} from 'react-native'; import {GestureHandlerRootView} from 'react-native-gesture-handler'; import {KeyboardProvider} from 'react-native-keyboard-controller'; -import Onyx from 'react-native-onyx'; import {PickerStateProvider} from 'react-native-picker-select'; import {SafeAreaProvider} from 'react-native-safe-area-context'; import '../wdyr'; @@ -37,7 +35,6 @@ import CONFIG from './CONFIG'; import Expensify from './Expensify'; import useDefaultDragAndDrop from './hooks/useDefaultDragAndDrop'; import {ReportIDsContextProvider} from './hooks/useReportIDs'; -import {KEYS_TO_PRESERVE} from './libs/actions/App'; import OnyxUpdateManager from './libs/actions/OnyxUpdateManager'; import {ReportAttachmentsProvider} from './pages/home/report/ReportAttachmentsContext'; import type {Route} from './ROUTES'; @@ -62,15 +59,6 @@ function App({url}: AppProps) { useDefaultDragAndDrop(); OnyxUpdateManager(); - useEffect(() => { - const params = new URLSearchParams(url); - const shouldClearOnyxOnStartParam = params.get('shouldClearOnyxOnStart'); - - if (shouldClearOnyxOnStartParam === 'true') { - Onyx.clear(KEYS_TO_PRESERVE); - } - }, [url]); - return ( diff --git a/src/components/InitialURLContextProvider.tsx b/src/components/InitialURLContextProvider.tsx index d58fae61d79d..0b497a5d2a3c 100644 --- a/src/components/InitialURLContextProvider.tsx +++ b/src/components/InitialURLContextProvider.tsx @@ -2,7 +2,6 @@ import React, {createContext, useEffect, useState} from 'react'; import type {ReactNode} from 'react'; import {Linking} from 'react-native'; import {signInAfterTransitionFromOldDot} from '@libs/actions/Session'; -import * as App from '@userActions/App'; import type {Route} from '@src/ROUTES'; /** Initial url that will be opened when NewDot is embedded into Hybrid App. */ @@ -22,7 +21,6 @@ function InitialURLContextProvider({children, url}: InitialURLContextProviderPro if (url) { signInAfterTransitionFromOldDot(url); setInitialURL(url); - App.openApp(); return; } Linking.getInitialURL().then((initURL) => { diff --git a/src/libs/actions/Session/index.ts b/src/libs/actions/Session/index.ts index 1dfeea6355f4..52814a1774c1 100644 --- a/src/libs/actions/Session/index.ts +++ b/src/libs/actions/Session/index.ts @@ -38,6 +38,7 @@ import * as SessionUtils from '@libs/SessionUtils'; import Timers from '@libs/Timers'; import {hideContextMenu} from '@pages/home/report/ContextMenu/ReportActionContextMenu'; import {KEYS_TO_PRESERVE, openApp} from '@userActions/App'; +import * as App from '@userActions/App'; import * as Device from '@userActions/Device'; import * as PriorityMode from '@userActions/PriorityMode'; import redirectToSignIn from '@userActions/SignInRedirect'; @@ -462,18 +463,26 @@ function signUpUser() { function signInAfterTransitionFromOldDot(transitionURL: string) { const queryParams = transitionURL.split('?')[1]; - const {email, authToken, accountID, autoGeneratedLogin, autoGeneratedPassword} = Object.fromEntries( + const {email, authToken, accountID, autoGeneratedLogin, autoGeneratedPassword, shouldClearOnyxOnStart} = Object.fromEntries( queryParams.split('&').map((param) => { const [key, value] = param.split('='); return [key, value]; }), ); + if (shouldClearOnyxOnStart === 'true') { + Onyx.clear(KEYS_TO_PRESERVE); + } + if (email && authToken && accountID && autoGeneratedLogin && autoGeneratedPassword) { Log.info('[HybridApp] Saving data from transition in Onyx'); Onyx.set(ONYXKEYS.SESSION, {email, authToken, accountID: Number(accountID)}); Onyx.set(ONYXKEYS.CREDENTIALS, {autoGeneratedLogin, autoGeneratedPassword}); } + + if (shouldClearOnyxOnStart === 'true') { + App.openApp(); + } } /** From 3acf03efeda698c9dc3c50b183668f110cf9764d Mon Sep 17 00:00:00 2001 From: Mateusz Rajski Date: Fri, 30 Aug 2024 15:51:11 +0200 Subject: [PATCH 12/33] Add React import --- src/App.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/App.tsx b/src/App.tsx index cfedba110b2e..98b5d4afeb1d 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,4 +1,5 @@ import {PortalProvider} from '@gorhom/portal'; +import React from 'react'; import {LogBox} from 'react-native'; import {GestureHandlerRootView} from 'react-native-gesture-handler'; import {KeyboardProvider} from 'react-native-keyboard-controller'; From c11189453aa9c0faac6a9cd8be25b0a4385b1131 Mon Sep 17 00:00:00 2001 From: Mateusz Rajski Date: Mon, 2 Sep 2024 15:36:09 +0200 Subject: [PATCH 13/33] Improve cache clearing logic --- src/libs/actions/Session/index.ts | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/libs/actions/Session/index.ts b/src/libs/actions/Session/index.ts index 52814a1774c1..6c821189e593 100644 --- a/src/libs/actions/Session/index.ts +++ b/src/libs/actions/Session/index.ts @@ -207,6 +207,7 @@ function signOutAndRedirectToSignIn(shouldResetToHome?: boolean, shouldStashSess if (!isAnonymousUser()) { // In the HybridApp, we want the Old Dot to handle the sign out process if (NativeModules.HybridAppModule && killHybridApp) { + Navigation.resetToHome(); NativeModules.HybridAppModule.closeReactNativeApp(true, false); return; } @@ -470,18 +471,17 @@ function signInAfterTransitionFromOldDot(transitionURL: string) { }), ); - if (shouldClearOnyxOnStart === 'true') { - Onyx.clear(KEYS_TO_PRESERVE); - } - - if (email && authToken && accountID && autoGeneratedLogin && autoGeneratedPassword) { - Log.info('[HybridApp] Saving data from transition in Onyx'); - Onyx.set(ONYXKEYS.SESSION, {email, authToken, accountID: Number(accountID)}); - Onyx.set(ONYXKEYS.CREDENTIALS, {autoGeneratedLogin, autoGeneratedPassword}); - } + const setSessionDataAndOpenApp = () => { + Onyx.multiSet({ + [ONYXKEYS.SESSION]: {email, authToken, accountID: Number(accountID)}, + [ONYXKEYS.CREDENTIALS]: {autoGeneratedLogin, autoGeneratedPassword}, + }).then(App.openApp); + }; if (shouldClearOnyxOnStart === 'true') { - App.openApp(); + Onyx.clear(KEYS_TO_PRESERVE).then(setSessionDataAndOpenApp); + } else { + setSessionDataAndOpenApp(); } } From 1e82645bc7064a5a0ac47ea7a47c38bce6608eb0 Mon Sep 17 00:00:00 2001 From: war-in Date: Mon, 2 Sep 2024 15:48:49 +0200 Subject: [PATCH 14/33] add splashScreenStateContext --- src/App.tsx | 85 ++++++++++--------- src/CONST.ts | 6 ++ src/Expensify.tsx | 50 ++++------- src/SplashScreenStateContext.tsx | 34 ++++++++ .../HybridAppMiddleware/index.ios.tsx | 8 +- src/components/InitialURLContextProvider.tsx | 5 +- src/components/Lottie/index.tsx | 7 +- src/hooks/useAutoFocusInput.ts | 10 +-- src/hooks/useSplashScreen.ts | 11 --- src/libs/actions/Session/index.ts | 8 +- .../BackgroundImage/index.ios.tsx | 6 +- 11 files changed, 126 insertions(+), 104 deletions(-) create mode 100644 src/SplashScreenStateContext.tsx delete mode 100644 src/hooks/useSplashScreen.ts diff --git a/src/App.tsx b/src/App.tsx index 28c22173efad..06ccdf596c55 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -38,6 +38,7 @@ import {ReportIDsContextProvider} from './hooks/useReportIDs'; import OnyxUpdateManager from './libs/actions/OnyxUpdateManager'; import {ReportAttachmentsProvider} from './pages/home/report/ReportAttachmentsContext'; import type {Route} from './ROUTES'; +import {SplashScreenStateContextProvider} from './SplashScreenStateContext'; type AppProps = { /** URL passed to our top-level React Native component by HybridApp. Will always be undefined in "pure" NewDot builds. */ @@ -64,47 +65,49 @@ function App({url}: AppProps) { return ( - - - - - - - - - - - - + + + + + + + + + + + + + + ); } diff --git a/src/CONST.ts b/src/CONST.ts index 48dff681560c..a418f5d48f58 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -5487,6 +5487,12 @@ const CONST = { REMOVE: 'remove', }, }, + + BOOT_SPLASH_STATE: { + OPENED: 1, + READY_TO_BE_HIDDEN: 2, + HIDDEN: 3, + }, } as const; type Country = keyof typeof CONST.ALL_COUNTRIES; diff --git a/src/Expensify.tsx b/src/Expensify.tsx index efdfce6caa40..656447247f07 100644 --- a/src/Expensify.tsx +++ b/src/Expensify.tsx @@ -1,5 +1,5 @@ import {Audio} from 'expo-av'; -import React, {useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState} from 'react'; +import React, {useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState} from 'react'; import type {NativeEventSubscription} from 'react-native'; import {AppState, Linking, NativeModules, Platform} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; @@ -42,6 +42,7 @@ import PopoverReportActionContextMenu from './pages/home/report/ContextMenu/Popo import * as ReportActionContextMenu from './pages/home/report/ContextMenu/ReportActionContextMenu'; import type {Route} from './ROUTES'; import ROUTES from './ROUTES'; +import SplashScreenStateContext from './SplashScreenStateContext'; import type {ScreenShareRequest} from './types/onyx'; Onyx.registerLogger(({level, message}) => { @@ -80,13 +81,6 @@ type ExpensifyOnyxProps = { type ExpensifyProps = ExpensifyOnyxProps; -// HybridApp needs access to SetStateAction in order to properly hide SplashScreen when React Native was booted before. -type SplashScreenHiddenContextType = {isSplashHidden?: boolean; setIsSplashHidden: React.Dispatch>}; - -const SplashScreenHiddenContext = React.createContext({ - setIsSplashHidden: () => {}, -}); - function Expensify({ isCheckingPublicRoom = true, updateAvailable, @@ -99,7 +93,7 @@ function Expensify({ const appStateChangeListener = useRef(null); const [isNavigationReady, setIsNavigationReady] = useState(false); const [isOnyxMigrated, setIsOnyxMigrated] = useState(false); - const [isSplashHidden, setIsSplashHidden] = useState(false); + const {splashScreenState, setSplashScreenState} = useContext(SplashScreenStateContext); const [hasAttemptedToOpenPublicRoom, setAttemptedToOpenPublicRoom] = useState(false); const {translate} = useLocalize(); const [account] = useOnyx(ONYXKEYS.ACCOUNT); @@ -127,7 +121,9 @@ function Expensify({ const autoAuthState = useMemo(() => session?.autoAuthState ?? '', [session]); const shouldInit = isNavigationReady && hasAttemptedToOpenPublicRoom; - const shouldHideSplash = shouldInit && !isSplashHidden; + const shouldHideSplash = + shouldInit && + (NativeModules.HybridAppModule ? splashScreenState === CONST.BOOT_SPLASH_STATE.READY_TO_BE_HIDDEN && isAuthenticated : splashScreenState === CONST.BOOT_SPLASH_STATE.OPENED); const initializeClient = () => { if (!Visibility.isVisible()) { @@ -145,17 +141,9 @@ function Expensify({ }, []); const onSplashHide = useCallback(() => { - setIsSplashHidden(true); + setSplashScreenState(CONST.BOOT_SPLASH_STATE.HIDDEN); Performance.markEnd(CONST.TIMING.SIDEBAR_LOADED); - }, []); - - const contextValue = useMemo( - () => ({ - isSplashHidden, - setIsSplashHidden, - }), - [isSplashHidden, setIsSplashHidden], - ); + }, [setSplashScreenState]); useLayoutEffect(() => { // Initialize this client as being an active client @@ -304,19 +292,15 @@ function Expensify({ {hasAttemptedToOpenPublicRoom && ( - - - + )} - {!NativeModules.HybridAppModule && shouldHideSplash && } - {/* On HybridApp we want to hide BootSplash once we're authenticated */} - {NativeModules.HybridAppModule && isAuthenticated && shouldHideSplash && } + {shouldHideSplash && } ); } @@ -350,5 +334,3 @@ export default withOnyx({ key: ONYXKEYS.LAST_VISITED_PATH, }, })(Expensify); - -export {SplashScreenHiddenContext}; diff --git a/src/SplashScreenStateContext.tsx b/src/SplashScreenStateContext.tsx new file mode 100644 index 000000000000..14b349e1b8bc --- /dev/null +++ b/src/SplashScreenStateContext.tsx @@ -0,0 +1,34 @@ +import React, {useContext, useMemo, useState} from 'react'; +import type {ValueOf} from 'type-fest'; +import CONST from './CONST'; +import type ChildrenProps from './types/utils/ChildrenProps'; + +type SplashScreenStateContextType = { + splashScreenState: ValueOf; + setSplashScreenState: React.Dispatch>>; +}; + +const SplashScreenStateContext = React.createContext({ + splashScreenState: CONST.BOOT_SPLASH_STATE.OPENED, + setSplashScreenState: () => {}, +}); + +function SplashScreenStateContextProvider({children}: ChildrenProps) { + const [splashScreenState, setSplashScreenState] = useState>(CONST.BOOT_SPLASH_STATE.OPENED); + const splashScreenStateContext = useMemo( + () => ({ + splashScreenState, + setSplashScreenState, + }), + [splashScreenState], + ); + + return {children}; +} + +function useSplashScreenStateContext() { + return useContext(SplashScreenStateContext); +} + +export default SplashScreenStateContext; +export {SplashScreenStateContextProvider, useSplashScreenStateContext}; diff --git a/src/components/HybridAppMiddleware/index.ios.tsx b/src/components/HybridAppMiddleware/index.ios.tsx index 494c0a6241fd..abcb0f2dca6d 100644 --- a/src/components/HybridAppMiddleware/index.ios.tsx +++ b/src/components/HybridAppMiddleware/index.ios.tsx @@ -4,10 +4,10 @@ import {NativeEventEmitter, NativeModules} from 'react-native'; import type {NativeModule} from 'react-native'; import {useOnyx} from 'react-native-onyx'; import type {OnyxEntry} from 'react-native-onyx'; -import useSplashScreen from '@hooks/useSplashScreen'; import Log from '@libs/Log'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; +import {useSplashScreenStateContext} from '@src/SplashScreenStateContext'; import type {TryNewDot} from '@src/types/onyx'; type HybridAppMiddlewareProps = { @@ -31,7 +31,7 @@ const onboardingStatusSelector = (tryNewDot: OnyxEntry) => { * The middleware assumes that the entry point for HybridApp is the /transition route. */ function HybridAppMiddleware({children}: HybridAppMiddlewareProps) { - const {setIsSplashHidden} = useSplashScreen(); + const {setSplashScreenState} = useSplashScreenStateContext(); const [completedHybridAppOnboarding] = useOnyx(ONYXKEYS.NVP_TRYNEWDOT, {selector: onboardingStatusSelector}); /** @@ -63,13 +63,13 @@ function HybridAppMiddleware({children}: HybridAppMiddlewareProps) { const HybridAppEvents = new NativeEventEmitter(NativeModules.HybridAppModule as unknown as NativeModule); const listener = HybridAppEvents.addListener(CONST.EVENTS.ON_RETURN_TO_OLD_DOT, () => { Log.info('[HybridApp] `onReturnToOldDot` event received. Resetting state of HybridAppMiddleware', true); - setIsSplashHidden(false); + setSplashScreenState(CONST.BOOT_SPLASH_STATE.OPENED); }); return () => { listener.remove(); }; - }, [setIsSplashHidden]); + }, [setSplashScreenState]); return children; } diff --git a/src/components/InitialURLContextProvider.tsx b/src/components/InitialURLContextProvider.tsx index 0b497a5d2a3c..0bb28293ccd6 100644 --- a/src/components/InitialURLContextProvider.tsx +++ b/src/components/InitialURLContextProvider.tsx @@ -3,6 +3,7 @@ import type {ReactNode} from 'react'; import {Linking} from 'react-native'; import {signInAfterTransitionFromOldDot} from '@libs/actions/Session'; import type {Route} from '@src/ROUTES'; +import {useSplashScreenStateContext} from '@src/SplashScreenStateContext'; /** Initial url that will be opened when NewDot is embedded into Hybrid App. */ const InitialURLContext = createContext(undefined); @@ -17,9 +18,11 @@ type InitialURLContextProviderProps = { function InitialURLContextProvider({children, url}: InitialURLContextProviderProps) { const [initialURL, setInitialURL] = useState(url); + const {setSplashScreenState} = useSplashScreenStateContext(); + useEffect(() => { if (url) { - signInAfterTransitionFromOldDot(url); + signInAfterTransitionFromOldDot(url, setSplashScreenState); setInitialURL(url); return; } diff --git a/src/components/Lottie/index.tsx b/src/components/Lottie/index.tsx index dd46b33a8400..7c85837644a2 100644 --- a/src/components/Lottie/index.tsx +++ b/src/components/Lottie/index.tsx @@ -6,8 +6,9 @@ import {View} from 'react-native'; import type DotLottieAnimation from '@components/LottieAnimations/types'; import useAppState from '@hooks/useAppState'; import useNetwork from '@hooks/useNetwork'; -import useSplashScreen from '@hooks/useSplashScreen'; import useThemeStyles from '@hooks/useThemeStyles'; +import CONST from '@src/CONST'; +import {useSplashScreenStateContext} from '@src/SplashScreenStateContext'; type Props = { source: DotLottieAnimation; @@ -15,7 +16,7 @@ type Props = { function Lottie({source, webStyle, ...props}: Props, ref: ForwardedRef) { const appState = useAppState(); - const {isSplashHidden} = useSplashScreen(); + const {splashScreenState} = useSplashScreenStateContext(); const styles = useThemeStyles(); const [isError, setIsError] = React.useState(false); @@ -33,7 +34,7 @@ function Lottie({source, webStyle, ...props}: Props, ref: ForwardedRef; } diff --git a/src/hooks/useAutoFocusInput.ts b/src/hooks/useAutoFocusInput.ts index 26f045ebd579..5509d3635299 100644 --- a/src/hooks/useAutoFocusInput.ts +++ b/src/hooks/useAutoFocusInput.ts @@ -1,10 +1,10 @@ import {useFocusEffect} from '@react-navigation/native'; -import {useCallback, useContext, useEffect, useRef, useState} from 'react'; +import {useCallback, useEffect, useRef, useState} from 'react'; import type {RefObject} from 'react'; import type {TextInput} from 'react-native'; import {InteractionManager} from 'react-native'; import CONST from '@src/CONST'; -import * as Expensify from '@src/Expensify'; +import {useSplashScreenStateContext} from '@src/SplashScreenStateContext'; type UseAutoFocusInput = { inputCallbackRef: (ref: TextInput | null) => void; @@ -15,13 +15,13 @@ export default function useAutoFocusInput(): UseAutoFocusInput { const [isInputInitialized, setIsInputInitialized] = useState(false); const [isScreenTransitionEnded, setIsScreenTransitionEnded] = useState(false); - const {isSplashHidden} = useContext(Expensify.SplashScreenHiddenContext); + const {splashScreenState} = useSplashScreenStateContext(); const inputRef = useRef(null); const focusTimeoutRef = useRef(null); useEffect(() => { - if (!isScreenTransitionEnded || !isInputInitialized || !inputRef.current || !isSplashHidden) { + if (!isScreenTransitionEnded || !isInputInitialized || !inputRef.current || splashScreenState !== CONST.BOOT_SPLASH_STATE.HIDDEN) { return; } const focusTaskHandle = InteractionManager.runAfterInteractions(() => { @@ -32,7 +32,7 @@ export default function useAutoFocusInput(): UseAutoFocusInput { return () => { focusTaskHandle.cancel(); }; - }, [isScreenTransitionEnded, isInputInitialized, isSplashHidden]); + }, [isScreenTransitionEnded, isInputInitialized, splashScreenState]); useFocusEffect( useCallback(() => { diff --git a/src/hooks/useSplashScreen.ts b/src/hooks/useSplashScreen.ts deleted file mode 100644 index 8838ac1289c7..000000000000 --- a/src/hooks/useSplashScreen.ts +++ /dev/null @@ -1,11 +0,0 @@ -import {useContext} from 'react'; -import {SplashScreenHiddenContext} from '@src/Expensify'; - -type SplashScreenHiddenContextType = {isSplashHidden: boolean; setIsSplashHidden: React.Dispatch>}; - -export default function useSplashScreen() { - const {isSplashHidden, setIsSplashHidden} = useContext(SplashScreenHiddenContext) as SplashScreenHiddenContextType; - return {isSplashHidden, setIsSplashHidden}; -} - -export type {SplashScreenHiddenContextType}; diff --git a/src/libs/actions/Session/index.ts b/src/libs/actions/Session/index.ts index 6c821189e593..538fd2355d39 100644 --- a/src/libs/actions/Session/index.ts +++ b/src/libs/actions/Session/index.ts @@ -461,7 +461,7 @@ function signUpUser() { API.write(WRITE_COMMANDS.SIGN_UP_USER, params, {optimisticData, successData, failureData}); } -function signInAfterTransitionFromOldDot(transitionURL: string) { +function signInAfterTransitionFromOldDot(transitionURL: string, setSplashScreenState: React.Dispatch>>) { const queryParams = transitionURL.split('?')[1]; const {email, authToken, accountID, autoGeneratedLogin, autoGeneratedPassword, shouldClearOnyxOnStart} = Object.fromEntries( @@ -479,8 +479,12 @@ function signInAfterTransitionFromOldDot(transitionURL: string) { }; if (shouldClearOnyxOnStart === 'true') { - Onyx.clear(KEYS_TO_PRESERVE).then(setSessionDataAndOpenApp); + Onyx.clear(KEYS_TO_PRESERVE).then(() => { + setSplashScreenState(CONST.BOOT_SPLASH_STATE.READY_TO_BE_HIDDEN); + setSessionDataAndOpenApp(); + }); } else { + setSplashScreenState(CONST.BOOT_SPLASH_STATE.READY_TO_BE_HIDDEN); setSessionDataAndOpenApp(); } } diff --git a/src/pages/signin/SignInPageLayout/BackgroundImage/index.ios.tsx b/src/pages/signin/SignInPageLayout/BackgroundImage/index.ios.tsx index 3aab8a003bc9..de9260dac537 100644 --- a/src/pages/signin/SignInPageLayout/BackgroundImage/index.ios.tsx +++ b/src/pages/signin/SignInPageLayout/BackgroundImage/index.ios.tsx @@ -4,10 +4,10 @@ import type {ImageSourcePropType} from 'react-native'; import Reanimated, {Easing, useAnimatedStyle, useSharedValue, withTiming} from 'react-native-reanimated'; import DesktopBackgroundImage from '@assets/images/home-background--desktop.svg'; import MobileBackgroundImage from '@assets/images/home-background--mobile-new.svg'; -import useSplashScreen from '@hooks/useSplashScreen'; import useStyleUtils from '@hooks/useStyleUtils'; import useThemeStyles from '@hooks/useThemeStyles'; import CONST from '@src/CONST'; +import {useSplashScreenStateContext} from '@src/SplashScreenStateContext'; import type BackgroundImageProps from './types'; function BackgroundImage({width, transitionDuration, isSmallScreen = false}: BackgroundImageProps) { @@ -26,10 +26,10 @@ function BackgroundImage({width, transitionDuration, isSmallScreen = false}: Bac }); } - const {isSplashHidden} = useSplashScreen(); + const {splashScreenState} = useSplashScreenStateContext(); // Prevent rendering the background image until the splash screen is hidden. // See issue: https://github.com/Expensify/App/issues/34696 - if (!isSplashHidden) { + if (splashScreenState !== CONST.BOOT_SPLASH_STATE.HIDDEN) { return; } From a3aa7556d9d66c9b13e99c3cef6f64cab5dda3c4 Mon Sep 17 00:00:00 2001 From: war-in Date: Mon, 2 Sep 2024 15:51:56 +0200 Subject: [PATCH 15/33] fix lint --- src/components/InitialURLContextProvider.tsx | 2 +- src/libs/actions/Session/index.ts | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/components/InitialURLContextProvider.tsx b/src/components/InitialURLContextProvider.tsx index 0bb28293ccd6..f3f9578a1ac5 100644 --- a/src/components/InitialURLContextProvider.tsx +++ b/src/components/InitialURLContextProvider.tsx @@ -29,7 +29,7 @@ function InitialURLContextProvider({children, url}: InitialURLContextProviderPro Linking.getInitialURL().then((initURL) => { setInitialURL(initURL as Route); }); - }, [url]); + }, [setSplashScreenState, url]); return {children}; } diff --git a/src/libs/actions/Session/index.ts b/src/libs/actions/Session/index.ts index 538fd2355d39..ab191e85fb05 100644 --- a/src/libs/actions/Session/index.ts +++ b/src/libs/actions/Session/index.ts @@ -480,11 +480,11 @@ function signInAfterTransitionFromOldDot(transitionURL: string, setSplashScreenS if (shouldClearOnyxOnStart === 'true') { Onyx.clear(KEYS_TO_PRESERVE).then(() => { - setSplashScreenState(CONST.BOOT_SPLASH_STATE.READY_TO_BE_HIDDEN); - setSessionDataAndOpenApp(); - }); + setSplashScreenState(CONST.BOOT_SPLASH_STATE.READY_TO_BE_HIDDEN); + setSessionDataAndOpenApp(); + }); } else { - setSplashScreenState(CONST.BOOT_SPLASH_STATE.READY_TO_BE_HIDDEN); + setSplashScreenState(CONST.BOOT_SPLASH_STATE.READY_TO_BE_HIDDEN); setSessionDataAndOpenApp(); } } From 320de61a509fbcae1ec5d2eba540b0be5b33b855 Mon Sep 17 00:00:00 2001 From: war-in Date: Mon, 2 Sep 2024 16:11:57 +0200 Subject: [PATCH 16/33] move ready to be hidden to InitialURLContextProvider --- src/components/InitialURLContextProvider.tsx | 4 +++- src/libs/actions/Session/index.ts | 8 ++------ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/components/InitialURLContextProvider.tsx b/src/components/InitialURLContextProvider.tsx index f3f9578a1ac5..01fbae7f3eb3 100644 --- a/src/components/InitialURLContextProvider.tsx +++ b/src/components/InitialURLContextProvider.tsx @@ -2,6 +2,7 @@ import React, {createContext, useEffect, useState} from 'react'; import type {ReactNode} from 'react'; import {Linking} from 'react-native'; import {signInAfterTransitionFromOldDot} from '@libs/actions/Session'; +import CONST from '@src/CONST'; import type {Route} from '@src/ROUTES'; import {useSplashScreenStateContext} from '@src/SplashScreenStateContext'; @@ -22,8 +23,9 @@ function InitialURLContextProvider({children, url}: InitialURLContextProviderPro useEffect(() => { if (url) { - signInAfterTransitionFromOldDot(url, setSplashScreenState); + signInAfterTransitionFromOldDot(url); setInitialURL(url); + setSplashScreenState(CONST.BOOT_SPLASH_STATE.READY_TO_BE_HIDDEN); return; } Linking.getInitialURL().then((initURL) => { diff --git a/src/libs/actions/Session/index.ts b/src/libs/actions/Session/index.ts index ab191e85fb05..6c821189e593 100644 --- a/src/libs/actions/Session/index.ts +++ b/src/libs/actions/Session/index.ts @@ -461,7 +461,7 @@ function signUpUser() { API.write(WRITE_COMMANDS.SIGN_UP_USER, params, {optimisticData, successData, failureData}); } -function signInAfterTransitionFromOldDot(transitionURL: string, setSplashScreenState: React.Dispatch>>) { +function signInAfterTransitionFromOldDot(transitionURL: string) { const queryParams = transitionURL.split('?')[1]; const {email, authToken, accountID, autoGeneratedLogin, autoGeneratedPassword, shouldClearOnyxOnStart} = Object.fromEntries( @@ -479,12 +479,8 @@ function signInAfterTransitionFromOldDot(transitionURL: string, setSplashScreenS }; if (shouldClearOnyxOnStart === 'true') { - Onyx.clear(KEYS_TO_PRESERVE).then(() => { - setSplashScreenState(CONST.BOOT_SPLASH_STATE.READY_TO_BE_HIDDEN); - setSessionDataAndOpenApp(); - }); + Onyx.clear(KEYS_TO_PRESERVE).then(setSessionDataAndOpenApp); } else { - setSplashScreenState(CONST.BOOT_SPLASH_STATE.READY_TO_BE_HIDDEN); setSessionDataAndOpenApp(); } } From 01a93f0566525267f2ccb2a21c0e6ac3da1c881a Mon Sep 17 00:00:00 2001 From: war-in Date: Mon, 2 Sep 2024 16:33:42 +0200 Subject: [PATCH 17/33] opened -> visible --- src/CONST.ts | 2 +- src/Expensify.tsx | 2 +- src/SplashScreenStateContext.tsx | 4 ++-- src/components/HybridAppMiddleware/index.ios.tsx | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/CONST.ts b/src/CONST.ts index a418f5d48f58..689c4906f25a 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -5489,7 +5489,7 @@ const CONST = { }, BOOT_SPLASH_STATE: { - OPENED: 1, + VISIBLE: 1, READY_TO_BE_HIDDEN: 2, HIDDEN: 3, }, diff --git a/src/Expensify.tsx b/src/Expensify.tsx index 656447247f07..19e4bfa85af1 100644 --- a/src/Expensify.tsx +++ b/src/Expensify.tsx @@ -123,7 +123,7 @@ function Expensify({ const shouldInit = isNavigationReady && hasAttemptedToOpenPublicRoom; const shouldHideSplash = shouldInit && - (NativeModules.HybridAppModule ? splashScreenState === CONST.BOOT_SPLASH_STATE.READY_TO_BE_HIDDEN && isAuthenticated : splashScreenState === CONST.BOOT_SPLASH_STATE.OPENED); + (NativeModules.HybridAppModule ? splashScreenState === CONST.BOOT_SPLASH_STATE.READY_TO_BE_HIDDEN && isAuthenticated : splashScreenState === CONST.BOOT_SPLASH_STATE.VISIBLE); const initializeClient = () => { if (!Visibility.isVisible()) { diff --git a/src/SplashScreenStateContext.tsx b/src/SplashScreenStateContext.tsx index 14b349e1b8bc..90a858f70c42 100644 --- a/src/SplashScreenStateContext.tsx +++ b/src/SplashScreenStateContext.tsx @@ -9,12 +9,12 @@ type SplashScreenStateContextType = { }; const SplashScreenStateContext = React.createContext({ - splashScreenState: CONST.BOOT_SPLASH_STATE.OPENED, + splashScreenState: CONST.BOOT_SPLASH_STATE.VISIBLE, setSplashScreenState: () => {}, }); function SplashScreenStateContextProvider({children}: ChildrenProps) { - const [splashScreenState, setSplashScreenState] = useState>(CONST.BOOT_SPLASH_STATE.OPENED); + const [splashScreenState, setSplashScreenState] = useState>(CONST.BOOT_SPLASH_STATE.VISIBLE); const splashScreenStateContext = useMemo( () => ({ splashScreenState, diff --git a/src/components/HybridAppMiddleware/index.ios.tsx b/src/components/HybridAppMiddleware/index.ios.tsx index abcb0f2dca6d..0fb61fb9ad7a 100644 --- a/src/components/HybridAppMiddleware/index.ios.tsx +++ b/src/components/HybridAppMiddleware/index.ios.tsx @@ -63,7 +63,7 @@ function HybridAppMiddleware({children}: HybridAppMiddlewareProps) { const HybridAppEvents = new NativeEventEmitter(NativeModules.HybridAppModule as unknown as NativeModule); const listener = HybridAppEvents.addListener(CONST.EVENTS.ON_RETURN_TO_OLD_DOT, () => { Log.info('[HybridApp] `onReturnToOldDot` event received. Resetting state of HybridAppMiddleware', true); - setSplashScreenState(CONST.BOOT_SPLASH_STATE.OPENED); + setSplashScreenState(CONST.BOOT_SPLASH_STATE.VISIBLE); }); return () => { From 3b5e1eb1b2b2d4a2524a7b0b0cd2c316feb7ee19 Mon Sep 17 00:00:00 2001 From: war-in Date: Mon, 2 Sep 2024 17:00:30 +0200 Subject: [PATCH 18/33] remove unused `useExitTo` hook --- src/hooks/useExitTo.ts | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100644 src/hooks/useExitTo.ts diff --git a/src/hooks/useExitTo.ts b/src/hooks/useExitTo.ts deleted file mode 100644 index 74226453d3f6..000000000000 --- a/src/hooks/useExitTo.ts +++ /dev/null @@ -1,17 +0,0 @@ -import {findFocusedRoute, useNavigationState} from '@react-navigation/native'; -import type {PublicScreensParamList, RootStackParamList} from '@libs/Navigation/types'; -import SCREENS from '@src/SCREENS'; - -export default function useExitTo() { - const activeRouteParams = useNavigationState((state) => { - const focusedRoute = findFocusedRoute(state); - - if (focusedRoute?.name !== SCREENS.TRANSITION_BETWEEN_APPS) { - return undefined; - } - - return focusedRoute?.params as PublicScreensParamList[typeof SCREENS.TRANSITION_BETWEEN_APPS]; - }); - - return activeRouteParams?.exitTo; -} From c47905b5ed3eb4830ca648b63b686d812de0059b Mon Sep 17 00:00:00 2001 From: Mateusz Rajski Date: Mon, 2 Sep 2024 17:02:49 +0200 Subject: [PATCH 19/33] Allow to navigate to routes different than transition --- src/libs/Navigation/AppNavigator/index.native.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libs/Navigation/AppNavigator/index.native.tsx b/src/libs/Navigation/AppNavigator/index.native.tsx index 0da93237d617..e848979e6993 100644 --- a/src/libs/Navigation/AppNavigator/index.native.tsx +++ b/src/libs/Navigation/AppNavigator/index.native.tsx @@ -2,7 +2,6 @@ import React, {memo, useContext, useEffect} from 'react'; import {NativeModules} from 'react-native'; import {InitialURLContext} from '@components/InitialURLContextProvider'; import Navigation from '@libs/Navigation/Navigation'; -import ROUTES from '@src/ROUTES'; import type ReactComponentModule from '@src/types/utils/ReactComponentModule'; type AppNavigatorProps = { @@ -14,7 +13,7 @@ function AppNavigator({authenticated}: AppNavigatorProps) { const initUrl = useContext(InitialURLContext); useEffect(() => { - if (!NativeModules.HybridAppModule || !initUrl || !initUrl.includes(ROUTES.TRANSITION_BETWEEN_APPS)) { + if (!NativeModules.HybridAppModule || !initUrl) { return; } From 2b772d01cf725f8dd4be27bdc281df79338ade61 Mon Sep 17 00:00:00 2001 From: Mateusz Rajski Date: Mon, 2 Sep 2024 17:06:35 +0200 Subject: [PATCH 20/33] Do not reset home on SignOut --- src/libs/actions/Session/index.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libs/actions/Session/index.ts b/src/libs/actions/Session/index.ts index 6c821189e593..e417191627c4 100644 --- a/src/libs/actions/Session/index.ts +++ b/src/libs/actions/Session/index.ts @@ -207,7 +207,6 @@ function signOutAndRedirectToSignIn(shouldResetToHome?: boolean, shouldStashSess if (!isAnonymousUser()) { // In the HybridApp, we want the Old Dot to handle the sign out process if (NativeModules.HybridAppModule && killHybridApp) { - Navigation.resetToHome(); NativeModules.HybridAppModule.closeReactNativeApp(true, false); return; } From b052157364f8e9242f8b1d6f718dd1609b19595b Mon Sep 17 00:00:00 2001 From: war-in Date: Mon, 2 Sep 2024 18:15:40 +0200 Subject: [PATCH 21/33] fix initialUrl while OD -> ND --- src/components/InitialURLContextProvider.tsx | 4 ++-- src/libs/actions/Session/index.ts | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/components/InitialURLContextProvider.tsx b/src/components/InitialURLContextProvider.tsx index 01fbae7f3eb3..3aa041b64798 100644 --- a/src/components/InitialURLContextProvider.tsx +++ b/src/components/InitialURLContextProvider.tsx @@ -23,8 +23,8 @@ function InitialURLContextProvider({children, url}: InitialURLContextProviderPro useEffect(() => { if (url) { - signInAfterTransitionFromOldDot(url); - setInitialURL(url); + const route = signInAfterTransitionFromOldDot(url); + setInitialURL(route); setSplashScreenState(CONST.BOOT_SPLASH_STATE.READY_TO_BE_HIDDEN); return; } diff --git a/src/libs/actions/Session/index.ts b/src/libs/actions/Session/index.ts index e417191627c4..deb4f1c7fbc3 100644 --- a/src/libs/actions/Session/index.ts +++ b/src/libs/actions/Session/index.ts @@ -461,7 +461,7 @@ function signUpUser() { } function signInAfterTransitionFromOldDot(transitionURL: string) { - const queryParams = transitionURL.split('?')[1]; + const [route, queryParams] = transitionURL.split('?'); const {email, authToken, accountID, autoGeneratedLogin, autoGeneratedPassword, shouldClearOnyxOnStart} = Object.fromEntries( queryParams.split('&').map((param) => { @@ -482,6 +482,8 @@ function signInAfterTransitionFromOldDot(transitionURL: string) { } else { setSessionDataAndOpenApp(); } + + return route as Route; } /** From 2e955e9414a4cf83d3090e7b3e2f96324413a534 Mon Sep 17 00:00:00 2001 From: war-in Date: Tue, 3 Sep 2024 14:17:15 +0200 Subject: [PATCH 22/33] reintroduce onboarding --- src/Expensify.tsx | 10 ++++++++++ src/libs/Navigation/NavigationRoot.tsx | 3 ++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/Expensify.tsx b/src/Expensify.tsx index 19e4bfa85af1..31456242df32 100644 --- a/src/Expensify.tsx +++ b/src/Expensify.tsx @@ -20,6 +20,7 @@ import {updateLastRoute} from './libs/actions/App'; import * as EmojiPickerAction from './libs/actions/EmojiPickerAction'; import * as Report from './libs/actions/Report'; import * as User from './libs/actions/User'; +import {handleHybridAppOnboarding} from './libs/actions/Welcome'; import * as ActiveClientManager from './libs/ActiveClientManager'; import BootSplash from './libs/BootSplash'; import FS from './libs/Fullstory'; @@ -99,6 +100,7 @@ function Expensify({ const [account] = useOnyx(ONYXKEYS.ACCOUNT); const [session] = useOnyx(ONYXKEYS.SESSION); const [lastRoute] = useOnyx(ONYXKEYS.LAST_ROUTE); + const [tryNewDotData] = useOnyx(ONYXKEYS.NVP_TRYNEWDOT); const [shouldShowRequire2FAModal, setShouldShowRequire2FAModal] = useState(false); useEffect(() => { @@ -117,6 +119,14 @@ function Expensify({ setAttemptedToOpenPublicRoom(true); }, [isCheckingPublicRoom]); + useEffect(() => { + if (splashScreenState !== CONST.BOOT_SPLASH_STATE.HIDDEN || tryNewDotData === undefined) { + return; + } + + handleHybridAppOnboarding(); + }, [splashScreenState, tryNewDotData]); + const isAuthenticated = useMemo(() => !!(session?.authToken ?? null), [session]); const autoAuthState = useMemo(() => session?.autoAuthState ?? '', [session]); diff --git a/src/libs/Navigation/NavigationRoot.tsx b/src/libs/Navigation/NavigationRoot.tsx index 8812c2c0f428..a253b6f2316e 100644 --- a/src/libs/Navigation/NavigationRoot.tsx +++ b/src/libs/Navigation/NavigationRoot.tsx @@ -1,6 +1,7 @@ import type {NavigationState} from '@react-navigation/native'; import {DefaultTheme, findFocusedRoute, NavigationContainer} from '@react-navigation/native'; import React, {useContext, useEffect, useMemo, useRef} from 'react'; +import {NativeModules} from 'react-native'; import {useOnyx} from 'react-native-onyx'; import HybridAppMiddleware from '@components/HybridAppMiddleware'; import {ScrollOffsetContext} from '@components/ScrollOffsetContextProvider'; @@ -97,7 +98,7 @@ function NavigationRoot({authenticated, lastVisitedPath, initialUrl, onReady, sh // If the user haven't completed the flow, we want to always redirect them to the onboarding flow. // We also make sure that the user is authenticated. - if (!hasCompletedGuidedSetupFlow && authenticated && !shouldShowRequire2FAModal) { + if (!NativeModules.HybridAppModule && !hasCompletedGuidedSetupFlow && authenticated && !shouldShowRequire2FAModal) { const {adaptedState} = getAdaptedStateFromPath(ROUTES.ONBOARDING_ROOT.route, linkingConfig.config); return adaptedState; } From 620150b2885457499e4ef953358b35b8acc4ef0b Mon Sep 17 00:00:00 2001 From: Mateusz Rajski Date: Tue, 3 Sep 2024 14:46:48 +0200 Subject: [PATCH 23/33] Fallback to SessionExpiredPage on HybridApp instead of SignUp page --- .../Navigation/AppNavigator/PublicScreens.tsx | 4 +- src/pages/ErrorPage/SessionExpiredPage.tsx | 62 +++++++++++++++++++ .../LogInWithShortLivedAuthTokenPage.tsx | 37 +---------- 3 files changed, 67 insertions(+), 36 deletions(-) create mode 100644 src/pages/ErrorPage/SessionExpiredPage.tsx diff --git a/src/libs/Navigation/AppNavigator/PublicScreens.tsx b/src/libs/Navigation/AppNavigator/PublicScreens.tsx index faf6563a0ef3..cfd41a4b1fa0 100644 --- a/src/libs/Navigation/AppNavigator/PublicScreens.tsx +++ b/src/libs/Navigation/AppNavigator/PublicScreens.tsx @@ -1,7 +1,9 @@ import {createStackNavigator} from '@react-navigation/stack'; import React from 'react'; +import {NativeModules} from 'react-native'; import type {PublicScreensParamList} from '@navigation/types'; import ConnectionCompletePage from '@pages/ConnectionCompletePage'; +import SessionExpiredPage from '@pages/ErrorPage/SessionExpiredPage'; import LogInWithShortLivedAuthTokenPage from '@pages/LogInWithShortLivedAuthTokenPage'; import AppleSignInDesktopPage from '@pages/signin/AppleSignInDesktopPage'; import GoogleSignInDesktopPage from '@pages/signin/GoogleSignInDesktopPage'; @@ -22,7 +24,7 @@ function PublicScreens() { + + + + + {translate('deeplinkWrapper.launching')} + + + {translate('deeplinkWrapper.expired')}{' '} + { + if (!NativeModules.HybridAppModule) { + Session.clearSignInData(); + Navigation.navigate(); + return; + } + NativeModules.HybridAppModule.closeReactNativeApp(true, false); + }} + > + {translate('deeplinkWrapper.signIn')} + + + + + + + + + ); +} + +SessionExpiredPage.displayName = 'SessionExpiredPage'; + +export default SessionExpiredPage; diff --git a/src/pages/LogInWithShortLivedAuthTokenPage.tsx b/src/pages/LogInWithShortLivedAuthTokenPage.tsx index 6eb6a6cc7161..5a6e12412ad9 100644 --- a/src/pages/LogInWithShortLivedAuthTokenPage.tsx +++ b/src/pages/LogInWithShortLivedAuthTokenPage.tsx @@ -22,6 +22,7 @@ import type {Route} from '@src/ROUTES'; import ROUTES from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; import type {Account} from '@src/types/onyx'; +import SessionExpiredPage from './ErrorPage/SessionExpiredPage'; type LogInWithShortLivedAuthTokenPageOnyxProps = { /** The details about the account that the user is signing in with */ @@ -76,41 +77,7 @@ function LogInWithShortLivedAuthTokenPage({route, account}: LogInWithShortLivedA return ; } - return ( - - - - - - {translate('deeplinkWrapper.launching')} - - - {translate('deeplinkWrapper.expired')}{' '} - { - Session.clearSignInData(); - Navigation.navigate(); - }} - > - {translate('deeplinkWrapper.signIn')} - - - - - - - - - ); + return ; } LogInWithShortLivedAuthTokenPage.displayName = 'LogInWithShortLivedAuthTokenPage'; From 94f67273d747bc0e806a6ce6ee9f355c10e55ca8 Mon Sep 17 00:00:00 2001 From: Mateusz Rajski Date: Tue, 3 Sep 2024 17:22:04 +0200 Subject: [PATCH 24/33] Remove unused code --- src/pages/LogInWithShortLivedAuthTokenPage.tsx | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/src/pages/LogInWithShortLivedAuthTokenPage.tsx b/src/pages/LogInWithShortLivedAuthTokenPage.tsx index 5a6e12412ad9..fcbeadaa4a47 100644 --- a/src/pages/LogInWithShortLivedAuthTokenPage.tsx +++ b/src/pages/LogInWithShortLivedAuthTokenPage.tsx @@ -1,17 +1,9 @@ import type {StackScreenProps} from '@react-navigation/stack'; import React, {useEffect} from 'react'; -import {NativeModules, View} from 'react-native'; +import {NativeModules} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; import {withOnyx} from 'react-native-onyx'; import FullScreenLoadingIndicator from '@components/FullscreenLoadingIndicator'; -import Icon from '@components/Icon'; -import * as Expensicons from '@components/Icon/Expensicons'; -import * as Illustrations from '@components/Icon/Illustrations'; -import Text from '@components/Text'; -import TextLink from '@components/TextLink'; -import useLocalize from '@hooks/useLocalize'; -import useTheme from '@hooks/useTheme'; -import useThemeStyles from '@hooks/useThemeStyles'; import Log from '@libs/Log'; import Navigation from '@libs/Navigation/Navigation'; import type {PublicScreensParamList} from '@libs/Navigation/types'; @@ -32,9 +24,6 @@ type LogInWithShortLivedAuthTokenPageOnyxProps = { type LogInWithShortLivedAuthTokenPageProps = LogInWithShortLivedAuthTokenPageOnyxProps & StackScreenProps; function LogInWithShortLivedAuthTokenPage({route, account}: LogInWithShortLivedAuthTokenPageProps) { - const theme = useTheme(); - const styles = useThemeStyles(); - const {translate} = useLocalize(); const {email = '', shortLivedAuthToken = '', shortLivedToken = '', authTokenType, exitTo, error} = route?.params ?? {}; useEffect(() => { From af4aabda105b6d2477ada1d611f2eab21b512aca Mon Sep 17 00:00:00 2001 From: war-in Date: Tue, 3 Sep 2024 18:19:59 +0200 Subject: [PATCH 25/33] remove getVisibilityStatus --- __mocks__/react-native.ts | 2 -- src/Expensify.tsx | 35 +++++++++---------- .../ErrorBoundary/BaseErrorBoundary.tsx | 5 ++- src/libs/BootSplash/index.native.ts | 1 - src/libs/BootSplash/index.ts | 6 ---- src/libs/BootSplash/types.ts | 1 - 6 files changed, 20 insertions(+), 30 deletions(-) diff --git a/__mocks__/react-native.ts b/__mocks__/react-native.ts index 3deeabf6df2a..4c2a86818e9b 100644 --- a/__mocks__/react-native.ts +++ b/__mocks__/react-native.ts @@ -26,7 +26,6 @@ jest.doMock('react-native', () => { type ReactNativeMock = typeof ReactNative & { NativeModules: typeof ReactNative.NativeModules & { BootSplash: { - getVisibilityStatus: typeof BootSplash.getVisibilityStatus; hide: typeof BootSplash.hide; logoSizeRatio: number; navigationBarHeight: number; @@ -46,7 +45,6 @@ jest.doMock('react-native', () => { NativeModules: { ...ReactNative.NativeModules, BootSplash: { - getVisibilityStatus: jest.fn(), hide: jest.fn(), logoSizeRatio: 1, navigationBarHeight: 0, diff --git a/src/Expensify.tsx b/src/Expensify.tsx index 31456242df32..62e7839b21f0 100644 --- a/src/Expensify.tsx +++ b/src/Expensify.tsx @@ -22,7 +22,6 @@ import * as Report from './libs/actions/Report'; import * as User from './libs/actions/User'; import {handleHybridAppOnboarding} from './libs/actions/Welcome'; import * as ActiveClientManager from './libs/ActiveClientManager'; -import BootSplash from './libs/BootSplash'; import FS from './libs/Fullstory'; import * as Growl from './libs/Growl'; import Log from './libs/Log'; @@ -175,24 +174,22 @@ function Expensify({ useEffect(() => { setTimeout(() => { - BootSplash.getVisibilityStatus().then((status) => { - const appState = AppState.currentState; - Log.info('[BootSplash] splash screen status', false, {appState, status}); - - if (status === 'visible') { - const propsToLog: Omit = { - isCheckingPublicRoom, - updateRequired, - updateAvailable, - isSidebarLoaded, - screenShareRequest, - focusModeNotification, - isAuthenticated, - lastVisitedPath, - }; - Log.alert('[BootSplash] splash screen is still visible', {propsToLog}, false); - } - }); + const appState = AppState.currentState; + Log.info('[BootSplash] splash screen status', false, {appState, splashScreenState}); + + if (splashScreenState === CONST.BOOT_SPLASH_STATE.VISIBLE) { + const propsToLog: Omit = { + isCheckingPublicRoom, + updateRequired, + updateAvailable, + isSidebarLoaded, + screenShareRequest, + focusModeNotification, + isAuthenticated, + lastVisitedPath, + }; + Log.alert('[BootSplash] splash screen is still visible', {propsToLog}, false); + } }, 30 * 1000); // This timer is set in the native layer when launching the app and we stop it here so we can measure how long diff --git a/src/components/ErrorBoundary/BaseErrorBoundary.tsx b/src/components/ErrorBoundary/BaseErrorBoundary.tsx index 75f65a06a2e6..f56441316f7c 100644 --- a/src/components/ErrorBoundary/BaseErrorBoundary.tsx +++ b/src/components/ErrorBoundary/BaseErrorBoundary.tsx @@ -4,6 +4,7 @@ import BootSplash from '@libs/BootSplash'; import GenericErrorPage from '@pages/ErrorPage/GenericErrorPage'; import UpdateRequiredView from '@pages/ErrorPage/UpdateRequiredView'; import CONST from '@src/CONST'; +import {useSplashScreenStateContext} from '@src/SplashScreenStateContext'; import type {BaseErrorBoundaryProps, LogError} from './types'; /** @@ -14,10 +15,12 @@ import type {BaseErrorBoundaryProps, LogError} from './types'; function BaseErrorBoundary({logError = () => {}, errorMessage, children}: BaseErrorBoundaryProps) { const [errorContent, setErrorContent] = useState(''); + const {setSplashScreenState} = useSplashScreenStateContext(); + const catchError = (errorObject: Error, errorInfo: React.ErrorInfo) => { logError(errorMessage, errorObject, JSON.stringify(errorInfo)); // We hide the splash screen since the error might happened during app init - BootSplash.hide(); + BootSplash.hide().then(() => setSplashScreenState(CONST.BOOT_SPLASH_STATE.HIDDEN)); setErrorContent(errorObject.message); }; const updateRequired = errorContent === CONST.ERROR.UPDATE_REQUIRED; diff --git a/src/libs/BootSplash/index.native.ts b/src/libs/BootSplash/index.native.ts index 9d472aec4a96..3c1ccb2ce7ce 100644 --- a/src/libs/BootSplash/index.native.ts +++ b/src/libs/BootSplash/index.native.ts @@ -10,7 +10,6 @@ function hide(): Promise { export default { hide, - getVisibilityStatus: BootSplash.getVisibilityStatus, logoSizeRatio: BootSplash.logoSizeRatio || 1, navigationBarHeight: BootSplash.navigationBarHeight || 0, }; diff --git a/src/libs/BootSplash/index.ts b/src/libs/BootSplash/index.ts index 774c5f7b06ac..a859f545abca 100644 --- a/src/libs/BootSplash/index.ts +++ b/src/libs/BootSplash/index.ts @@ -1,5 +1,4 @@ import Log from '@libs/Log'; -import type {VisibilityStatus} from './types'; function resolveAfter(delay: number): Promise { return new Promise((resolve) => { @@ -25,13 +24,8 @@ function hide(): Promise { }); } -function getVisibilityStatus(): Promise { - return Promise.resolve(document.getElementById('splash') ? 'visible' : 'hidden'); -} - export default { hide, - getVisibilityStatus, logoSizeRatio: 1, navigationBarHeight: 0, }; diff --git a/src/libs/BootSplash/types.ts b/src/libs/BootSplash/types.ts index b50b5a3397aa..106535453ed8 100644 --- a/src/libs/BootSplash/types.ts +++ b/src/libs/BootSplash/types.ts @@ -4,7 +4,6 @@ type BootSplashModule = { logoSizeRatio: number; navigationBarHeight: number; hide: () => Promise; - getVisibilityStatus: () => Promise; }; export type {BootSplashModule, VisibilityStatus}; From ca8bfac94e7c0f301910951b1250b467f6ea219b Mon Sep 17 00:00:00 2001 From: war-in Date: Wed, 4 Sep 2024 10:51:14 +0200 Subject: [PATCH 26/33] rename BOOT_SPLASH_STATE values --- src/CONST.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/CONST.ts b/src/CONST.ts index 40593725de31..173c1de9a814 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -5495,9 +5495,9 @@ const CONST = { }, BOOT_SPLASH_STATE: { - VISIBLE: 1, - READY_TO_BE_HIDDEN: 2, - HIDDEN: 3, + VISIBLE: 'visible', + READY_TO_BE_HIDDEN: 'readyToBeHidden', + HIDDEN: `hidden`, }, CSV_IMPORT_COLUMNS: { From 9d431592c9cdbc49dc73f536ef84749b9fe76a28 Mon Sep 17 00:00:00 2001 From: war-in Date: Wed, 4 Sep 2024 12:31:13 +0200 Subject: [PATCH 27/33] reset initial url on return to OD --- src/components/InitialURLContextProvider.tsx | 25 ++++++++++++++++--- .../Navigation/AppNavigator/index.native.tsx | 8 +++--- src/libs/Navigation/AppNavigator/index.tsx | 8 +++--- src/pages/LogOutPreviousUserPage.tsx | 2 +- src/pages/settings/InitialSettingsPage.tsx | 5 +++- 5 files changed, 34 insertions(+), 14 deletions(-) diff --git a/src/components/InitialURLContextProvider.tsx b/src/components/InitialURLContextProvider.tsx index 3aa041b64798..85ad54ca6c94 100644 --- a/src/components/InitialURLContextProvider.tsx +++ b/src/components/InitialURLContextProvider.tsx @@ -1,4 +1,4 @@ -import React, {createContext, useEffect, useState} from 'react'; +import React, {createContext, useEffect, useMemo, useState} from 'react'; import type {ReactNode} from 'react'; import {Linking} from 'react-native'; import {signInAfterTransitionFromOldDot} from '@libs/actions/Session'; @@ -6,8 +6,16 @@ import CONST from '@src/CONST'; import type {Route} from '@src/ROUTES'; import {useSplashScreenStateContext} from '@src/SplashScreenStateContext'; +type InitialUrlContextType = { + initialURL: Route | undefined; + setInitialURL: React.Dispatch>; +}; + /** Initial url that will be opened when NewDot is embedded into Hybrid App. */ -const InitialURLContext = createContext(undefined); +const InitialURLContext = createContext({ + initialURL: undefined, + setInitialURL: () => {}, +}); type InitialURLContextProviderProps = { /** URL passed to our top-level React Native component by HybridApp. Will always be undefined in "pure" NewDot builds. */ @@ -18,7 +26,7 @@ type InitialURLContextProviderProps = { }; function InitialURLContextProvider({children, url}: InitialURLContextProviderProps) { - const [initialURL, setInitialURL] = useState(url); + const [initialURL, setInitialURL] = useState(url); const {setSplashScreenState} = useSplashScreenStateContext(); useEffect(() => { @@ -32,7 +40,16 @@ function InitialURLContextProvider({children, url}: InitialURLContextProviderPro setInitialURL(initURL as Route); }); }, [setSplashScreenState, url]); - return {children}; + + const initialUrlContext = useMemo( + () => ({ + initialURL, + setInitialURL, + }), + [initialURL], + ); + + return {children}; } InitialURLContextProvider.displayName = 'InitialURLContextProvider'; diff --git a/src/libs/Navigation/AppNavigator/index.native.tsx b/src/libs/Navigation/AppNavigator/index.native.tsx index e848979e6993..984ed8a2e46f 100644 --- a/src/libs/Navigation/AppNavigator/index.native.tsx +++ b/src/libs/Navigation/AppNavigator/index.native.tsx @@ -10,17 +10,17 @@ type AppNavigatorProps = { }; function AppNavigator({authenticated}: AppNavigatorProps) { - const initUrl = useContext(InitialURLContext); + const {initialURL} = useContext(InitialURLContext); useEffect(() => { - if (!NativeModules.HybridAppModule || !initUrl) { + if (!NativeModules.HybridAppModule || !initialURL) { return; } Navigation.isNavigationReady().then(() => { - Navigation.navigate(initUrl); + Navigation.navigate(initialURL); }); - }, [initUrl]); + }, [initialURL]); if (authenticated) { const AuthScreens = require('./AuthScreens').default; diff --git a/src/libs/Navigation/AppNavigator/index.tsx b/src/libs/Navigation/AppNavigator/index.tsx index e0f1dae94f62..1901a51563e9 100644 --- a/src/libs/Navigation/AppNavigator/index.tsx +++ b/src/libs/Navigation/AppNavigator/index.tsx @@ -14,17 +14,17 @@ type AppNavigatorProps = { }; function AppNavigator({authenticated}: AppNavigatorProps) { - const initUrl = useContext(InitialURLContext); + const {initialURL} = useContext(InitialURLContext); useEffect(() => { - if (!NativeModules.HybridAppModule || !initUrl || !initUrl.includes(ROUTES.TRANSITION_BETWEEN_APPS)) { + if (!NativeModules.HybridAppModule || !initialURL || !initialURL.includes(ROUTES.TRANSITION_BETWEEN_APPS)) { return; } Navigation.isNavigationReady().then(() => { - Navigation.navigate(initUrl); + Navigation.navigate(initialURL); }); - }, [initUrl]); + }, [initialURL]); if (authenticated) { // These are the protected screens and only accessible when an authToken is present diff --git a/src/pages/LogOutPreviousUserPage.tsx b/src/pages/LogOutPreviousUserPage.tsx index f5b96e2d57c5..deb95a576c3d 100644 --- a/src/pages/LogOutPreviousUserPage.tsx +++ b/src/pages/LogOutPreviousUserPage.tsx @@ -31,7 +31,7 @@ type LogOutPreviousUserPageProps = LogOutPreviousUserPageOnyxProps & StackScreen // // This component should not do any other navigation as that handled in App.setUpPoliciesAndNavigate function LogOutPreviousUserPage({session, route, isAccountLoading}: LogOutPreviousUserPageProps) { - const initialURL = useContext(InitialURLContext); + const {initialURL} = useContext(InitialURLContext); useEffect(() => { const sessionEmail = session?.email; diff --git a/src/pages/settings/InitialSettingsPage.tsx b/src/pages/settings/InitialSettingsPage.tsx index 230e81fbd859..eeacd56f8d5c 100755 --- a/src/pages/settings/InitialSettingsPage.tsx +++ b/src/pages/settings/InitialSettingsPage.tsx @@ -11,6 +11,7 @@ import AccountSwitcherSkeletonView from '@components/AccountSwitcherSkeletonView import ConfirmModal from '@components/ConfirmModal'; import Icon from '@components/Icon'; import * as Expensicons from '@components/Icon/Expensicons'; +import {InitialURLContext} from '@components/InitialURLContextProvider'; import MenuItem from '@components/MenuItem'; import {PressableWithFeedback} from '@components/Pressable'; import ScreenWrapper from '@components/ScreenWrapper'; @@ -104,6 +105,7 @@ function InitialSettingsPage({userWallet, bankAccountList, fundList, walletTerms const activeCentralPaneRoute = useActiveCentralPaneRoute(); const emojiCode = currentUserPersonalDetails?.status?.emojiCode ?? ''; const [allConnectionSyncProgresses] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_CONNECTION_SYNC_PROGRESS}`); + const {setInitialURL} = useContext(InitialURLContext); const [privateSubscription] = useOnyx(ONYXKEYS.NVP_PRIVATE_SUBSCRIPTION); const subscriptionPlan = useSubscriptionPlan(); @@ -149,6 +151,7 @@ function InitialSettingsPage({userWallet, bankAccountList, fundList, walletTerms ? { action: () => { NativeModules.HybridAppModule.closeReactNativeApp(false, true); + setInitialURL(undefined); }, } : { @@ -184,7 +187,7 @@ function InitialSettingsPage({userWallet, bankAccountList, fundList, walletTerms }; return defaultMenu; - }, [loginList, fundList, styles.accountSettingsSectionContainer, bankAccountList, userWallet?.errors, walletTerms?.errors]); + }, [loginList, fundList, styles.accountSettingsSectionContainer, bankAccountList, userWallet?.errors, walletTerms?.errors, setInitialURL]); /** * Retuns a list of menu items data for workspace section From f650f9bcac0c15b4cc98282f90fe6c350d3cd6a9 Mon Sep 17 00:00:00 2001 From: Mateusz Rajski Date: Wed, 4 Sep 2024 12:38:39 +0200 Subject: [PATCH 28/33] Change naming conventions --- src/libs/actions/Session/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/actions/Session/index.ts b/src/libs/actions/Session/index.ts index 16455e4be424..1d7e695fa2e3 100644 --- a/src/libs/actions/Session/index.ts +++ b/src/libs/actions/Session/index.ts @@ -464,7 +464,7 @@ function signUpUser() { function signInAfterTransitionFromOldDot(transitionURL: string) { const [route, queryParams] = transitionURL.split('?'); - const {email, authToken, accountID, autoGeneratedLogin, autoGeneratedPassword, shouldClearOnyxOnStart} = Object.fromEntries( + const {email, authToken, accountID, autoGeneratedLogin, autoGeneratedPassword, clearOnyxOnStart} = Object.fromEntries( queryParams.split('&').map((param) => { const [key, value] = param.split('='); return [key, value]; @@ -478,7 +478,7 @@ function signInAfterTransitionFromOldDot(transitionURL: string) { }).then(App.openApp); }; - if (shouldClearOnyxOnStart === 'true') { + if (clearOnyxOnStart === 'true') { Onyx.clear(KEYS_TO_PRESERVE).then(setSessionDataAndOpenApp); } else { setSessionDataAndOpenApp(); From 6ecbb5e41d4a399c9c0f1b76eb04fe25eac74898 Mon Sep 17 00:00:00 2001 From: Mateusz Rajski Date: Wed, 4 Sep 2024 15:27:01 +0200 Subject: [PATCH 29/33] Redact sensitive data logs --- .../react-native+0.75.2+016+hybrid-app.patch | 26954 ++++++++++++++++ 1 file changed, 26954 insertions(+) diff --git a/patches/react-native+0.75.2+016+hybrid-app.patch b/patches/react-native+0.75.2+016+hybrid-app.patch index 43c432191ebe..8ba33f01b7d7 100644 --- a/patches/react-native+0.75.2+016+hybrid-app.patch +++ b/patches/react-native+0.75.2+016+hybrid-app.patch @@ -1,3 +1,26957 @@ +diff --git a/node_modules/react-native/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/node_modules/react-native/.gradle/buildOutputCleanup/buildOutputCleanup.lock +new file mode 100644 +index 0000000..a403fbb +Binary files /dev/null and b/node_modules/react-native/.gradle/buildOutputCleanup/buildOutputCleanup.lock differ +diff --git a/node_modules/react-native/.gradle/buildOutputCleanup/cache.properties b/node_modules/react-native/.gradle/buildOutputCleanup/cache.properties +new file mode 100644 +index 0000000..17fb517 +--- /dev/null ++++ b/node_modules/react-native/.gradle/buildOutputCleanup/cache.properties +@@ -0,0 +1,2 @@ ++#Wed Sep 04 14:07:41 CEST 2024 ++gradle.version=8.8 +diff --git a/node_modules/react-native/.project b/node_modules/react-native/.project +new file mode 100644 +index 0000000..dacc2de +--- /dev/null ++++ b/node_modules/react-native/.project +@@ -0,0 +1,28 @@ ++ ++ ++ react-native-build-from-source-react-native ++ Project react-native-build-from-source-react-native created by Buildship. ++ ++ ++ ++ ++ org.eclipse.buildship.core.gradleprojectbuilder ++ ++ ++ ++ ++ ++ org.eclipse.buildship.core.gradleprojectnature ++ ++ ++ ++ 1724676428902 ++ ++ 30 ++ ++ org.eclipse.core.resources.regexFilterMatcher ++ node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ ++ ++ ++ ++ +diff --git a/node_modules/react-native/Libraries/ReactNative/AppRegistry.js b/node_modules/react-native/Libraries/ReactNative/AppRegistry.js +index 68bd389..4d1925e 100644 +--- a/node_modules/react-native/Libraries/ReactNative/AppRegistry.js ++++ b/node_modules/react-native/Libraries/ReactNative/AppRegistry.js +@@ -232,12 +232,31 @@ const AppRegistry = { + appParameters: Object, + displayMode?: number, + ): void { ++ const redactAppParameters = (parameters) => { ++ const initialProps = parameters['initialProps']; ++ const url = initialProps['url']; ++ ++ if(!url) { ++ return parameters; ++ } ++ ++ const sensitiveParams = ['authToken', 'autoGeneratedPassword', 'autoGeneratedLogin']; ++ const [urlBase, queryString] = url.split('?'); ++ ++ if (!queryString) { ++ return parameters; ++ } ++ ++ const redactedSearchParams = [...new URLSearchParams(queryString).entries()].map(([key, value]) => `${key}=${sensitiveParams.includes(key) ? '' : value}`); ++ return {...parameters, initialProps: {...initialProps, url: `${urlBase}?${redactedSearchParams.join('&')}`}}; ++ } ++ + if (appKey !== 'LogBox') { + const msg = + 'Updating props for Surface "' + + appKey + + '" with ' + +- JSON.stringify(appParameters); ++ JSON.stringify(redactAppParameters(appParameters)); + infoLog(msg); + BugReporting.addSource( + 'AppRegistry.setSurfaceProps' + runCount++, +diff --git a/node_modules/react-native/React/Fabric/RCTThirdPartyFabricComponentsProvider.h b/node_modules/react-native/React/Fabric/RCTThirdPartyFabricComponentsProvider.h +new file mode 100644 +index 0000000..b9aa690 +--- /dev/null ++++ b/node_modules/react-native/React/Fabric/RCTThirdPartyFabricComponentsProvider.h +@@ -0,0 +1,218 @@ ++ ++/* ++ * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). ++ * ++ * Do not edit this file as changes may cause incorrect behavior and will be lost ++ * once the code is regenerated. ++ * ++ * @generated by GenerateRCTThirdPartyFabricComponentsProviderH ++ */ ++ ++#pragma GCC diagnostic push ++#pragma GCC diagnostic ignored "-Wreturn-type-c-linkage" ++ ++#import ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++Class RCTThirdPartyFabricComponentsProvider(const char *name); ++#if RCT_NEW_ARCH_ENABLED ++#ifndef RCT_DYNAMIC_FRAMEWORKS ++ ++#if !TARGET_OS_OSX && !TARGET_OS_TV && !TARGET_OS_VISION ++Class MarkdownTextInputDecoratorViewCls(void) __attribute__((used)); // 0 ++#endif ++ ++#if !TARGET_OS_OSX && !TARGET_OS_TV && !TARGET_OS_VISION ++ ++#endif ++ ++#if !TARGET_OS_OSX && !TARGET_OS_TV && !TARGET_OS_VISION ++ ++#endif ++ ++#if !TARGET_OS_OSX && !TARGET_OS_TV && !TARGET_OS_VISION ++ ++#endif ++ ++ ++#if !TARGET_OS_OSX && !TARGET_OS_TV && !TARGET_OS_VISION ++ ++#endif ++ ++#if !TARGET_OS_VISION ++ ++#endif ++ ++#if !TARGET_OS_VISION ++Class RNCPickerCls(void) __attribute__((used)); // 7 ++#endif ++ ++#if !TARGET_OS_OSX && !TARGET_OS_TV && !TARGET_OS_VISION ++Class RNMBXAtmosphereCls(void) __attribute__((used)); // 8 ++Class RNMBXBackgroundLayerCls(void) __attribute__((used)); // 8 ++Class RNMBXCalloutCls(void) __attribute__((used)); // 8 ++Class RNMBXCameraCls(void) __attribute__((used)); // 8 ++Class RNMBXCircleLayerCls(void) __attribute__((used)); // 8 ++Class RNMBXCustomLocationProviderCls(void) __attribute__((used)); // 8 ++Class RNMBXFillExtrusionLayerCls(void) __attribute__((used)); // 8 ++Class RNMBXFillLayerCls(void) __attribute__((used)); // 8 ++Class RNMBXHeatmapLayerCls(void) __attribute__((used)); // 8 ++Class RNMBXImageCls(void) __attribute__((used)); // 8 ++Class RNMBXImagesCls(void) __attribute__((used)); // 8 ++Class RNMBXImageSourceCls(void) __attribute__((used)); // 8 ++Class RNMBXLightCls(void) __attribute__((used)); // 8 ++Class RNMBXLineLayerCls(void) __attribute__((used)); // 8 ++Class RNMBXMapViewCls(void) __attribute__((used)); // 8 ++Class RNMBXMarkerViewContentCls(void) __attribute__((used)); // 8 ++Class RNMBXMarkerViewCls(void) __attribute__((used)); // 8 ++Class RNMBXModelLayerCls(void) __attribute__((used)); // 8 ++Class RNMBXModelsCls(void) __attribute__((used)); // 8 ++Class RNMBXNativeUserLocationCls(void) __attribute__((used)); // 8 ++Class RNMBXPointAnnotationCls(void) __attribute__((used)); // 8 ++Class RNMBXRasterDemSourceCls(void) __attribute__((used)); // 8 ++Class RNMBXRasterLayerCls(void) __attribute__((used)); // 8 ++Class RNMBXRasterSourceCls(void) __attribute__((used)); // 8 ++Class RNMBXShapeSourceCls(void) __attribute__((used)); // 8 ++Class RNMBXSkyLayerCls(void) __attribute__((used)); // 8 ++Class RNMBXStyleImportCls(void) __attribute__((used)); // 8 ++Class RNMBXSymbolLayerCls(void) __attribute__((used)); // 8 ++Class RNMBXTerrainCls(void) __attribute__((used)); // 8 ++Class RNMBXVectorSourceCls(void) __attribute__((used)); // 8 ++Class RNMBXViewportCls(void) __attribute__((used)); // 8 ++#endif ++ ++#if !TARGET_OS_OSX && !TARGET_OS_VISION ++Class AutoLayoutViewCls(void) __attribute__((used)); // 9 ++Class CellContainerCls(void) __attribute__((used)); // 9 ++#endif ++ ++#if !TARGET_OS_OSX && !TARGET_OS_TV && !TARGET_OS_VISION ++Class RTNAirshipMessageViewCls(void) __attribute__((used)); // 10 ++#endif ++ ++#if !TARGET_OS_OSX && !TARGET_OS_TV && !TARGET_OS_VISION ++Class RTNAirshipMessageViewCls(void) __attribute__((used)); // 11 ++#endif ++ ++#if !TARGET_OS_VISION ++Class LottieAnimationViewCls(void) __attribute__((used)); // 12 ++#endif ++ ++#if !TARGET_OS_OSX && !TARGET_OS_TV && !TARGET_OS_VISION ++ ++#endif ++ ++#if !TARGET_OS_OSX && !TARGET_OS_VISION ++ ++#endif ++ ++#if !TARGET_OS_OSX && !TARGET_OS_VISION ++ ++#endif ++ ++#if !TARGET_OS_OSX && !TARGET_OS_TV && !TARGET_OS_VISION ++ ++#endif ++ ++Class RNGestureHandlerButtonCls(void) __attribute__((used)); // 17 ++Class RNGestureHandlerRootViewCls(void) __attribute__((used)); // 17 ++#if !TARGET_OS_OSX && !TARGET_OS_TV && !TARGET_OS_VISION ++ ++#endif ++ ++#if !TARGET_OS_OSX && !TARGET_OS_TV && !TARGET_OS_VISION ++ ++#endif ++ ++ ++#if !TARGET_OS_OSX && !TARGET_OS_TV && !TARGET_OS_VISION ++Class KeyboardControllerViewCls(void) __attribute__((used)); // 21 ++#endif ++ ++#if !TARGET_OS_OSX && !TARGET_OS_TV ++Class LEGACY_RNCViewPagerCls(void) __attribute__((used)); // 22 ++Class RNCViewPagerCls(void) __attribute__((used)); // 22 ++#endif ++ ++#if !TARGET_OS_OSX && !TARGET_OS_VISION ++Class RNPDFPdfViewCls(void) __attribute__((used)); // 23 ++#endif ++ ++#if !TARGET_OS_OSX && !TARGET_OS_TV && !TARGET_OS_VISION ++ ++#endif ++ ++#if !TARGET_OS_OSX && !TARGET_OS_VISION ++ ++#endif ++ ++#if !TARGET_OS_OSX && !TARGET_OS_TV && !TARGET_OS_VISION ++Class PLKEmbeddedViewCls(void) __attribute__((used)); // 26 ++#endif ++ ++ ++#if !TARGET_OS_OSX ++Class RNCSafeAreaProviderCls(void) __attribute__((used)); // 28 ++Class RNCSafeAreaViewCls(void) __attribute__((used)); // 28 ++#endif ++ ++#if !TARGET_OS_OSX ++Class RNSFullWindowOverlayCls(void) __attribute__((used)); // 29 ++Class RNSModalScreenCls(void) __attribute__((used)); // 29 ++Class RNSScreenContainerCls(void) __attribute__((used)); // 29 ++Class RNSScreenCls(void) __attribute__((used)); // 29 ++Class RNSScreenNavigationContainerCls(void) __attribute__((used)); // 29 ++Class RNSScreenStackHeaderConfigCls(void) __attribute__((used)); // 29 ++Class RNSScreenStackHeaderSubviewCls(void) __attribute__((used)); // 29 ++Class RNSScreenStackCls(void) __attribute__((used)); // 29 ++Class RNSSearchBarCls(void) __attribute__((used)); // 29 ++#endif ++ ++#if !TARGET_OS_OSX && !TARGET_OS_TV && !TARGET_OS_VISION ++ ++#endif ++ ++Class RNSVGCircleCls(void) __attribute__((used)); // 31 ++Class RNSVGClipPathCls(void) __attribute__((used)); // 31 ++Class RNSVGDefsCls(void) __attribute__((used)); // 31 ++Class RNSVGEllipseCls(void) __attribute__((used)); // 31 ++Class RNSVGFeColorMatrixCls(void) __attribute__((used)); // 31 ++Class RNSVGFilterCls(void) __attribute__((used)); // 31 ++Class RNSVGForeignObjectCls(void) __attribute__((used)); // 31 ++Class RNSVGGroupCls(void) __attribute__((used)); // 31 ++Class RNSVGImageCls(void) __attribute__((used)); // 31 ++Class RNSVGSvgViewCls(void) __attribute__((used)); // 31 ++Class RNSVGLinearGradientCls(void) __attribute__((used)); // 31 ++Class RNSVGLineCls(void) __attribute__((used)); // 31 ++Class RNSVGMarkerCls(void) __attribute__((used)); // 31 ++Class RNSVGMaskCls(void) __attribute__((used)); // 31 ++Class RNSVGPathCls(void) __attribute__((used)); // 31 ++Class RNSVGPatternCls(void) __attribute__((used)); // 31 ++Class RNSVGRadialGradientCls(void) __attribute__((used)); // 31 ++Class RNSVGRectCls(void) __attribute__((used)); // 31 ++Class RNSVGSymbolCls(void) __attribute__((used)); // 31 ++Class RNSVGTextCls(void) __attribute__((used)); // 31 ++Class RNSVGTextPathCls(void) __attribute__((used)); // 31 ++Class RNSVGTSpanCls(void) __attribute__((used)); // 31 ++Class RNSVGUseCls(void) __attribute__((used)); // 31 ++#if !TARGET_OS_OSX && !TARGET_OS_TV && !TARGET_OS_VISION ++Class CameraViewCls(void) __attribute__((used)); // 32 ++#endif ++ ++#if !TARGET_OS_TV && !TARGET_OS_VISION ++Class RNCWebViewCls(void) __attribute__((used)); // 33 ++#endif ++ ++ ++#endif ++#endif ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#pragma GCC diagnostic pop ++ +diff --git a/node_modules/react-native/React/Fabric/RCTThirdPartyFabricComponentsProvider.mm b/node_modules/react-native/React/Fabric/RCTThirdPartyFabricComponentsProvider.mm +new file mode 100644 +index 0000000..4cf41d7 +--- /dev/null ++++ b/node_modules/react-native/React/Fabric/RCTThirdPartyFabricComponentsProvider.mm +@@ -0,0 +1,298 @@ ++ ++/** ++ * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). ++ * ++ * Do not edit this file as changes may cause incorrect behavior and will be lost ++ * once the code is regenerated. ++ * ++ * @generated by GenerateRCTThirdPartyFabricComponentsProviderCpp ++ */ ++ ++// OSS-compatibility layer ++ ++#import "RCTThirdPartyFabricComponentsProvider.h" ++ ++#import ++#import ++ ++Class RCTThirdPartyFabricComponentsProvider(const char *name) { ++ static std::unordered_map sFabricComponentsClassMap = { ++ #if RCT_NEW_ARCH_ENABLED ++ #ifndef RCT_DYNAMIC_FRAMEWORKS ++#if !TARGET_OS_OSX && !TARGET_OS_TV && !TARGET_OS_VISION ++ ++ {"MarkdownTextInputDecoratorView", MarkdownTextInputDecoratorViewCls}, // 0 ++#endif ++ ++#if !TARGET_OS_OSX && !TARGET_OS_TV && !TARGET_OS_VISION ++ ++#endif ++ ++#if !TARGET_OS_OSX && !TARGET_OS_TV && !TARGET_OS_VISION ++ ++#endif ++ ++#if !TARGET_OS_OSX && !TARGET_OS_TV && !TARGET_OS_VISION ++ ++#endif ++ ++ ++#if !TARGET_OS_OSX && !TARGET_OS_TV && !TARGET_OS_VISION ++ ++#endif ++ ++#if !TARGET_OS_VISION ++ ++#endif ++ ++#if !TARGET_OS_VISION ++ ++ {"RNCPicker", RNCPickerCls}, // 7 ++#endif ++ ++#if !TARGET_OS_OSX && !TARGET_OS_TV && !TARGET_OS_VISION ++ ++ {"RNMBXAtmosphere", RNMBXAtmosphereCls}, // 8 ++ ++ {"RNMBXBackgroundLayer", RNMBXBackgroundLayerCls}, // 8 ++ ++ {"RNMBXCallout", RNMBXCalloutCls}, // 8 ++ ++ {"RNMBXCamera", RNMBXCameraCls}, // 8 ++ ++ {"RNMBXCircleLayer", RNMBXCircleLayerCls}, // 8 ++ ++ {"RNMBXCustomLocationProvider", RNMBXCustomLocationProviderCls}, // 8 ++ ++ {"RNMBXFillExtrusionLayer", RNMBXFillExtrusionLayerCls}, // 8 ++ ++ {"RNMBXFillLayer", RNMBXFillLayerCls}, // 8 ++ ++ {"RNMBXHeatmapLayer", RNMBXHeatmapLayerCls}, // 8 ++ ++ {"RNMBXImage", RNMBXImageCls}, // 8 ++ ++ {"RNMBXImages", RNMBXImagesCls}, // 8 ++ ++ {"RNMBXImageSource", RNMBXImageSourceCls}, // 8 ++ ++ {"RNMBXLight", RNMBXLightCls}, // 8 ++ ++ {"RNMBXLineLayer", RNMBXLineLayerCls}, // 8 ++ ++ {"RNMBXMapView", RNMBXMapViewCls}, // 8 ++ ++ {"RNMBXMarkerViewContent", RNMBXMarkerViewContentCls}, // 8 ++ ++ {"RNMBXMarkerView", RNMBXMarkerViewCls}, // 8 ++ ++ {"RNMBXModelLayer", RNMBXModelLayerCls}, // 8 ++ ++ {"RNMBXModels", RNMBXModelsCls}, // 8 ++ ++ {"RNMBXNativeUserLocation", RNMBXNativeUserLocationCls}, // 8 ++ ++ {"RNMBXPointAnnotation", RNMBXPointAnnotationCls}, // 8 ++ ++ {"RNMBXRasterDemSource", RNMBXRasterDemSourceCls}, // 8 ++ ++ {"RNMBXRasterLayer", RNMBXRasterLayerCls}, // 8 ++ ++ {"RNMBXRasterSource", RNMBXRasterSourceCls}, // 8 ++ ++ {"RNMBXShapeSource", RNMBXShapeSourceCls}, // 8 ++ ++ {"RNMBXSkyLayer", RNMBXSkyLayerCls}, // 8 ++ ++ {"RNMBXStyleImport", RNMBXStyleImportCls}, // 8 ++ ++ {"RNMBXSymbolLayer", RNMBXSymbolLayerCls}, // 8 ++ ++ {"RNMBXTerrain", RNMBXTerrainCls}, // 8 ++ ++ {"RNMBXVectorSource", RNMBXVectorSourceCls}, // 8 ++ ++ {"RNMBXViewport", RNMBXViewportCls}, // 8 ++#endif ++ ++#if !TARGET_OS_OSX && !TARGET_OS_VISION ++ ++ {"AutoLayoutView", AutoLayoutViewCls}, // 9 ++ ++ {"CellContainer", CellContainerCls}, // 9 ++#endif ++ ++#if !TARGET_OS_OSX && !TARGET_OS_TV && !TARGET_OS_VISION ++ ++ {"RTNAirshipMessageView", RTNAirshipMessageViewCls}, // 10 ++#endif ++ ++#if !TARGET_OS_OSX && !TARGET_OS_TV && !TARGET_OS_VISION ++ ++ {"RTNAirshipMessageView", RTNAirshipMessageViewCls}, // 11 ++#endif ++ ++#if !TARGET_OS_VISION ++ ++ {"LottieAnimationView", LottieAnimationViewCls}, // 12 ++#endif ++ ++#if !TARGET_OS_OSX && !TARGET_OS_TV && !TARGET_OS_VISION ++ ++#endif ++ ++#if !TARGET_OS_OSX && !TARGET_OS_VISION ++ ++#endif ++ ++#if !TARGET_OS_OSX && !TARGET_OS_VISION ++ ++#endif ++ ++#if !TARGET_OS_OSX && !TARGET_OS_TV && !TARGET_OS_VISION ++ ++#endif ++ ++ ++ {"RNGestureHandlerButton", RNGestureHandlerButtonCls}, // 17 ++ ++ {"RNGestureHandlerRootView", RNGestureHandlerRootViewCls}, // 17 ++#if !TARGET_OS_OSX && !TARGET_OS_TV && !TARGET_OS_VISION ++ ++#endif ++ ++#if !TARGET_OS_OSX && !TARGET_OS_TV && !TARGET_OS_VISION ++ ++#endif ++ ++ ++#if !TARGET_OS_OSX && !TARGET_OS_TV && !TARGET_OS_VISION ++ ++ {"KeyboardControllerView", KeyboardControllerViewCls}, // 21 ++#endif ++ ++#if !TARGET_OS_OSX && !TARGET_OS_TV ++ ++ {"LEGACY_RNCViewPager", LEGACY_RNCViewPagerCls}, // 22 ++ ++ {"RNCViewPager", RNCViewPagerCls}, // 22 ++#endif ++ ++#if !TARGET_OS_OSX && !TARGET_OS_VISION ++ ++ {"RNPDFPdfView", RNPDFPdfViewCls}, // 23 ++#endif ++ ++#if !TARGET_OS_OSX && !TARGET_OS_TV && !TARGET_OS_VISION ++ ++#endif ++ ++#if !TARGET_OS_OSX && !TARGET_OS_VISION ++ ++#endif ++ ++#if !TARGET_OS_OSX && !TARGET_OS_TV && !TARGET_OS_VISION ++ ++ {"PLKEmbeddedView", PLKEmbeddedViewCls}, // 26 ++#endif ++ ++ ++#if !TARGET_OS_OSX ++ ++ {"RNCSafeAreaProvider", RNCSafeAreaProviderCls}, // 28 ++ ++ {"RNCSafeAreaView", RNCSafeAreaViewCls}, // 28 ++#endif ++ ++#if !TARGET_OS_OSX ++ ++ {"RNSFullWindowOverlay", RNSFullWindowOverlayCls}, // 29 ++ ++ {"RNSModalScreen", RNSModalScreenCls}, // 29 ++ ++ {"RNSScreenContainer", RNSScreenContainerCls}, // 29 ++ ++ {"RNSScreen", RNSScreenCls}, // 29 ++ ++ {"RNSScreenNavigationContainer", RNSScreenNavigationContainerCls}, // 29 ++ ++ {"RNSScreenStackHeaderConfig", RNSScreenStackHeaderConfigCls}, // 29 ++ ++ {"RNSScreenStackHeaderSubview", RNSScreenStackHeaderSubviewCls}, // 29 ++ ++ {"RNSScreenStack", RNSScreenStackCls}, // 29 ++ ++ {"RNSSearchBar", RNSSearchBarCls}, // 29 ++#endif ++ ++#if !TARGET_OS_OSX && !TARGET_OS_TV && !TARGET_OS_VISION ++ ++#endif ++ ++ ++ {"RNSVGCircle", RNSVGCircleCls}, // 31 ++ ++ {"RNSVGClipPath", RNSVGClipPathCls}, // 31 ++ ++ {"RNSVGDefs", RNSVGDefsCls}, // 31 ++ ++ {"RNSVGEllipse", RNSVGEllipseCls}, // 31 ++ ++ {"RNSVGFeColorMatrix", RNSVGFeColorMatrixCls}, // 31 ++ ++ {"RNSVGFilter", RNSVGFilterCls}, // 31 ++ ++ {"RNSVGForeignObject", RNSVGForeignObjectCls}, // 31 ++ ++ {"RNSVGGroup", RNSVGGroupCls}, // 31 ++ ++ {"RNSVGImage", RNSVGImageCls}, // 31 ++ ++ {"RNSVGSvgView", RNSVGSvgViewCls}, // 31 ++ ++ {"RNSVGLinearGradient", RNSVGLinearGradientCls}, // 31 ++ ++ {"RNSVGLine", RNSVGLineCls}, // 31 ++ ++ {"RNSVGMarker", RNSVGMarkerCls}, // 31 ++ ++ {"RNSVGMask", RNSVGMaskCls}, // 31 ++ ++ {"RNSVGPath", RNSVGPathCls}, // 31 ++ ++ {"RNSVGPattern", RNSVGPatternCls}, // 31 ++ ++ {"RNSVGRadialGradient", RNSVGRadialGradientCls}, // 31 ++ ++ {"RNSVGRect", RNSVGRectCls}, // 31 ++ ++ {"RNSVGSymbol", RNSVGSymbolCls}, // 31 ++ ++ {"RNSVGText", RNSVGTextCls}, // 31 ++ ++ {"RNSVGTextPath", RNSVGTextPathCls}, // 31 ++ ++ {"RNSVGTSpan", RNSVGTSpanCls}, // 31 ++ ++ {"RNSVGUse", RNSVGUseCls}, // 31 ++#if !TARGET_OS_OSX && !TARGET_OS_TV && !TARGET_OS_VISION ++ ++ {"CameraView", CameraViewCls}, // 32 ++#endif ++ ++#if !TARGET_OS_TV && !TARGET_OS_VISION ++ ++ {"RNCWebView", RNCWebViewCls}, // 33 ++#endif ++ ++ #endif ++ #endif ++ }; ++ ++ auto p = sFabricComponentsClassMap.find(name); ++ if (p != sFabricComponentsClassMap.end()) { ++ auto classFunc = p->second; ++ return classFunc(); ++ } ++ return nil; ++} +diff --git a/node_modules/react-native/ReactAndroid/.project b/node_modules/react-native/ReactAndroid/.project +new file mode 100644 +index 0000000..ae3e089 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/.project +@@ -0,0 +1,28 @@ ++ ++ ++ ReactAndroid ++ Project ReactAndroid created by Buildship. ++ ++ ++ ++ ++ org.eclipse.buildship.core.gradleprojectbuilder ++ ++ ++ ++ ++ ++ org.eclipse.buildship.core.gradleprojectnature ++ ++ ++ ++ 1724676428878 ++ ++ 30 ++ ++ org.eclipse.core.resources.regexFilterMatcher ++ node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ ++ ++ ++ ++ +diff --git a/node_modules/react-native/ReactAndroid/bin/.project b/node_modules/react-native/ReactAndroid/bin/.project +new file mode 100644 +index 0000000..86cee17 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/.project +@@ -0,0 +1,34 @@ ++ ++ ++ ReactAndroid ++ Project ReactAndroid created by Buildship. ++ ++ ++ ++ ++ org.eclipse.jdt.core.javabuilder ++ ++ ++ ++ ++ org.eclipse.buildship.core.gradleprojectbuilder ++ ++ ++ ++ ++ ++ org.eclipse.jdt.core.javanature ++ org.eclipse.buildship.core.gradleprojectnature ++ ++ ++ ++ 1724676428878 ++ ++ 30 ++ ++ org.eclipse.core.resources.regexFilterMatcher ++ node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ ++ ++ ++ ++ +diff --git a/node_modules/react-native/ReactAndroid/bin/README.md b/node_modules/react-native/ReactAndroid/bin/README.md +new file mode 100644 +index 0000000..54719f3 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/README.md +@@ -0,0 +1,8 @@ ++# Building React Native for Android ++ ++See the [Building from Source guide](https://reactnative.dev/contributing/how-to-build-from-source#prerequisites) on the React Native website. ++ ++# Running tests ++ ++When you submit a pull request CircleCI will automatically run all tests. ++To run tests locally, see [Testing guide](https://reactnative.dev/contributing/how-to-run-and-write-tests) on the React Native website. +diff --git a/node_modules/react-native/ReactAndroid/bin/cmake-utils/ReactNative-application.cmake b/node_modules/react-native/ReactAndroid/bin/cmake-utils/ReactNative-application.cmake +new file mode 100644 +index 0000000..de13935 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/cmake-utils/ReactNative-application.cmake +@@ -0,0 +1,159 @@ ++# 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. ++ ++# This CMake file takes care of creating everything you need to build and link ++# your C++ source code in a React Native Application for Android. ++# You just need to call `project()` and import this file. ++# Specifically this file will: ++# - Take care of creating a shared library called as your project ++# - Take care of setting the correct compile options ++# - Include all the pre-built libraries in your build graph ++# - Link your library against those prebuilt libraries so you can access JSI, Fabric, etc. ++# - Link your library against any autolinked library. ++# - Make sure ccache is used as part of the compilation process, if you have it installed. ++ ++cmake_minimum_required(VERSION 3.13) ++set(CMAKE_VERBOSE_MAKEFILE on) ++ ++include(${CMAKE_CURRENT_LIST_DIR}/folly-flags.cmake) ++ ++# We configured the REACT_COMMON_DIR variable as it's commonly used to reference ++# shared C++ code in other targets. ++set(REACT_COMMON_DIR ${REACT_ANDROID_DIR}/../ReactCommon) ++ ++# If you have ccache installed, we're going to honor it. ++find_program(CCACHE_FOUND ccache) ++if(CCACHE_FOUND) ++ set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache) ++ set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache) ++endif(CCACHE_FOUND) ++ ++set(BUILD_DIR ${PROJECT_BUILD_DIR}) ++if(CMAKE_HOST_WIN32) ++ string(REPLACE "\\" "/" BUILD_DIR ${BUILD_DIR}) ++endif() ++ ++file(GLOB input_SRC CONFIGURE_DEPENDS ++ *.cpp ++ ${BUILD_DIR}/generated/autolinking/src/main/jni/*.cpp) ++ ++add_library(${CMAKE_PROJECT_NAME} SHARED ${input_SRC}) ++ ++target_include_directories(${CMAKE_PROJECT_NAME} ++ PUBLIC ++ ${CMAKE_CURRENT_SOURCE_DIR} ++ ${PROJECT_BUILD_DIR}/generated/autolinking/src/main/jni) ++ ++target_compile_options(${CMAKE_PROJECT_NAME} ++ PRIVATE ++ -Wall ++ -Werror ++ # We suppress cpp #error and #warning to don't fail the build ++ # due to use migrating away from ++ # #include ++ # This can be removed for React Native 0.73 ++ -Wno-error=cpp ++ -fexceptions ++ -frtti ++ -std=c++20 ++ -DLOG_TAG=\"ReactNative\") ++ ++# Prefab packages from React Native ++find_package(ReactAndroid REQUIRED CONFIG) ++add_library(react_render_debug ALIAS ReactAndroid::react_render_debug) ++add_library(turbomodulejsijni ALIAS ReactAndroid::turbomodulejsijni) ++add_library(runtimeexecutor ALIAS ReactAndroid::runtimeexecutor) ++add_library(react_codegen_rncore ALIAS ReactAndroid::react_codegen_rncore) ++add_library(react_debug ALIAS ReactAndroid::react_debug) ++add_library(react_utils ALIAS ReactAndroid::react_utils) ++add_library(react_render_componentregistry ALIAS ReactAndroid::react_render_componentregistry) ++add_library(react_newarchdefaults ALIAS ReactAndroid::react_newarchdefaults) ++add_library(react_render_core ALIAS ReactAndroid::react_render_core) ++add_library(react_render_graphics ALIAS ReactAndroid::react_render_graphics) ++add_library(rrc_view ALIAS ReactAndroid::rrc_view) ++add_library(rrc_text ALIAS ReactAndroid::rrc_text) ++add_library(rrc_textinput ALIAS ReactAndroid::rrc_textinput) ++add_library(jsi ALIAS ReactAndroid::jsi) ++add_library(glog ALIAS ReactAndroid::glog) ++add_library(fabricjni ALIAS ReactAndroid::fabricjni) ++add_library(mapbufferjni ALIAS ReactAndroid::mapbufferjni) ++add_library(react_render_mapbuffer ALIAS ReactAndroid::react_render_mapbuffer) ++add_library(react_render_textlayoutmanager ALIAS ReactAndroid::react_render_textlayoutmanager) ++add_library(yoga ALIAS ReactAndroid::yoga) ++add_library(folly_runtime ALIAS ReactAndroid::folly_runtime) ++add_library(react_nativemodule_core ALIAS ReactAndroid::react_nativemodule_core) ++add_library(react_render_imagemanager ALIAS ReactAndroid::react_render_imagemanager) ++add_library(rrc_image ALIAS ReactAndroid::rrc_image) ++add_library(rrc_legacyviewmanagerinterop ALIAS ReactAndroid::rrc_legacyviewmanagerinterop) ++add_library(reactnativejni ALIAS ReactAndroid::reactnativejni) ++add_library(react_render_consistency ALIAS ReactAndroid::react_render_consistency) ++add_library(react_performance_timeline ALIAS ReactAndroid::react_performance_timeline) ++add_library(react_render_observers_events ALIAS ReactAndroid::react_render_observers_events) ++add_library(react_featureflags ALIAS ReactAndroid::react_featureflags) ++ ++find_package(fbjni REQUIRED CONFIG) ++add_library(fbjni ALIAS fbjni::fbjni) ++ ++target_link_libraries(${CMAKE_PROJECT_NAME} ++ fabricjni # prefab ready ++ mapbufferjni # prefab ready ++ fbjni # via 3rd party prefab ++ folly_runtime # prefab ready ++ glog # prefab ready ++ jsi # prefab ready ++ react_codegen_rncore # prefab ready ++ react_debug # prefab ready ++ react_utils # prefab ready ++ react_nativemodule_core # prefab ready ++ react_newarchdefaults # prefab ready ++ react_render_componentregistry # prefab ready ++ react_render_core # prefab ready ++ react_render_debug # prefab ready ++ react_render_graphics # prefab ready ++ react_render_imagemanager # prefab ready ++ react_render_mapbuffer # prefab ready ++ react_render_textlayoutmanager # prefab ready ++ rrc_image # prefab ready ++ rrc_view # prefab ready ++ rrc_text # prefab ready ++ rrc_textinput # prefab ready ++ rrc_legacyviewmanagerinterop # prefab ready ++ runtimeexecutor # prefab ready ++ turbomodulejsijni # prefab ready ++ yoga) # prefab ready ++ ++# We use an interface target to propagate flags to all the generated targets ++# such as the folly flags or others. ++add_library(common_flags INTERFACE) ++target_compile_options(common_flags INTERFACE ${folly_FLAGS}) ++target_link_libraries(ReactAndroid::react_codegen_rncore INTERFACE common_flags) ++ ++# If project is on RN CLI v9, then we can use the following lines to link against the autolinked 3rd party libraries. ++if(EXISTS ${PROJECT_BUILD_DIR}/generated/autolinking/src/main/jni/Android-autolinking.cmake) ++ include(${PROJECT_BUILD_DIR}/generated/autolinking/src/main/jni/Android-autolinking.cmake) ++ target_link_libraries(${CMAKE_PROJECT_NAME} ${AUTOLINKED_LIBRARIES}) ++ foreach(autolinked_library ${AUTOLINKED_LIBRARIES}) ++ target_link_libraries(${autolinked_library} common_flags) ++ endforeach() ++endif() ++ ++# If project is running codegen at the app level, we want to link and build the generated library. ++if(EXISTS ${PROJECT_BUILD_DIR}/generated/source/codegen/jni/CMakeLists.txt) ++ add_subdirectory(${PROJECT_BUILD_DIR}/generated/source/codegen/jni/ codegen_app_build) ++ get_property(APP_CODEGEN_TARGET DIRECTORY ${PROJECT_BUILD_DIR}/generated/source/codegen/jni/ PROPERTY BUILDSYSTEM_TARGETS) ++ target_link_libraries(${CMAKE_PROJECT_NAME} ${APP_CODEGEN_TARGET}) ++ target_link_libraries(${APP_CODEGEN_TARGET} common_flags) ++ ++ # We need to pass the generated header and module provider to the OnLoad.cpp file so ++ # local app modules can properly be linked. ++ string(REGEX REPLACE "react_codegen_" "" APP_CODEGEN_HEADER "${APP_CODEGEN_TARGET}") ++ target_compile_options(${CMAKE_PROJECT_NAME} ++ PRIVATE ++ -DREACT_NATIVE_APP_CODEGEN_HEADER="${APP_CODEGEN_HEADER}.h" ++ -DREACT_NATIVE_APP_COMPONENT_DESCRIPTORS_HEADER="react/renderer/components/${APP_CODEGEN_HEADER}/ComponentDescriptors.h" ++ -DREACT_NATIVE_APP_COMPONENT_REGISTRATION=${APP_CODEGEN_HEADER}_registerComponentDescriptorsFromCodegen ++ -DREACT_NATIVE_APP_MODULE_PROVIDER=${APP_CODEGEN_HEADER}_ModuleProvider ++ ) ++endif() +diff --git a/node_modules/react-native/ReactAndroid/bin/cmake-utils/default-app-setup/CMakeLists.txt b/node_modules/react-native/ReactAndroid/bin/cmake-utils/default-app-setup/CMakeLists.txt +new file mode 100644 +index 0000000..9755671 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/cmake-utils/default-app-setup/CMakeLists.txt +@@ -0,0 +1,31 @@ ++# 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. ++ ++# This CMake file is the default used by apps and is placed inside react-native ++# to encapsulate it from user space (so you won't need to touch C++/Cmake code at all on Android). ++# ++# If you wish to customize it (because you want to manually link a C++ library or pass a custom ++# compilation flag) you can: ++# ++# 1. Copy this CMake file inside the `android/app/src/main/jni` folder of your project ++# 2. Copy the OnLoad.cpp (in this same folder) file inside the same folder as above. ++# 3. Extend your `android/app/build.gradle` as follows ++# ++# android { ++# // Other config here... ++# externalNativeBuild { ++# cmake { ++# path "src/main/jni/CMakeLists.txt" ++# } ++# } ++# } ++ ++cmake_minimum_required(VERSION 3.13) ++ ++# Define the library name here. ++project(appmodules) ++ ++# This file includes all the necessary to let you build your application with the New Architecture. ++include(${REACT_ANDROID_DIR}/cmake-utils/ReactNative-application.cmake) +diff --git a/node_modules/react-native/ReactAndroid/bin/cmake-utils/default-app-setup/OnLoad.cpp b/node_modules/react-native/ReactAndroid/bin/cmake-utils/default-app-setup/OnLoad.cpp +new file mode 100644 +index 0000000..db2e6c1 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/cmake-utils/default-app-setup/OnLoad.cpp +@@ -0,0 +1,124 @@ ++/* ++ * 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. ++ */ ++ ++// This C++ file is part of the default configuration used by apps and is placed ++// inside react-native to encapsulate it from user space (so you won't need to ++// touch C++/Cmake code at all on Android). ++// ++// If you wish to customize it (because you want to manually link a C++ library ++// or pass a custom compilation flag) you can: ++// ++// 1. Copy this CMake file inside the `android/app/src/main/jni` folder of your ++// project ++// 2. Copy the OnLoad.cpp (in this same folder) file inside the same folder as ++// above. ++// 3. Extend your `android/app/build.gradle` as follows ++// ++// android { ++// // Other config here... ++// externalNativeBuild { ++// cmake { ++// path "src/main/jni/CMakeLists.txt" ++// } ++// } ++// } ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#ifdef REACT_NATIVE_APP_CODEGEN_HEADER ++#include REACT_NATIVE_APP_CODEGEN_HEADER ++#endif ++#ifdef REACT_NATIVE_APP_COMPONENT_DESCRIPTORS_HEADER ++#include REACT_NATIVE_APP_COMPONENT_DESCRIPTORS_HEADER ++#endif ++ ++namespace facebook::react { ++ ++void registerComponents( ++ std::shared_ptr registry) { ++ // Custom Fabric Components go here. You can register custom ++ // components coming from your App or from 3rd party libraries here. ++ // ++ // providerRegistry->add(concreteComponentDescriptorProvider< ++ // MyComponentDescriptor>()); ++ ++ // We link app local components if available ++#ifdef REACT_NATIVE_APP_COMPONENT_REGISTRATION ++ REACT_NATIVE_APP_COMPONENT_REGISTRATION(registry); ++#endif ++ ++ // And we fallback to the components autolinked ++ autolinking_registerProviders(registry); ++} ++ ++std::shared_ptr cxxModuleProvider( ++ const std::string& name, ++ const std::shared_ptr& jsInvoker) { ++ // Here you can provide your CXX Turbo Modules coming from ++ // either your application or from external libraries. The approach to follow ++ // is similar to the following (for a module called `NativeCxxModuleExample`): ++ // ++ // if (name == NativeCxxModuleExample::kModuleName) { ++ // return std::make_shared(jsInvoker); ++ // } ++ ++ // And we fallback to the CXX module providers autolinked ++ return autolinking_cxxModuleProvider(name, jsInvoker); ++} ++ ++std::shared_ptr javaModuleProvider( ++ const std::string& name, ++ const JavaTurboModule::InitParams& params) { ++ // Here you can provide your own module provider for TurboModules coming from ++ // either your application or from external libraries. The approach to follow ++ // is similar to the following (for a library called `samplelibrary`): ++ // ++ // auto module = samplelibrary_ModuleProvider(name, params); ++ // if (module != nullptr) { ++ // return module; ++ // } ++ // return rncore_ModuleProvider(name, params); ++ ++ // We link app local modules if available ++#ifdef REACT_NATIVE_APP_MODULE_PROVIDER ++ auto module = REACT_NATIVE_APP_MODULE_PROVIDER(name, params); ++ if (module != nullptr) { ++ return module; ++ } ++#endif ++ ++ // We first try to look up core modules ++ if (auto module = rncore_ModuleProvider(name, params)) { ++ return module; ++ } ++ ++ // And we fallback to the module providers autolinked ++ if (auto module = autolinking_ModuleProvider(name, params)) { ++ return module; ++ } ++ ++ return nullptr; ++} ++ ++} // namespace facebook::react ++ ++JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*) { ++ return facebook::jni::initialize(vm, [] { ++ facebook::react::DefaultTurboModuleManagerDelegate::cxxModuleProvider = ++ &facebook::react::cxxModuleProvider; ++ facebook::react::DefaultTurboModuleManagerDelegate::javaModuleProvider = ++ &facebook::react::javaModuleProvider; ++ facebook::react::DefaultComponentsRegistry:: ++ registerComponentDescriptorsFromEntryPoint = ++ &facebook::react::registerComponents; ++ }); ++} +diff --git a/node_modules/react-native/ReactAndroid/bin/cmake-utils/folly-flags.cmake b/node_modules/react-native/ReactAndroid/bin/cmake-utils/folly-flags.cmake +new file mode 100644 +index 0000000..0cd19ec +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/cmake-utils/folly-flags.cmake +@@ -0,0 +1,23 @@ ++# 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. ++ ++cmake_minimum_required(VERSION 3.13) ++set(CMAKE_VERBOSE_MAKEFILE on) ++ ++# This CMake file exposes the Folly Flags that all the libraries should use when ++# compiling/linking against a dependency which requires folly. ++ ++SET(folly_FLAGS ++ -DFOLLY_NO_CONFIG=1 ++ -DFOLLY_HAVE_CLOCK_GETTIME=1 ++ -DFOLLY_USE_LIBCPP=1 ++ -DFOLLY_CFG_NO_COROUTINES=1 ++ -DFOLLY_MOBILE=1 ++ -DFOLLY_HAVE_RECVMMSG=1 ++ -DFOLLY_HAVE_PTHREAD=1 ++ # Once we target android-23 above, we can comment ++ # the following line. NDK uses GNU style stderror_r() after API 23. ++ -DFOLLY_HAVE_XSI_STRERROR_R=1 ++ ) +diff --git a/node_modules/react-native/ReactAndroid/bin/external-artifacts/build.gradle.kts b/node_modules/react-native/ReactAndroid/bin/external-artifacts/build.gradle.kts +new file mode 100644 +index 0000000..685d77e +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/external-artifacts/build.gradle.kts +@@ -0,0 +1,68 @@ ++/* ++ * 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 org.jetbrains.kotlin.gradle.plugin.extraProperties ++ ++plugins { id("maven-publish") } ++ ++group = "com.facebook.react" ++ ++version = ++ parent?.extraProperties?.get("publishing_version") ++ ?: error("publishing_version not set for external-artifacts") ++ ++configurations.maybeCreate("default") ++ ++// Those artifacts should be placed inside the `artifacts/hermes-ios-*.tar.gz` location. ++val hermesiOSDebugArtifactFile: RegularFile = ++ layout.projectDirectory.file("artifacts/hermes-ios-debug.tar.gz") ++val hermesiOSDebugArtifact: PublishArtifact = ++ artifacts.add("default", hermesiOSDebugArtifactFile) { ++ type = "tgz" ++ extension = "tar.gz" ++ classifier = "hermes-ios-debug" ++ } ++val hermesiOSReleaseArtifactFile: RegularFile = ++ layout.projectDirectory.file("artifacts/hermes-ios-release.tar.gz") ++val hermesiOSReleaseArtifact: PublishArtifact = ++ artifacts.add("default", hermesiOSReleaseArtifactFile) { ++ type = "tgz" ++ extension = "tar.gz" ++ classifier = "hermes-ios-release" ++ } ++ ++// Those artifacts should be placed inside the `artifacts/hermes-*.framework.dSYM` location ++val hermesDSYMDebugArtifactFile: RegularFile = ++ layout.projectDirectory.file("artifacts/hermes-framework-dSYM-debug.tar.gz") ++val hermesDSYMDebugArtifact: PublishArtifact = ++ artifacts.add("default", hermesDSYMDebugArtifactFile) { ++ type = "tgz" ++ extension = "tar.gz" ++ classifier = "hermes-framework-dSYM-debug" ++ } ++val hermesDSYMReleaseArtifactFile: RegularFile = ++ layout.projectDirectory.file("artifacts/hermes-framework-dSYM-release.tar.gz") ++val hermesDSYMReleaseArtifact: PublishArtifact = ++ artifacts.add("default", hermesDSYMReleaseArtifactFile) { ++ type = "tgz" ++ extension = "tar.gz" ++ classifier = "hermes-framework-dSYM-release" ++ } ++ ++apply(from = "../publish.gradle") ++ ++publishing { ++ publications { ++ getByName("release", MavenPublication::class) { ++ artifactId = "react-native-artifacts" ++ artifact(hermesiOSDebugArtifact) ++ artifact(hermesiOSReleaseArtifact) ++ artifact(hermesDSYMDebugArtifact) ++ artifact(hermesDSYMReleaseArtifact) ++ } ++ } ++} +diff --git a/node_modules/react-native/ReactAndroid/bin/flipper-integration/.project b/node_modules/react-native/ReactAndroid/bin/flipper-integration/.project +new file mode 100644 +index 0000000..ae05168 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/flipper-integration/.project +@@ -0,0 +1,34 @@ ++ ++ ++ flipper-integration ++ Project flipper-integration created by Buildship. ++ ++ ++ ++ ++ org.eclipse.jdt.core.javabuilder ++ ++ ++ ++ ++ org.eclipse.buildship.core.gradleprojectbuilder ++ ++ ++ ++ ++ ++ org.eclipse.jdt.core.javanature ++ org.eclipse.buildship.core.gradleprojectnature ++ ++ ++ ++ 1724676428893 ++ ++ 30 ++ ++ org.eclipse.core.resources.regexFilterMatcher ++ node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ ++ ++ ++ ++ +diff --git a/node_modules/react-native/ReactAndroid/bin/gradle.properties b/node_modules/react-native/ReactAndroid/bin/gradle.properties +new file mode 100644 +index 0000000..a052c9e +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/gradle.properties +@@ -0,0 +1,28 @@ ++VERSION_NAME=0.75.2 ++react.internal.publishingGroup=com.facebook.react ++ ++android.useAndroidX=true ++ ++# We want to have more fine grained control on the Java version for ++# ReactAndroid, therefore we disable RGNP Java version alignment mechanism ++react.internal.disableJavaVersionAlignment=true ++ ++# Binary Compatibility Validator properties ++binaryCompatibilityValidator.ignoredClasses=com.facebook.react.BuildConfig ++binaryCompatibilityValidator.ignoredPackages=com.facebook.debug,\ ++ com.facebook.fbreact,\ ++ com.facebook.hermes,\ ++ com.facebook.perftest,\ ++ com.facebook.proguard,\ ++ com.facebook.react.bridgeless.internal,\ ++ com.facebook.react.flipper,\ ++ com.facebook.react.internal,\ ++ com.facebook.react.module.processing,\ ++ com.facebook.react.processing,\ ++ com.facebook.react.views.text.internal,\ ++ com.facebook.systrace,\ ++ com.facebook.yoga ++binaryCompatibilityValidator.nonPublicMarkers=com.facebook.react.common.annotations.VisibleForTesting,\ ++ com.facebook.react.common.annotations.UnstableReactNativeAPI ++binaryCompatibilityValidator.validationDisabled=true ++binaryCompatibilityValidator.outputApiFileName=ReactAndroid +diff --git a/node_modules/react-native/ReactAndroid/bin/hermes-engine/.project b/node_modules/react-native/ReactAndroid/bin/hermes-engine/.project +new file mode 100644 +index 0000000..d877f4a +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/hermes-engine/.project +@@ -0,0 +1,34 @@ ++ ++ ++ hermes-engine ++ Project hermes-engine created by Buildship. ++ ++ ++ ++ ++ org.eclipse.jdt.core.javabuilder ++ ++ ++ ++ ++ org.eclipse.buildship.core.gradleprojectbuilder ++ ++ ++ ++ ++ ++ org.eclipse.jdt.core.javanature ++ org.eclipse.buildship.core.gradleprojectnature ++ ++ ++ ++ 1724676428895 ++ ++ 30 ++ ++ org.eclipse.core.resources.regexFilterMatcher ++ node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ ++ ++ ++ ++ +diff --git a/node_modules/react-native/ReactAndroid/bin/hermes-engine/gradle.properties b/node_modules/react-native/ReactAndroid/bin/hermes-engine/gradle.properties +new file mode 100644 +index 0000000..8b53deb +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/hermes-engine/gradle.properties +@@ -0,0 +1 @@ ++android.disableAutomaticComponentCreation=true +diff --git a/node_modules/react-native/ReactAndroid/bin/proguard-rules.pro b/node_modules/react-native/ReactAndroid/bin/proguard-rules.pro +new file mode 100644 +index 0000000..70c7e22 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/proguard-rules.pro +@@ -0,0 +1,76 @@ ++# 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. ++ ++# Add project specific ProGuard rules here. ++# By default, the flags in this file are appended to flags specified ++# in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt ++# You can edit the include path and order by changing the proguardFiles ++# directive in build.gradle. ++# ++# For more details, see ++# http://developer.android.com/guide/developing/tools/proguard.html ++ ++# Add any project specific keep options here: ++ ++# Disabling obfuscation is useful if you collect stack traces from production crashes ++# (unless you are using a system that supports de-obfuscate the stack traces). ++# -dontobfuscate ++ ++# React Native ++ ++# Keep our interfaces so they can be used by other ProGuard rules. ++# See http://sourceforge.net/p/proguard/bugs/466/ ++-keep,allowobfuscation @interface com.facebook.proguard.annotations.DoNotStrip ++-keep,allowobfuscation @interface com.facebook.proguard.annotations.KeepGettersAndSetters ++ ++# Do not strip any method/class that is annotated with @DoNotStrip ++-keep @com.facebook.proguard.annotations.DoNotStrip class * ++-keepclassmembers class * { ++ @com.facebook.proguard.annotations.DoNotStrip *; ++} ++-keep @com.facebook.proguard.annotations.DoNotStripAny class * { ++ *; ++} ++-keep @com.facebook.jni.annotations.DoNotStrip class * ++-keepclassmembers class * { ++ @com.facebook.jni.annotations.DoNotStrip *; ++} ++-keep @com.facebook.jni.annotations.DoNotStripAny class * { ++ *; ++} ++ ++-keepclassmembers @com.facebook.proguard.annotations.KeepGettersAndSetters class * { ++ void set*(***); ++ *** get*(); ++} ++ ++-keep class * implements com.facebook.react.bridge.JavaScriptModule { *; } ++-keep class * implements com.facebook.react.bridge.NativeModule { *; } ++-keepclassmembers,includedescriptorclasses class * { native ; } ++-keepclassmembers class * { @com.facebook.react.uimanager.annotations.ReactProp ; } ++-keepclassmembers class * { @com.facebook.react.uimanager.annotations.ReactPropGroup ; } ++ ++-dontwarn com.facebook.react.** ++-keep,includedescriptorclasses class com.facebook.react.bridge.** { *; } ++-keep,includedescriptorclasses class com.facebook.react.turbomodule.core.** { *; } ++-keep,includedescriptorclasses class com.facebook.react.internal.turbomodule.core.** { *; } ++ ++# hermes ++-keep class com.facebook.jni.** { *; } ++ ++ ++# okio ++ ++-keep class sun.misc.Unsafe { *; } ++-dontwarn java.nio.file.* ++-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement ++-dontwarn okio.** ++ ++# yoga ++-keep,allowobfuscation @interface com.facebook.yoga.annotations.DoNotStrip ++-keep @com.facebook.yoga.annotations.DoNotStrip class * ++-keepclassmembers class * { ++ @com.facebook.yoga.annotations.DoNotStrip *; ++} +diff --git a/node_modules/react-native/ReactAndroid/bin/publish.gradle b/node_modules/react-native/ReactAndroid/bin/publish.gradle +new file mode 100644 +index 0000000..32287a7 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/publish.gradle +@@ -0,0 +1,82 @@ ++/* ++ * 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. ++ */ ++ ++apply plugin: 'maven-publish' ++apply plugin: 'signing' ++ ++def isSnapshot = findProperty("isSnapshot")?.toBoolean() ++def signingKey = findProperty("SIGNING_KEY") ++def signingPwd = findProperty("SIGNING_PWD") ++ ++def reactAndroidProjectDir = project(':packages:react-native:ReactAndroid').projectDir ++def mavenTempLocalUrl = "file:///tmp/maven-local" ++ ++publishing { ++ publications { ++ release(MavenPublication) { ++ afterEvaluate { ++ // We do a multi variant release, so for Android libraries ++ // we publish `components.release` ++ if (plugins.hasPlugin("com.android.library")) { ++ from components.default ++ } ++ } ++ ++ // We populate the publishing version using the project version, ++ // appending -SNAPSHOT if on nightly or prerelase. ++ if (isSnapshot) { ++ version = this.version + "-SNAPSHOT" ++ } else { ++ version = this.version ++ } ++ ++ pom { ++ name = "react-native" ++ description = "A framework for building native apps with React" ++ url = "https://github.com/facebook/react-native" ++ ++ developers { ++ developer { ++ id = "facebook" ++ name = "Facebook" ++ } ++ } ++ ++ licenses { ++ license { ++ name = "MIT License" ++ url = "https://github.com/facebook/react-native/blob/HEAD/LICENSE" ++ distribution = "repo" ++ } ++ } ++ ++ scm { ++ url = "https://github.com/facebook/react-native.git" ++ connection = "scm:git:https://github.com/facebook/react-native.git" ++ developerConnection = "scm:git:git@github.com:facebook/react-native.git" ++ } ++ } ++ } ++ } ++ ++ repositories { ++ maven { ++ name = "mavenTempLocal" ++ url = mavenTempLocalUrl ++ } ++ } ++ ++ if (signingKey && signingPwd) { ++ logger.info("PGP Key found - Signing enabled") ++ signing { ++ useInMemoryPgpKeys(signingKey, signingPwd) ++ sign(publishing.publications.release) ++ } ++ } else { ++ logger.info("Signing disabled as the PGP key was not found") ++ } ++} +diff --git a/node_modules/react-native/ReactAndroid/bin/src/debug/AndroidManifest.xml b/node_modules/react-native/ReactAndroid/bin/src/debug/AndroidManifest.xml +new file mode 100644 +index 0000000..ac05d07 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/debug/AndroidManifest.xml +@@ -0,0 +1,15 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/AndroidManifest.xml b/node_modules/react-native/ReactAndroid/bin/src/main/AndroidManifest.xml +new file mode 100644 +index 0000000..fe6accd +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/AndroidManifest.xml +@@ -0,0 +1,15 @@ ++ ++ ++ ++ ++ ++ ++ +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/hermes/reactexecutor/fbjni.pro b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/hermes/reactexecutor/fbjni.pro +new file mode 100644 +index 0000000..ca54067 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/hermes/reactexecutor/fbjni.pro +@@ -0,0 +1,16 @@ ++# 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. ++ ++# For common use cases for the hybrid pattern, keep symbols which may ++# be referenced only from C++. ++ ++-keepclassmembers class * { ++ com.facebook.jni.HybridData *; ++ (com.facebook.jni.HybridData); ++} ++ ++-keepclasseswithmembers class * { ++ com.facebook.jni.HybridData *; ++} +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/proguard/annotations/proguard_annotations.pro b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/proguard/annotations/proguard_annotations.pro +new file mode 100644 +index 0000000..a4a7187 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/proguard/annotations/proguard_annotations.pro +@@ -0,0 +1,21 @@ ++# 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. ++ ++# Keep our interfaces so they can be used by other ProGuard rules. ++# See http://sourceforge.net/p/proguard/bugs/466/ ++-keep,allowobfuscation @interface com.facebook.proguard.annotations.DoNotStrip ++-keep,allowobfuscation @interface com.facebook.proguard.annotations.DoNotStripAny ++-keep,allowobfuscation @interface com.facebook.proguard.annotations.KeepGettersAndSetters ++ ++# Do not strip any method/class that is annotated with @DoNotStrip ++-keep @com.facebook.proguard.annotations.DoNotStrip class * ++-keepclassmembers class * { ++ @com.facebook.proguard.annotations.DoNotStrip *; ++} ++ ++-keepclassmembers @com.facebook.proguard.annotations.KeepGettersAndSetters class * { ++ void set*(***); ++ *** get*(); ++} +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/ReactApplication.kt b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/ReactApplication.kt +new file mode 100644 +index 0000000..9360b51 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/ReactApplication.kt +@@ -0,0 +1,21 @@ ++/* ++ * 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. ++ */ ++ ++package com.facebook.react ++ ++/** Interface that represents an instance of a React Native application */ ++public interface ReactApplication { ++ /** Get the default [ReactNativeHost] for this app. */ ++ public val reactNativeHost: ReactNativeHost ++ ++ /** ++ * Get the default [ReactHost] for this app. This method will be used by the new architecture of ++ * react native ++ */ ++ public val reactHost: ReactHost? ++ get() = null ++} +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/ReactHost.kt b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/ReactHost.kt +new file mode 100644 +index 0000000..5f09366 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/ReactHost.kt +@@ -0,0 +1,137 @@ ++/* ++ * 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. ++ */ ++ ++package com.facebook.react ++ ++import android.app.Activity ++import android.content.Context ++import android.content.Intent ++import android.os.Bundle ++import com.facebook.react.bridge.ReactContext ++import com.facebook.react.bridge.queue.ReactQueueConfiguration ++import com.facebook.react.common.LifecycleState ++import com.facebook.react.devsupport.interfaces.DevSupportManager ++import com.facebook.react.interfaces.TaskInterface ++import com.facebook.react.interfaces.fabric.ReactSurface ++import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler ++ ++/** ++ * A ReactHost is an object that manages a single {@link ReactInstance}. A ReactHost can be ++ * constructed without initializing the ReactInstance, and it will continue to exist after the ++ * instance is destroyed. ++ * ++ * The implementation of this interface should be Thread Safe ++ */ ++public interface ReactHost { ++ ++ /** The current [LifecycleState] for React Host */ ++ public val lifecycleState: LifecycleState ++ ++ /** ++ * The current [ReactContext] associated with ReactInstance. It could be nullable if ReactInstance ++ * hasn't been created. ++ */ ++ public val currentReactContext: ReactContext? ++ ++ // TODO: review if DevSupportManager should be nullable ++ /** [DevSupportManager] used by this ReactHost */ ++ public val devSupportManager: DevSupportManager? ++ ++ // TODO: review if possible to remove ReactQueueConfiguration ++ /** [ReactQueueConfiguration] for caller to post jobs in React Native threads */ ++ public val reactQueueConfiguration: ReactQueueConfiguration? ++ ++ /** [JSEngineResolutionAlgorithm] used by this host. */ ++ public var jsEngineResolutionAlgorithm: JSEngineResolutionAlgorithm? ++ ++ /** Routes memory pressure events to interested components */ ++ public val memoryPressureRouter: MemoryPressureRouter ++ ++ /** To be called when back button is pressed */ ++ public fun onBackPressed(): Boolean ++ ++ // TODO: review why activity is nullable in all of the lifecycle methods ++ /** To be called when the host activity is resumed. */ ++ public fun onHostResume( ++ activity: Activity?, ++ defaultBackButtonImpl: DefaultHardwareBackBtnHandler? ++ ) ++ ++ /** To be called when the host activity is resumed. */ ++ public fun onHostResume(activity: Activity?) ++ ++ /** To be called when the host activity is paused. */ ++ public fun onHostPause(activity: Activity?) ++ ++ /** To be called when the host activity is paused. */ ++ public fun onHostPause() ++ ++ /** To be called when the host activity is destroyed. */ ++ public fun onHostDestroy() ++ ++ /** To be called when the host activity is destroyed. */ ++ public fun onHostDestroy(activity: Activity?) ++ ++ /** To be called to create and setup an ReactSurface. */ ++ public fun createSurface( ++ context: Context, ++ moduleName: String, ++ initialProps: Bundle? ++ ): ReactSurface? ++ ++ /** ++ * This function can be used to initialize the ReactInstance in a background thread before a ++ * surface needs to be rendered. It is not necessary to call this function; startSurface() will ++ * initialize the ReactInstance if it hasn't been preloaded. ++ * ++ * @return A Task that completes when the instance is initialized. The task will be faulted if any ++ * errors occur during initialization, and will be cancelled if ReactHost.destroy() is called ++ * before it completes. ++ */ ++ public fun start(): TaskInterface ++ ++ /** ++ * Entrypoint to reload the ReactInstance. If the ReactInstance is destroying, will wait until ++ * destroy is finished, before reloading. ++ * ++ * @param reason describing why ReactHost is being reloaded (e.g. js error, user tap on reload ++ * button) ++ * @return A task that completes when React Native reloads ++ */ ++ public fun reload(reason: String): TaskInterface ++ ++ /** ++ * Entrypoint to destroy the ReactInstance. If the ReactInstance is reloading, will wait until ++ * reload is finished, before destroying. ++ * ++ * @param reason describing why ReactHost is being destroyed (e.g. memmory pressure) ++ * @param ex exception that caused the trigger to destroy ReactHost (or null) This exception will ++ * be used to log properly the cause of destroy operation. ++ * @return A task that completes when React Native gets destroyed. ++ */ ++ public fun destroy(reason: String, ex: Exception?): TaskInterface ++ ++ /* To be called when the host activity receives an activity result. */ ++ public fun onActivityResult( ++ activity: Activity, ++ requestCode: Int, ++ resultCode: Int, ++ data: Intent?, ++ ) ++ ++ /* To be called when focus has changed for the hosting window. */ ++ public fun onWindowFocusChange(hasFocus: Boolean) ++ ++ /* This method will give JS the opportunity to receive intents via Linking. */ ++ public fun onNewIntent(intent: Intent) ++ ++ public fun onConfigurationChanged(context: Context) ++ ++ public fun addBeforeDestroyListener(onBeforeDestroy: () -> Unit) ++ ++ public fun removeBeforeDestroyListener(onBeforeDestroy: () -> Unit) ++} +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/bridge/bridge.pro b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/bridge/bridge.pro +new file mode 100644 +index 0000000..ce18d10 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/bridge/bridge.pro +@@ -0,0 +1,12 @@ ++# 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. ++ ++## Putting this here is kind of a hack. I don't want to modify the OSS bridge. ++## TODO mhorowitz: add @DoNotStrip to the interface directly. ++ ++-keepclassmembers class com.facebook.react.bridge.queue.MessageQueueThread { ++ public boolean isOnThread(); ++ public void assertIsOnThread(); ++} +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/bridge/reactnative.pro b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/bridge/reactnative.pro +new file mode 100644 +index 0000000..72f1131 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/bridge/reactnative.pro +@@ -0,0 +1,32 @@ ++# 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. ++ ++-keepnames class * extends com.facebook.react.bridge.JavaScriptModule { *; } ++-keepnames class * extends com.facebook.react.bridge.CxxModuleWrapper {*; } ++-keepclassmembers class * extends com.facebook.react.bridge.NativeModule { ++ @com.facebook.react.bridge.ReactMethod *; ++ public (...); ++} ++ ++-keepclassmembers class * { @com.facebook.react.uimanager.annotations.ReactProp ; } ++-keepclassmembers class * { @com.facebook.react.uimanager.annotations.ReactPropGroup ; } ++-keepnames class * extends com.facebook.react.uimanager.ViewManager ++-keepnames class * extends com.facebook.react.uimanager.ReactShadowNode ++-keep class **$$PropsSetter ++-keep class **$$ReactModuleInfoProvider ++-keep class com.facebook.react.bridge.ReadableType { *; } ++ ++-keepnames class com.facebook.quicklog.QuickPerformanceLogger { ++ void markerAnnotate(int,int,java.lang.String,java.lang.String); ++ void markerTag(int,int,java.lang.String); ++} ++ ++## Putting this here is kind of a hack. I don't want to modify the OSS bridge. ++## TODO mhorowitz: add @DoNotStrip to the interface directly. ++ ++-keepclassmembers class com.facebook.react.bridge.queue.MessageQueueThread { ++ public boolean isOnThread(); ++ public void assertIsOnThread(); ++} +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/common/annotations/DeprecatedInNewArchitecture.kt b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/common/annotations/DeprecatedInNewArchitecture.kt +new file mode 100644 +index 0000000..be2c473 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/common/annotations/DeprecatedInNewArchitecture.kt +@@ -0,0 +1,16 @@ ++/* ++ * 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. ++ */ ++ ++package com.facebook.react.common.annotations ++ ++/** ++ * Annotates a method or class that will be deprecated once the NewArchitecture is fully released in ++ * OSS. ++ */ ++@Retention(AnnotationRetention.SOURCE) ++@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) ++public annotation class DeprecatedInNewArchitecture(val message: String = "") +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/common/annotations/FrameworkAPI.kt b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/common/annotations/FrameworkAPI.kt +new file mode 100644 +index 0000000..37e2863 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/common/annotations/FrameworkAPI.kt +@@ -0,0 +1,18 @@ ++/* ++ * 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. ++ */ ++ ++package com.facebook.react.common.annotations ++ ++@Retention(AnnotationRetention.RUNTIME) ++@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) ++@RequiresOptIn( ++ level = RequiresOptIn.Level.ERROR, ++ message = ++ "This API is provided only for React Native frameworks and not intended for general users. " + ++ "This API can change between minor versions in alignment with React Native frameworks " + ++ "and won't be considered a breaking change.") ++public annotation class FrameworkAPI +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/common/annotations/UnstableReactNativeAPI.kt b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/common/annotations/UnstableReactNativeAPI.kt +new file mode 100644 +index 0000000..bd728ef +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/common/annotations/UnstableReactNativeAPI.kt +@@ -0,0 +1,15 @@ ++/* ++ * 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. ++ */ ++ ++package com.facebook.react.common.annotations ++ ++@Retention(AnnotationRetention.RUNTIME) ++@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY) ++@RequiresOptIn( ++ level = RequiresOptIn.Level.ERROR, ++ message = "This API is experimental and is likely to change or to be removed in the future") ++public annotation class UnstableReactNativeAPI +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/common/annotations/VisibleForTesting.kt b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/common/annotations/VisibleForTesting.kt +new file mode 100644 +index 0000000..5d30f3e +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/common/annotations/VisibleForTesting.kt +@@ -0,0 +1,14 @@ ++/* ++ * 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. ++ */ ++ ++package com.facebook.react.common.annotations ++ ++/** ++ * Annotates a method that should have restricted visibility but it's required to be public for use ++ * in test code only. ++ */ ++public annotation class VisibleForTesting +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/common/mapbuffer/MapBuffer.kt b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/common/mapbuffer/MapBuffer.kt +new file mode 100644 +index 0000000..53bb6b8 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/common/mapbuffer/MapBuffer.kt +@@ -0,0 +1,217 @@ ++/* ++ * 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. ++ */ ++ ++package com.facebook.react.common.mapbuffer ++ ++import com.facebook.react.common.annotations.StableReactNativeAPI ++ ++/** ++ * MapBuffer is an optimized sparse array format for transferring props-like data between C++ and ++ * JNI. It is designed to: ++ * - be compact to optimize space when sparse (sparse is the common case). ++ * - be accessible through JNI with zero/minimal copying. ++ * - work recursively for nested maps/arrays. ++ * - support dynamic types that map to JSON. ++ * - have minimal APK size and build time impact. ++ * ++ * See for more information and native implementation. ++ * ++ * Limitations: ++ * - Keys are usually sized as 2 bytes, with each buffer supporting up to 65536 entries as a result. ++ * - O(log(N)) random key access for native buffers due to selected structure. Faster access can be ++ * achieved by retrieving [MapBuffer.Entry] with [entryAt] on known offsets. ++ */ ++@StableReactNativeAPI ++public interface MapBuffer : Iterable { ++ public companion object { ++ /** ++ * Key are represented as 2 byte values, and typed as Int for ease of access. The serialization ++ * format only allows to store [UShort] values. ++ */ ++ internal val KEY_RANGE = IntRange(UShort.MIN_VALUE.toInt(), UShort.MAX_VALUE.toInt()) ++ } ++ ++ /** ++ * Data types supported by [MapBuffer]. Keep in sync with definition in ++ * ``, as enum serialization relies on correct order. ++ */ ++ public enum class DataType { ++ BOOL, ++ INT, ++ DOUBLE, ++ STRING, ++ MAP, ++ LONG ++ } ++ ++ /** ++ * Number of elements inserted into current MapBuffer. ++ * ++ * @return number of elements in the [MapBuffer] ++ */ ++ public val count: Int ++ ++ /** ++ * Checks whether entry for given key exists in MapBuffer. ++ * ++ * @param key key to lookup the entry ++ * @return whether entry for the given key exists in the MapBuffer. ++ */ ++ public fun contains(key: Int): Boolean ++ ++ /** ++ * Provides offset of the key to use for [entryAt], for cases when offset is not statically known ++ * but can be cached. ++ * ++ * @param key key to lookup offset for ++ * @return offset for the given key to be used for entry access, -1 if key wasn't found. ++ */ ++ public fun getKeyOffset(key: Int): Int ++ ++ /** ++ * Provides parsed access to a MapBuffer without additional lookups for provided offset. ++ * ++ * @param offset offset of entry in the MapBuffer structure. Can be looked up for known keys with ++ * [getKeyOffset]. ++ * @return parsed entry for structured access for given offset ++ */ ++ public fun entryAt(offset: Int): MapBuffer.Entry ++ ++ /** ++ * Provides parsed [DataType] annotation associated with the given key. ++ * ++ * @param key key to lookup type for ++ * @return data type of the given key. ++ * @throws IllegalArgumentException if the key doesn't exist ++ */ ++ public fun getType(key: Int): DataType ++ ++ /** ++ * Provides parsed [Boolean] value if the entry for given key exists with [DataType.BOOL] type ++ * ++ * @param key key to lookup [Boolean] value for ++ * @return value associated with the requested key ++ * @throws IllegalArgumentException if the key doesn't exist ++ * @throws IllegalStateException if the data type doesn't match ++ */ ++ public fun getBoolean(key: Int): Boolean ++ ++ /** ++ * Provides parsed [Int] value if the entry for given key exists with [DataType.INT] type ++ * ++ * @param key key to lookup [Int] value for ++ * @return value associated with the requested key ++ * @throws IllegalArgumentException if the key doesn't exist ++ * @throws IllegalStateException if the data type doesn't match ++ */ ++ public fun getInt(key: Int): Int ++ ++ /** ++ * Provides parsed [Long] value if the entry for given key exists with [DataType.LONG] type ++ * ++ * @param key key to lookup [Long] value for ++ * @return value associated with the requested key ++ * @throws IllegalArgumentException if the key doesn't exist ++ * @throws IllegalStateException if the data type doesn't match ++ */ ++ public fun getLong(key: Int): Long ++ ++ /** ++ * Provides parsed [Double] value if the entry for given key exists with [DataType.DOUBLE] type ++ * ++ * @param key key to lookup [Double] value for ++ * @return value associated with the requested key ++ * @throws IllegalArgumentException if the key doesn't exist ++ * @throws IllegalStateException if the data type doesn't match ++ */ ++ public fun getDouble(key: Int): Double ++ ++ /** ++ * Provides parsed [String] value if the entry for given key exists with [DataType.STRING] type ++ * ++ * @param key key to lookup [String] value for ++ * @return value associated with the requested key ++ * @throws IllegalArgumentException if the key doesn't exist ++ * @throws IllegalStateException if the data type doesn't match ++ */ ++ public fun getString(key: Int): String ++ ++ /** ++ * Provides parsed [MapBuffer] value if the entry for given key exists with [DataType.MAP] type ++ * ++ * @param key key to lookup [MapBuffer] value for ++ * @return value associated with the requested key ++ * @throws IllegalArgumentException if the key doesn't exist ++ * @throws IllegalStateException if the data type doesn't match ++ */ ++ public fun getMapBuffer(key: Int): MapBuffer ++ ++ /** ++ * Provides parsed [List] value if the entry for given key exists with [DataType.MAP] ++ * type ++ * ++ * @param key key to lookup [List] value for ++ * @return value associated with the requested key ++ * @throws IllegalArgumentException if the key doesn't exist ++ * @throws IllegalStateException if the data type doesn't match ++ */ ++ public fun getMapBufferList(key: Int): List ++ ++ /** Iterable entry representing parsed MapBuffer values */ ++ public interface Entry { ++ /** ++ * Key of the given entry. Usually represented as 2 byte unsigned integer with the value range ++ * of [0,65536) ++ */ ++ public val key: Int ++ ++ /** Parsed [DataType] of the entry */ ++ public val type: DataType ++ ++ /** ++ * Entry value represented as [Boolean] ++ * ++ * @throws IllegalStateException if the data type doesn't match [DataType.BOOL] ++ */ ++ public val booleanValue: Boolean ++ ++ /** ++ * Entry value represented as [Int] ++ * ++ * @throws IllegalStateException if the data type doesn't match [DataType.INT] ++ */ ++ public val intValue: Int ++ ++ /** ++ * Entry value represented as [Long] ++ * ++ * @throws IllegalStateException if the data type doesn't match [DataType.LONG] ++ */ ++ public val longValue: Long ++ ++ /** ++ * Entry value represented as [Double] ++ * ++ * @throws IllegalStateException if the data type doesn't match [DataType.DOUBLE] ++ */ ++ public val doubleValue: Double ++ ++ /** ++ * Entry value represented as [String] ++ * ++ * @throws IllegalStateException if the data type doesn't match [DataType.STRING] ++ */ ++ public val stringValue: String ++ ++ /** ++ * Entry value represented as [MapBuffer] ++ * ++ * @throws IllegalStateException if the data type doesn't match [DataType.MAP] ++ */ ++ public val mapBufferValue: MapBuffer ++ } ++} +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/common/mapbuffer/MapBufferSoLoader.kt b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/common/mapbuffer/MapBufferSoLoader.kt +new file mode 100644 +index 0000000..1c9536c +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/common/mapbuffer/MapBufferSoLoader.kt +@@ -0,0 +1,35 @@ ++/* ++ * 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. ++ */ ++ ++package com.facebook.react.common.mapbuffer ++ ++import com.facebook.react.bridge.ReactMarker ++import com.facebook.react.bridge.ReactMarkerConstants ++import com.facebook.react.common.annotations.StableReactNativeAPI ++import com.facebook.soloader.SoLoader ++import com.facebook.systrace.Systrace ++ ++@StableReactNativeAPI ++public object MapBufferSoLoader { ++ @Volatile private var didInit = false ++ ++ @JvmStatic ++ public fun staticInit() { ++ if (didInit) { ++ return ++ } ++ didInit = true ++ ++ Systrace.beginSection( ++ Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, ++ "ReadableMapBufferSoLoader.staticInit::load:mapbufferjni") ++ ReactMarker.logMarker(ReactMarkerConstants.LOAD_REACT_NATIVE_MAPBUFFER_SO_FILE_START) ++ SoLoader.loadLibrary("mapbufferjni") ++ ReactMarker.logMarker(ReactMarkerConstants.LOAD_REACT_NATIVE_MAPBUFFER_SO_FILE_END) ++ Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE) ++ } ++} +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/common/mapbuffer/ReadableMapBuffer.kt b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/common/mapbuffer/ReadableMapBuffer.kt +new file mode 100644 +index 0000000..ad6cdd4 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/common/mapbuffer/ReadableMapBuffer.kt +@@ -0,0 +1,343 @@ ++/* ++ * 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. ++ */ ++ ++package com.facebook.react.common.mapbuffer ++ ++import com.facebook.jni.HybridData ++import com.facebook.proguard.annotations.DoNotStrip ++import com.facebook.react.common.annotations.StableReactNativeAPI ++import com.facebook.react.common.mapbuffer.MapBuffer.Companion.KEY_RANGE ++import java.lang.StringBuilder ++import java.nio.ByteBuffer ++import java.nio.ByteOrder ++import javax.annotation.concurrent.NotThreadSafe ++ ++/** ++ * Read-only implementation of the [MapBuffer], imported from C++ environment. Use ++ * ` to create it. ++ * ++ * See [MapBuffer] documentation for more details ++ */ ++@StableReactNativeAPI ++@NotThreadSafe ++@DoNotStrip ++public class ReadableMapBuffer : MapBuffer { ++ ++ // Hybrid data must be kept in the `mHybridData` field for fbjni to work ++ @field:DoNotStrip private val mHybridData: HybridData? ++ ++ // Byte data of the mapBuffer ++ private val buffer: ByteBuffer ++ // Offset to the start of the MapBuffer ++ private val offsetToMapBuffer: Int ++ // Amount of items serialized on the ByteBuffer ++ override var count: Int = 0 ++ private set ++ ++ @DoNotStrip ++ private constructor(hybridData: HybridData) { ++ mHybridData = hybridData ++ buffer = importByteBuffer() ++ offsetToMapBuffer = 0 ++ readHeader() ++ } ++ ++ private constructor(buffer: ByteBuffer) { ++ mHybridData = null ++ this.buffer = buffer ++ offsetToMapBuffer = 0 ++ readHeader() ++ } ++ ++ private constructor(buffer: ByteBuffer, offset: Int) { ++ mHybridData = null ++ this.buffer = buffer.duplicate().apply { position(offset) } ++ offsetToMapBuffer = offset ++ readHeader() ++ } ++ ++ private external fun importByteBuffer(): ByteBuffer ++ ++ private fun readHeader() { ++ // byte order ++ val storedAlignment = buffer.short ++ if (storedAlignment.toInt() != ALIGNMENT) { ++ buffer.order(ByteOrder.LITTLE_ENDIAN) ++ } ++ // count ++ count = readUnsignedShort(buffer.position()).toInt() ++ } ++ ++ // returns the relative offset of the first byte of dynamic data ++ private val offsetForDynamicData: Int ++ get() = getKeyOffsetForBucketIndex(count) ++ ++ /** ++ * @param key Key to search for ++ * @return the "bucket index" for a key or -1 if not found. It uses a binary search algorithm ++ * (log(n)) ++ */ ++ private fun getBucketIndexForKey(intKey: Int): Int { ++ if (intKey !in KEY_RANGE) { ++ return -1 ++ } ++ val key = intKey.toUShort() ++ ++ var lo = 0 ++ var hi = count - 1 ++ while (lo <= hi) { ++ val mid = lo + hi ushr 1 ++ val midVal = readUnsignedShort(getKeyOffsetForBucketIndex(mid)) ++ when { ++ midVal < key -> lo = mid + 1 ++ midVal > key -> hi = mid - 1 ++ else -> return mid ++ } ++ } ++ return -1 ++ } ++ ++ private fun readDataType(bucketIndex: Int): MapBuffer.DataType { ++ val value = readUnsignedShort(getKeyOffsetForBucketIndex(bucketIndex) + TYPE_OFFSET).toInt() ++ return MapBuffer.DataType.values()[value] ++ } ++ ++ private fun getTypedValueOffsetForKey(key: Int, expected: MapBuffer.DataType): Int { ++ val bucketIndex = getBucketIndexForKey(key) ++ require(bucketIndex != -1) { "Key not found: $key" } ++ val dataType = readDataType(bucketIndex) ++ check(!(dataType !== expected)) { "Expected $expected for key: $key, found $dataType instead." } ++ return getKeyOffsetForBucketIndex(bucketIndex) + VALUE_OFFSET ++ } ++ ++ private fun readUnsignedShort(bufferPosition: Int): UShort { ++ return buffer.getShort(bufferPosition).toUShort() ++ } ++ ++ private fun readDoubleValue(bufferPosition: Int): Double { ++ return buffer.getDouble(bufferPosition) ++ } ++ ++ private fun readIntValue(bufferPosition: Int): Int { ++ return buffer.getInt(bufferPosition) ++ } ++ ++ private fun readLongValue(bufferPosition: Int): Long { ++ return buffer.getLong(bufferPosition) ++ } ++ ++ private fun readBooleanValue(bufferPosition: Int): Boolean { ++ return readIntValue(bufferPosition) == 1 ++ } ++ ++ private fun readStringValue(bufferPosition: Int): String { ++ val offset = offsetForDynamicData + buffer.getInt(bufferPosition) ++ val sizeOfString = buffer.getInt(offset) ++ val result = ByteArray(sizeOfString) ++ val stringOffset = offset + Int.SIZE_BYTES ++ buffer.position(stringOffset) ++ buffer[result, 0, sizeOfString] ++ return String(result) ++ } ++ ++ private fun readMapBufferValue(position: Int): ReadableMapBuffer { ++ val offset = offsetForDynamicData + buffer.getInt(position) ++ return ReadableMapBuffer(buffer, offset + Int.SIZE_BYTES) ++ } ++ ++ private fun readMapBufferListValue(position: Int): List { ++ val readMapBufferList = arrayListOf() ++ var offset = offsetForDynamicData + buffer.getInt(position) ++ val sizeMapBufferList = buffer.getInt(offset) ++ offset += Int.SIZE_BYTES ++ var curLen = 0 ++ while (curLen < sizeMapBufferList) { ++ val sizeMapBuffer = buffer.getInt(offset + curLen) ++ curLen = curLen + Int.SIZE_BYTES ++ readMapBufferList.add(ReadableMapBuffer(buffer, offset + curLen)) ++ curLen = curLen + sizeMapBuffer ++ } ++ return readMapBufferList ++ } ++ ++ private fun getKeyOffsetForBucketIndex(bucketIndex: Int): Int { ++ return offsetToMapBuffer + HEADER_SIZE + BUCKET_SIZE * bucketIndex ++ } ++ ++ override fun contains(key: Int): Boolean { ++ // TODO T83483191: Add tests ++ return getBucketIndexForKey(key) != -1 ++ } ++ ++ override fun getKeyOffset(key: Int): Int = getBucketIndexForKey(key) ++ ++ override fun entryAt(offset: Int): MapBuffer.Entry = ++ MapBufferEntry(getKeyOffsetForBucketIndex(offset)) ++ ++ override fun getType(key: Int): MapBuffer.DataType { ++ val bucketIndex = getBucketIndexForKey(key) ++ require(bucketIndex != -1) { "Key not found: $key" } ++ return readDataType(bucketIndex) ++ } ++ ++ override fun getInt(key: Int): Int = ++ readIntValue(getTypedValueOffsetForKey(key, MapBuffer.DataType.INT)) ++ ++ override fun getLong(key: Int): Long = ++ readLongValue(getTypedValueOffsetForKey(key, MapBuffer.DataType.LONG)) ++ ++ override fun getDouble(key: Int): Double = ++ readDoubleValue(getTypedValueOffsetForKey(key, MapBuffer.DataType.DOUBLE)) ++ ++ override fun getString(key: Int): String = ++ readStringValue(getTypedValueOffsetForKey(key, MapBuffer.DataType.STRING)) ++ ++ override fun getBoolean(key: Int): Boolean = ++ readBooleanValue(getTypedValueOffsetForKey(key, MapBuffer.DataType.BOOL)) ++ ++ override fun getMapBuffer(key: Int): ReadableMapBuffer = ++ readMapBufferValue(getTypedValueOffsetForKey(key, MapBuffer.DataType.MAP)) ++ ++ override fun getMapBufferList(key: Int): List = ++ readMapBufferListValue(getTypedValueOffsetForKey(key, MapBuffer.DataType.MAP)) ++ ++ override fun hashCode(): Int { ++ buffer.rewind() ++ return buffer.hashCode() ++ } ++ ++ override fun equals(other: Any?): Boolean { ++ if (other !is ReadableMapBuffer) { ++ return false ++ } ++ val thisByteBuffer = buffer ++ val otherByteBuffer = other.buffer ++ if (thisByteBuffer === otherByteBuffer) { ++ return true ++ } ++ thisByteBuffer.rewind() ++ otherByteBuffer.rewind() ++ return thisByteBuffer == otherByteBuffer ++ } ++ ++ override fun toString(): String { ++ val builder = StringBuilder("{") ++ joinTo(builder) { entry -> ++ StringBuilder().apply { ++ append(entry.key) ++ append('=') ++ when (entry.type) { ++ MapBuffer.DataType.BOOL -> append(entry.booleanValue) ++ MapBuffer.DataType.INT -> append(entry.intValue) ++ MapBuffer.DataType.LONG -> append(entry.longValue) ++ MapBuffer.DataType.DOUBLE -> append(entry.doubleValue) ++ MapBuffer.DataType.STRING -> { ++ append('"') ++ append(entry.stringValue) ++ append('"') ++ } ++ MapBuffer.DataType.MAP -> append(entry.mapBufferValue.toString()) ++ } ++ } ++ } ++ builder.append('}') ++ return builder.toString() ++ } ++ ++ override fun iterator(): Iterator { ++ return object : Iterator { ++ var current = 0 ++ val last = count - 1 ++ ++ override fun hasNext(): Boolean { ++ return current <= last ++ } ++ ++ override fun next(): MapBuffer.Entry { ++ return MapBufferEntry(getKeyOffsetForBucketIndex(current++)) ++ } ++ } ++ } ++ ++ private inner class MapBufferEntry(private val bucketOffset: Int) : MapBuffer.Entry { ++ private fun assertType(expected: MapBuffer.DataType) { ++ val dataType = type ++ check(!(expected !== dataType)) { ++ ("Expected " + ++ expected + ++ " for key: " + ++ key + ++ " found " + ++ dataType.toString() + ++ " instead.") ++ } ++ } ++ ++ override val key: Int ++ get() = readUnsignedShort(bucketOffset).toInt() ++ ++ override val type: MapBuffer.DataType ++ get() = MapBuffer.DataType.values()[readUnsignedShort(bucketOffset + TYPE_OFFSET).toInt()] ++ ++ override val doubleValue: Double ++ get() { ++ assertType(MapBuffer.DataType.DOUBLE) ++ return readDoubleValue(bucketOffset + VALUE_OFFSET) ++ } ++ ++ override val intValue: Int ++ get() { ++ assertType(MapBuffer.DataType.INT) ++ return readIntValue(bucketOffset + VALUE_OFFSET) ++ } ++ ++ override val longValue: Long ++ get() { ++ assertType(MapBuffer.DataType.LONG) ++ return readLongValue(bucketOffset + VALUE_OFFSET) ++ } ++ ++ override val booleanValue: Boolean ++ get() { ++ assertType(MapBuffer.DataType.BOOL) ++ return readBooleanValue(bucketOffset + VALUE_OFFSET) ++ } ++ ++ override val stringValue: String ++ get() { ++ assertType(MapBuffer.DataType.STRING) ++ return readStringValue(bucketOffset + VALUE_OFFSET) ++ } ++ ++ override val mapBufferValue: MapBuffer ++ get() { ++ assertType(MapBuffer.DataType.MAP) ++ return readMapBufferValue(bucketOffset + VALUE_OFFSET) ++ } ++ } ++ ++ public companion object { ++ // Value used to verify if the data is serialized with LittleEndian order. ++ private const val ALIGNMENT = 0xFE ++ ++ // 8 bytes = 2 (alignment) + 2 (count) + 4 (size) ++ private const val HEADER_SIZE = 8 ++ ++ // 10 bytes = 2 (key) + 2 (type) + 8 (value) ++ private const val BUCKET_SIZE = 12 ++ ++ // 2 bytes = 2 (key) ++ private const val TYPE_OFFSET = 2 ++ ++ // 4 bytes = 2 (key) + 2 (type) ++ private const val VALUE_OFFSET = 4 ++ ++ init { ++ MapBufferSoLoader.staticInit() ++ } ++ } ++} +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/common/mapbuffer/WritableMapBuffer.kt b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/common/mapbuffer/WritableMapBuffer.kt +new file mode 100644 +index 0000000..f79e912 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/common/mapbuffer/WritableMapBuffer.kt +@@ -0,0 +1,200 @@ ++/* ++ * 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. ++ */ ++ ++package com.facebook.react.common.mapbuffer ++ ++import android.util.SparseArray ++import com.facebook.proguard.annotations.DoNotStrip ++import com.facebook.react.common.annotations.StableReactNativeAPI ++import com.facebook.react.common.mapbuffer.MapBuffer.Companion.KEY_RANGE ++import com.facebook.react.common.mapbuffer.MapBuffer.DataType ++import javax.annotation.concurrent.NotThreadSafe ++ ++/** ++ * Implementation of writeable Java-only MapBuffer, which can be used to send information through ++ * JNI. ++ * ++ * See [MapBuffer] for more details ++ */ ++@StableReactNativeAPI ++@NotThreadSafe ++@DoNotStrip ++public class WritableMapBuffer : MapBuffer { ++ private val values: SparseArray = SparseArray() ++ ++ /* ++ * Write methods ++ */ ++ ++ /** ++ * Adds a boolean value for given key to the MapBuffer. ++ * ++ * @param key entry key ++ * @param value entry value ++ * @throws IllegalArgumentException if key is out of [UShort] range ++ */ ++ public fun put(key: Int, value: Boolean): WritableMapBuffer = putInternal(key, value) ++ ++ /** ++ * Adds an int value for given key to the MapBuffer. ++ * ++ * @param key entry key ++ * @param value entry value ++ * @throws IllegalArgumentException if key is out of [UShort] range ++ */ ++ public fun put(key: Int, value: Int): WritableMapBuffer = putInternal(key, value) ++ ++ /** ++ * Adds a long value for given key to the MapBuffer. ++ * ++ * @param key entry key ++ * @param value entry value ++ * @throws IllegalArgumentException if key is out of [UShort] range ++ */ ++ public fun put(key: Int, value: Long): WritableMapBuffer = putInternal(key, value) ++ ++ /** ++ * Adds a double value for given key to the MapBuffer. ++ * ++ * @param key entry key ++ * @param value entry value ++ * @throws IllegalArgumentException if key is out of [UShort] range ++ */ ++ public fun put(key: Int, value: Double): WritableMapBuffer = putInternal(key, value) ++ ++ /** ++ * Adds a string value for given key to the MapBuffer. ++ * ++ * @param key entry key ++ * @param value entry value ++ * @throws IllegalArgumentException if key is out of [UShort] range ++ */ ++ public fun put(key: Int, value: String): WritableMapBuffer = putInternal(key, value) ++ ++ /** ++ * Adds a [MapBuffer] value for given key to the current MapBuffer. ++ * ++ * @param key entry key ++ * @param value entry value ++ * @throws IllegalArgumentException if key is out of [UShort] range ++ */ ++ public fun put(key: Int, value: MapBuffer): WritableMapBuffer = putInternal(key, value) ++ ++ private fun putInternal(key: Int, value: Any): WritableMapBuffer { ++ require(key in KEY_RANGE) { ++ "Only integers in [${UShort.MIN_VALUE};${UShort.MAX_VALUE}] range are allowed for keys." ++ } ++ ++ values.put(key, value) ++ return this ++ } ++ ++ /* ++ * Read methods ++ */ ++ ++ override val count: Int ++ get() = values.size() ++ ++ override fun contains(key: Int): Boolean = values.get(key) != null ++ ++ override fun getKeyOffset(key: Int): Int = values.indexOfKey(key) ++ ++ override fun entryAt(offset: Int): MapBuffer.Entry = MapBufferEntry(offset) ++ ++ override fun getType(key: Int): DataType { ++ val value = values.get(key) ++ require(value != null) { "Key not found: $key" } ++ return value.dataType(key) ++ } ++ ++ override fun getBoolean(key: Int): Boolean = verifyValue(key, values.get(key)) ++ ++ override fun getInt(key: Int): Int = verifyValue(key, values.get(key)) ++ ++ override fun getLong(key: Int): Long = verifyValue(key, values.get(key)) ++ ++ override fun getDouble(key: Int): Double = verifyValue(key, values.get(key)) ++ ++ override fun getString(key: Int): String = verifyValue(key, values.get(key)) ++ ++ override fun getMapBuffer(key: Int): MapBuffer = verifyValue(key, values.get(key)) ++ ++ override fun getMapBufferList(key: Int): List = verifyValue(key, values.get(key)) ++ ++ /** Generalizes verification of the value types based on the requested type. */ ++ private inline fun verifyValue(key: Int, value: Any?): T { ++ require(value != null) { "Key not found: $key" } ++ check(value is T) { ++ "Expected ${T::class.java} for key: $key, found ${value.javaClass} instead." ++ } ++ return value ++ } ++ ++ private fun Any.dataType(key: Int): DataType { ++ return when (val value = this) { ++ is Boolean -> DataType.BOOL ++ is Int -> DataType.INT ++ is Long -> DataType.LONG ++ is Double -> DataType.DOUBLE ++ is String -> DataType.STRING ++ is MapBuffer -> DataType.MAP ++ else -> throw IllegalStateException("Key $key has value of unknown type: ${value.javaClass}") ++ } ++ } ++ ++ override fun iterator(): Iterator = ++ object : Iterator { ++ var count = 0 ++ ++ override fun hasNext(): Boolean = count < values.size() ++ ++ override fun next(): MapBuffer.Entry = MapBufferEntry(count++) ++ } ++ ++ private inner class MapBufferEntry(private val index: Int) : MapBuffer.Entry { ++ override val key: Int = values.keyAt(index) ++ override val type: DataType = values.valueAt(index).dataType(key) ++ override val booleanValue: Boolean ++ get() = verifyValue(key, values.valueAt(index)) ++ ++ override val intValue: Int ++ get() = verifyValue(key, values.valueAt(index)) ++ ++ override val longValue: Long ++ get() = verifyValue(key, values.valueAt(index)) ++ ++ override val doubleValue: Double ++ get() = verifyValue(key, values.valueAt(index)) ++ ++ override val stringValue: String ++ get() = verifyValue(key, values.valueAt(index)) ++ ++ override val mapBufferValue: MapBuffer ++ get() = verifyValue(key, values.valueAt(index)) ++ } ++ ++ /* ++ * JNI hooks ++ */ ++ ++ @DoNotStrip ++ @Suppress("UNUSED") ++ /** JNI hook for MapBuffer to retrieve sorted keys from this class. */ ++ private fun getKeys(): IntArray = IntArray(values.size()) { values.keyAt(it) } ++ ++ @DoNotStrip ++ @Suppress("UNUSED") ++ /** JNI hook for MapBuffer to retrieve sorted values from this class. */ ++ private fun getValues(): Array = Array(values.size()) { values.valueAt(it) } ++ ++ private companion object { ++ init { ++ MapBufferSoLoader.staticInit() ++ } ++ } ++} +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/defaults/DefaultComponentsRegistry.kt b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/defaults/DefaultComponentsRegistry.kt +new file mode 100644 +index 0000000..14d33e5 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/defaults/DefaultComponentsRegistry.kt +@@ -0,0 +1,44 @@ ++/* ++ * 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. ++ */ ++ ++package com.facebook.react.defaults ++ ++import com.facebook.jni.HybridData ++import com.facebook.proguard.annotations.DoNotStrip ++import com.facebook.react.fabric.ComponentFactory ++ ++/** ++ * A utility class that provides users a ComponentRegistry they can customize with a C++ ++ * implementation of its native methods. ++ * ++ * This class works together with the [DefaultNewArchitectureEntryPoint] and it's C++ implementation ++ * is hosted inside the React Native framework ++ * ++ * TODO(T186951312): Should this be @UnstableReactNativeAPI? ++ */ ++@DoNotStrip ++public class DefaultComponentsRegistry ++@DoNotStrip ++private constructor(componentFactory: ComponentFactory) { ++ ++ @DoNotStrip ++ @Suppress("NoHungarianNotation") ++ private val mHybridData: HybridData = initHybrid(componentFactory) ++ ++ @DoNotStrip private external fun initHybrid(componentFactory: ComponentFactory): HybridData ++ ++ public companion object { ++ init { ++ DefaultSoLoader.maybeLoadSoLibrary() ++ } ++ ++ @JvmStatic ++ @DoNotStrip ++ public fun register(componentFactory: ComponentFactory): DefaultComponentsRegistry = ++ DefaultComponentsRegistry(componentFactory) ++ } ++} +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/defaults/DefaultNewArchitectureEntryPoint.kt b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/defaults/DefaultNewArchitectureEntryPoint.kt +new file mode 100644 +index 0000000..0f8dfad +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/defaults/DefaultNewArchitectureEntryPoint.kt +@@ -0,0 +1,152 @@ ++/* ++ * 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. ++ */ ++ ++@file:Suppress("DEPRECATION") // We want to use ReactFeatureFlags here specifically ++ ++package com.facebook.react.defaults ++ ++import com.facebook.infer.annotation.Assertions ++import com.facebook.react.common.annotations.VisibleForTesting ++import com.facebook.react.config.ReactFeatureFlags ++import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags ++import com.facebook.react.internal.featureflags.ReactNativeFeatureFlagsDefaults ++ ++/** ++ * A utility class that serves as an entry point for users setup the New Architecture. ++ * ++ * This class needs to be invoked as `DefaultNewArchitectureEntryPoint.load(...)` by passing a ++ * series of optional parameters. ++ * ++ * By default it loads a library called `appmodules`. `appmodules` is a convention used to refer to ++ * the application dynamic library. If changed here should be updated also inside the template. ++ * ++ * By default it also enables both TurboModules, Fabric and Concurrent React (aka React 18), and ++ * Bridgeless ++ */ ++public object DefaultNewArchitectureEntryPoint { ++ @JvmStatic ++ @JvmOverloads ++ public fun load( ++ turboModulesEnabled: Boolean = true, ++ fabricEnabled: Boolean = true, ++ bridgelessEnabled: Boolean = true ++ ) { ++ val (isValid, errorMessage) = ++ isConfigurationValid(turboModulesEnabled, fabricEnabled, bridgelessEnabled) ++ if (!isValid) { ++ error(errorMessage) ++ } ++ ReactFeatureFlags.useTurboModules = turboModulesEnabled ++ ReactFeatureFlags.enableFabricRenderer = fabricEnabled ++ ReactFeatureFlags.unstable_useFabricInterop = fabricEnabled ++ ReactFeatureFlags.enableBridgelessArchitecture = bridgelessEnabled ++ ReactFeatureFlags.unstable_useTurboModuleInterop = bridgelessEnabled ++ val fuseboxEnabledDebug = fuseboxEnabled ++ ++ if (bridgelessEnabled) { ++ ReactNativeFeatureFlags.override( ++ object : ReactNativeFeatureFlagsDefaults() { ++ override fun useModernRuntimeScheduler(): Boolean = true ++ ++ override fun enableMicrotasks(): Boolean = true ++ ++ override fun batchRenderingUpdatesInEventLoop(): Boolean = true ++ ++ override fun useNativeViewConfigsInBridgelessMode(): Boolean = true ++ ++ // We need to assign this now as we can't call ReactNativeFeatureFlags.override() ++ // more than once. ++ override fun fuseboxEnabledDebug(): Boolean = fuseboxEnabledDebug ++ }) ++ } ++ ++ privateFabricEnabled = fabricEnabled ++ privateTurboModulesEnabled = turboModulesEnabled ++ privateConcurrentReactEnabled = fabricEnabled ++ privateBridgelessEnabled = bridgelessEnabled ++ ++ DefaultSoLoader.maybeLoadSoLibrary() ++ loaded = true ++ } ++ ++ private var privateFabricEnabled: Boolean = false ++ ++ @JvmStatic ++ public val fabricEnabled: Boolean ++ get() = privateFabricEnabled ++ ++ private var privateTurboModulesEnabled: Boolean = false ++ ++ @JvmStatic ++ public val turboModulesEnabled: Boolean ++ get() = privateTurboModulesEnabled ++ ++ private var privateConcurrentReactEnabled: Boolean = false ++ ++ @JvmStatic ++ public val concurrentReactEnabled: Boolean ++ get() = privateConcurrentReactEnabled ++ ++ private var privateBridgelessEnabled: Boolean = false ++ ++ @JvmStatic ++ public val bridgelessEnabled: Boolean ++ get() = privateBridgelessEnabled ++ ++ @VisibleForTesting ++ public fun isConfigurationValid( ++ turboModulesEnabled: Boolean, ++ fabricEnabled: Boolean, ++ bridgelessEnabled: Boolean ++ ): Pair = ++ when { ++ fabricEnabled && !turboModulesEnabled -> ++ false to ++ "fabricEnabled=true requires turboModulesEnabled=true (is now false) - Please update your DefaultNewArchitectureEntryPoint.load() parameters." ++ bridgelessEnabled && (!turboModulesEnabled || !fabricEnabled) -> ++ false to ++ "bridgelessEnabled=true requires (turboModulesEnabled=true AND fabricEnabled=true) - Please update your DefaultNewArchitectureEntryPoint.load() parameters." ++ else -> true to "" ++ } ++ ++ // region unstable_loadFusebox (short-lived API for testing Fusebox - EXPERIMENTAL) ++ ++ /** ++ * Set to {@code true} when {@link #load()} is called. Used for assertion in ++ * {@link #unstable_loadFusebox()}. ++ */ ++ private var loaded: Boolean = false ++ ++ /** Set to {@code true} if {@link #unstable_loadFusebox()} was called. */ ++ private var fuseboxEnabled: Boolean = false ++ ++ /** ++ * If called, enables the new debugger stack (codename Fusebox). Must be called before ++ * {@link #load()}. ++ * ++ * @param isNewArchEnabled Please pass {@code BuildConfig.IS_NEW_ARCH_ENABLED} here. ++ */ ++ @JvmStatic ++ public fun unstable_loadFusebox( ++ isNewArchEnabled: Boolean, ++ ) { ++ fuseboxEnabled = true ++ ++ if (!isNewArchEnabled) { ++ ReactNativeFeatureFlags.override( ++ object : ReactNativeFeatureFlagsDefaults() { ++ override fun fuseboxEnabledDebug(): Boolean = true ++ }) ++ } else { ++ Assertions.assertCondition( ++ loaded == false, "unstable_loadFusebox() must be called before load()") ++ } ++ } ++ ++ // endregion ++ ++} +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/defaults/DefaultReactActivityDelegate.kt b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/defaults/DefaultReactActivityDelegate.kt +new file mode 100644 +index 0000000..4cb4263 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/defaults/DefaultReactActivityDelegate.kt +@@ -0,0 +1,44 @@ ++/* ++ * 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. ++ */ ++ ++package com.facebook.react.defaults ++ ++import com.facebook.react.ReactActivity ++import com.facebook.react.ReactActivityDelegate ++ ++/** ++ * A utility class that allows you to simplify the setup of a [ReactActivityDelegate] for new apps ++ * in Open Source. ++ * ++ * Specifically, with this class you can simply control if Fabric is enabled for an Activity using ++ * the boolean flag in the constructor. ++ * ++ * @param fabricEnabled Whether Fabric should be enabled for the RootView of this Activity. ++ */ ++public open class DefaultReactActivityDelegate( ++ activity: ReactActivity, ++ mainComponentName: String, ++ private val fabricEnabled: Boolean = false, ++) : ReactActivityDelegate(activity, mainComponentName) { ++ ++ @Deprecated( ++ message = ++ "Creating DefaultReactActivityDelegate with both fabricEnabled and " + ++ "concurrentReactEnabled is deprecated. Please pass only one boolean value that will" + ++ " be used for both flags", ++ level = DeprecationLevel.WARNING, ++ replaceWith = ++ ReplaceWith("DefaultReactActivityDelegate(activity, mainComponentName, fabricEnabled)")) ++ public constructor( ++ activity: ReactActivity, ++ mainComponentName: String, ++ fabricEnabled: Boolean, ++ @Suppress("UNUSED_PARAMETER") concurrentReactEnabled: Boolean, ++ ) : this(activity, mainComponentName, fabricEnabled) ++ ++ override fun isFabricEnabled(): Boolean = fabricEnabled ++} +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/defaults/DefaultReactHost.kt b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/defaults/DefaultReactHost.kt +new file mode 100644 +index 0000000..06452e5 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/defaults/DefaultReactHost.kt +@@ -0,0 +1,123 @@ ++/* ++ * 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. ++ */ ++ ++package com.facebook.react.defaults ++ ++import android.content.Context ++import com.facebook.react.JSEngineResolutionAlgorithm ++import com.facebook.react.ReactHost ++import com.facebook.react.ReactNativeHost ++import com.facebook.react.ReactPackage ++import com.facebook.react.bridge.JSBundleLoader ++import com.facebook.react.bridge.ReactContext ++import com.facebook.react.common.annotations.UnstableReactNativeAPI ++import com.facebook.react.common.build.ReactBuildConfig ++import com.facebook.react.fabric.ComponentFactory ++import com.facebook.react.runtime.JSCInstance ++import com.facebook.react.runtime.ReactHostImpl ++import com.facebook.react.runtime.cxxreactpackage.CxxReactPackage ++import com.facebook.react.runtime.hermes.HermesInstance ++ ++/** ++ * A utility class that allows you to simplify the setup of a [ReactHost] for new apps in Open ++ * Source. ++ * ++ * [ReactHost] is an interface responsible of handling the lifecycle of a React Native app when ++ * running in bridgeless mode. ++ */ ++public object DefaultReactHost { ++ private var reactHost: ReactHost? = null ++ ++ /** ++ * Util function to create a default [ReactHost] to be used in your application. This method is ++ * used by the New App template. ++ * ++ * @param context the Android [Context] to use for creating the [ReactHost] ++ * @param packageList the list of [ReactPackage]s to use for creating the [ReactHost] ++ * @param jsMainModulePath the path to your app's main module on Metro. Usually `index` or ++ * `index.` ++ * @param jsBundleAssetPath the path to the JS bundle relative to the assets directory. Will be ++ * composed in a `asset://...` URL ++ * @param isHermesEnabled whether to use Hermes as the JS engine, default to true. ++ * @param useDevSupport whether to enable dev support, default to ReactBuildConfig.DEBUG. ++ * @param cxxReactPackageProviders a list of cxxreactpackage providers (to register c++ turbo ++ * modules) ++ * ++ * TODO(T186951312): Should this be @UnstableReactNativeAPI? ++ */ ++ @OptIn(UnstableReactNativeAPI::class) ++ @JvmStatic ++ public fun getDefaultReactHost( ++ context: Context, ++ packageList: List, ++ jsMainModulePath: String = "index", ++ jsBundleAssetPath: String = "index", ++ isHermesEnabled: Boolean = true, ++ useDevSupport: Boolean = ReactBuildConfig.DEBUG, ++ cxxReactPackageProviders: List<(ReactContext) -> CxxReactPackage> = emptyList(), ++ ): ReactHost { ++ if (reactHost == null) { ++ val jsBundleLoader = ++ JSBundleLoader.createAssetLoader(context, "assets://$jsBundleAssetPath", true) ++ val jsRuntimeFactory = if (isHermesEnabled) HermesInstance() else JSCInstance() ++ val defaultTmmDelegateBuilder = DefaultTurboModuleManagerDelegate.Builder() ++ cxxReactPackageProviders.forEach { defaultTmmDelegateBuilder.addCxxReactPackage(it) } ++ val defaultReactHostDelegate = ++ DefaultReactHostDelegate( ++ jsMainModulePath = jsMainModulePath, ++ jsBundleLoader = jsBundleLoader, ++ reactPackages = packageList, ++ jsRuntimeFactory = jsRuntimeFactory, ++ turboModuleManagerDelegateBuilder = defaultTmmDelegateBuilder) ++ val componentFactory = ComponentFactory() ++ DefaultComponentsRegistry.register(componentFactory) ++ // TODO: T164788699 find alternative of accessing ReactHostImpl for initialising reactHost ++ reactHost = ++ ReactHostImpl( ++ context, ++ defaultReactHostDelegate, ++ componentFactory, ++ true /* allowPackagerServerAccess */, ++ useDevSupport, ++ ) ++ .apply { ++ jsEngineResolutionAlgorithm = ++ if (isHermesEnabled) { ++ JSEngineResolutionAlgorithm.HERMES ++ } else { ++ JSEngineResolutionAlgorithm.JSC ++ } ++ } ++ } ++ return reactHost as ReactHost ++ } ++ ++ /** ++ * Util function to create a default [ReactHost] to be used in your application. This method is ++ * used by the New App template. ++ * ++ * This method takes in input a [ReactNativeHost] (bridge-mode) and uses its configuration to ++ * create an equivalent [ReactHost] (bridgeless-mode). ++ * ++ * @param context the Android [Context] to use for creating the [ReactHost] ++ * @param reactNativeHost the [ReactNativeHost] to use for creating the [ReactHost] ++ * ++ * TODO(T186951312): Should this be @UnstableReactNativeAPI? It's not, to maintain consistency ++ * with above getDefaultReactHost. ++ */ ++ @OptIn(UnstableReactNativeAPI::class) ++ @JvmStatic ++ public fun getDefaultReactHost( ++ context: Context, ++ reactNativeHost: ReactNativeHost, ++ ): ReactHost { ++ require(reactNativeHost is DefaultReactNativeHost) { ++ "You can call getDefaultReactHost only with instances of DefaultReactNativeHost" ++ } ++ return reactNativeHost.toReactHost(context) ++ } ++} +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/defaults/DefaultReactHostDelegate.kt b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/defaults/DefaultReactHostDelegate.kt +new file mode 100644 +index 0000000..3c50cac +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/defaults/DefaultReactHostDelegate.kt +@@ -0,0 +1,55 @@ ++/* ++ * 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. ++ */ ++ ++package com.facebook.react.defaults ++ ++import com.facebook.jni.annotations.DoNotStrip ++import com.facebook.react.ReactPackage ++import com.facebook.react.ReactPackageTurboModuleManagerDelegate ++import com.facebook.react.bridge.JSBundleLoader ++import com.facebook.react.common.annotations.UnstableReactNativeAPI ++import com.facebook.react.fabric.ReactNativeConfig ++import com.facebook.react.runtime.BindingsInstaller ++import com.facebook.react.runtime.JSRuntimeFactory ++import com.facebook.react.runtime.ReactHostDelegate ++import com.facebook.react.runtime.hermes.HermesInstance ++ ++/** ++ * A utility class that allows you to simplify the initialization of React Native by setting up a ++ * [ReactHostDelegate] that uses recommended dependencies. ++ * ++ * @param jsMainModulePath Path to your app's main module on Metro. This is used when reloading JS ++ * during development. All paths are relative to the root folder the packager is serving files ++ * from. Examples: `index.android` or `subdirectory/index.android` ++ * @param jsBundleLoader Bundle loader to use when setting up JS environment.

Example: ++ * [JSBundleLoader.createFileLoader(application, bundleFile)] ++ * @param reactPackages list of reactPackages to expose Native Modules and View Components to JS ++ * @param jsRuntimeFactory Object that holds a native reference to the JS Runtime factory ++ * @param bindingsInstaller Object that holds a native C++ references that allow host applications ++ * to install C++ objects into jsi::Runtime during the initialization of React Native ++ * @param reactNativeConfig ReactNative Configuration that allows to customize the behavior of ++ * key/value pairs used by the framework to enable/disable experimental capabilities ++ * @param exceptionHandler Callback that can be used by React Native host applications to react to ++ * exceptions thrown by the internals of React Native. ++ */ ++@DoNotStrip ++@UnstableReactNativeAPI ++public class DefaultReactHostDelegate( ++ override val jsMainModulePath: String, ++ override val jsBundleLoader: JSBundleLoader, ++ override val reactPackages: List = emptyList(), ++ override val jsRuntimeFactory: JSRuntimeFactory = HermesInstance(), ++ override val bindingsInstaller: BindingsInstaller? = null, ++ private val reactNativeConfig: ReactNativeConfig = ReactNativeConfig.DEFAULT_CONFIG, ++ private val exceptionHandler: (Exception) -> Unit = {}, ++ override val turboModuleManagerDelegateBuilder: ReactPackageTurboModuleManagerDelegate.Builder ++) : ReactHostDelegate { ++ ++ override fun getReactNativeConfig(): ReactNativeConfig = reactNativeConfig ++ ++ override fun handleInstanceException(error: Exception): Unit = exceptionHandler(error) ++} +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/defaults/DefaultReactNativeHost.kt b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/defaults/DefaultReactNativeHost.kt +new file mode 100644 +index 0000000..e309410 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/defaults/DefaultReactNativeHost.kt +@@ -0,0 +1,117 @@ ++/* ++ * 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. ++ */ ++ ++package com.facebook.react.defaults ++ ++import android.app.Application ++import android.content.Context ++import com.facebook.react.JSEngineResolutionAlgorithm ++import com.facebook.react.ReactHost ++import com.facebook.react.ReactNativeHost ++import com.facebook.react.ReactPackageTurboModuleManagerDelegate ++import com.facebook.react.bridge.ReactApplicationContext ++import com.facebook.react.bridge.UIManagerProvider ++import com.facebook.react.common.annotations.UnstableReactNativeAPI ++import com.facebook.react.fabric.ComponentFactory ++import com.facebook.react.fabric.FabricUIManagerProviderImpl ++import com.facebook.react.fabric.ReactNativeConfig ++import com.facebook.react.uimanager.ViewManagerRegistry ++import com.facebook.react.uimanager.ViewManagerResolver ++ ++/** ++ * A utility class that allows you to simplify the setup of a [ReactNativeHost] for new apps in Open ++ * Source. ++ * ++ * Specifically, for apps that are using the New Architecture, this Default class takes care of ++ * providing the default TurboModuleManagerDelegateBuilder and the default JSIModulePackage, ++ * provided the name of the dynamic library to load. ++ */ ++public abstract class DefaultReactNativeHost ++protected constructor( ++ application: Application, ++) : ReactNativeHost(application) { ++ ++ override fun getReactPackageTurboModuleManagerDelegateBuilder(): ++ ReactPackageTurboModuleManagerDelegate.Builder? = ++ if (isNewArchEnabled) { ++ DefaultTurboModuleManagerDelegate.Builder() ++ } else { ++ null ++ } ++ ++ override fun getUIManagerProvider(): UIManagerProvider? = ++ if (isNewArchEnabled) { ++ UIManagerProvider { reactApplicationContext: ReactApplicationContext -> ++ val componentFactory = ComponentFactory() ++ DefaultComponentsRegistry.register(componentFactory) ++ ++ val viewManagerRegistry = ++ if (lazyViewManagersEnabled) { ++ ViewManagerRegistry( ++ object : ViewManagerResolver { ++ override fun getViewManager(viewManagerName: String) = ++ reactInstanceManager.createViewManager(viewManagerName) ++ ++ override fun getViewManagerNames() = reactInstanceManager.viewManagerNames ++ }) ++ } else { ++ ViewManagerRegistry( ++ reactInstanceManager.getOrCreateViewManagers(reactApplicationContext)) ++ } ++ ++ FabricUIManagerProviderImpl( ++ componentFactory, ReactNativeConfig.DEFAULT_CONFIG, viewManagerRegistry) ++ .createUIManager(reactApplicationContext) ++ } ++ } else { ++ null ++ } ++ ++ override fun getJSEngineResolutionAlgorithm(): JSEngineResolutionAlgorithm? = ++ when (isHermesEnabled) { ++ true -> JSEngineResolutionAlgorithm.HERMES ++ false -> JSEngineResolutionAlgorithm.JSC ++ null -> null ++ } ++ ++ /** ++ * Returns whether the user wants to use the New Architecture or not. ++ * ++ * If true, we will load the default JSI Module Package and TurboModuleManagerDelegate needed to ++ * enable the New Architecture ++ * ++ * If false, the app will not attempt to load the New Architecture modules. ++ */ ++ protected open val isNewArchEnabled: Boolean ++ get() = false ++ ++ /** ++ * Returns whether the user wants to use Hermes. ++ * ++ * If true, the app will load the Hermes engine, and fail if not found. If false, the app will ++ * load the JSC engine, and fail if not found. If null, the app will attempt to load JSC first and ++ * fallback to Hermes if not found. ++ */ ++ protected open val isHermesEnabled: Boolean? ++ get() = null ++ ++ /** ++ * Converts this [ReactNativeHost] (bridge-mode) to a [ReactHost] (bridgeless-mode). ++ * ++ * @param context the Android [Context] to use for creating the [ReactHost] ++ */ ++ @UnstableReactNativeAPI ++ internal fun toReactHost(context: Context): ReactHost = ++ DefaultReactHost.getDefaultReactHost( ++ context, ++ packages, ++ jsMainModuleName, ++ bundleAssetName ?: "index", ++ isHermesEnabled ?: true, ++ useDeveloperSupport, ++ ) ++} +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/defaults/DefaultTurboModuleManagerDelegate.kt b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/defaults/DefaultTurboModuleManagerDelegate.kt +new file mode 100644 +index 0000000..3da64ba +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/defaults/DefaultTurboModuleManagerDelegate.kt +@@ -0,0 +1,79 @@ ++/* ++ * 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. ++ */ ++ ++package com.facebook.react.defaults ++ ++import com.facebook.jni.HybridData ++import com.facebook.proguard.annotations.DoNotStrip ++import com.facebook.react.ReactPackage ++import com.facebook.react.ReactPackageTurboModuleManagerDelegate ++import com.facebook.react.bridge.ReactApplicationContext ++import com.facebook.react.common.annotations.UnstableReactNativeAPI ++import com.facebook.react.runtime.cxxreactpackage.CxxReactPackage ++ ++/** ++ * A utility class that allows you to simplify the setup of a ++ * [ReactPackageTurboModuleManagerDelegate] for new apps in Open Source. ++ * ++ * This class works together with the [DefaultNewArchitectureEntryPoint] and it's C++ implementation ++ * is hosted inside the React Native framework ++ * ++ * TODO(T186951312): Should this be @UnstableReactNativeAPI? ++ */ ++@OptIn(UnstableReactNativeAPI::class) ++public class DefaultTurboModuleManagerDelegate ++private constructor( ++ context: ReactApplicationContext, ++ packages: List, ++ cxxReactPackages: List, ++) : ReactPackageTurboModuleManagerDelegate(context, packages, initHybrid(cxxReactPackages)) { ++ ++ override fun initHybrid(): HybridData { ++ throw UnsupportedOperationException( ++ "DefaultTurboModuleManagerDelegate.initHybrid() must never be called!") ++ } ++ ++ public class Builder : ReactPackageTurboModuleManagerDelegate.Builder() { ++ private var cxxReactPackageProviders: ++ MutableList<((context: ReactApplicationContext) -> CxxReactPackage)> = ++ mutableListOf() ++ ++ public fun addCxxReactPackage(provider: () -> CxxReactPackage): Builder { ++ cxxReactPackageProviders.add { _ -> provider() } ++ return this ++ } ++ ++ public fun addCxxReactPackage( ++ provider: (context: ReactApplicationContext) -> CxxReactPackage ++ ): Builder { ++ cxxReactPackageProviders.add(provider) ++ return this ++ } ++ ++ override fun build( ++ context: ReactApplicationContext, ++ packages: List ++ ): DefaultTurboModuleManagerDelegate { ++ val cxxReactPackages = mutableListOf() ++ for (cxxReactPackageProvider in cxxReactPackageProviders) { ++ cxxReactPackages.add(cxxReactPackageProvider(context)) ++ } ++ ++ return DefaultTurboModuleManagerDelegate(context, packages, cxxReactPackages) ++ } ++ } ++ ++ private companion object { ++ init { ++ DefaultSoLoader.maybeLoadSoLibrary() ++ } ++ ++ @DoNotStrip ++ @JvmStatic ++ external fun initHybrid(cxxReactPackages: List): HybridData ++ } ++} +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/devsupport/AndroidManifest.xml b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/devsupport/AndroidManifest.xml +new file mode 100644 +index 0000000..8e8524c +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/devsupport/AndroidManifest.xml +@@ -0,0 +1,10 @@ ++ ++ ++ ++ ++ ++ ++ +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/fabric/ReactNativeConfig.kt b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/fabric/ReactNativeConfig.kt +new file mode 100644 +index 0000000..7cc81c4 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/fabric/ReactNativeConfig.kt +@@ -0,0 +1,54 @@ ++/* ++ * 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. ++ */ ++ ++package com.facebook.react.fabric ++ ++import com.facebook.proguard.annotations.DoNotStrip ++ ++/** ++ * ReactNative Configuration that allows to customize the behavior of key/value pairs used by the ++ * framework to enable/disable capabilities. ++ * ++ * The hosting app should provide an implementation of this interface to allow specific ++ * customization of single keys. An empty implementation is available as [EmptyReactNativeConfig]. ++ * ++ * This is a wrapper for the ReactNativeConfig object in C++ ++ */ ++@DoNotStrip ++public interface ReactNativeConfig { ++ /** ++ * Get a boolean param by string name. Default should be false. ++ * ++ * @param param The string name of the parameter being requested. ++ */ ++ @DoNotStrip public fun getBool(param: String): Boolean ++ ++ /** ++ * Get a Long param by string name. Default should be 0. ++ * ++ * @param param The string name of the parameter being requested. ++ */ ++ @DoNotStrip public fun getInt64(param: String): Long ++ ++ /** ++ * Get a string param by string name. Default should be "", empty string. ++ * ++ * @param param The string name of the parameter being requested. ++ */ ++ @DoNotStrip public fun getString(param: String): String ++ ++ /** ++ * Get a double param by string name. Default should be 0. ++ * ++ * @param param The string name of the parameter being requested. ++ */ ++ @DoNotStrip public fun getDouble(param: String): Double ++ ++ public companion object { ++ @JvmField public val DEFAULT_CONFIG: ReactNativeConfig = EmptyReactNativeConfig() ++ } ++} +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/interfaces/TaskInterface.kt b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/interfaces/TaskInterface.kt +new file mode 100644 +index 0000000..c7d9680 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/interfaces/TaskInterface.kt +@@ -0,0 +1,44 @@ ++/* ++ * 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. ++ */ ++ ++package com.facebook.react.interfaces ++ ++import java.util.concurrent.TimeUnit ++ ++/** ++ * This is the public interface for Task which represents the result of an asynchronous computation. ++ */ ++public interface TaskInterface { ++ ++ /** Blocks until the task is complete. */ ++ @Throws(InterruptedException::class) public fun waitForCompletion() ++ ++ /** ++ * Blocks until the task is complete or times out. ++ * ++ * @return true if the task completed (has a result, an error, or was cancelled). false otherwise. ++ */ ++ @Throws(InterruptedException::class) ++ public fun waitForCompletion(duration: Long, timeUnit: TimeUnit?): Boolean ++ ++ /** @return The result of the task, if set. null otherwise. */ ++ public fun getResult(): TResult? ++ ++ /** @return The error for the task, if set. null otherwise. */ ++ public fun getError(): Exception? ++ ++ /** ++ * @return true if the task completed (has a result, an error, or was cancelled. false otherwise. ++ */ ++ public fun isCompleted(): Boolean ++ ++ /** @return true if the task was cancelled, false otherwise. */ ++ public fun isCancelled(): Boolean ++ ++ /** @return true if the task has an error, false otherwise. */ ++ public fun isFaulted(): Boolean ++} +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/interfaces/exceptionmanager/ReactJsExceptionHandler.kt b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/interfaces/exceptionmanager/ReactJsExceptionHandler.kt +new file mode 100644 +index 0000000..c12a1eb +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/interfaces/exceptionmanager/ReactJsExceptionHandler.kt +@@ -0,0 +1,50 @@ ++/* ++ * 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. ++ */ ++ ++package com.facebook.react.interfaces.exceptionmanager ++ ++import com.facebook.proguard.annotations.DoNotStripAny ++import com.facebook.react.common.annotations.UnstableReactNativeAPI ++import java.util.ArrayList ++ ++@DoNotStripAny ++@UnstableReactNativeAPI ++public fun interface ReactJsExceptionHandler { ++ @DoNotStripAny ++ public interface ParsedError { ++ @DoNotStripAny ++ public interface StackFrame { ++ public val fileName: String ++ public val methodName: String ++ public val lineNumber: Int ++ public val columnNumber: Int ++ } ++ ++ public val frames: List ++ public val message: String ++ public val exceptionId: Int ++ public val isFatal: Boolean ++ } ++ ++ @DoNotStripAny ++ private data class ParsedStackFrameImpl( ++ override val fileName: String, ++ override val methodName: String, ++ override val lineNumber: Int, ++ override val columnNumber: Int, ++ ) : ParsedError.StackFrame ++ ++ @DoNotStripAny ++ private data class ParsedErrorImpl( ++ override val frames: ArrayList, ++ override val message: String, ++ override val exceptionId: Int, ++ override val isFatal: Boolean, ++ ) : ParsedError ++ ++ public fun reportJsException(errorMap: ParsedError) ++} +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/interfaces/fabric/ReactSurface.kt b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/interfaces/fabric/ReactSurface.kt +new file mode 100644 +index 0000000..5f2e13b +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/interfaces/fabric/ReactSurface.kt +@@ -0,0 +1,49 @@ ++/* ++ * 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. ++ */ ++ ++package com.facebook.react.interfaces.fabric ++ ++import android.content.Context ++import android.view.ViewGroup ++import com.facebook.react.interfaces.TaskInterface ++ ++/** Represents a Surface in React Native. */ ++public interface ReactSurface { ++ ++ // the API of this interface will be completed as we analyze and refactor API of ReactSurface, ++ // ReactRootView, etc. ++ ++ // Returns surface ID of this surface ++ public val surfaceID: Int ++ ++ // Returns module name of this surface ++ public val moduleName: String ++ ++ // Returns whether the surface is running or not ++ public val isRunning: Boolean ++ ++ // Returns React root view of this surface ++ public val view: ViewGroup? ++ ++ // Returns context associated with the surface ++ public val context: Context ++ ++ // Prerender this surface ++ public fun prerender(): TaskInterface ++ ++ // Start running this surface ++ public fun start(): TaskInterface ++ ++ // Stop running this surface ++ public fun stop(): TaskInterface ++ ++ // Clear surface ++ public fun clear() ++ ++ // Detach surface from Host ++ public fun detach() ++} +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/interfaces/fabric/SurfaceHandler.kt b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/interfaces/fabric/SurfaceHandler.kt +new file mode 100644 +index 0000000..e6a50ed +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/interfaces/fabric/SurfaceHandler.kt +@@ -0,0 +1,51 @@ ++/* ++ * 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. ++ */ ++ ++package com.facebook.react.interfaces.fabric ++ ++import com.facebook.react.bridge.NativeMap ++import javax.annotation.concurrent.ThreadSafe ++ ++/** Represents a Java variant of the surface, its status and inner data required to display it. */ ++@ThreadSafe ++public interface SurfaceHandler { ++ ++ /** ++ * Provides current surface id. Id should be updated after each call to {@link ++ * SurfaceHandler#stop} ++ */ ++ public val surfaceId: Int ++ ++ public val isRunning: Boolean ++ ++ public val moduleName: String ++ ++ /** Starts the surface if the surface is not running */ ++ public fun start() ++ ++ /** Stops the surface if it is currently running */ ++ public fun stop() ++ ++ public fun setProps(props: NativeMap) ++ ++ /** ++ * Updates current surface id. Id should be updated after each call to {@link SurfaceHandler#stop} ++ */ ++ public fun setSurfaceId(surfaceId: Int) ++ ++ public fun setLayoutConstraints( ++ widthMeasureSpec: Int, ++ heightMeasureSpec: Int, ++ offsetX: Int, ++ offsetY: Int, ++ doLeftAndRightSwapInRTL: Boolean, ++ isRTL: Boolean, ++ pixelDensity: Float ++ ) ++ ++ public fun setMountable(mountable: Boolean) ++} +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/jscexecutor/JSCExecutor.kt b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/jscexecutor/JSCExecutor.kt +new file mode 100644 +index 0000000..ed92a48 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/jscexecutor/JSCExecutor.kt +@@ -0,0 +1,36 @@ ++/* ++ * 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. ++ */ ++ ++package com.facebook.react.jscexecutor ++ ++import com.facebook.jni.HybridData ++import com.facebook.proguard.annotations.DoNotStrip ++import com.facebook.react.bridge.JavaScriptExecutor ++import com.facebook.react.bridge.ReadableNativeMap ++import com.facebook.soloader.SoLoader ++ ++@DoNotStrip ++public class JSCExecutor internal constructor(jscConfig: ReadableNativeMap) : ++ JavaScriptExecutor(initHybrid(jscConfig)) { ++ override fun getName(): String { ++ return "JSCExecutor" ++ } ++ ++ private companion object { ++ init { ++ loadLibrary() ++ } ++ ++ @JvmStatic ++ @Throws(UnsatisfiedLinkError::class) ++ fun loadLibrary() { ++ SoLoader.loadLibrary("jscexecutor") ++ } ++ ++ @JvmStatic private external fun initHybrid(jscConfig: ReadableNativeMap): HybridData ++ } ++} +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/jscexecutor/JSCExecutorFactory.kt b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/jscexecutor/JSCExecutorFactory.kt +new file mode 100644 +index 0000000..d4b9ea0 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/jscexecutor/JSCExecutorFactory.kt +@@ -0,0 +1,37 @@ ++/* ++ * 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. ++ */ ++ ++package com.facebook.react.jscexecutor ++ ++import com.facebook.react.bridge.JavaScriptExecutor ++import com.facebook.react.bridge.JavaScriptExecutorFactory ++import com.facebook.react.bridge.WritableNativeMap ++ ++public class JSCExecutorFactory(private val appName: String, private val deviceName: String) : ++ JavaScriptExecutorFactory { ++ ++ @Throws(Exception::class) ++ override fun create(): JavaScriptExecutor { ++ val jscConfig = ++ WritableNativeMap().apply { ++ putString("OwnerIdentity", "ReactNative") ++ putString("AppIdentity", appName) ++ putString("DeviceIdentity", deviceName) ++ } ++ return JSCExecutor(jscConfig) ++ } ++ ++ override fun startSamplingProfiler() { ++ throw UnsupportedOperationException("Starting sampling profiler not supported on ${toString()}") ++ } ++ ++ override fun stopSamplingProfiler(filename: String) { ++ throw UnsupportedOperationException("Stopping sampling profiler not supported on ${toString()}") ++ } ++ ++ override fun toString(): String = "JSIExecutor+JSCRuntime" ++} +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/runtime/BindingsInstaller.kt b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/runtime/BindingsInstaller.kt +new file mode 100644 +index 0000000..c229320 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/runtime/BindingsInstaller.kt +@@ -0,0 +1,22 @@ ++/* ++ * 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. ++ */ ++ ++package com.facebook.react.runtime ++ ++import com.facebook.jni.HybridData ++import com.facebook.proguard.annotations.DoNotStrip ++import com.facebook.proguard.annotations.DoNotStripAny ++import com.facebook.soloader.SoLoader ++ ++@DoNotStripAny ++public abstract class BindingsInstaller(@field:DoNotStrip private val mHybridData: HybridData?) { ++ private companion object { ++ init { ++ SoLoader.loadLibrary("rninstance") ++ } ++ } ++} +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/runtime/README.md b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/runtime/README.md +new file mode 100644 +index 0000000..60660d6 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/runtime/README.md +@@ -0,0 +1,3 @@ ++# Bridgeless Mode for Android ++ ++This library is not ready for integration for production nor local experimentation. Expect breaking changes regularly if you use any of these APIs. Use at your own risk! +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/runtime/ReactHostDelegate.kt b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/runtime/ReactHostDelegate.kt +new file mode 100644 +index 0000000..7c53923 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/runtime/ReactHostDelegate.kt +@@ -0,0 +1,84 @@ ++/* ++ * 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. ++ */ ++ ++package com.facebook.react.runtime ++ ++import com.facebook.infer.annotation.ThreadSafe ++import com.facebook.react.ReactPackage ++import com.facebook.react.ReactPackageTurboModuleManagerDelegate ++import com.facebook.react.bridge.JSBundleLoader ++import com.facebook.react.common.annotations.UnstableReactNativeAPI ++import com.facebook.react.fabric.ReactNativeConfig ++ ++/** ++ * [ReactHostDelegate] is an interface that defines parameters required to initialize React Native. ++ * This interface works in combination with [ReactHost] ++ */ ++@ThreadSafe ++@UnstableReactNativeAPI ++public interface ReactHostDelegate { ++ /** ++ * Path to your app's main module on Metro. This is used when reloading JS during development. All ++ * paths are relative to the root folder the packager is serving files from. Examples: ++ * `index.android` or `subdirectory/index.android` ++ */ ++ public val jsMainModulePath: String ++ ++ /** ++ * Object that holds a native C++ references that allow host applications to install C++ objects ++ * into jsi::Runtime during the initialization of React Native ++ */ ++ public val bindingsInstaller: BindingsInstaller? ++ ++ /** list of [ReactPackage] to expose Native Modules and View Components to JS */ ++ public val reactPackages: List ++ ++ /** Object that holds a native reference to the javascript engine */ ++ public val jsRuntimeFactory: JSRuntimeFactory ++ ++ /** ++ * Bundle loader to use when setting up JS environment.

Example: ++ * [JSBundleLoader.createFileLoader(application, bundleFile)] ++ */ ++ public val jsBundleLoader: JSBundleLoader ++ ++ /** TODO: combine getTurboModuleManagerDelegate inside [ReactPackage] */ ++ public val turboModuleManagerDelegateBuilder: ReactPackageTurboModuleManagerDelegate.Builder ++ ++ /** ++ * Callback that can be used by React Native host applications to react to exceptions thrown by ++ * the internals of React Native. ++ */ ++ public fun handleInstanceException(error: Exception) ++ ++ /** ++ * ReactNative Configuration that allows to customize the behavior of key/value pairs used by the ++ * framework to enable/disable experimental capabilities ++ * ++ * [moduleProvider] is a function that returns the Native Module with the name received as a ++ * parameter. ++ */ ++ public fun getReactNativeConfig(): ReactNativeConfig ++ ++ @UnstableReactNativeAPI ++ public class ReactHostDelegateBase( ++ override val jsMainModulePath: String, ++ override val jsBundleLoader: JSBundleLoader, ++ override val jsRuntimeFactory: JSRuntimeFactory, ++ override val turboModuleManagerDelegateBuilder: ++ ReactPackageTurboModuleManagerDelegate.Builder, ++ override val reactPackages: List = emptyList(), ++ override val bindingsInstaller: BindingsInstaller? = null, ++ private val reactNativeConfig: ReactNativeConfig = ReactNativeConfig.DEFAULT_CONFIG, ++ private val exceptionHandler: (error: Exception) -> Unit = {} ++ ) : ReactHostDelegate { ++ ++ override fun getReactNativeConfig(): ReactNativeConfig = reactNativeConfig ++ ++ override fun handleInstanceException(error: Exception): Unit = exceptionHandler(error) ++ } ++} +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/runtime/hermes/HermesInstance.kt b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/runtime/hermes/HermesInstance.kt +new file mode 100644 +index 0000000..47efb3f +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/runtime/hermes/HermesInstance.kt +@@ -0,0 +1,28 @@ ++/* ++ * 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. ++ */ ++ ++package com.facebook.react.runtime.hermes ++ ++import com.facebook.jni.HybridData ++import com.facebook.jni.annotations.DoNotStrip ++import com.facebook.react.fabric.ReactNativeConfig ++import com.facebook.react.runtime.JSRuntimeFactory ++import com.facebook.soloader.SoLoader ++ ++public class HermesInstance(reactNativeConfig: ReactNativeConfig?) : ++ JSRuntimeFactory(initHybrid(reactNativeConfig as Any?)) { ++ ++ public constructor() : this(null) ++ ++ public companion object { ++ @JvmStatic @DoNotStrip protected external fun initHybrid(reactNativeConfig: Any?): HybridData ++ ++ init { ++ SoLoader.loadLibrary("hermesinstancejni") ++ } ++ } ++} +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/turbomodule/core/interfaces/CallInvokerHolder.kt b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/turbomodule/core/interfaces/CallInvokerHolder.kt +new file mode 100644 +index 0000000..de3d307 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/turbomodule/core/interfaces/CallInvokerHolder.kt +@@ -0,0 +1,17 @@ ++/* ++ * 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. ++ */ ++ ++package com.facebook.react.turbomodule.core.interfaces ++/** ++ * JS CallInvoker is created by CatalystInstance.cpp, but used by TurboModuleManager.cpp. Both C++ ++ * classes are instantiated at different times/places. Therefore, to pass the JS CallInvoker ++ * instance from CatalystInstance to TurboModuleManager, we make it take a trip through Java. ++ * ++ * This interface represents the opaque Java object that contains a pointer to and instance of ++ * CallInvoker. ++ */ ++public interface CallInvokerHolder +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/turbomodule/core/interfaces/NativeMethodCallInvokerHolder.kt b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/turbomodule/core/interfaces/NativeMethodCallInvokerHolder.kt +new file mode 100644 +index 0000000..1748a6d +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/turbomodule/core/interfaces/NativeMethodCallInvokerHolder.kt +@@ -0,0 +1,13 @@ ++/* ++ * 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. ++ */ ++ ++package com.facebook.react.turbomodule.core.interfaces ++/** ++ * This interface represents the opaque Java object that contains a pointer to and instance of ++ * NativeMethodCallInvoker. ++ */ ++public interface NativeMethodCallInvokerHolder +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/turbomodule/core/interfaces/TurboModule.kt b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/turbomodule/core/interfaces/TurboModule.kt +new file mode 100644 +index 0000000..6333b81 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/turbomodule/core/interfaces/TurboModule.kt +@@ -0,0 +1,19 @@ ++/* ++ * 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. ++ */ ++ ++package com.facebook.react.turbomodule.core.interfaces ++/** All turbo modules should inherit from this interface */ ++public interface TurboModule { ++ /** Initialize the TurboModule. */ ++ public fun initialize() ++ ++ /** ++ * Called during the turn down process of ReactHost. This method is called before React Native is ++ * stopped. Override this method to clean up resources used by the TurboModule. ++ */ ++ public fun invalidate() ++} +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/views/modal/ReactModalHostManager.kt b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/views/modal/ReactModalHostManager.kt +new file mode 100644 +index 0000000..d5e053c +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/views/modal/ReactModalHostManager.kt +@@ -0,0 +1,141 @@ ++/* ++ * 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. ++ */ ++ ++package com.facebook.react.views.modal ++ ++import android.content.DialogInterface.OnShowListener ++import com.facebook.react.bridge.ReadableArray ++import com.facebook.react.common.MapBuilder ++import com.facebook.react.module.annotations.ReactModule ++import com.facebook.react.uimanager.LayoutShadowNode ++import com.facebook.react.uimanager.ReactStylesDiffMap ++import com.facebook.react.uimanager.StateWrapper ++import com.facebook.react.uimanager.ThemedReactContext ++import com.facebook.react.uimanager.UIManagerHelper ++import com.facebook.react.uimanager.ViewGroupManager ++import com.facebook.react.uimanager.ViewManagerDelegate ++import com.facebook.react.uimanager.annotations.ReactProp ++import com.facebook.react.viewmanagers.ModalHostViewManagerDelegate ++import com.facebook.react.viewmanagers.ModalHostViewManagerInterface ++import com.facebook.react.views.modal.ReactModalHostView.OnRequestCloseListener ++ ++/** View manager for [ReactModalHostView] components. */ ++@ReactModule(name = ReactModalHostManager.REACT_CLASS) ++public class ReactModalHostManager : ++ ViewGroupManager(), ModalHostViewManagerInterface { ++ private val delegate: ViewManagerDelegate = ModalHostViewManagerDelegate(this) ++ ++ public override fun getName(): String = REACT_CLASS ++ ++ protected override fun createViewInstance(reactContext: ThemedReactContext): ReactModalHostView = ++ ReactModalHostView(reactContext) ++ ++ public override fun onDropViewInstance(view: ReactModalHostView) { ++ super.onDropViewInstance(view) ++ view.onDropInstance() ++ } ++ ++ @ReactProp(name = "animationType") ++ public override fun setAnimationType(view: ReactModalHostView, animationType: String?) { ++ if (animationType != null) { ++ view.animationType = animationType ++ } ++ } ++ ++ @ReactProp(name = "transparent") ++ public override fun setTransparent(view: ReactModalHostView, transparent: Boolean) { ++ view.transparent = transparent ++ } ++ ++ @ReactProp(name = "statusBarTranslucent") ++ public override fun setStatusBarTranslucent( ++ view: ReactModalHostView, ++ statusBarTranslucent: Boolean ++ ) { ++ view.statusBarTranslucent = statusBarTranslucent ++ } ++ ++ @ReactProp(name = "hardwareAccelerated") ++ public override fun setHardwareAccelerated( ++ view: ReactModalHostView, ++ hardwareAccelerated: Boolean ++ ) { ++ view.hardwareAccelerated = hardwareAccelerated ++ } ++ ++ @ReactProp(name = "visible") ++ public override fun setVisible(view: ReactModalHostView, visible: Boolean) { ++ // iOS only ++ } ++ ++ @ReactProp(name = "presentationStyle") ++ public override fun setPresentationStyle(view: ReactModalHostView, value: String?): Unit = Unit ++ ++ @ReactProp(name = "animated") ++ public override fun setAnimated(view: ReactModalHostView, value: Boolean): Unit = Unit ++ ++ @ReactProp(name = "supportedOrientations") ++ public override fun setSupportedOrientations( ++ view: ReactModalHostView, ++ value: ReadableArray? ++ ): Unit = Unit ++ ++ @ReactProp(name = "identifier") ++ public override fun setIdentifier(view: ReactModalHostView, value: Int): Unit = Unit ++ ++ protected override fun addEventEmitters( ++ reactContext: ThemedReactContext, ++ view: ReactModalHostView ++ ) { ++ val dispatcher = UIManagerHelper.getEventDispatcherForReactTag(reactContext, view.id) ++ if (dispatcher != null) { ++ view.onRequestCloseListener = OnRequestCloseListener { ++ dispatcher.dispatchEvent( ++ RequestCloseEvent(UIManagerHelper.getSurfaceId(reactContext), view.id)) ++ } ++ view.onShowListener = OnShowListener { ++ dispatcher.dispatchEvent(ShowEvent(UIManagerHelper.getSurfaceId(reactContext), view.id)) ++ } ++ view.eventDispatcher = dispatcher ++ } ++ } ++ ++ public override fun getExportedCustomDirectEventTypeConstants(): Map = ++ (super.getExportedCustomDirectEventTypeConstants() ?: mutableMapOf()).apply { ++ putAll( ++ MapBuilder.builder() ++ .put( ++ RequestCloseEvent.EVENT_NAME, ++ MapBuilder.of("registrationName", "onRequestClose")) ++ .put(ShowEvent.EVENT_NAME, MapBuilder.of("registrationName", "onShow")) // iOS only ++ .put("topDismiss", MapBuilder.of("registrationName", "onDismiss")) // iOS only ++ .put( ++ "topOrientationChange", ++ MapBuilder.of("registrationName", "onOrientationChange")) ++ .build()) ++ } ++ ++ protected override fun onAfterUpdateTransaction(view: ReactModalHostView) { ++ super.onAfterUpdateTransaction(view) ++ view.showOrUpdate() ++ } ++ ++ public override fun updateState( ++ view: ReactModalHostView, ++ props: ReactStylesDiffMap, ++ stateWrapper: StateWrapper ++ ): Any? { ++ view.stateWrapper = stateWrapper ++ return null ++ } ++ ++ public override fun getDelegate(): ViewManagerDelegate = delegate ++ ++ public companion object { ++ public const val REACT_CLASS: String = "RCTModalHostView" ++ } ++} +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/views/modal/ReactModalHostView.kt b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/views/modal/ReactModalHostView.kt +new file mode 100644 +index 0000000..f6e0d82 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/views/modal/ReactModalHostView.kt +@@ -0,0 +1,531 @@ ++/* ++ * 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. ++ */ ++ ++@file:Suppress("DEPRECATION") ++ ++package com.facebook.react.views.modal ++ ++import android.annotation.SuppressLint ++import android.app.Activity ++import android.app.Dialog ++import android.content.Context ++import android.content.DialogInterface ++import android.os.Build ++import android.view.KeyEvent ++import android.view.MotionEvent ++import android.view.View ++import android.view.ViewGroup ++import android.view.ViewStructure ++import android.view.Window ++import android.view.WindowInsetsController ++import android.view.WindowManager ++import android.view.accessibility.AccessibilityEvent ++import android.widget.FrameLayout ++import androidx.annotation.UiThread ++import com.facebook.react.R ++import com.facebook.react.bridge.GuardedRunnable ++import com.facebook.react.bridge.LifecycleEventListener ++import com.facebook.react.bridge.ReactContext ++import com.facebook.react.bridge.ReadableMap ++import com.facebook.react.bridge.UiThreadUtil ++import com.facebook.react.bridge.WritableMap ++import com.facebook.react.bridge.WritableNativeMap ++import com.facebook.react.common.annotations.VisibleForTesting ++import com.facebook.react.config.ReactFeatureFlags ++import com.facebook.react.uimanager.JSPointerDispatcher ++import com.facebook.react.uimanager.JSTouchDispatcher ++import com.facebook.react.uimanager.PixelUtil ++import com.facebook.react.uimanager.RootView ++import com.facebook.react.uimanager.StateWrapper ++import com.facebook.react.uimanager.ThemedReactContext ++import com.facebook.react.uimanager.UIManagerModule ++import com.facebook.react.uimanager.events.EventDispatcher ++import com.facebook.react.views.common.ContextUtils ++import com.facebook.react.views.view.ReactViewGroup ++import java.util.Objects ++import kotlin.math.abs ++ ++/** ++ * ReactModalHostView is a view that sits in the view hierarchy representing a Modal view. ++ * ++ * It does a number of things: ++ * 1. It creates a [Dialog]. We use this Dialog to actually display the Modal in the window. ++ * 2. It creates a [DialogRootViewGroup]. This view is the view that is displayed by the Dialog. To ++ * display a view within a Dialog, that view must have its parent set to the window the Dialog ++ * creates. Because of this, we can not use the ReactModalHostView since it sits in the normal ++ * React view hierarchy. We do however want all of the layout magic to happen as if the ++ * DialogRootViewGroup were part of the hierarchy. Therefore, we forward all view changes around ++ * addition and removal of views to the DialogRootViewGroup. ++ */ ++@SuppressLint("ViewConstructor") ++public class ReactModalHostView(context: ThemedReactContext) : ++ ViewGroup(context), LifecycleEventListener { ++ ++ @get:VisibleForTesting ++ public var dialog: Dialog? = null ++ private set ++ ++ public var transparent: Boolean = false ++ public var onShowListener: DialogInterface.OnShowListener? = null ++ public var onRequestCloseListener: OnRequestCloseListener? = null ++ public var statusBarTranslucent: Boolean = false ++ set(value) { ++ field = value ++ createNewDialog = true ++ } ++ ++ public var animationType: String? = null ++ set(value) { ++ field = value ++ createNewDialog = true ++ } ++ ++ public var hardwareAccelerated: Boolean = false ++ set(value) { ++ field = value ++ createNewDialog = true ++ } ++ ++ public var stateWrapper: StateWrapper? ++ get() = hostView.stateWrapper ++ public set(stateWrapper) { ++ hostView.stateWrapper = stateWrapper ++ } ++ ++ public var eventDispatcher: EventDispatcher? ++ get() = hostView.eventDispatcher ++ public set(eventDispatcher) { ++ hostView.eventDispatcher = eventDispatcher ++ } ++ ++ private var hostView: DialogRootViewGroup ++ ++ // Set this flag to true if changing a particular property on the view requires a new Dialog to ++ // be created or Dialog was destroyed. For instance, animation does since it affects Dialog ++ // creation through the theme ++ // but transparency does not since we can access the window to update the property. ++ private var createNewDialog = false ++ ++ init { ++ context.addLifecycleEventListener(this) ++ hostView = DialogRootViewGroup(context) ++ } ++ ++ public override fun dispatchProvideStructure(structure: ViewStructure) { ++ hostView.dispatchProvideStructure(structure) ++ } ++ ++ protected override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) { ++ // Do nothing as we are laid out by UIManager ++ } ++ ++ protected override fun onDetachedFromWindow() { ++ super.onDetachedFromWindow() ++ dismiss() ++ } ++ ++ public override fun addView(child: View?, index: Int) { ++ UiThreadUtil.assertOnUiThread() ++ hostView.addView(child, index) ++ } ++ ++ public override fun getChildCount(): Int = hostView.childCount ++ ++ public override fun getChildAt(index: Int): View? = hostView.getChildAt(index) ++ ++ public override fun removeView(child: View?) { ++ UiThreadUtil.assertOnUiThread() ++ ++ if (child != null) { ++ hostView.removeView(child) ++ } ++ } ++ ++ public override fun removeViewAt(index: Int) { ++ UiThreadUtil.assertOnUiThread() ++ val child = getChildAt(index) ++ hostView.removeView(child) ++ } ++ ++ public override fun addChildrenForAccessibility(outChildren: ArrayList) { ++ // Explicitly override this to prevent accessibility events being passed down to children ++ // Those will be handled by the mHostView which lives in the dialog ++ } ++ ++ // Explicitly override this to prevent accessibility events being passed down to children ++ // Those will be handled by the mHostView which lives in the dialog ++ public override fun dispatchPopulateAccessibilityEvent(event: AccessibilityEvent): Boolean = false ++ ++ public fun onDropInstance() { ++ (context as ThemedReactContext).removeLifecycleEventListener(this) ++ dismiss() ++ } ++ ++ private fun dismiss() { ++ UiThreadUtil.assertOnUiThread() ++ ++ dialog?.let { nonNullDialog -> ++ if (nonNullDialog.isShowing) { ++ val dialogContext = ++ ContextUtils.findContextOfType(nonNullDialog.context, Activity::class.java) ++ if (dialogContext == null || !dialogContext.isFinishing) { ++ nonNullDialog.dismiss() ++ } ++ } ++ dialog = null ++ createNewDialog = true ++ ++ // We need to remove the mHostView from the parent ++ // It is possible we are dismissing this dialog and reattaching the hostView to another ++ (hostView.parent as? ViewGroup)?.removeViewAt(0) ++ } ++ } ++ ++ public override fun onHostResume() { ++ // We show the dialog again when the host resumes ++ showOrUpdate() ++ } ++ ++ public override fun onHostPause() { ++ // do nothing ++ } ++ ++ public override fun onHostDestroy() { ++ // Drop the instance if the host is destroyed which will dismiss the dialog ++ onDropInstance() ++ } ++ ++ private fun getCurrentActivity(): Activity? = (context as ThemedReactContext).currentActivity ++ ++ /** ++ * showOrUpdate will display the Dialog. It is called by the manager once all properties are set ++ * because we need to know all of them before creating the Dialog. It is also smart during updates ++ * if the changed properties can be applied directly to the Dialog or require the recreation of a ++ * new Dialog. ++ */ ++ public fun showOrUpdate() { ++ UiThreadUtil.assertOnUiThread() ++ ++ // If the existing Dialog is currently up, we may need to redraw it or we may be able to update ++ // the property without having to recreate the dialog ++ if (createNewDialog) { ++ dismiss() ++ } else { ++ updateProperties() ++ return ++ } ++ ++ // Reset the flag since we are going to create a new dialog ++ createNewDialog = false ++ val theme: Int = ++ when (animationType) { ++ "fade" -> R.style.Theme_FullScreenDialogAnimatedFade ++ "slide" -> R.style.Theme_FullScreenDialogAnimatedSlide ++ else -> R.style.Theme_FullScreenDialog ++ } ++ ++ val currentActivity = getCurrentActivity() ++ val newDialog = Dialog(currentActivity ?: context, theme) ++ dialog = newDialog ++ Objects.requireNonNull(newDialog.window) ++ .setFlags( ++ WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, ++ WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) ++ ++ newDialog.setContentView(contentView) ++ updateProperties() ++ ++ newDialog.setOnShowListener(onShowListener) ++ newDialog.setOnKeyListener( ++ object : DialogInterface.OnKeyListener { ++ override fun onKey(dialog: DialogInterface, keyCode: Int, event: KeyEvent): Boolean { ++ if (event.action == KeyEvent.ACTION_UP) { ++ // We need to stop the BACK button and ESCAPE key from closing the dialog by default ++ // so we capture that event and instead inform JS so that it can make the decision as ++ // to whether or not to allow the back/escape key to close the dialog. If it chooses ++ // to, it can just set visible to false on the Modal and the Modal will go away ++ if (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_ESCAPE) { ++ val listener = ++ checkNotNull(onRequestCloseListener) { ++ "onRequestClose callback must be set if back key is expected to close the modal" ++ } ++ listener.onRequestClose(dialog) ++ return true ++ } else { ++ // We redirect the rest of the key events to the current activity, since the ++ // activity expects to receive those events and react to them, ie. in the case of ++ // the dev menu ++ val innerCurrentActivity = ++ (this@ReactModalHostView.context as ReactContext).currentActivity ++ if (innerCurrentActivity != null) { ++ return innerCurrentActivity.onKeyUp(keyCode, event) ++ } ++ } ++ } ++ return false ++ } ++ }) ++ ++ newDialog.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE) ++ if (hardwareAccelerated) { ++ newDialog.window?.addFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) ++ } ++ if (currentActivity?.isFinishing == false) { ++ newDialog.show() ++ updateSystemAppearance() ++ newDialog.window?.clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) ++ } ++ } ++ ++ private val contentView: View ++ /** ++ * Returns the view that will be the root view of the dialog. We are wrapping this in a ++ * FrameLayout because this is the system's way of notifying us that the dialog size has ++ * changed. This has the pleasant side-effect of us not having to preface all Modals with "top: ++ * statusBarHeight", since that margin will be included in the FrameLayout. ++ */ ++ get() { ++ val frameLayout = FrameLayout(context) ++ frameLayout.addView(hostView) ++ if (statusBarTranslucent) { ++ frameLayout.systemUiVisibility = SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN ++ } else { ++ frameLayout.fitsSystemWindows = true ++ } ++ return frameLayout ++ } ++ ++ /** ++ * updateProperties will update the properties that do not require us to recreate the dialog ++ * Properties that do require us to recreate the dialog should set mPropertyRequiresNewDialog to ++ * true when the property changes ++ */ ++ private fun updateProperties() { ++ val dialog = checkNotNull(dialog) { "dialog must exist when we call updateProperties" } ++ val currentActivity = getCurrentActivity() ++ val window = ++ checkNotNull(dialog.window) { "dialog must have window when we call updateProperties" } ++ if (currentActivity == null || currentActivity.isFinishing || !window.isActive) { ++ // If the activity has disappeared, then we shouldn't update the window associated to the ++ // Dialog. ++ return ++ } ++ val activityWindow = currentActivity.window ++ if (activityWindow != null) { ++ val activityWindowFlags = activityWindow.attributes.flags ++ if ((activityWindowFlags and WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0) { ++ window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN) ++ } else { ++ window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN) ++ } ++ } ++ ++ if (transparent) { ++ window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND) ++ } else { ++ window.setDimAmount(0.5f) ++ window.setFlags( ++ WindowManager.LayoutParams.FLAG_DIM_BEHIND, WindowManager.LayoutParams.FLAG_DIM_BEHIND) ++ } ++ } ++ ++ private fun updateSystemAppearance() { ++ val currentActivity = getCurrentActivity() ?: return ++ val dialog = checkNotNull(dialog) { "dialog must exist when we call updateProperties" } ++ val window = ++ checkNotNull(dialog.window) { "dialog must have window when we call updateProperties" } ++ // Modeled after the version check in StatusBarModule.setStyle ++ if (Build.VERSION.SDK_INT > Build.VERSION_CODES.R) { ++ val currentActivityWindow = currentActivity.window ++ val insetsController: WindowInsetsController = ++ checkNotNull(currentActivityWindow.insetsController) ++ val activityAppearance: Int = insetsController.systemBarsAppearance ++ ++ val activityLightStatusBars = ++ activityAppearance and WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS ++ ++ window.insetsController?.setSystemBarsAppearance( ++ activityLightStatusBars, WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS) ++ } else { ++ val currentActivityWindow = checkNotNull(currentActivity.window) ++ val decorView = currentActivityWindow.decorView ++ decorView.setSystemUiVisibility(decorView.systemUiVisibility) ++ } ++ } ++ ++ public fun updateState(width: Int, height: Int) { ++ hostView.updateState(width, height) ++ } ++ ++ // This listener is called when the user presses KeyEvent.KEYCODE_BACK ++ // An event is then passed to JS which can either close or not close the Modal by setting the ++ // visible property ++ public fun interface OnRequestCloseListener { ++ public fun onRequestClose(dialog: DialogInterface?) ++ } ++ ++ private companion object { ++ private const val TAG = "ReactModalHost" ++ } ++ ++ /** ++ * DialogRootViewGroup is the ViewGroup which contains all the children of a Modal. It gets all ++ * child information forwarded from [ReactModalHostView] and uses that to create children. It is ++ * also responsible for acting as a RootView and handling touch events. It does this the same way ++ * as ReactRootView. ++ * ++ * To get layout to work properly, we need to layout all the elements within the Modal as if they ++ * can fill the entire window. To do that, we need to explicitly set the styleWidth and ++ * styleHeight on the LayoutShadowNode to be the window size. This is done through the ++ * UIManagerModule, and will then cause the children to layout as if they can fill the window. ++ */ ++ public inner class DialogRootViewGroup(context: Context?) : ReactViewGroup(context), RootView { ++ internal var stateWrapper: StateWrapper? = null ++ ++ private var hasAdjustedSize = false ++ private var viewWidth = 0 ++ private var viewHeight = 0 ++ private val jSTouchDispatcher: JSTouchDispatcher = JSTouchDispatcher(this) ++ private var jSPointerDispatcher: JSPointerDispatcher? = null ++ internal var eventDispatcher: EventDispatcher? = null ++ ++ private val reactContext: ThemedReactContext ++ get() = context as ThemedReactContext ++ ++ init { ++ if (ReactFeatureFlags.dispatchPointerEvents) { ++ jSPointerDispatcher = JSPointerDispatcher(this) ++ } ++ } ++ ++ override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) { ++ super.onSizeChanged(w, h, oldw, oldh) ++ viewWidth = w ++ viewHeight = h ++ updateFirstChildView() ++ } ++ ++ private fun updateFirstChildView() { ++ if (childCount > 0) { ++ hasAdjustedSize = false ++ val viewTag: Int = getChildAt(0).id ++ if (stateWrapper != null) { ++ // This will only be called under Fabric ++ updateState(viewWidth, viewHeight) ++ } else { ++ // TODO: T44725185 remove after full migration to Fabric ++ val reactContext: ReactContext = reactContext ++ reactContext.runOnNativeModulesQueueThread( ++ object : GuardedRunnable(reactContext) { ++ override fun runGuarded() { ++ this@DialogRootViewGroup.reactContext.reactApplicationContext ++ .getNativeModule(UIManagerModule::class.java) ++ ?.updateNodeSize(viewTag, viewWidth, viewHeight) ++ } ++ }) ++ } ++ } else { ++ hasAdjustedSize = true ++ } ++ } ++ ++ @UiThread ++ public fun updateState(width: Int, height: Int) { ++ val realWidth: Float = PixelUtil.toDIPFromPixel(width.toFloat()) ++ val realHeight: Float = PixelUtil.toDIPFromPixel(height.toFloat()) ++ ++ // Check incoming state values. If they're already the correct value, return early to prevent ++ // infinite UpdateState/SetState loop. ++ val currentState: ReadableMap? = stateWrapper?.getStateData() ++ if (currentState != null) { ++ val delta = 0.9f ++ val stateScreenHeight = ++ if (currentState.hasKey("screenHeight")) { ++ currentState.getDouble("screenHeight").toFloat() ++ } else { ++ 0f ++ } ++ val stateScreenWidth = ++ if (currentState.hasKey("screenWidth")) { ++ currentState.getDouble("screenWidth").toFloat() ++ } else { ++ 0f ++ } ++ ++ if (abs((stateScreenWidth - realWidth).toDouble()) < delta && ++ abs((stateScreenHeight - realHeight).toDouble()) < delta) { ++ return ++ } ++ } ++ ++ stateWrapper?.let { sw -> ++ val newStateData: WritableMap = WritableNativeMap() ++ newStateData.putDouble("screenWidth", realWidth.toDouble()) ++ newStateData.putDouble("screenHeight", realHeight.toDouble()) ++ sw.updateState(newStateData) ++ } ++ } ++ ++ override fun addView(child: View, index: Int, params: LayoutParams) { ++ super.addView(child, index, params) ++ if (hasAdjustedSize) { ++ updateFirstChildView() ++ } ++ } ++ ++ override fun handleException(t: Throwable) { ++ reactContext.reactApplicationContext.handleException(RuntimeException(t)) ++ } ++ ++ override fun onInterceptTouchEvent(event: MotionEvent): Boolean { ++ eventDispatcher?.let { eventDispatcher -> ++ jSTouchDispatcher.handleTouchEvent(event, eventDispatcher) ++ jSPointerDispatcher?.handleMotionEvent(event, eventDispatcher, true) ++ } ++ return super.onInterceptTouchEvent(event) ++ } ++ ++ @SuppressLint("ClickableViewAccessibility") ++ override fun onTouchEvent(event: MotionEvent): Boolean { ++ eventDispatcher?.let { eventDispatcher -> ++ jSTouchDispatcher.handleTouchEvent(event, eventDispatcher) ++ jSPointerDispatcher?.handleMotionEvent(event, eventDispatcher, false) ++ } ++ super.onTouchEvent(event) ++ // In case when there is no children interested in handling touch event, we return true from ++ // the root view in order to receive subsequent events related to that gesture ++ return true ++ } ++ ++ override fun onInterceptHoverEvent(event: MotionEvent): Boolean { ++ eventDispatcher?.let { jSPointerDispatcher?.handleMotionEvent(event, it, true) } ++ return super.onHoverEvent(event) ++ } ++ ++ override fun onHoverEvent(event: MotionEvent): Boolean { ++ eventDispatcher?.let { jSPointerDispatcher?.handleMotionEvent(event, it, false) } ++ return super.onHoverEvent(event) ++ } ++ ++ override fun onChildStartedNativeGesture(childView: View, ev: MotionEvent) { ++ eventDispatcher?.let { eventDispatcher -> ++ jSTouchDispatcher.onChildStartedNativeGesture(ev, eventDispatcher) ++ jSPointerDispatcher?.onChildStartedNativeGesture(childView, ev, eventDispatcher) ++ } ++ } ++ ++ override fun onChildEndedNativeGesture(childView: View, ev: MotionEvent) { ++ eventDispatcher?.let { jSTouchDispatcher.onChildEndedNativeGesture(ev, it) } ++ jSPointerDispatcher?.onChildEndedNativeGesture() ++ } ++ ++ override fun requestDisallowInterceptTouchEvent(disallowIntercept: Boolean) { ++ // No-op - override in order to still receive events to onInterceptTouchEvent ++ // even when some other view disallow that ++ } ++ } ++} +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/views/modal/RequestCloseEvent.kt b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/views/modal/RequestCloseEvent.kt +new file mode 100644 +index 0000000..13aa821 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/views/modal/RequestCloseEvent.kt +@@ -0,0 +1,31 @@ ++/* ++ * 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. ++ */ ++ ++package com.facebook.react.views.modal ++ ++import com.facebook.react.bridge.Arguments ++import com.facebook.react.bridge.WritableMap ++import com.facebook.react.uimanager.common.ViewUtil ++import com.facebook.react.uimanager.events.Event ++ ++/** [Event] for dismissing a Dialog. */ ++internal class RequestCloseEvent(surfaceId: Int, viewTag: Int) : ++ Event(surfaceId, viewTag) { ++ ++ @Deprecated( ++ "Do not use this constructor, use the one with explicit surfaceId", ++ ReplaceWith("ShowEvent(surfaceId, viewTag)")) ++ constructor(viewTag: Int) : this(ViewUtil.NO_SURFACE_ID, viewTag) ++ ++ override fun getEventName(): String = EVENT_NAME ++ ++ override fun getEventData(): WritableMap = Arguments.createMap() ++ ++ companion object { ++ const val EVENT_NAME: String = "topRequestClose" ++ } ++} +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/views/modal/ShowEvent.kt b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/views/modal/ShowEvent.kt +new file mode 100644 +index 0000000..20ae8ab +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/views/modal/ShowEvent.kt +@@ -0,0 +1,30 @@ ++/* ++ * 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. ++ */ ++ ++package com.facebook.react.views.modal ++ ++import com.facebook.react.bridge.Arguments ++import com.facebook.react.bridge.WritableMap ++import com.facebook.react.uimanager.common.ViewUtil ++import com.facebook.react.uimanager.events.Event ++ ++/** [Event] for showing a Dialog. */ ++internal class ShowEvent(surfaceId: Int, viewTag: Int) : Event(surfaceId, viewTag) { ++ ++ @Deprecated( ++ "Do not use this constructor, use the one with explicit surfaceId", ++ ReplaceWith("ShowEvent(surfaceId, viewTag)")) ++ constructor(viewTag: Int) : this(ViewUtil.NO_SURFACE_ID, viewTag) ++ ++ override fun getEventName(): String = EVENT_NAME ++ ++ override fun getEventData(): WritableMap? = Arguments.createMap() ++ ++ companion object { ++ const val EVENT_NAME: String = "topShow" ++ } ++} +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollContainerViewManager.kt b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollContainerViewManager.kt +new file mode 100644 +index 0000000..bbe48af +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollContainerViewManager.kt +@@ -0,0 +1,28 @@ ++/* ++ * 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. ++ */ ++ ++package com.facebook.react.views.scroll ++ ++import com.facebook.react.module.annotations.ReactModule ++import com.facebook.react.uimanager.ThemedReactContext ++import com.facebook.react.views.view.ReactClippingViewManager ++ ++/** View manager for {@link ReactHorizontalScrollContainerView} components. */ ++@ReactModule(name = ReactHorizontalScrollContainerViewManager.REACT_CLASS) ++public class ReactHorizontalScrollContainerViewManager : ++ ReactClippingViewManager() { ++ ++ override public fun getName(): String = REACT_CLASS ++ ++ override public fun createViewInstance( ++ context: ThemedReactContext ++ ): ReactHorizontalScrollContainerView = ReactHorizontalScrollContainerView(context) ++ ++ public companion object { ++ public const val REACT_CLASS: String = "AndroidHorizontalScrollContentView" ++ } ++} +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/views/scroll/ReactScrollViewHelper.kt b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/views/scroll/ReactScrollViewHelper.kt +new file mode 100644 +index 0000000..603c47c +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/views/scroll/ReactScrollViewHelper.kt +@@ -0,0 +1,570 @@ ++/* ++ * 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. ++ */ ++ ++package com.facebook.react.views.scroll ++ ++import android.animation.Animator ++import android.animation.ValueAnimator ++import android.content.Context ++import android.graphics.Point ++import android.view.View ++import android.view.ViewGroup ++import android.widget.OverScroller ++import androidx.core.view.ViewCompat ++import com.facebook.common.logging.FLog ++import com.facebook.react.bridge.ReactContext ++import com.facebook.react.bridge.WritableMap ++import com.facebook.react.bridge.WritableNativeMap ++import com.facebook.react.common.ReactConstants ++import com.facebook.react.uimanager.PixelUtil.toDIPFromPixel ++import com.facebook.react.uimanager.StateWrapper ++import com.facebook.react.uimanager.UIManagerHelper ++import com.facebook.react.uimanager.common.UIManagerType ++import com.facebook.react.uimanager.common.ViewUtil ++import java.util.Collections ++import java.util.WeakHashMap ++ ++/** Helper class that deals with emitting Scroll Events. */ ++public object ReactScrollViewHelper { ++ private val TAG = ReactHorizontalScrollView::class.java.simpleName ++ private val DEBUG_MODE = false // ReactBuildConfig.DEBUG ++ private const val CONTENT_OFFSET_LEFT = "contentOffsetLeft" ++ private const val CONTENT_OFFSET_TOP = "contentOffsetTop" ++ private const val SCROLL_AWAY_PADDING_TOP = "scrollAwayPaddingTop" ++ ++ public const val MOMENTUM_DELAY: Long = 20 ++ public const val OVER_SCROLL_ALWAYS: String = "always" ++ public const val AUTO: String = "auto" ++ public const val OVER_SCROLL_NEVER: String = "never" ++ public const val SNAP_ALIGNMENT_DISABLED: Int = 0 ++ public const val SNAP_ALIGNMENT_START: Int = 1 ++ public const val SNAP_ALIGNMENT_CENTER: Int = 2 ++ public const val SNAP_ALIGNMENT_END: Int = 3 ++ ++ // Support global native listeners for scroll events ++ private val scrollListeners = Collections.newSetFromMap(WeakHashMap()) ++ ++ // If all else fails, this is the hardcoded value in OverScroller.java, in AOSP. ++ // The default is defined here (as of this diff): ++ // https://android.googlesource.com/platform/frameworks/base/+/ae5bcf23b5f0875e455790d6af387184dbd009c1/core/java/android/widget/OverScroller.java#44 ++ private var SMOOTH_SCROLL_DURATION = 250 ++ private var smoothScrollDurationInitialized = false ++ ++ /** Shared by [ReactScrollView] and [ReactHorizontalScrollView]. */ ++ @JvmStatic ++ public fun emitScrollEvent(scrollView: T, xVelocity: Float, yVelocity: Float) where ++ T : HasScrollEventThrottle?, ++ T : ViewGroup { ++ emitScrollEvent(scrollView, ScrollEventType.SCROLL, xVelocity, yVelocity) ++ } ++ ++ @JvmStatic ++ public fun emitScrollBeginDragEvent(scrollView: T) where ++ T : HasScrollEventThrottle?, ++ T : ViewGroup { ++ emitScrollEvent(scrollView, ScrollEventType.BEGIN_DRAG) ++ } ++ ++ @JvmStatic ++ public fun emitScrollEndDragEvent(scrollView: T, xVelocity: Float, yVelocity: Float) where ++ T : HasScrollEventThrottle?, ++ T : ViewGroup { ++ emitScrollEvent(scrollView, ScrollEventType.END_DRAG, xVelocity, yVelocity) ++ } ++ ++ @JvmStatic ++ public fun emitScrollMomentumBeginEvent(scrollView: T, xVelocity: Int, yVelocity: Int) where ++ T : HasScrollEventThrottle?, ++ T : ViewGroup { ++ emitScrollEvent( ++ scrollView, ScrollEventType.MOMENTUM_BEGIN, xVelocity.toFloat(), yVelocity.toFloat()) ++ } ++ ++ @JvmStatic ++ public fun emitScrollMomentumEndEvent(scrollView: T) where ++ T : HasScrollEventThrottle?, ++ T : ViewGroup { ++ emitScrollEvent(scrollView, ScrollEventType.MOMENTUM_END) ++ } ++ ++ private fun emitScrollEvent(scrollView: T, scrollEventType: ScrollEventType) where ++ T : HasScrollEventThrottle?, ++ T : ViewGroup { ++ emitScrollEvent(scrollView, scrollEventType, 0f, 0f) ++ } ++ ++ private fun emitScrollEvent( ++ scrollView: T, ++ scrollEventType: ScrollEventType, ++ xVelocity: Float, ++ yVelocity: Float, ++ experimental_isSynchronous: Boolean = false, ++ ) where T : HasScrollEventThrottle?, T : ViewGroup { ++ val now = System.currentTimeMillis() ++ // Throttle the scroll event if scrollEventThrottle is set to be equal or more than 17 ms. ++ // We limit the delta to 17ms so that small throttles intended to enable 60fps updates will not ++ // inadvertently filter out any scroll events. ++ if (scrollView.scrollEventThrottle >= Math.max(17, now - scrollView.lastScrollDispatchTime)) { ++ // Scroll events are throttled. ++ return ++ } ++ val contentView = scrollView.getChildAt(0) ?: return ++ for (scrollListener in scrollListeners) { ++ scrollListener.onScroll(scrollView, scrollEventType, xVelocity, yVelocity) ++ } ++ val reactContext = scrollView.context as ReactContext ++ val surfaceId = UIManagerHelper.getSurfaceId(reactContext) ++ ++ // It's possible for the EventDispatcher to go away - for example, ++ // if there's a crash initiated from JS and we tap on a ScrollView ++ // around teardown of RN, this will cause a NPE. We can safely ignore ++ // this since the crash is usually a red herring. ++ val eventDispatcher = UIManagerHelper.getEventDispatcherForReactTag(reactContext, scrollView.id) ++ if (eventDispatcher != null) { ++ eventDispatcher.dispatchEvent( ++ ScrollEvent.obtain( ++ surfaceId, ++ scrollView.id, ++ scrollEventType, ++ scrollView.scrollX.toFloat(), ++ scrollView.scrollY.toFloat(), ++ xVelocity, ++ yVelocity, ++ contentView.width, ++ contentView.height, ++ scrollView.width, ++ scrollView.height, ++ experimental_isSynchronous)) ++ scrollView.lastScrollDispatchTime = now ++ } ++ } ++ ++ /** This is only for Java listeners. onLayout events emitted to JS are handled elsewhere. */ ++ @JvmStatic ++ public fun emitLayoutEvent(scrollView: ViewGroup) { ++ for (scrollListener in scrollListeners) { ++ scrollListener.onLayout(scrollView) ++ } ++ } ++ ++ @JvmStatic ++ public fun parseOverScrollMode(jsOverScrollMode: String?): Int { ++ return if (jsOverScrollMode == null || jsOverScrollMode == AUTO) { ++ View.OVER_SCROLL_IF_CONTENT_SCROLLS ++ } else if (jsOverScrollMode == OVER_SCROLL_ALWAYS) { ++ View.OVER_SCROLL_ALWAYS ++ } else if (jsOverScrollMode == OVER_SCROLL_NEVER) { ++ View.OVER_SCROLL_NEVER ++ } else { ++ FLog.w(ReactConstants.TAG, "wrong overScrollMode: $jsOverScrollMode") ++ View.OVER_SCROLL_IF_CONTENT_SCROLLS ++ } ++ } ++ ++ @JvmStatic ++ public fun parseSnapToAlignment(alignment: String?): Int { ++ return if (alignment == null) { ++ SNAP_ALIGNMENT_DISABLED ++ } else if ("start".equals(alignment, ignoreCase = true)) { ++ SNAP_ALIGNMENT_START ++ } else if ("center".equals(alignment, ignoreCase = true)) { ++ SNAP_ALIGNMENT_CENTER ++ } else if ("end" == alignment) { ++ SNAP_ALIGNMENT_END ++ } else { ++ FLog.w(ReactConstants.TAG, "wrong snap alignment value: $alignment") ++ SNAP_ALIGNMENT_DISABLED ++ } ++ } ++ ++ @JvmStatic ++ public fun getDefaultScrollAnimationDuration(context: Context?): Int { ++ if (!smoothScrollDurationInitialized) { ++ smoothScrollDurationInitialized = true ++ try { ++ val overScrollerDurationGetter = OverScrollerDurationGetter(context) ++ SMOOTH_SCROLL_DURATION = overScrollerDurationGetter.scrollAnimationDuration ++ } catch (e: Throwable) {} ++ } ++ return SMOOTH_SCROLL_DURATION ++ } ++ ++ /** ++ * Adds a scroll listener. ++ * ++ * Note that you must keep a reference to this scroll listener because this class only keeps a ++ * weak reference to it (to prevent memory leaks). This means that code like ` ++ * addScrollListener(new ScrollListener() {...})` won't work, you need to do this instead: ` ++ * mScrollListener = new ScrollListener() {...}; ++ * ReactScrollViewHelper.addScrollListener(mScrollListener); ` * instead. ++ * ++ * @param listener ++ */ ++ @JvmStatic ++ public fun addScrollListener(listener: ScrollListener?) { ++ if (listener != null) { ++ scrollListeners.add(listener) ++ } ++ } ++ ++ @JvmStatic ++ public fun removeScrollListener(listener: ScrollListener?) { ++ if (listener != null) { ++ scrollListeners.remove(listener) ++ } ++ } ++ ++ /** ++ * Scroll the given view to the location (x, y), with provided initial velocity. This method works ++ * by calculate the "would be" initial velocity with internal friction to move to the point (x, ++ * y), then apply that to the animator. ++ */ ++ @JvmStatic ++ public fun smoothScrollTo(scrollView: T, x: Int, y: Int) where ++ T : HasFlingAnimator?, ++ T : HasScrollState?, ++ T : HasStateWrapper?, ++ T : ViewGroup { ++ if (DEBUG_MODE) { ++ FLog.i(TAG, "smoothScrollTo[%d] x %d y %d", scrollView.id, x, y) ++ } ++ ++ // Register the listeners for the fling animator if there isn't any ++ val flingAnimator = scrollView.getFlingAnimator() ++ if (flingAnimator.listeners == null || flingAnimator.listeners.size == 0) { ++ registerFlingAnimator(scrollView) ++ } ++ val scrollState = scrollView.reactScrollViewScrollState ++ scrollState.setFinalAnimatedPositionScroll(x, y) ++ val scrollX = scrollView.scrollX ++ val scrollY = scrollView.scrollY ++ // Only one fling animator will be started. For the horizontal scroll view, scrollY will always ++ // be the same to y. This is the same to the vertical scroll view. ++ if (scrollX != x) { ++ scrollView.startFlingAnimator(scrollX, x) ++ } ++ if (scrollY != y) { ++ scrollView.startFlingAnimator(scrollY, y) ++ } ++ updateFabricScrollState(scrollView, x, y) ++ } ++ ++ /** Get current position or position after current animation finishes, if any. */ ++ @JvmStatic ++ public fun getNextFlingStartValue( ++ scrollView: T, ++ currentValue: Int, ++ postAnimationValue: Int, ++ velocity: Int ++ ): Int where T : HasFlingAnimator?, T : HasScrollState?, T : ViewGroup { ++ val scrollState = scrollView.reactScrollViewScrollState ++ val velocityDirectionMask = if (velocity != 0) velocity / Math.abs(velocity) else 0 ++ val isMovingTowardsAnimatedValue = ++ velocityDirectionMask * (postAnimationValue - currentValue) > 0 ++ ++ // When the fling animation is not finished, or it was canceled and now we are moving towards ++ // the final animated value, we will return the final animated value. This is because follow up ++ // animation should consider the "would be" animated location, so that previous quick small ++ // scrolls are still working. ++ return if (!scrollState.isFinished || ++ (scrollState.isCanceled && isMovingTowardsAnimatedValue)) { ++ postAnimationValue ++ } else { ++ currentValue ++ } ++ } ++ ++ @JvmStatic ++ public fun updateFabricScrollState(scrollView: T) where ++ T : HasFlingAnimator?, ++ T : HasScrollState?, ++ T : HasStateWrapper?, ++ T : ViewGroup { ++ updateFabricScrollState(scrollView, scrollView.scrollX, scrollView.scrollY) ++ } ++ ++ /** ++ * Called on any stabilized onScroll change to propagate content offset value to a Shadow Node. ++ */ ++ public fun updateFabricScrollState(scrollView: T, scrollX: Int, scrollY: Int) where ++ T : HasFlingAnimator?, ++ T : HasScrollState?, ++ T : HasStateWrapper?, ++ T : ViewGroup { ++ if (DEBUG_MODE) { ++ FLog.i( ++ TAG, "updateFabricScrollState[%d] scrollX %d scrollY %d", scrollView.id, scrollX, scrollY) ++ } ++ if (ViewUtil.getUIManagerType(scrollView.id) == UIManagerType.DEFAULT) { ++ return ++ } ++ val scrollState = scrollView.reactScrollViewScrollState ++ // Dedupe events to reduce JNI traffic ++ if (scrollState.lastStateUpdateScroll.equals(scrollX, scrollY)) { ++ return ++ } ++ scrollState.setLastStateUpdateScroll(scrollX, scrollY) ++ forceUpdateState(scrollView) ++ return ++ } ++ ++ @JvmStatic ++ public fun forceUpdateState(scrollView: T) where ++ T : HasFlingAnimator?, ++ T : HasScrollState?, ++ T : HasStateWrapper?, ++ T : ViewGroup { ++ val scrollState = scrollView.reactScrollViewScrollState ++ val scrollAwayPaddingTop = scrollState.scrollAwayPaddingTop ++ val scrollPos = scrollState.lastStateUpdateScroll ++ val scrollX = scrollPos.x ++ val scrollY = scrollPos.y ++ val fabricScrollX: Int ++ val layoutDirection = scrollState.layoutDirection ++ fabricScrollX = ++ if (layoutDirection == View.LAYOUT_DIRECTION_RTL) { ++ // getScrollX returns offset from left even when layout direction is RTL. ++ // The following line calculates offset from right. ++ val child = scrollView.getChildAt(0) ++ val contentWidth = child?.width ?: 0 ++ -(contentWidth - scrollX - scrollView.width) ++ } else { ++ scrollX ++ } ++ if (DEBUG_MODE) { ++ FLog.i( ++ TAG, ++ "updateFabricScrollState[%d] scrollX %d scrollY %d fabricScrollX", ++ scrollView.id, ++ scrollX, ++ scrollY, ++ fabricScrollX) ++ } ++ val stateWrapper = scrollView.stateWrapper ++ if (stateWrapper != null) { ++ val newStateData: WritableMap = WritableNativeMap() ++ newStateData.putDouble(CONTENT_OFFSET_LEFT, toDIPFromPixel(scrollX.toFloat()).toDouble()) ++ newStateData.putDouble(CONTENT_OFFSET_TOP, toDIPFromPixel(scrollY.toFloat()).toDouble()) ++ newStateData.putDouble( ++ SCROLL_AWAY_PADDING_TOP, toDIPFromPixel(scrollAwayPaddingTop.toFloat()).toDouble()) ++ stateWrapper.updateState(newStateData) ++ } ++ } ++ ++ @JvmStatic ++ public fun updateStateOnScrollChanged( ++ scrollView: T, ++ xVelocity: Float, ++ yVelocity: Float ++ ) where ++ T : HasFlingAnimator?, ++ T : HasScrollEventThrottle?, ++ T : HasScrollState?, ++ T : HasStateWrapper?, ++ T : ViewGroup { ++ updateStateOnScrollChanged(scrollView, xVelocity, yVelocity, false) ++ } ++ ++ @JvmStatic ++ public fun updateStateOnScrollChanged( ++ scrollView: T, ++ xVelocity: Float, ++ yVelocity: Float, ++ experimental_synchronous: Boolean, ++ ) where ++ T : HasFlingAnimator?, ++ T : HasScrollEventThrottle?, ++ T : HasScrollState?, ++ T : HasStateWrapper?, ++ T : ViewGroup { ++ // Race an UpdateState with every onScroll. This makes it more likely that, in Fabric, ++ // when JS processes the scroll event, the C++ ShadowNode representation will have a ++ // "more correct" scroll position. It will frequently be /incorrect/ but this decreases ++ // the error as much as possible. ++ updateFabricScrollState(scrollView) ++ emitScrollEvent( ++ scrollView, ScrollEventType.SCROLL, xVelocity, yVelocity, experimental_synchronous) ++ } ++ ++ public fun registerFlingAnimator(scrollView: T) where ++ T : HasFlingAnimator?, ++ T : HasScrollState?, ++ T : HasStateWrapper?, ++ T : ViewGroup { ++ scrollView ++ .getFlingAnimator() ++ .addListener( ++ object : Animator.AnimatorListener { ++ override fun onAnimationStart(animator: Animator) { ++ val scrollState = scrollView.reactScrollViewScrollState ++ scrollState.isCanceled = false ++ scrollState.isFinished = false ++ } ++ ++ override fun onAnimationEnd(animator: Animator) { ++ scrollView.reactScrollViewScrollState.isFinished = true ++ updateFabricScrollState(scrollView) ++ } ++ ++ override fun onAnimationCancel(animator: Animator) { ++ scrollView.reactScrollViewScrollState.isCanceled = true ++ } ++ ++ override fun onAnimationRepeat(animator: Animator) = Unit ++ }) ++ } ++ ++ @JvmStatic ++ public fun predictFinalScrollPosition( ++ scrollView: T, ++ velocityX: Int, ++ velocityY: Int, ++ maximumOffsetX: Int, ++ maximumOffsetY: Int ++ ): Point where T : HasFlingAnimator?, T : HasScrollState?, T : ViewGroup { ++ val scrollState = scrollView.reactScrollViewScrollState ++ // ScrollView can *only* scroll for 250ms when using smoothScrollTo and there's ++ // no way to customize the scroll duration. So, we create a temporary OverScroller ++ // so we can predict where a fling would land and snap to nearby that point. ++ val scroller = OverScroller(scrollView.context) ++ scroller.setFriction(1.0f - scrollState.decelerationRate) ++ ++ // predict where a fling would end up so we can scroll to the nearest snap offset ++ val width = ++ (scrollView.width - ++ ViewCompat.getPaddingStart(scrollView) - ++ ViewCompat.getPaddingEnd(scrollView)) ++ val height = scrollView.height - scrollView.paddingBottom - scrollView.paddingTop ++ val finalAnimatedPositionScroll = scrollState.finalAnimatedPositionScroll ++ scroller.fling( ++ getNextFlingStartValue( ++ scrollView, scrollView.scrollX, finalAnimatedPositionScroll.x, velocityX), // startX ++ getNextFlingStartValue( ++ scrollView, scrollView.scrollY, finalAnimatedPositionScroll.y, velocityY), // startY ++ velocityX, // velocityX ++ velocityY, // velocityY ++ 0, // minX ++ maximumOffsetX, // maxX ++ 0, // minY ++ maximumOffsetY, // maxY ++ width / 2, // overX ++ height / 2 // overY ++ ) ++ return Point(scroller.finalX, scroller.finalY) ++ } ++ ++ public interface ScrollListener { ++ public fun onScroll( ++ scrollView: ViewGroup?, ++ scrollEventType: ScrollEventType?, ++ xVelocity: Float, ++ yVelocity: Float ++ ) ++ ++ public fun onLayout(scrollView: ViewGroup?) ++ } ++ ++ public interface HasStateWrapper { ++ public val stateWrapper: StateWrapper? ++ } ++ ++ private class OverScrollerDurationGetter internal constructor(context: Context?) : ++ OverScroller(context) { ++ // This is the default in AOSP, hardcoded in OverScroller.java. ++ private var currentScrollAnimationDuration = 250 ++ val scrollAnimationDuration: Int ++ get() { ++ // If startScroll is called without a duration, OverScroller will call `startScroll(x, y, ++ // dx, ++ // dy, duration)` with the default duration. ++ super.startScroll(0, 0, 0, 0) ++ return currentScrollAnimationDuration ++ } ++ ++ override fun startScroll(startX: Int, startY: Int, dx: Int, dy: Int, duration: Int) { ++ currentScrollAnimationDuration = duration ++ } ++ } ++ ++ public class ReactScrollViewScrollState( ++ /** ++ * Get the layout direction. Can be either scrollView.LAYOUT_DIRECTION_RTL (1) or ++ * scrollView.LAYOUT_DIRECTION_LTR (0). If the value is -1, it means unknown layout. ++ */ ++ public val layoutDirection: Int ++ ) { ++ ++ /** Get the position after current animation is finished */ ++ public val finalAnimatedPositionScroll: Point = Point() ++ /** Get the padding on the top for nav bar */ ++ public var scrollAwayPaddingTop: Int = 0 ++ /** Get the Fabric state of last scroll position */ ++ public val lastStateUpdateScroll: Point = Point(0, 0) ++ /** Get true if the previous animation was canceled */ ++ public var isCanceled: Boolean = false ++ /** Get true if previous animation was finished */ ++ public var isFinished: Boolean = true ++ /** Get true if previous animation was finished */ ++ public var decelerationRate: Float = 0.985f ++ ++ /** Set the final scroll position after scrolling animation is finished */ ++ public fun setFinalAnimatedPositionScroll( ++ finalAnimatedPositionScrollX: Int, ++ finalAnimatedPositionScrollY: Int ++ ): ReactScrollViewScrollState { ++ finalAnimatedPositionScroll[finalAnimatedPositionScrollX] = finalAnimatedPositionScrollY ++ return this ++ } ++ ++ /** Set the Fabric state of last scroll position */ ++ public fun setLastStateUpdateScroll( ++ lastStateUpdateScrollX: Int, ++ lastStateUpdateScrollY: Int ++ ): ReactScrollViewScrollState { ++ lastStateUpdateScroll[lastStateUpdateScrollX] = lastStateUpdateScrollY ++ return this ++ } ++ } ++ ++ public interface HasScrollState { ++ /** Get the scroll state for the current ScrollView */ ++ public val reactScrollViewScrollState: ReactScrollViewScrollState ++ } ++ ++ public interface HasFlingAnimator { ++ /** ++ * Start the fling animator that the ScrollView has to go from the start position to end ++ * position. ++ */ ++ public fun startFlingAnimator(start: Int, end: Int) ++ ++ /** Get the fling animator that is reused for the ScrollView to handle fling animation. */ ++ public fun getFlingAnimator(): ValueAnimator ++ ++ /** Get the fling distance with current velocity for prediction */ ++ public fun getFlingExtrapolatedDistance(velocity: Int): Int ++ } ++ ++ public interface HasScrollEventThrottle { ++ /** Get the scroll event throttle in ms. */ ++ /** ++ * Set the scroll event throttle in ms. This number is used to throttle the scroll events. The ++ * default value is zero, which means the scroll events are sent with no throttle. ++ */ ++ public var scrollEventThrottle: Int ++ ++ /** Get the scroll view dispatch time for throttling */ ++ /** Set the scroll view's last dispatch time for throttling */ ++ public var lastScrollDispatchTime: Long ++ } ++ ++ public interface HasSmoothScroll { ++ public fun reactSmoothScrollTo(x: Int, y: Int) ++ ++ public fun scrollToPreservingMomentum(x: Int, y: Int) ++ } ++} +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/views/scroll/ScrollEvent.kt b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/views/scroll/ScrollEvent.kt +new file mode 100644 +index 0000000..1f9fafd +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/views/scroll/ScrollEvent.kt +@@ -0,0 +1,174 @@ ++/* ++ * 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. ++ */ ++ ++package com.facebook.react.views.scroll ++ ++import androidx.core.util.Pools.SynchronizedPool ++import com.facebook.infer.annotation.Assertions ++import com.facebook.react.bridge.Arguments ++import com.facebook.react.bridge.ReactSoftExceptionLogger ++import com.facebook.react.bridge.WritableMap ++import com.facebook.react.uimanager.PixelUtil.toDIPFromPixel ++import com.facebook.react.uimanager.common.ViewUtil ++import com.facebook.react.uimanager.events.Event ++ ++/** A event dispatched from a ScrollView scrolling. */ ++public class ScrollEvent private constructor() : Event() { ++ private var scrollX = 0f ++ private var scrollY = 0f ++ private var xVelocity = 0f ++ private var yVelocity = 0f ++ private var contentWidth = 0 ++ private var contentHeight = 0 ++ private var scrollViewWidth = 0 ++ private var scrollViewHeight = 0 ++ private var scrollEventType: ScrollEventType? = null ++ private var experimental_isSynchronous = false ++ ++ override fun onDispose() { ++ try { ++ EVENTS_POOL.release(this) ++ } catch (e: IllegalStateException) { ++ // This exception can be thrown when an event is double-released. ++ // This is a problem but won't cause user-visible impact, so it's okay to fail silently. ++ ReactSoftExceptionLogger.logSoftException(TAG, e) ++ } ++ } ++ ++ private fun init( ++ surfaceId: Int, ++ viewTag: Int, ++ scrollEventType: ScrollEventType?, ++ scrollX: Float, ++ scrollY: Float, ++ xVelocity: Float, ++ yVelocity: Float, ++ contentWidth: Int, ++ contentHeight: Int, ++ scrollViewWidth: Int, ++ scrollViewHeight: Int, ++ experimental_isSynchronous: Boolean, ++ ) { ++ super.init(surfaceId, viewTag) ++ this.scrollEventType = scrollEventType ++ this.scrollX = scrollX ++ this.scrollY = scrollY ++ this.xVelocity = xVelocity ++ this.yVelocity = yVelocity ++ this.contentWidth = contentWidth ++ this.contentHeight = contentHeight ++ this.scrollViewWidth = scrollViewWidth ++ this.scrollViewHeight = scrollViewHeight ++ this.experimental_isSynchronous = experimental_isSynchronous ++ } ++ ++ override fun getEventName(): String = ++ ScrollEventType.getJSEventName(Assertions.assertNotNull(scrollEventType)) ++ ++ override fun canCoalesce(): Boolean = scrollEventType == ScrollEventType.SCROLL ++ ++ override fun experimental_isSynchronous(): Boolean { ++ return experimental_isSynchronous ++ } ++ ++ override fun getEventData(): WritableMap { ++ val contentInset = Arguments.createMap() ++ contentInset.putDouble("top", 0.0) ++ contentInset.putDouble("bottom", 0.0) ++ contentInset.putDouble("left", 0.0) ++ contentInset.putDouble("right", 0.0) ++ val contentOffset = Arguments.createMap() ++ contentOffset.putDouble("x", toDIPFromPixel(scrollX).toDouble()) ++ contentOffset.putDouble("y", toDIPFromPixel(scrollY).toDouble()) ++ val contentSize = Arguments.createMap() ++ contentSize.putDouble("width", toDIPFromPixel(contentWidth.toFloat()).toDouble()) ++ contentSize.putDouble("height", toDIPFromPixel(contentHeight.toFloat()).toDouble()) ++ val layoutMeasurement = Arguments.createMap() ++ layoutMeasurement.putDouble("width", toDIPFromPixel(scrollViewWidth.toFloat()).toDouble()) ++ layoutMeasurement.putDouble("height", toDIPFromPixel(scrollViewHeight.toFloat()).toDouble()) ++ val velocity = Arguments.createMap() ++ velocity.putDouble("x", xVelocity.toDouble()) ++ velocity.putDouble("y", yVelocity.toDouble()) ++ val event = Arguments.createMap() ++ event.putMap("contentInset", contentInset) ++ event.putMap("contentOffset", contentOffset) ++ event.putMap("contentSize", contentSize) ++ event.putMap("layoutMeasurement", layoutMeasurement) ++ event.putMap("velocity", velocity) ++ event.putInt("target", viewTag) ++ event.putBoolean("responderIgnoreScroll", true) ++ return event ++ } ++ ++ public companion object { ++ private val TAG = ScrollEvent::class.java.simpleName ++ private val EVENTS_POOL = SynchronizedPool(3) ++ ++ @JvmStatic ++ public fun obtain( ++ surfaceId: Int, ++ viewTag: Int, ++ scrollEventType: ScrollEventType?, ++ scrollX: Float, ++ scrollY: Float, ++ xVelocity: Float, ++ yVelocity: Float, ++ contentWidth: Int, ++ contentHeight: Int, ++ scrollViewWidth: Int, ++ scrollViewHeight: Int, ++ experimental_isSynchronous: Boolean, ++ ): ScrollEvent = ++ (EVENTS_POOL.acquire() ?: ScrollEvent()).apply { ++ init( ++ surfaceId, ++ viewTag, ++ scrollEventType, ++ scrollX, ++ scrollY, ++ xVelocity, ++ yVelocity, ++ contentWidth, ++ contentHeight, ++ scrollViewWidth, ++ scrollViewHeight, ++ experimental_isSynchronous) ++ } ++ ++ @Deprecated( ++ "Use the obtain version that explicitly takes surfaceId as an argument", ++ ReplaceWith( ++ "obtain(surfaceId, viewTag, scrollEventType, scrollX, scrollY, xVelocity, yVelocity, contentWidth, contentHeight, scrollViewWidth, scrollViewHeight)")) ++ @JvmStatic ++ public fun obtain( ++ viewTag: Int, ++ scrollEventType: ScrollEventType?, ++ scrollX: Float, ++ scrollY: Float, ++ xVelocity: Float, ++ yVelocity: Float, ++ contentWidth: Int, ++ contentHeight: Int, ++ scrollViewWidth: Int, ++ scrollViewHeight: Int ++ ): ScrollEvent = ++ obtain( ++ ViewUtil.NO_SURFACE_ID, ++ viewTag, ++ scrollEventType, ++ scrollX, ++ scrollY, ++ xVelocity, ++ yVelocity, ++ contentWidth, ++ contentHeight, ++ scrollViewWidth, ++ scrollViewHeight, ++ false, ++ ) ++ } ++} +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/views/scroll/ScrollEventType.kt b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/views/scroll/ScrollEventType.kt +new file mode 100644 +index 0000000..94d8d82 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/java/com/facebook/react/views/scroll/ScrollEventType.kt +@@ -0,0 +1,29 @@ ++/* ++ * 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. ++ */ ++ ++package com.facebook.react.views.scroll ++ ++/** Scroll event types that JS module RCTEventEmitter can understand */ ++public enum class ScrollEventType { ++ BEGIN_DRAG, ++ END_DRAG, ++ SCROLL, ++ MOMENTUM_BEGIN, ++ MOMENTUM_END; ++ ++ public companion object { ++ @JvmStatic ++ public fun getJSEventName(type: ScrollEventType): String = ++ when (type) { ++ BEGIN_DRAG -> "topScrollBeginDrag" ++ END_DRAG -> "topScrollEndDrag" ++ SCROLL -> "topScroll" ++ MOMENTUM_BEGIN -> "topMomentumScrollBegin" ++ MOMENTUM_END -> "topMomentumScrollEnd" ++ } ++ } ++} +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/CMakeLists.txt b/node_modules/react-native/ReactAndroid/bin/src/main/jni/CMakeLists.txt +new file mode 100644 +index 0000000..488cd4a +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/CMakeLists.txt +@@ -0,0 +1,225 @@ ++# 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. ++ ++cmake_minimum_required(VERSION 3.13) ++set(CMAKE_VERBOSE_MAKEFILE on) ++ ++project(ReactAndroid) ++ ++# Convert input paths to CMake format (with forward slashes) ++file(TO_CMAKE_PATH "${REACT_ANDROID_DIR}" REACT_ANDROID_DIR) ++file(TO_CMAKE_PATH "${REACT_BUILD_DIR}" REACT_BUILD_DIR) ++file(TO_CMAKE_PATH "${REACT_COMMON_DIR}" REACT_COMMON_DIR) ++ ++# If you have ccache installed, we're going to honor it. ++find_program(CCACHE_FOUND ccache) ++if(CCACHE_FOUND) ++ set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache) ++ set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache) ++endif(CCACHE_FOUND) ++ ++# Make sure every shared lib includes a .note.gnu.build-id header ++add_link_options(-Wl,--build-id) ++add_compile_options(-Wall -Werror -std=c++20) ++ ++function(add_react_android_subdir relative_path) ++ add_subdirectory(${REACT_ANDROID_DIR}/${relative_path} ReactAndroid/${relative_path}) ++endfunction() ++ ++function(add_react_build_subdir relative_path) ++ add_subdirectory(${REACT_BUILD_DIR}/${relative_path} build/${relative_path}) ++endfunction() ++ ++function(add_react_third_party_ndk_subdir relative_path) ++ add_react_build_subdir(third-party-ndk/${relative_path}) ++endfunction() ++ ++function(add_react_common_subdir relative_path) ++ add_subdirectory(${REACT_COMMON_DIR}/${relative_path} ReactCommon/${relative_path}) ++endfunction() ++ ++# Third-party prefabs ++find_package(hermes-engine REQUIRED CONFIG) ++find_package(fbjni REQUIRED CONFIG) ++add_library(fbjni ALIAS fbjni::fbjni) ++ ++# Third-party downloaded targets ++add_react_third_party_ndk_subdir(glog) ++add_react_third_party_ndk_subdir(boost) ++add_react_third_party_ndk_subdir(double-conversion) ++add_react_third_party_ndk_subdir(fmt) ++add_react_third_party_ndk_subdir(folly) ++add_react_third_party_ndk_subdir(jsc) ++add_react_third_party_ndk_subdir(googletest) ++ ++# Common targets ++add_react_common_subdir(yoga) ++add_react_common_subdir(runtimeexecutor) ++add_react_common_subdir(reactperflogger) ++add_react_common_subdir(logger) ++add_react_common_subdir(jsiexecutor) ++add_react_common_subdir(cxxreact) ++add_react_common_subdir(jsc) ++add_react_common_subdir(jsi) ++add_react_common_subdir(callinvoker) ++add_react_common_subdir(jsinspector-modern) ++add_react_common_subdir(hermes/executor) ++add_react_common_subdir(hermes/inspector-modern) ++add_react_common_subdir(react/renderer/runtimescheduler) ++add_react_common_subdir(react/debug) ++add_react_common_subdir(react/config) ++add_react_common_subdir(react/featureflags) ++add_react_common_subdir(react/performance/timeline) ++add_react_common_subdir(react/renderer/animations) ++add_react_common_subdir(react/renderer/attributedstring) ++add_react_common_subdir(react/renderer/componentregistry) ++add_react_common_subdir(react/renderer/mounting) ++add_react_common_subdir(react/renderer/scheduler) ++add_react_common_subdir(react/renderer/telemetry) ++add_react_common_subdir(react/renderer/uimanager) ++add_react_common_subdir(react/renderer/core) ++add_react_common_subdir(react/renderer/consistency) ++add_react_common_subdir(react/renderer/uimanager/consistency) ++add_react_common_subdir(react/renderer/dom) ++add_react_common_subdir(react/renderer/element) ++add_react_common_subdir(react/renderer/graphics) ++add_react_common_subdir(react/renderer/debug) ++add_react_common_subdir(react/renderer/imagemanager) ++add_react_common_subdir(react/renderer/components/view) ++add_react_common_subdir(react/renderer/components/switch) ++add_react_common_subdir(react/renderer/components/textinput) ++add_react_common_subdir(react/renderer/components/progressbar) ++add_react_common_subdir(react/renderer/components/root) ++add_react_common_subdir(react/renderer/components/image) ++add_react_common_subdir(react/renderer/components/legacyviewmanagerinterop) ++add_react_common_subdir(react/renderer/componentregistry/native) ++add_react_common_subdir(react/renderer/components/text) ++add_react_common_subdir(react/renderer/components/unimplementedview) ++add_react_common_subdir(react/renderer/components/modal) ++add_react_common_subdir(react/renderer/components/scrollview) ++add_react_common_subdir(react/renderer/leakchecker) ++add_react_common_subdir(react/renderer/observers/events) ++add_react_common_subdir(react/renderer/textlayoutmanager) ++add_react_common_subdir(react/utils) ++add_react_common_subdir(react/bridging) ++add_react_common_subdir(react/renderer/mapbuffer) ++add_react_common_subdir(react/nativemodule/core) ++add_react_common_subdir(react/nativemodule/defaults) ++add_react_common_subdir(react/nativemodule/dom) ++add_react_common_subdir(react/nativemodule/featureflags) ++add_react_common_subdir(react/nativemodule/microtasks) ++add_react_common_subdir(react/nativemodule/idlecallbacks) ++add_react_common_subdir(jserrorhandler) ++add_react_common_subdir(react/runtime) ++add_react_common_subdir(react/runtime/hermes) ++add_react_common_subdir(react/runtime/nativeviewconfig) ++ ++# ReactAndroid JNI targets ++add_react_build_subdir(generated/source/codegen/jni) ++add_react_android_subdir(src/main/jni/first-party/fb) ++add_react_android_subdir(src/main/jni/first-party/fbgloginit) ++add_react_android_subdir(src/main/jni/first-party/yogajni) ++add_react_android_subdir(src/main/jni/react/jni) ++add_react_android_subdir(src/main/jni/react/reactperflogger) ++add_react_android_subdir(src/main/jni/react/jscexecutor) ++add_react_android_subdir(src/main/jni/react/turbomodule) ++add_react_android_subdir(src/main/jni/react/uimanager) ++add_react_android_subdir(src/main/jni/react/mapbuffer) ++add_react_android_subdir(src/main/jni/react/reactnativeblob) ++add_react_android_subdir(src/main/jni/react/fabric) ++add_react_android_subdir(src/main/jni/react/featureflags) ++add_react_android_subdir(src/main/jni/react/newarchdefaults) ++add_react_android_subdir(src/main/jni/react/hermes/reactexecutor) ++add_react_android_subdir(src/main/jni/react/hermes/instrumentation/) ++add_react_android_subdir(src/main/jni/react/runtime/cxxreactpackage) ++add_react_android_subdir(src/main/jni/react/runtime/jni) ++add_react_android_subdir(src/main/jni/react/runtime/hermes/jni) ++add_react_android_subdir(src/main/jni/react/runtime/jsc/jni) ++add_react_android_subdir(src/main/jni/react/devsupport) ++ ++# GTest dependencies ++add_executable(reactnative_unittest ++ ${REACT_COMMON_DIR}/cxxreact/tests/jsarg_helpers.cpp ++ ${REACT_COMMON_DIR}/cxxreact/tests/jsbigstring.cpp ++ ${REACT_COMMON_DIR}/cxxreact/tests/methodcall.cpp ++ ${REACT_COMMON_DIR}/cxxreact/tests/RecoverableErrorTest.cpp ++ ${REACT_COMMON_DIR}/react/bridging/tests/BridgingTest.cpp ++ ${REACT_COMMON_DIR}/react/renderer/attributedstring/tests/AttributedStringBoxTest.cpp ++ ${REACT_COMMON_DIR}/react/renderer/components/image/tests/ImageTest.cpp ++ ${REACT_COMMON_DIR}/react/renderer/components/root/tests/RootShadowNodeTest.cpp ++ ${REACT_COMMON_DIR}/react/renderer/components/scrollview/tests/ScrollViewTest.cpp ++ ${REACT_COMMON_DIR}/react/renderer/components/view/tests/LayoutTest.cpp ++ ${REACT_COMMON_DIR}/react/renderer/components/view/tests/ViewTest.cpp ++ ${REACT_COMMON_DIR}/react/renderer/core/tests/DynamicPropsUtilitiesTest.cpp ++ ${REACT_COMMON_DIR}/react/renderer/core/tests/EventQueueProcessorTest.cpp ++ ${REACT_COMMON_DIR}/react/renderer/core/tests/FindNodeAtPointTest.cpp ++ ${REACT_COMMON_DIR}/react/renderer/core/tests/LayoutableShadowNodeTest.cpp ++ ${REACT_COMMON_DIR}/react/renderer/core/tests/PrimitivesTest.cpp ++ ${REACT_COMMON_DIR}/react/renderer/core/tests/RawPropsTest.cpp ++ ${REACT_COMMON_DIR}/react/renderer/core/tests/ShadowNodeFamilyTest.cpp ++ ${REACT_COMMON_DIR}/react/renderer/debug/tests/DebugStringConvertibleTest.cpp ++ ${REACT_COMMON_DIR}/react/renderer/element/tests/ElementTest.cpp ++ ${REACT_COMMON_DIR}/react/renderer/graphics/tests/GraphicsTest.cpp ++ ${REACT_COMMON_DIR}/react/renderer/graphics/tests/TransformTest.cpp ++ ${REACT_COMMON_DIR}/react/renderer/imagemanager/tests/ImageManagerTest.cpp ++ ${REACT_COMMON_DIR}/react/renderer/mapbuffer/tests/MapBufferTest.cpp ++ ${REACT_COMMON_DIR}/react/renderer/mounting/tests/StackingContextTest.cpp ++ ${REACT_COMMON_DIR}/react/renderer/mounting/tests/StateReconciliationTest.cpp ++ ${REACT_COMMON_DIR}/react/renderer/runtimescheduler/tests/RuntimeSchedulerTest.cpp ++ ${REACT_COMMON_DIR}/react/renderer/runtimescheduler/tests/SchedulerPriorityTest.cpp ++ ${REACT_COMMON_DIR}/react/renderer/telemetry/tests/TransactionTelemetryTest.cpp ++ ${REACT_COMMON_DIR}/react/renderer/textlayoutmanager/tests/TextLayoutManagerTest.cpp ++ ${REACT_COMMON_DIR}/react/renderer/uimanager/tests/FabricUIManagerTest.cpp ++ ++ ########## (COMPILE BUT FAIL ON ASSERTS) ########### ++ # ${REACT_COMMON_DIR}/react/renderer/animations/tests/LayoutAnimationTest.cpp ++ # ${REACT_COMMON_DIR}/react/renderer/mounting/tests/MountingTest.cpp ++ # ${REACT_COMMON_DIR}/react/renderer/mounting/tests/ShadowTreeLifeCycleTest.cpp ++ ++ ########## (COMPILE BUT FAIL WITH RUNTIME EXCEPTIONS) ########### ++ # ${REACT_COMMON_DIR}/hermes/inspector-modern/chrome/tests/ConnectionDemuxTests.cpp ++ ++ ########## (DO NOT COMPILE) ########### ++ # ${REACT_COMMON_DIR}/react/renderer/core/tests/ShadowNodeTest.cpp ++ # ${REACT_COMMON_DIR}/react/renderer/core/tests/ConcreteShadowNodeTest.cpp ++ # ${REACT_COMMON_DIR}/react/renderer/core/tests/ComponentDescriptorTest.cpp ++ ) ++ target_compile_options(reactnative_unittest ++ PRIVATE ++ -Wall ++ -Werror ++ -fexceptions ++ -frtti ++ -std=c++20 ++ -DHERMES_ENABLE_DEBUGGER) ++ ++ target_link_libraries(reactnative_unittest ++ folly_runtime ++ glog ++ glog_init ++ gtest_main ++ hermes-engine::libhermes ++ hermes_inspector_modern ++ jsi ++ react_cxxreact ++ react_codegen_rncore ++ react_debug ++ react_render_animations ++ react_render_attributedstring ++ react_render_core ++ react_render_debug ++ react_render_element ++ react_render_graphics ++ react_render_mapbuffer ++ react_render_mounting ++ react_render_textlayoutmanager ++ react_render_uimanager ++ react_utils ++ rrc_modal ++ rrc_scrollview ++ rrc_text ++ rrc_view ++ yoga ++) +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fb/CMakeLists.txt b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fb/CMakeLists.txt +new file mode 100644 +index 0000000..572123b +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fb/CMakeLists.txt +@@ -0,0 +1,31 @@ ++# 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. ++ ++cmake_minimum_required(VERSION 3.13) ++set(CMAKE_VERBOSE_MAKEFILE on) ++ ++add_library(fb ++ STATIC ++ assert.cpp ++ log.cpp) ++ ++add_compile_options( ++ -DLOG_TAG=\"libfb\" ++ -DDISABLE_CPUCAP ++ -DDISABLE_XPLAT ++ -fexceptions ++ -frtti ++ -Wno-unused-parameter ++ -Wno-error=unused-but-set-variable ++ -DHAVE_POSIX_CLOCKS ++) ++if(NOT ${CMAKE_BUILD_TYPE} MATCHES Debug) ++ add_compile_options(-DNDEBUG) ++endif() ++ ++# Yogacore needs to link towards android and log from the NDK libs ++target_link_libraries(fb dl android log) ++ ++target_include_directories(fb PUBLIC include) +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fb/assert.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fb/assert.cpp +new file mode 100644 +index 0000000..3ffd43a +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fb/assert.cpp +@@ -0,0 +1,39 @@ ++/* ++ * 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. ++ */ ++ ++#include ++#include ++ ++#include ++#include ++ ++namespace facebook { ++ ++#define ASSERT_BUF_SIZE 4096 ++static char sAssertBuf[ASSERT_BUF_SIZE]; ++static AssertHandler gAssertHandler; ++ ++void assertInternal(const char* formatstr...) { ++ va_list va_args; ++ va_start(va_args, formatstr); ++ vsnprintf(sAssertBuf, sizeof(sAssertBuf), formatstr, va_args); ++ va_end(va_args); ++ if (gAssertHandler != NULL) { ++ gAssertHandler(sAssertBuf); ++ } ++ FBLOG(LOG_FATAL, "fbassert", "%s", sAssertBuf); ++ // crash at this specific address so that we can find our crashes easier ++ *(int*)0xdeadb00c = 0; ++ // let the compiler know we won't reach the end of the function ++ __builtin_unreachable(); ++} ++ ++void setAssertHandler(AssertHandler assertHandler) { ++ gAssertHandler = assertHandler; ++} ++ ++} // namespace facebook +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fb/include/fb/ALog.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fb/include/fb/ALog.h +new file mode 100644 +index 0000000..8d87f05 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fb/include/fb/ALog.h +@@ -0,0 +1,82 @@ ++/* ++ * 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. ++ */ ++ ++/** @file ALog.h ++ * ++ * Very simple android only logging. Define LOG_TAG to enable the macros. ++ */ ++ ++#pragma once ++ ++#ifdef __ANDROID__ ++ ++#include ++ ++namespace facebook { ++namespace alog { ++ ++template ++inline void ++log(int level, const char* tag, const char* msg, ARGS... args) noexcept { ++ __android_log_print(level, tag, msg, args...); ++} ++ ++template ++inline void log(int level, const char* tag, const char* msg) noexcept { ++ __android_log_write(level, tag, msg); ++} ++ ++template ++inline void logv(const char* tag, const char* msg, ARGS... args) noexcept { ++ log(ANDROID_LOG_VERBOSE, tag, msg, args...); ++} ++ ++template ++inline void logd(const char* tag, const char* msg, ARGS... args) noexcept { ++ log(ANDROID_LOG_DEBUG, tag, msg, args...); ++} ++ ++template ++inline void logi(const char* tag, const char* msg, ARGS... args) noexcept { ++ log(ANDROID_LOG_INFO, tag, msg, args...); ++} ++ ++template ++inline void logw(const char* tag, const char* msg, ARGS... args) noexcept { ++ log(ANDROID_LOG_WARN, tag, msg, args...); ++} ++ ++template ++inline void loge(const char* tag, const char* msg, ARGS... args) noexcept { ++ log(ANDROID_LOG_ERROR, tag, msg, args...); ++} ++ ++template ++inline void logf(const char* tag, const char* msg, ARGS... args) noexcept { ++ log(ANDROID_LOG_FATAL, tag, msg, args...); ++} ++ ++#ifdef LOG_TAG ++#define ALOGV(...) ::facebook::alog::logv(LOG_TAG, __VA_ARGS__) ++#define ALOGD(...) ::facebook::alog::logd(LOG_TAG, __VA_ARGS__) ++#define ALOGI(...) ::facebook::alog::logi(LOG_TAG, __VA_ARGS__) ++#define ALOGW(...) ::facebook::alog::logw(LOG_TAG, __VA_ARGS__) ++#define ALOGE(...) ::facebook::alog::loge(LOG_TAG, __VA_ARGS__) ++#define ALOGF(...) ::facebook::alog::logf(LOG_TAG, __VA_ARGS__) ++#endif ++ ++} // namespace alog ++} // namespace facebook ++ ++#else ++#define ALOGV(...) ((void)0) ++#define ALOGD(...) ((void)0) ++#define ALOGI(...) ((void)0) ++#define ALOGW(...) ((void)0) ++#define ALOGE(...) ((void)0) ++#define ALOGF(...) ((void)0) ++#endif +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fb/include/fb/Build.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fb/include/fb/Build.h +new file mode 100644 +index 0000000..94916b1 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fb/include/fb/Build.h +@@ -0,0 +1,31 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++ ++#if defined(__ANDROID__) ++#include ++#endif ++ ++namespace facebook { ++namespace build { ++ ++struct Build { ++ static int getAndroidSdk() { ++ static auto android_sdk = ([] { ++ char sdk_version_str[PROP_VALUE_MAX]; ++ __system_property_get("ro.build.version.sdk", sdk_version_str); ++ return atoi(sdk_version_str); ++ })(); ++ return android_sdk; ++ } ++}; ++ ++} // namespace build ++} // namespace facebook +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fb/include/fb/Countable.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fb/include/fb/Countable.h +new file mode 100644 +index 0000000..6ba2439 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fb/include/fb/Countable.h +@@ -0,0 +1,45 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++#include ++#include ++#include ++#include ++#include ++ ++namespace facebook { ++ ++class Countable : public noncopyable, public nonmovable { ++ public: ++ // RefPtr expects refcount to start at 0 ++ Countable() : m_refcount(0) {} ++ virtual ~Countable() { ++ FBASSERT(m_refcount == 0); ++ } ++ ++ private: ++ void ref() { ++ ++m_refcount; ++ } ++ ++ void unref() { ++ if (0 == --m_refcount) { ++ delete this; ++ } ++ } ++ ++ bool hasOnlyOneRef() const { ++ return m_refcount == 1; ++ } ++ ++ template ++ friend class RefPtr; ++ std::atomic m_refcount; ++}; ++ ++} // namespace facebook +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fb/include/fb/Doxyfile b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fb/include/fb/Doxyfile +new file mode 100644 +index 0000000..8b4df6a +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fb/include/fb/Doxyfile +@@ -0,0 +1,18 @@ ++PROJECT_NAME = "Facebook JNI" ++PROJECT_BRIEF = "Helper library to provide safe and convenient access to JNI with very low overhead" ++JAVADOC_AUTOBRIEF = YES ++EXTRACT_ALL = YES ++RECURSIVE = YES ++EXCLUDE = tests Asserts.h Countable.h GlobalReference.h LocalReference.h LocalString.h Registration.h WeakReference.h jni_helpers.h Environment.h ++EXCLUDE_PATTERNS = *-inl.h *.cpp ++GENERATE_HTML = YES ++GENERATE_LATEX = NO ++ENABLE_PREPROCESSING = YES ++HIDE_UNDOC_MEMBERS = YES ++HIDE_SCOPE_NAMES = YES ++HIDE_FRIEND_COMPOUNDS = YES ++HIDE_UNDOC_CLASSES = YES ++SHOW_INCLUDE_FILES = NO ++PREDEFINED = LOG_TAG=fbjni ++EXAMPLE_PATH = samples ++#ENABLED_SECTIONS = INTERNAL +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fb/include/fb/Environment.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fb/include/fb/Environment.h +new file mode 100644 +index 0000000..f6f5318 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fb/include/fb/Environment.h +@@ -0,0 +1,93 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++#include ++#include ++#include ++ ++#include ++ ++namespace facebook { ++namespace jni { ++ ++namespace internal { ++struct CacheEnvTag {}; ++} // namespace internal ++ ++// Keeps a thread-local reference to the current thread's JNIEnv. ++struct Environment { ++ // May be null if this thread isn't attached to the JVM ++ FBEXPORT static JNIEnv* current(); ++ static void initialize(JavaVM* vm); ++ ++ // There are subtle issues with calling the next functions directly. It is ++ // much better to always use a ThreadScope to manage attaching/detaching for ++ // you. ++ FBEXPORT static JNIEnv* ensureCurrentThreadIsAttached(); ++ FBEXPORT static void detachCurrentThread(); ++}; ++ ++/** ++ * RAII Object that attaches a thread to the JVM. Failing to detach from a ++ * thread before it exits will cause a crash, as will calling Detach an extra ++ * time, and this guard class helps keep that straight. In addition, it ++ * remembers whether it performed the attach or not, so it is safe to nest it ++ * with itself or with non-fbjni code that manages the attachment correctly. ++ * ++ * Potential concerns: ++ * - Attaching to the JVM is fast (~100us on MotoG), but ideally you would ++ * attach while the app is not busy. ++ * - Having a thread detach at arbitrary points is not safe in Dalvik; you need ++ * to be sure that there is no Java code on the current stack or you run the ++ * risk of a crash like: ERROR: detaching thread with interp frames (count=18) ++ * (More detail at ++ * https://groups.google.com/forum/#!topic/android-ndk/2H8z5grNqjo) ThreadScope ++ * won't do a detach if the thread was already attached before the guard is ++ * instantiated, but there's probably some usage that could trip this up. ++ * - Newly attached C++ threads only get the bootstrap class loader -- i.e. ++ * java language classes, not any of our application's classes. This will be ++ * different behavior than threads that were initiated on the Java side. A ++ * workaround is to pass a global reference for a class or instance to the new ++ * thread; this bypasses the need for the class loader. (See ++ * http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/invocation.html#attach_current_thread) ++ * If you need access to the application's classes, you can use ++ * ThreadScope::WithClassLoader. ++ */ ++class FBEXPORT ThreadScope { ++ public: ++ ThreadScope(); ++ ThreadScope(ThreadScope&) = delete; ++ ThreadScope(ThreadScope&&) = default; ++ ThreadScope& operator=(ThreadScope&) = delete; ++ ThreadScope& operator=(ThreadScope&&) = delete; ++ ~ThreadScope(); ++ ++ /** ++ * This runs the closure in a scope with fbjni's classloader. This should be ++ * the same classloader as the rest of the application and thus anything ++ * running in the closure will have access to the same classes as in a normal ++ * java-create thread. ++ */ ++ static void WithClassLoader(std::function&& runnable); ++ ++ static void OnLoad(); ++ ++ // This constructor is only used internally by fbjni. ++ ThreadScope(JNIEnv*, internal::CacheEnvTag); ++ ++ private: ++ friend struct Environment; ++ ThreadScope* previous_; ++ // If the JNIEnv* is set, it is guaranteed to be valid at least through the ++ // lifetime of this ThreadScope. The only case where that guarantee can be ++ // made is when there is a java frame in the stack below this. ++ JNIEnv* env_; ++ bool attachedWithThisScope_; ++}; ++} // namespace jni ++} // namespace facebook +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fb/include/fb/ProgramLocation.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fb/include/fb/ProgramLocation.h +new file mode 100644 +index 0000000..45c4ca5 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fb/include/fb/ProgramLocation.h +@@ -0,0 +1,58 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++#include ++#include ++#include ++ ++namespace facebook { ++ ++#define FROM_HERE facebook::ProgramLocation(__FUNCTION__, __FILE__, __LINE__) ++ ++class ProgramLocation { ++ public: ++ ProgramLocation() ++ : m_functionName("Unspecified"), ++ m_fileName("Unspecified"), ++ m_lineNumber(0) {} ++ ++ ProgramLocation(const char* functionName, const char* fileName, int line) ++ : m_functionName(functionName), ++ m_fileName(fileName), ++ m_lineNumber(line) {} ++ ++ const char* functionName() const { ++ return m_functionName; ++ } ++ const char* fileName() const { ++ return m_fileName; ++ } ++ int lineNumber() const { ++ return m_lineNumber; ++ } ++ ++ std::string asFormattedString() const { ++ std::stringstream str; ++ str << "Function " << m_functionName << " in file " << m_fileName << ":" ++ << m_lineNumber; ++ return str.str(); ++ } ++ ++ bool operator==(const ProgramLocation& other) const { ++ // Assumes that the strings are static ++ return (m_functionName == other.m_functionName) && ++ (m_fileName == other.m_fileName) && m_lineNumber == other.m_lineNumber; ++ } ++ ++ private: ++ const char* m_functionName; ++ const char* m_fileName; ++ int m_lineNumber; ++}; ++ ++} // namespace facebook +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fb/include/fb/RefPtr.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fb/include/fb/RefPtr.h +new file mode 100644 +index 0000000..c7acd78 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fb/include/fb/RefPtr.h +@@ -0,0 +1,266 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++#include ++#include ++ ++namespace facebook { ++ ++// Reference counting smart pointer. This is designed to work with the ++// Countable class or other implementations in the future. It is designed in a ++// way to be both efficient and difficult to misuse. Typical usage is very ++// simple once you learn the patterns (and the compiler will help!): ++// ++// By default, the internal pointer is null. ++// RefPtr ref; ++// ++// Object creation requires explicit construction: ++// RefPtr ref = createNew(...); ++// ++// Or if the constructor is not public: ++// RefPtr ref = adoptRef(new Foo(...)); ++// ++// But you can implicitly create from nullptr: ++// RefPtr maybeRef = cond ? ref : nullptr; ++// ++// Move/Copy Construction/Assignment are straightforward: ++// RefPtr ref2 = ref; ++// ref = std::move(ref2); ++// ++// Destruction automatically drops the RefPtr's reference as expected. ++// ++// Upcasting is implicit but downcasting requires an explicit cast: ++// struct Bar : public Foo {}; ++// RefPtr barRef = static_cast>(ref); ++// ref = barRef; ++// ++template ++class RefPtr { ++ public: ++ constexpr RefPtr() : m_ptr(nullptr) {} ++ ++ // Allow implicit construction from a pointer only from nullptr ++ constexpr RefPtr(std::nullptr_t ptr) : m_ptr(nullptr) {} ++ ++ RefPtr(const RefPtr& ref) : m_ptr(ref.m_ptr) { ++ refIfNecessary(m_ptr); ++ } ++ ++ // Only allow implicit upcasts. A downcast will result in a compile error ++ // unless you use static_cast (which will end up invoking the explicit ++ // operator below). ++ template ++ RefPtr( ++ const RefPtr& ref, ++ typename std::enable_if::value, U>::type* = nullptr) ++ : m_ptr(ref.get()) { ++ refIfNecessary(m_ptr); ++ } ++ ++ RefPtr(RefPtr&& ref) : m_ptr(nullptr) { ++ *this = std::move(ref); ++ } ++ ++ // Only allow implicit upcasts. A downcast will result in a compile error ++ // unless you use static_cast (which will end up invoking the explicit ++ // operator below). ++ template ++ RefPtr( ++ RefPtr&& ref, ++ typename std::enable_if::value, U>::type* = nullptr) ++ : m_ptr(nullptr) { ++ *this = std::move(ref); ++ } ++ ++ ~RefPtr() { ++ unrefIfNecessary(m_ptr); ++ m_ptr = nullptr; ++ } ++ ++ RefPtr& operator=(const RefPtr& ref) { ++ if (m_ptr != ref.m_ptr) { ++ unrefIfNecessary(m_ptr); ++ m_ptr = ref.m_ptr; ++ refIfNecessary(m_ptr); ++ } ++ return *this; ++ } ++ ++ // The STL assumes rvalue references are unique and for simplicity's sake, we ++ // make the same assumption here, that &ref != this. ++ RefPtr& operator=(RefPtr&& ref) { ++ unrefIfNecessary(m_ptr); ++ m_ptr = ref.m_ptr; ++ ref.m_ptr = nullptr; ++ return *this; ++ } ++ ++ template ++ RefPtr& operator=(RefPtr&& ref) { ++ unrefIfNecessary(m_ptr); ++ m_ptr = ref.m_ptr; ++ ref.m_ptr = nullptr; ++ return *this; ++ } ++ ++ void reset() { ++ unrefIfNecessary(m_ptr); ++ m_ptr = nullptr; ++ } ++ ++ T* get() const { ++ return m_ptr; ++ } ++ ++ T* operator->() const { ++ return m_ptr; ++ } ++ ++ T& operator*() const { ++ return *m_ptr; ++ } ++ ++ template ++ explicit operator RefPtr() const; ++ ++ explicit operator bool() const { ++ return m_ptr ? true : false; ++ } ++ ++ bool isTheLastRef() const { ++ FBASSERT(m_ptr); ++ return m_ptr->hasOnlyOneRef(); ++ } ++ ++ // Creates a strong reference from a raw pointer, assuming that is already ++ // referenced from some other RefPtr. This should be used sparingly. ++ static inline RefPtr assumeAlreadyReffed(T* ptr) { ++ return RefPtr(ptr, ConstructionMode::External); ++ } ++ ++ // Creates a strong reference from a raw pointer, assuming that it points to a ++ // freshly-created object. See the documentation for RefPtr for usage. ++ static inline RefPtr adoptRef(T* ptr) { ++ return RefPtr(ptr, ConstructionMode::Adopted); ++ } ++ ++ private: ++ enum class ConstructionMode { Adopted, External }; ++ ++ RefPtr(T* ptr, ConstructionMode mode) : m_ptr(ptr) { ++ FBASSERTMSGF( ++ ptr, ++ "Got null pointer in %s construction mode", ++ mode == ConstructionMode::Adopted ? "adopted" : "external"); ++ ptr->ref(); ++ if (mode == ConstructionMode::Adopted) { ++ FBASSERT(ptr->hasOnlyOneRef()); ++ } ++ } ++ ++ static inline void refIfNecessary(T* ptr) { ++ if (ptr) { ++ ptr->ref(); ++ } ++ } ++ static inline void unrefIfNecessary(T* ptr) { ++ if (ptr) { ++ ptr->unref(); ++ } ++ } ++ ++ template ++ friend class RefPtr; ++ ++ T* m_ptr; ++}; ++ ++// Creates a strong reference from a raw pointer, assuming that is already ++// referenced from some other RefPtr and that it is non-null. This should be ++// used sparingly. ++template ++static inline RefPtr assumeAlreadyReffed(T* ptr) { ++ return RefPtr::assumeAlreadyReffed(ptr); ++} ++ ++// As above, but tolerant of nullptr. ++template ++static inline RefPtr assumeAlreadyReffedOrNull(T* ptr) { ++ return ptr ? RefPtr::assumeAlreadyReffed(ptr) : nullptr; ++} ++ ++// Creates a strong reference from a raw pointer, assuming that it points to a ++// freshly-created object. See the documentation for RefPtr for usage. ++template ++static inline RefPtr adoptRef(T* ptr) { ++ return RefPtr::adoptRef(ptr); ++} ++ ++template ++static inline RefPtr createNew(Args&&... arguments) { ++ return RefPtr::adoptRef(new T(std::forward(arguments)...)); ++} ++ ++template ++template ++RefPtr::operator RefPtr() const { ++ static_assert(std::is_base_of::value, "Invalid static cast"); ++ return assumeAlreadyReffedOrNull(static_cast(m_ptr)); ++} ++ ++template ++inline bool operator==(const RefPtr& a, const RefPtr& b) { ++ return a.get() == b.get(); ++} ++ ++template ++inline bool operator!=(const RefPtr& a, const RefPtr& b) { ++ return a.get() != b.get(); ++} ++ ++template ++inline bool operator==(const RefPtr& ref, U* ptr) { ++ return ref.get() == ptr; ++} ++ ++template ++inline bool operator!=(const RefPtr& ref, U* ptr) { ++ return ref.get() != ptr; ++} ++ ++template ++inline bool operator==(U* ptr, const RefPtr& ref) { ++ return ref.get() == ptr; ++} ++ ++template ++inline bool operator!=(U* ptr, const RefPtr& ref) { ++ return ref.get() != ptr; ++} ++ ++template ++inline bool operator==(const RefPtr& ref, std::nullptr_t ptr) { ++ return ref.get() == ptr; ++} ++ ++template ++inline bool operator!=(const RefPtr& ref, std::nullptr_t ptr) { ++ return ref.get() != ptr; ++} ++ ++template ++inline bool operator==(std::nullptr_t ptr, const RefPtr& ref) { ++ return ref.get() == ptr; ++} ++ ++template ++inline bool operator!=(std::nullptr_t ptr, const RefPtr& ref) { ++ return ref.get() != ptr; ++} ++ ++} // namespace facebook +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fb/include/fb/StaticInitialized.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fb/include/fb/StaticInitialized.h +new file mode 100644 +index 0000000..4139b42 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fb/include/fb/StaticInitialized.h +@@ -0,0 +1,37 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++#include ++#include ++ ++namespace facebook { ++ ++// Class that lets you declare a global but does not add a static constructor ++// to the binary. Eventually I'd like to have this auto-initialize in a ++// multithreaded environment but for now it's easiest just to use manual ++// initialization. ++template ++class StaticInitialized { ++ public: ++ constexpr StaticInitialized() : m_instance(nullptr) {} ++ ++ template ++ void initialize(Args&&... arguments) { ++ FBASSERT(!m_instance); ++ m_instance = new T(std::forward(arguments)...); ++ } ++ ++ T* operator->() const { ++ return m_instance; ++ } ++ ++ private: ++ T* m_instance; ++}; ++ ++} // namespace facebook +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fb/include/fb/ThreadLocal.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fb/include/fb/ThreadLocal.h +new file mode 100644 +index 0000000..acd5d24 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fb/include/fb/ThreadLocal.h +@@ -0,0 +1,112 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++#include ++ ++#include ++ ++namespace facebook { ++ ++/////////////////////////////////////////////////////////////////////////////// ++ ++/** ++ * A thread-local object is a "global" object within a thread. This is useful ++ * for writing apartment-threaded code, where nothing is actullay shared ++ * between different threads (hence no locking) but those variables are not ++ * on stack in local scope. To use it, just do something like this, ++ * ++ * ThreadLocal static_object; ++ * static_object->data_ = ...; ++ * static_object->doSomething(); ++ * ++ * ThreadLocal static_number; ++ * int value = *static_number; ++ * ++ * So, syntax-wise it's similar to pointers. T can be primitive types, and if ++ * it's a class, there has to be a default constructor. ++ */ ++template ++class ThreadLocal { ++ public: ++ /** ++ * Constructor that has to be called from a thread-neutral place. ++ */ ++ ThreadLocal() : m_key(0), m_cleanup(OnThreadExit) { ++ initialize(); ++ } ++ ++ /** ++ * As above but with a custom cleanup function ++ */ ++ typedef void (*CleanupFunction)(void* obj); ++ explicit ThreadLocal(CleanupFunction cleanup) : m_key(0), m_cleanup(cleanup) { ++ FBASSERT(cleanup); ++ initialize(); ++ } ++ ++ /** ++ * Access object's member or method through this operator overload. ++ */ ++ T* operator->() const { ++ return get(); ++ } ++ ++ T& operator*() const { ++ return *get(); ++ } ++ ++ T* get() const { ++ return (T*)pthread_getspecific(m_key); ++ } ++ ++ T* release() { ++ T* obj = get(); ++ pthread_setspecific(m_key, NULL); ++ return obj; ++ } ++ ++ void reset(T* other = NULL) { ++ T* old = (T*)pthread_getspecific(m_key); ++ if (old != other) { ++ FBASSERT(m_cleanup); ++ m_cleanup(old); ++ pthread_setspecific(m_key, other); ++ } ++ } ++ ++ private: ++ void initialize() { ++ int ret = pthread_key_create(&m_key, m_cleanup); ++ if (ret != 0) { ++ const char* msg = "(unknown error)"; ++ switch (ret) { ++ case EAGAIN: ++ msg = "PTHREAD_KEYS_MAX (1024) is exceeded"; ++ break; ++ case ENOMEM: ++ msg = "Out-of-memory"; ++ break; ++ } ++ (void)msg; ++ FBASSERTMSGF(0, "pthread_key_create failed: %d %s", ret, msg); ++ } ++ } ++ ++ static void OnThreadExit(void* obj) { ++ if (NULL != obj) { ++ delete (T*)obj; ++ } ++ } ++ ++ pthread_key_t m_key; ++ CleanupFunction m_cleanup; ++}; ++ ++} // namespace facebook +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fb/include/fb/assert.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fb/include/fb/assert.h +new file mode 100644 +index 0000000..25914cb +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fb/include/fb/assert.h +@@ -0,0 +1,43 @@ ++/* ++ * 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. ++ */ ++ ++#ifndef FBASSERT_H ++#define FBASSERT_H ++ ++#include ++ ++namespace facebook { ++#define ENABLE_FBASSERT 1 ++ ++#if ENABLE_FBASSERT ++#define FBASSERTMSGF(expr, msg, ...) \ ++ !(expr) ? facebook::assertInternal( \ ++ "Assert (%s:%d): " msg, __FILE__, __LINE__, ##__VA_ARGS__) \ ++ : (void)0 ++#else ++#define FBASSERTMSGF(expr, msg, ...) ++#endif // ENABLE_FBASSERT ++ ++#define FBASSERT(expr) FBASSERTMSGF(expr, "%s", #expr) ++ ++#define FBCRASH(msg, ...) \ ++ facebook::assertInternal( \ ++ "Fatal error (%s:%d): " msg, __FILE__, __LINE__, ##__VA_ARGS__) ++#define FBUNREACHABLE() \ ++ facebook::assertInternal( \ ++ "This code should be unreachable (%s:%d)", __FILE__, __LINE__) ++ ++FBEXPORT void assertInternal(const char* formatstr, ...) ++ __attribute__((noreturn)); ++ ++// This allows storing the assert message before the current process terminates ++// due to a crash ++typedef void (*AssertHandler)(const char* message); ++void setAssertHandler(AssertHandler assertHandler); ++ ++} // namespace facebook ++#endif // FBASSERT_H +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fb/include/fb/log.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fb/include/fb/log.h +new file mode 100644 +index 0000000..0185c7c +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fb/include/fb/log.h +@@ -0,0 +1,350 @@ ++/* ++ * Copyright (C) 2005 The Android Open Source Project ++ * ++ * Licensed under the Apache License, Version 2.0 (the "License"); ++ * you may not use this file except in compliance with the License. ++ * You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ */ ++ ++/* ++ * FB Wrapper for logging functions. ++ * ++ * The android logging API uses the macro "LOG()" for its logic, which means ++ * that it conflicts with random other places that use LOG for their own ++ * purposes and doesn't work right half the places you include it ++ * ++ * FBLOG uses exactly the same semantics (FBLOGD for debug etc) but because of ++ * the FB prefix it's strictly better. FBLOGV also gets stripped out based on ++ * whether NDEBUG is set, but can be overridden by FBLOG_NDEBUG ++ * ++ * Most of the rest is a copy of with minor changes. ++ */ ++ ++// ++// C/C++ logging functions. See the logging documentation for API details. ++// ++// We'd like these to be available from C code (in case we import some from ++// somewhere), so this has a C interface. ++// ++// The output will be correct when the log file is shared between multiple ++// threads and/or multiple processes so long as the operating system ++// supports O_APPEND. These calls have mutex-protected data structures ++// and so are NOT reentrant. Do not use LOG in a signal handler. ++// ++#pragma once ++ ++#include ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++#ifdef ANDROID ++#include ++#else ++// These declarations are needed for our internal use even on non-Android ++// builds. ++// (they are borrowed from ) ++ ++/* ++ * Android log priority values, in ascending priority order. ++ */ ++typedef enum android_LogPriority { ++ ANDROID_LOG_UNKNOWN = 0, ++ ANDROID_LOG_DEFAULT, /* only for SetMinPriority() */ ++ ANDROID_LOG_VERBOSE, ++ ANDROID_LOG_DEBUG, ++ ANDROID_LOG_INFO, ++ ANDROID_LOG_WARN, ++ ANDROID_LOG_ERROR, ++ ANDROID_LOG_FATAL, ++ ANDROID_LOG_SILENT, /* only for SetMinPriority(); must be last */ ++} android_LogPriority; ++ ++/* ++ * Send a simple string to the log. ++ */ ++int __android_log_write(int prio, const char* tag, const char* text); ++ ++/* ++ * Send a formatted string to the log, used like printf(fmt,...) ++ */ ++int __android_log_print(int prio, const char* tag, const char* fmt, ...) ++#if defined(__GNUC__) ++ __attribute__((format(printf, 3, 4))) ++#endif ++ ; ++ ++#endif ++ ++// --------------------------------------------------------------------- ++ ++/* ++ * Normally we strip FBLOGV (VERBOSE messages) from release builds. ++ * You can modify this (for example with "#define FBLOG_NDEBUG 0" ++ * at the top of your source file) to change that behavior. ++ */ ++#ifndef FBLOG_NDEBUG ++#ifdef NDEBUG ++#define FBLOG_NDEBUG 1 ++#else ++#define FBLOG_NDEBUG 0 ++#endif ++#endif ++ ++/* ++ * This is the local tag used for the following simplified ++ * logging macros. You can change this preprocessor definition ++ * before using the other macros to change the tag. ++ */ ++#ifndef LOG_TAG ++#define LOG_TAG NULL ++#endif ++ ++// --------------------------------------------------------------------- ++ ++/* ++ * Simplified macro to send a verbose log message using the current LOG_TAG. ++ */ ++#ifndef FBLOGV ++#if FBLOG_NDEBUG ++#define FBLOGV(...) ((void)0) ++#else ++#define FBLOGV(...) ((void)FBLOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) ++#endif ++#endif ++ ++#define CONDITION(cond) (__builtin_expect((cond) != 0, 0)) ++ ++#ifndef FBLOGV_IF ++#if FBLOG_NDEBUG ++#define FBLOGV_IF(cond, ...) ((void)0) ++#else ++#define FBLOGV_IF(cond, ...) \ ++ ((CONDITION(cond)) ? ((void)FBLOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) \ ++ : (void)0) ++#endif ++#endif ++ ++/* ++ * Simplified macro to send a debug log message using the current LOG_TAG. ++ */ ++#ifndef FBLOGD ++#define FBLOGD(...) ((void)FBLOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)) ++#endif ++ ++#ifndef FBLOGD_IF ++#define FBLOGD_IF(cond, ...) \ ++ ((CONDITION(cond)) ? ((void)FBLOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)) : (void)0) ++#endif ++ ++/* ++ * Simplified macro to send an info log message using the current LOG_TAG. ++ */ ++#ifndef FBLOGI ++#define FBLOGI(...) ((void)FBLOG(LOG_INFO, LOG_TAG, __VA_ARGS__)) ++#endif ++ ++#ifndef FBLOGI_IF ++#define FBLOGI_IF(cond, ...) \ ++ ((CONDITION(cond)) ? ((void)FBLOG(LOG_INFO, LOG_TAG, __VA_ARGS__)) : (void)0) ++#endif ++ ++/* ++ * Simplified macro to send a warning log message using the current LOG_TAG. ++ */ ++#ifndef FBLOGW ++#define FBLOGW(...) ((void)FBLOG(LOG_WARN, LOG_TAG, __VA_ARGS__)) ++#endif ++ ++#ifndef FBLOGW_IF ++#define FBLOGW_IF(cond, ...) \ ++ ((CONDITION(cond)) ? ((void)FBLOG(LOG_WARN, LOG_TAG, __VA_ARGS__)) : (void)0) ++#endif ++ ++/* ++ * Simplified macro to send an error log message using the current LOG_TAG. ++ */ ++#ifndef FBLOGE ++#define FBLOGE(...) ((void)FBLOG(LOG_ERROR, LOG_TAG, __VA_ARGS__)) ++#endif ++ ++#ifndef FBLOGE_IF ++#define FBLOGE_IF(cond, ...) \ ++ ((CONDITION(cond)) ? ((void)FBLOG(LOG_ERROR, LOG_TAG, __VA_ARGS__)) : (void)0) ++#endif ++ ++// --------------------------------------------------------------------- ++ ++/* ++ * Conditional based on whether the current LOG_TAG is enabled at ++ * verbose priority. ++ */ ++#ifndef IF_FBLOGV ++#if FBLOG_NDEBUG ++#define IF_FBLOGV() if (false) ++#else ++#define IF_FBLOGV() IF_FBLOG(LOG_VERBOSE, LOG_TAG) ++#endif ++#endif ++ ++/* ++ * Conditional based on whether the current LOG_TAG is enabled at ++ * debug priority. ++ */ ++#ifndef IF_FBLOGD ++#define IF_FBLOGD() IF_FBLOG(LOG_DEBUG, LOG_TAG) ++#endif ++ ++/* ++ * Conditional based on whether the current LOG_TAG is enabled at ++ * info priority. ++ */ ++#ifndef IF_FBLOGI ++#define IF_FBLOGI() IF_FBLOG(LOG_INFO, LOG_TAG) ++#endif ++ ++/* ++ * Conditional based on whether the current LOG_TAG is enabled at ++ * warn priority. ++ */ ++#ifndef IF_FBLOGW ++#define IF_FBLOGW() IF_FBLOG(LOG_WARN, LOG_TAG) ++#endif ++ ++/* ++ * Conditional based on whether the current LOG_TAG is enabled at ++ * error priority. ++ */ ++#ifndef IF_FBLOGE ++#define IF_FBLOGE() IF_FBLOG(LOG_ERROR, LOG_TAG) ++#endif ++ ++// --------------------------------------------------------------------- ++ ++/* ++ * Log a fatal error. If the given condition fails, this stops program ++ * execution like a normal assertion, but also generating the given message. ++ * It is NOT stripped from release builds. Note that the condition test ++ * is -inverted- from the normal assert() semantics. ++ */ ++#define FBLOG_ALWAYS_FATAL_IF(cond, ...) \ ++ ((CONDITION(cond)) ? ((void)fb_printAssert(#cond, LOG_TAG, __VA_ARGS__)) \ ++ : (void)0) ++ ++#define FBLOG_ALWAYS_FATAL(...) \ ++ (((void)fb_printAssert(NULL, LOG_TAG, __VA_ARGS__))) ++ ++/* ++ * Versions of LOG_ALWAYS_FATAL_IF and LOG_ALWAYS_FATAL that ++ * are stripped out of release builds. ++ */ ++#if FBLOG_NDEBUG ++ ++#define FBLOG_FATAL_IF(cond, ...) ((void)0) ++#define FBLOG_FATAL(...) ((void)0) ++ ++#else ++ ++#define FBLOG_FATAL_IF(cond, ...) FBLOG_ALWAYS_FATAL_IF(cond, __VA_ARGS__) ++#define FBLOG_FATAL(...) FBLOG_ALWAYS_FATAL(__VA_ARGS__) ++ ++#endif ++ ++/* ++ * Assertion that generates a log message when the assertion fails. ++ * Stripped out of release builds. Uses the current LOG_TAG. ++ */ ++#define FBLOG_ASSERT(cond, ...) FBLOG_FATAL_IF(!(cond), __VA_ARGS__) ++// #define LOG_ASSERT(cond) LOG_FATAL_IF(!(cond), "Assertion failed: " #cond) ++ ++// --------------------------------------------------------------------- ++ ++/* ++ * Basic log message macro. ++ * ++ * Example: ++ * FBLOG(LOG_WARN, NULL, "Failed with error %d", errno); ++ * ++ * The second argument may be NULL or "" to indicate the "global" tag. ++ */ ++#ifndef FBLOG ++#define FBLOG(priority, tag, ...) \ ++ FBLOG_PRI(ANDROID_##priority, tag, __VA_ARGS__) ++#endif ++ ++#ifndef FBLOG_BY_DELIMS ++#define FBLOG_BY_DELIMS(priority, tag, delims, msg, ...) \ ++ logPrintByDelims(ANDROID_##priority, tag, delims, msg, ##__VA_ARGS__) ++#endif ++ ++/* ++ * Log macro that allows you to specify a number for the priority. ++ */ ++#ifndef FBLOG_PRI ++#define FBLOG_PRI(priority, tag, ...) fb_printLog(priority, tag, __VA_ARGS__) ++#endif ++ ++/* ++ * Log macro that allows you to pass in a varargs ("args" is a va_list). ++ */ ++#ifndef FBLOG_PRI_VA ++#define FBLOG_PRI_VA(priority, tag, fmt, args) \ ++ fb_vprintLog(priority, NULL, tag, fmt, args) ++#endif ++ ++/* ++ * Conditional given a desired logging priority and tag. ++ */ ++#ifndef IF_FBLOG ++#define IF_FBLOG(priority, tag) if (fb_testLog(ANDROID_##priority, tag)) ++#endif ++ ++typedef void (*LogHandler)(int priority, const char* tag, const char* message); ++FBEXPORT void setLogHandler(LogHandler logHandler); ++ ++/* ++ * =========================================================================== ++ * ++ * The stuff in the rest of this file should not be used directly. ++ */ ++FBEXPORT int fb_printLog(int prio, const char* tag, const char* fmt, ...) ++#if defined(__GNUC__) ++ __attribute__((format(printf, 3, 4))) ++#endif ++ ; ++ ++#define fb_vprintLog(prio, cond, tag, fmt...) \ ++ __android_log_vprint(prio, tag, fmt) ++ ++#define fb_printAssert(cond, tag, fmt...) __android_log_assert(cond, tag, fmt) ++ ++#define fb_writeLog(prio, tag, text) __android_log_write(prio, tag, text) ++ ++#define fb_bWriteLog(tag, payload, len) __android_log_bwrite(tag, payload, len) ++#define fb_btWriteLog(tag, type, payload, len) \ ++ __android_log_btwrite(tag, type, payload, len) ++ ++#define fb_testLog(prio, tag) (1) ++ ++/* ++ * FB extensions ++ */ ++void logPrintByDelims( ++ int priority, ++ const char* tag, ++ const char* delims, ++ const char* msg, ++ ...); ++ ++#ifdef __cplusplus ++} ++#endif +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fb/include/fb/noncopyable.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fb/include/fb/noncopyable.h +new file mode 100644 +index 0000000..329ff5d +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fb/include/fb/noncopyable.h +@@ -0,0 +1,20 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++namespace facebook { ++ ++struct noncopyable { ++ noncopyable(const noncopyable&) = delete; ++ noncopyable& operator=(const noncopyable&) = delete; ++ ++ protected: ++ noncopyable() = default; ++}; ++ ++} // namespace facebook +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fb/include/fb/nonmovable.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fb/include/fb/nonmovable.h +new file mode 100644 +index 0000000..856b2f4 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fb/include/fb/nonmovable.h +@@ -0,0 +1,20 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++namespace facebook { ++ ++struct nonmovable { ++ nonmovable(nonmovable&&) = delete; ++ nonmovable& operator=(nonmovable&&) = delete; ++ ++ protected: ++ nonmovable() = default; ++}; ++ ++} // namespace facebook +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fb/include/fb/visibility.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fb/include/fb/visibility.h +new file mode 100644 +index 0000000..f44ef60 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fb/include/fb/visibility.h +@@ -0,0 +1,10 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#define FBEXPORT __attribute__((visibility("default"))) +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fb/log.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fb/log.cpp +new file mode 100644 +index 0000000..8e9aa14 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fb/log.cpp +@@ -0,0 +1,102 @@ ++/* ++ * 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. ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#define LOG_BUFFER_SIZE 4096 ++static LogHandler gLogHandler; ++ ++void setLogHandler(LogHandler logHandler) { ++ gLogHandler = logHandler; ++} ++ ++int fb_printLog(int prio, const char* tag, const char* fmt, ...) { ++ char logBuffer[LOG_BUFFER_SIZE]; ++ ++ va_list va_args; ++ va_start(va_args, fmt); ++ int result = vsnprintf(logBuffer, sizeof(logBuffer), fmt, va_args); ++ va_end(va_args); ++ if (gLogHandler != NULL) { ++ gLogHandler(prio, tag, logBuffer); ++ } ++ __android_log_write(prio, tag, logBuffer); ++ return result; ++} ++ ++void logPrintByDelims( ++ int priority, ++ const char* tag, ++ const char* delims, ++ const char* msg, ++ ...) { ++ va_list ap; ++ char buf[32768]; ++ char* context; ++ char* tok; ++ ++ va_start(ap, msg); ++ vsnprintf(buf, sizeof(buf), msg, ap); ++ va_end(ap); ++ ++ tok = strtok_r(buf, delims, &context); ++ ++ if (!tok) { ++ return; ++ } ++ ++ do { ++ __android_log_write(priority, tag, tok); ++ } while ((tok = strtok_r(NULL, delims, &context))); ++} ++ ++#ifndef ANDROID ++ ++// Implementations of the basic android logging functions for non-android ++// platforms. ++ ++static char logTagChar(int prio) { ++ switch (prio) { ++ default: ++ case ANDROID_LOG_UNKNOWN: ++ case ANDROID_LOG_DEFAULT: ++ case ANDROID_LOG_SILENT: ++ return ' '; ++ case ANDROID_LOG_VERBOSE: ++ return 'V'; ++ case ANDROID_LOG_DEBUG: ++ return 'D'; ++ case ANDROID_LOG_INFO: ++ return 'I'; ++ case ANDROID_LOG_WARN: ++ return 'W'; ++ case ANDROID_LOG_ERROR: ++ return 'E'; ++ case ANDROID_LOG_FATAL: ++ return 'F'; ++ } ++} ++ ++int __android_log_write(int prio, const char* tag, const char* text) { ++ return fprintf(stderr, "[%c/%.16s] %s\n", logTagChar(prio), tag, text); ++} ++ ++int __android_log_print(int prio, const char* tag, const char* fmt, ...) { ++ va_list ap; ++ va_start(ap, fmt); ++ ++ int res = fprintf(stderr, "[%c/%.16s] ", logTagChar(prio), tag); ++ res += vfprintf(stderr, "%s\n", ap); ++ ++ va_end(ap); ++ return res; ++} ++ ++#endif +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fbgloginit/CMakeLists.txt b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fbgloginit/CMakeLists.txt +new file mode 100644 +index 0000000..194f607 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fbgloginit/CMakeLists.txt +@@ -0,0 +1,15 @@ ++# 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. ++ ++cmake_minimum_required(VERSION 3.13) ++set(CMAKE_VERBOSE_MAKEFILE on) ++ ++add_compile_options(-fexceptions -fno-omit-frame-pointer) ++ ++add_library(glog_init STATIC glog_init.cpp) ++ ++target_include_directories(glog_init PUBLIC .) ++ ++target_link_libraries(glog_init log glog) +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fbgloginit/fb/glog_init.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fbgloginit/fb/glog_init.h +new file mode 100644 +index 0000000..9b48573 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fbgloginit/fb/glog_init.h +@@ -0,0 +1,18 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++ ++namespace facebook { ++namespace gloginit { ++ ++void initialize(const char* tag = "ReactNativeJNI"); ++ ++} ++} // namespace facebook +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fbgloginit/glog_init.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fbgloginit/glog_init.cpp +new file mode 100644 +index 0000000..f12d226 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/fbgloginit/glog_init.cpp +@@ -0,0 +1,141 @@ ++/* ++ * 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. ++ */ ++ ++#include "fb/glog_init.h" ++ ++#include ++#include ++#include ++ ++#include ++ ++#ifdef __ANDROID__ ++ ++#include ++ ++static int toAndroidLevel(google::LogSeverity severity) { ++ switch (severity) { ++ case google::GLOG_INFO: ++ return ANDROID_LOG_INFO; ++ case google::GLOG_WARNING: ++ return ANDROID_LOG_WARN; ++ case google::GLOG_ERROR: ++ return ANDROID_LOG_ERROR; ++ case google::GLOG_FATAL: ++ return ANDROID_LOG_FATAL; ++ default: ++ return ANDROID_LOG_FATAL; ++ } ++} ++ ++/** ++ * Sends GLog output to adb logcat. ++ */ ++class LogcatSink : public google::LogSink { ++ public: ++ void send( ++ google::LogSeverity severity, ++ const char* full_filename, ++ const char* base_filename, ++ int line, ++ const struct ::tm* tm_time, ++ const char* message, ++ size_t message_len) override { ++ auto level = toAndroidLevel(severity); ++ __android_log_print( ++ level, base_filename, "%.*s", (int)message_len, message); ++ } ++}; ++ ++/** ++ * Sends GLog output to adb logcat. ++ */ ++class TaggedLogcatSink : public google::LogSink { ++ const std::string tag_; ++ ++ public: ++ TaggedLogcatSink(const std::string& tag) : tag_{tag} {} ++ ++ void send( ++ google::LogSeverity severity, ++ const char* full_filename, ++ const char* base_filename, ++ int line, ++ const struct ::tm* tm_time, ++ const char* message, ++ size_t message_len) override { ++ auto level = toAndroidLevel(severity); ++ __android_log_print(level, tag_.c_str(), "%.*s", (int)message_len, message); ++ } ++}; ++ ++static google::LogSink* make_sink(const std::string& tag) { ++ if (tag.empty()) { ++ return new LogcatSink{}; ++ } else { ++ return new TaggedLogcatSink{tag}; ++ } ++} ++ ++static void sendGlogOutputToLogcat(const char* tag) { ++ google::AddLogSink(make_sink(tag)); ++ ++ // Disable logging to files ++ for (auto i = 0; i < google::NUM_SEVERITIES; ++i) { ++ google::SetLogDestination(i, ""); ++ } ++} ++ ++#endif // __ANDROID__ ++ ++static void ++lastResort(const char* tag, const char* msg, const char* arg = nullptr) { ++#ifdef __ANDROID__ ++ if (!arg) { ++ __android_log_write(ANDROID_LOG_ERROR, tag, msg); ++ } else { ++ __android_log_print(ANDROID_LOG_ERROR, tag, "%s: %s", msg, arg); ++ } ++#else ++ std::cerr << msg; ++ if (arg) { ++ std::cerr << ": " << arg; ++ } ++ std::cerr << std::endl; ++#endif ++} ++ ++namespace facebook { ++namespace gloginit { ++ ++void initialize(const char* tag) { ++ static std::once_flag flag{}; ++ static auto failed = false; ++ ++ std::call_once(flag, [tag] { ++ try { ++ google::InitGoogleLogging(tag); ++ ++#ifdef __ANDROID__ ++ sendGlogOutputToLogcat(tag); ++#endif ++ } catch (std::exception& ex) { ++ lastResort(tag, "Failed to initialize glog", ex.what()); ++ failed = true; ++ } catch (...) { ++ lastResort(tag, "Failed to initialize glog"); ++ failed = true; ++ } ++ }); ++ ++ if (failed) { ++ throw std::runtime_error{"Failed to initialize glog"}; ++ } ++} ++ ++} // namespace gloginit ++} // namespace facebook +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/hermes/CMakeLists.txt b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/hermes/CMakeLists.txt +new file mode 100644 +index 0000000..4bfbaa1 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/hermes/CMakeLists.txt +@@ -0,0 +1,13 @@ ++# 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. ++ ++cmake_minimum_required(VERSION 3.13) ++set(CMAKE_VERBOSE_MAKEFILE on) ++ ++add_library(hermes SHARED IMPORTED GLOBAL) ++set_target_properties(hermes ++ PROPERTIES ++ IMPORTED_LOCATION ++ ${CMAKE_CURRENT_SOURCE_DIR}/jni/${ANDROID_ABI}/libhermes.so) +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/jni-hack/README.md b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/jni-hack/README.md +new file mode 100644 +index 0000000..c30486e +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/jni-hack/README.md +@@ -0,0 +1 @@ ++This buck module exists so that targets that need to be built against both 1) Android (where we can and should use the Android NDK jni headers) and 2) the host platform(generally for local unit tests) can depend on a single target and get the right jni header for whatever platform they're building against automatically. +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/jni-hack/jni.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/jni-hack/jni.h +new file mode 100644 +index 0000000..cd49dc5 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/jni-hack/jni.h +@@ -0,0 +1,14 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#ifdef __ANDROID__ ++#include_next ++#else ++#include "real/jni.h" ++#endif +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/jni-hack/real/jni.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/jni-hack/real/jni.h +new file mode 100644 +index 0000000..1eb30b6 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/jni-hack/real/jni.h +@@ -0,0 +1,1330 @@ ++/* ++ * Copyright (C) 2006 The Android Open Source Project ++ * ++ * Licensed under the Apache License, Version 2.0 (the "License"); ++ * you may not use this file except in compliance with the License. ++ * You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ */ ++ ++/* ++ * JNI specification, as defined by Sun: ++ * http://java.sun.com/javase/6/docs/technotes/guides/jni/spec/jniTOC.html ++ * ++ * Everything here is expected to be VM-neutral. ++ */ ++ ++#ifndef JNI_H_ ++#define JNI_H_ ++ ++#include ++#include ++ ++/* Primitive types that match up with Java equivalents. */ ++typedef uint8_t jboolean; /* unsigned 8 bits */ ++typedef int8_t jbyte; /* signed 8 bits */ ++typedef uint16_t jchar; /* unsigned 16 bits */ ++typedef int16_t jshort; /* signed 16 bits */ ++typedef int32_t jint; /* signed 32 bits */ ++typedef int64_t jlong; /* signed 64 bits */ ++typedef float jfloat; /* 32-bit IEEE 754 */ ++typedef double jdouble; /* 64-bit IEEE 754 */ ++ ++/* "cardinal indices and sizes" */ ++typedef jint jsize; ++ ++#ifdef __cplusplus ++/* ++ * Reference types, in C++ ++ */ ++class _jobject {}; ++class _jclass : public _jobject {}; ++class _jstring : public _jobject {}; ++class _jarray : public _jobject {}; ++class _jobjectArray : public _jarray {}; ++class _jbooleanArray : public _jarray {}; ++class _jbyteArray : public _jarray {}; ++class _jcharArray : public _jarray {}; ++class _jshortArray : public _jarray {}; ++class _jintArray : public _jarray {}; ++class _jlongArray : public _jarray {}; ++class _jfloatArray : public _jarray {}; ++class _jdoubleArray : public _jarray {}; ++class _jthrowable : public _jobject {}; ++ ++typedef _jobject* jobject; ++typedef _jclass* jclass; ++typedef _jstring* jstring; ++typedef _jarray* jarray; ++typedef _jobjectArray* jobjectArray; ++typedef _jbooleanArray* jbooleanArray; ++typedef _jbyteArray* jbyteArray; ++typedef _jcharArray* jcharArray; ++typedef _jshortArray* jshortArray; ++typedef _jintArray* jintArray; ++typedef _jlongArray* jlongArray; ++typedef _jfloatArray* jfloatArray; ++typedef _jdoubleArray* jdoubleArray; ++typedef _jthrowable* jthrowable; ++typedef _jobject* jweak; ++ ++#else /* not __cplusplus */ ++ ++/* ++ * Reference types, in C. ++ */ ++typedef void* jobject; ++typedef jobject jclass; ++typedef jobject jstring; ++typedef jobject jarray; ++typedef jarray jobjectArray; ++typedef jarray jbooleanArray; ++typedef jarray jbyteArray; ++typedef jarray jcharArray; ++typedef jarray jshortArray; ++typedef jarray jintArray; ++typedef jarray jlongArray; ++typedef jarray jfloatArray; ++typedef jarray jdoubleArray; ++typedef jobject jthrowable; ++typedef jobject jweak; ++ ++#endif /* not __cplusplus */ ++ ++struct _jfieldID; /* opaque structure */ ++typedef struct _jfieldID* jfieldID; /* field IDs */ ++ ++struct _jmethodID; /* opaque structure */ ++typedef struct _jmethodID* jmethodID; /* method IDs */ ++ ++struct JNIInvokeInterface; ++ ++typedef union jvalue { ++ jboolean z; ++ jbyte b; ++ jchar c; ++ jshort s; ++ jint i; ++ jlong j; ++ jfloat f; ++ jdouble d; ++ jobject l; ++} jvalue; ++ ++typedef enum jobjectRefType { ++ JNIInvalidRefType = 0, ++ JNILocalRefType = 1, ++ JNIGlobalRefType = 2, ++ JNIWeakGlobalRefType = 3 ++} jobjectRefType; ++ ++typedef struct { ++ const char* name; ++ const char* signature; ++ void* fnPtr; ++} JNINativeMethod; ++ ++struct _JNIEnv; ++struct _JavaVM; ++typedef const struct JNINativeInterface* C_JNIEnv; ++ ++#if defined(__cplusplus) ++typedef _JNIEnv JNIEnv; ++typedef _JavaVM JavaVM; ++#else ++typedef const struct JNINativeInterface* JNIEnv; ++typedef const struct JNIInvokeInterface* JavaVM; ++#endif ++ ++/* ++ * Table of interface function pointers. ++ */ ++struct JNINativeInterface { ++ void* reserved0; ++ void* reserved1; ++ void* reserved2; ++ void* reserved3; ++ ++ jint (*GetVersion)(JNIEnv*); ++ ++ jclass (*DefineClass)(JNIEnv*, const char*, jobject, const jbyte*, jsize); ++ jclass (*FindClass)(JNIEnv*, const char*); ++ ++ jmethodID (*FromReflectedMethod)(JNIEnv*, jobject); ++ jfieldID (*FromReflectedField)(JNIEnv*, jobject); ++ /* spec doesn't show jboolean parameter */ ++ jobject (*ToReflectedMethod)(JNIEnv*, jclass, jmethodID, jboolean); ++ ++ jclass (*GetSuperclass)(JNIEnv*, jclass); ++ jboolean (*IsAssignableFrom)(JNIEnv*, jclass, jclass); ++ ++ /* spec doesn't show jboolean parameter */ ++ jobject (*ToReflectedField)(JNIEnv*, jclass, jfieldID, jboolean); ++ ++ jint (*Throw)(JNIEnv*, jthrowable); ++ jint (*ThrowNew)(JNIEnv*, jclass, const char*); ++ jthrowable (*ExceptionOccurred)(JNIEnv*); ++ void (*ExceptionDescribe)(JNIEnv*); ++ void (*ExceptionClear)(JNIEnv*); ++ void (*FatalError)(JNIEnv*, const char*); ++ ++ jint (*PushLocalFrame)(JNIEnv*, jint); ++ jobject (*PopLocalFrame)(JNIEnv*, jobject); ++ ++ jobject (*NewGlobalRef)(JNIEnv*, jobject); ++ void (*DeleteGlobalRef)(JNIEnv*, jobject); ++ void (*DeleteLocalRef)(JNIEnv*, jobject); ++ jboolean (*IsSameObject)(JNIEnv*, jobject, jobject); ++ ++ jobject (*NewLocalRef)(JNIEnv*, jobject); ++ jint (*EnsureLocalCapacity)(JNIEnv*, jint); ++ ++ jobject (*AllocObject)(JNIEnv*, jclass); ++ jobject (*NewObject)(JNIEnv*, jclass, jmethodID, ...); ++ jobject (*NewObjectV)(JNIEnv*, jclass, jmethodID, va_list); ++ jobject (*NewObjectA)(JNIEnv*, jclass, jmethodID, jvalue*); ++ ++ jclass (*GetObjectClass)(JNIEnv*, jobject); ++ jboolean (*IsInstanceOf)(JNIEnv*, jobject, jclass); ++ jmethodID (*GetMethodID)(JNIEnv*, jclass, const char*, const char*); ++ ++ jobject (*CallObjectMethod)(JNIEnv*, jobject, jmethodID, ...); ++ jobject (*CallObjectMethodV)(JNIEnv*, jobject, jmethodID, va_list); ++ jobject (*CallObjectMethodA)(JNIEnv*, jobject, jmethodID, jvalue*); ++ jboolean (*CallBooleanMethod)(JNIEnv*, jobject, jmethodID, ...); ++ jboolean (*CallBooleanMethodV)(JNIEnv*, jobject, jmethodID, va_list); ++ jboolean (*CallBooleanMethodA)(JNIEnv*, jobject, jmethodID, jvalue*); ++ jbyte (*CallByteMethod)(JNIEnv*, jobject, jmethodID, ...); ++ jbyte (*CallByteMethodV)(JNIEnv*, jobject, jmethodID, va_list); ++ jbyte (*CallByteMethodA)(JNIEnv*, jobject, jmethodID, jvalue*); ++ jchar (*CallCharMethod)(JNIEnv*, jobject, jmethodID, ...); ++ jchar (*CallCharMethodV)(JNIEnv*, jobject, jmethodID, va_list); ++ jchar (*CallCharMethodA)(JNIEnv*, jobject, jmethodID, jvalue*); ++ jshort (*CallShortMethod)(JNIEnv*, jobject, jmethodID, ...); ++ jshort (*CallShortMethodV)(JNIEnv*, jobject, jmethodID, va_list); ++ jshort (*CallShortMethodA)(JNIEnv*, jobject, jmethodID, jvalue*); ++ jint (*CallIntMethod)(JNIEnv*, jobject, jmethodID, ...); ++ jint (*CallIntMethodV)(JNIEnv*, jobject, jmethodID, va_list); ++ jint (*CallIntMethodA)(JNIEnv*, jobject, jmethodID, jvalue*); ++ jlong (*CallLongMethod)(JNIEnv*, jobject, jmethodID, ...); ++ jlong (*CallLongMethodV)(JNIEnv*, jobject, jmethodID, va_list); ++ jlong (*CallLongMethodA)(JNIEnv*, jobject, jmethodID, jvalue*); ++ jfloat (*CallFloatMethod)(JNIEnv*, jobject, jmethodID, ...); ++ jfloat (*CallFloatMethodV)(JNIEnv*, jobject, jmethodID, va_list); ++ jfloat (*CallFloatMethodA)(JNIEnv*, jobject, jmethodID, jvalue*); ++ jdouble (*CallDoubleMethod)(JNIEnv*, jobject, jmethodID, ...); ++ jdouble (*CallDoubleMethodV)(JNIEnv*, jobject, jmethodID, va_list); ++ jdouble (*CallDoubleMethodA)(JNIEnv*, jobject, jmethodID, jvalue*); ++ void (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...); ++ void (*CallVoidMethodV)(JNIEnv*, jobject, jmethodID, va_list); ++ void (*CallVoidMethodA)(JNIEnv*, jobject, jmethodID, jvalue*); ++ ++ jobject ( ++ *CallNonvirtualObjectMethod)(JNIEnv*, jobject, jclass, jmethodID, ...); ++ jobject (*CallNonvirtualObjectMethodV)( ++ JNIEnv*, ++ jobject, ++ jclass, ++ jmethodID, ++ va_list); ++ jobject (*CallNonvirtualObjectMethodA)( ++ JNIEnv*, ++ jobject, ++ jclass, ++ jmethodID, ++ jvalue*); ++ jboolean ( ++ *CallNonvirtualBooleanMethod)(JNIEnv*, jobject, jclass, jmethodID, ...); ++ jboolean (*CallNonvirtualBooleanMethodV)( ++ JNIEnv*, ++ jobject, ++ jclass, ++ jmethodID, ++ va_list); ++ jboolean (*CallNonvirtualBooleanMethodA)( ++ JNIEnv*, ++ jobject, ++ jclass, ++ jmethodID, ++ jvalue*); ++ jbyte (*CallNonvirtualByteMethod)(JNIEnv*, jobject, jclass, jmethodID, ...); ++ jbyte ( ++ *CallNonvirtualByteMethodV)(JNIEnv*, jobject, jclass, jmethodID, va_list); ++ jbyte ( ++ *CallNonvirtualByteMethodA)(JNIEnv*, jobject, jclass, jmethodID, jvalue*); ++ jchar (*CallNonvirtualCharMethod)(JNIEnv*, jobject, jclass, jmethodID, ...); ++ jchar ( ++ *CallNonvirtualCharMethodV)(JNIEnv*, jobject, jclass, jmethodID, va_list); ++ jchar ( ++ *CallNonvirtualCharMethodA)(JNIEnv*, jobject, jclass, jmethodID, jvalue*); ++ jshort (*CallNonvirtualShortMethod)(JNIEnv*, jobject, jclass, jmethodID, ...); ++ jshort (*CallNonvirtualShortMethodV)( ++ JNIEnv*, ++ jobject, ++ jclass, ++ jmethodID, ++ va_list); ++ jshort (*CallNonvirtualShortMethodA)( ++ JNIEnv*, ++ jobject, ++ jclass, ++ jmethodID, ++ jvalue*); ++ jint (*CallNonvirtualIntMethod)(JNIEnv*, jobject, jclass, jmethodID, ...); ++ jint ( ++ *CallNonvirtualIntMethodV)(JNIEnv*, jobject, jclass, jmethodID, va_list); ++ jint ( ++ *CallNonvirtualIntMethodA)(JNIEnv*, jobject, jclass, jmethodID, jvalue*); ++ jlong (*CallNonvirtualLongMethod)(JNIEnv*, jobject, jclass, jmethodID, ...); ++ jlong ( ++ *CallNonvirtualLongMethodV)(JNIEnv*, jobject, jclass, jmethodID, va_list); ++ jlong ( ++ *CallNonvirtualLongMethodA)(JNIEnv*, jobject, jclass, jmethodID, jvalue*); ++ jfloat (*CallNonvirtualFloatMethod)(JNIEnv*, jobject, jclass, jmethodID, ...); ++ jfloat (*CallNonvirtualFloatMethodV)( ++ JNIEnv*, ++ jobject, ++ jclass, ++ jmethodID, ++ va_list); ++ jfloat (*CallNonvirtualFloatMethodA)( ++ JNIEnv*, ++ jobject, ++ jclass, ++ jmethodID, ++ jvalue*); ++ jdouble ( ++ *CallNonvirtualDoubleMethod)(JNIEnv*, jobject, jclass, jmethodID, ...); ++ jdouble (*CallNonvirtualDoubleMethodV)( ++ JNIEnv*, ++ jobject, ++ jclass, ++ jmethodID, ++ va_list); ++ jdouble (*CallNonvirtualDoubleMethodA)( ++ JNIEnv*, ++ jobject, ++ jclass, ++ jmethodID, ++ jvalue*); ++ void (*CallNonvirtualVoidMethod)(JNIEnv*, jobject, jclass, jmethodID, ...); ++ void ( ++ *CallNonvirtualVoidMethodV)(JNIEnv*, jobject, jclass, jmethodID, va_list); ++ void ( ++ *CallNonvirtualVoidMethodA)(JNIEnv*, jobject, jclass, jmethodID, jvalue*); ++ ++ jfieldID (*GetFieldID)(JNIEnv*, jclass, const char*, const char*); ++ ++ jobject (*GetObjectField)(JNIEnv*, jobject, jfieldID); ++ jboolean (*GetBooleanField)(JNIEnv*, jobject, jfieldID); ++ jbyte (*GetByteField)(JNIEnv*, jobject, jfieldID); ++ jchar (*GetCharField)(JNIEnv*, jobject, jfieldID); ++ jshort (*GetShortField)(JNIEnv*, jobject, jfieldID); ++ jint (*GetIntField)(JNIEnv*, jobject, jfieldID); ++ jlong (*GetLongField)(JNIEnv*, jobject, jfieldID); ++ jfloat (*GetFloatField)(JNIEnv*, jobject, jfieldID); ++ jdouble (*GetDoubleField)(JNIEnv*, jobject, jfieldID); ++ ++ void (*SetObjectField)(JNIEnv*, jobject, jfieldID, jobject); ++ void (*SetBooleanField)(JNIEnv*, jobject, jfieldID, jboolean); ++ void (*SetByteField)(JNIEnv*, jobject, jfieldID, jbyte); ++ void (*SetCharField)(JNIEnv*, jobject, jfieldID, jchar); ++ void (*SetShortField)(JNIEnv*, jobject, jfieldID, jshort); ++ void (*SetIntField)(JNIEnv*, jobject, jfieldID, jint); ++ void (*SetLongField)(JNIEnv*, jobject, jfieldID, jlong); ++ void (*SetFloatField)(JNIEnv*, jobject, jfieldID, jfloat); ++ void (*SetDoubleField)(JNIEnv*, jobject, jfieldID, jdouble); ++ ++ jmethodID (*GetStaticMethodID)(JNIEnv*, jclass, const char*, const char*); ++ ++ jobject (*CallStaticObjectMethod)(JNIEnv*, jclass, jmethodID, ...); ++ jobject (*CallStaticObjectMethodV)(JNIEnv*, jclass, jmethodID, va_list); ++ jobject (*CallStaticObjectMethodA)(JNIEnv*, jclass, jmethodID, jvalue*); ++ jboolean (*CallStaticBooleanMethod)(JNIEnv*, jclass, jmethodID, ...); ++ jboolean (*CallStaticBooleanMethodV)(JNIEnv*, jclass, jmethodID, va_list); ++ jboolean (*CallStaticBooleanMethodA)(JNIEnv*, jclass, jmethodID, jvalue*); ++ jbyte (*CallStaticByteMethod)(JNIEnv*, jclass, jmethodID, ...); ++ jbyte (*CallStaticByteMethodV)(JNIEnv*, jclass, jmethodID, va_list); ++ jbyte (*CallStaticByteMethodA)(JNIEnv*, jclass, jmethodID, jvalue*); ++ jchar (*CallStaticCharMethod)(JNIEnv*, jclass, jmethodID, ...); ++ jchar (*CallStaticCharMethodV)(JNIEnv*, jclass, jmethodID, va_list); ++ jchar (*CallStaticCharMethodA)(JNIEnv*, jclass, jmethodID, jvalue*); ++ jshort (*CallStaticShortMethod)(JNIEnv*, jclass, jmethodID, ...); ++ jshort (*CallStaticShortMethodV)(JNIEnv*, jclass, jmethodID, va_list); ++ jshort (*CallStaticShortMethodA)(JNIEnv*, jclass, jmethodID, jvalue*); ++ jint (*CallStaticIntMethod)(JNIEnv*, jclass, jmethodID, ...); ++ jint (*CallStaticIntMethodV)(JNIEnv*, jclass, jmethodID, va_list); ++ jint (*CallStaticIntMethodA)(JNIEnv*, jclass, jmethodID, jvalue*); ++ jlong (*CallStaticLongMethod)(JNIEnv*, jclass, jmethodID, ...); ++ jlong (*CallStaticLongMethodV)(JNIEnv*, jclass, jmethodID, va_list); ++ jlong (*CallStaticLongMethodA)(JNIEnv*, jclass, jmethodID, jvalue*); ++ jfloat (*CallStaticFloatMethod)(JNIEnv*, jclass, jmethodID, ...); ++ jfloat (*CallStaticFloatMethodV)(JNIEnv*, jclass, jmethodID, va_list); ++ jfloat (*CallStaticFloatMethodA)(JNIEnv*, jclass, jmethodID, jvalue*); ++ jdouble (*CallStaticDoubleMethod)(JNIEnv*, jclass, jmethodID, ...); ++ jdouble (*CallStaticDoubleMethodV)(JNIEnv*, jclass, jmethodID, va_list); ++ jdouble (*CallStaticDoubleMethodA)(JNIEnv*, jclass, jmethodID, jvalue*); ++ void (*CallStaticVoidMethod)(JNIEnv*, jclass, jmethodID, ...); ++ void (*CallStaticVoidMethodV)(JNIEnv*, jclass, jmethodID, va_list); ++ void (*CallStaticVoidMethodA)(JNIEnv*, jclass, jmethodID, jvalue*); ++ ++ jfieldID (*GetStaticFieldID)(JNIEnv*, jclass, const char*, const char*); ++ ++ jobject (*GetStaticObjectField)(JNIEnv*, jclass, jfieldID); ++ jboolean (*GetStaticBooleanField)(JNIEnv*, jclass, jfieldID); ++ jbyte (*GetStaticByteField)(JNIEnv*, jclass, jfieldID); ++ jchar (*GetStaticCharField)(JNIEnv*, jclass, jfieldID); ++ jshort (*GetStaticShortField)(JNIEnv*, jclass, jfieldID); ++ jint (*GetStaticIntField)(JNIEnv*, jclass, jfieldID); ++ jlong (*GetStaticLongField)(JNIEnv*, jclass, jfieldID); ++ jfloat (*GetStaticFloatField)(JNIEnv*, jclass, jfieldID); ++ jdouble (*GetStaticDoubleField)(JNIEnv*, jclass, jfieldID); ++ ++ void (*SetStaticObjectField)(JNIEnv*, jclass, jfieldID, jobject); ++ void (*SetStaticBooleanField)(JNIEnv*, jclass, jfieldID, jboolean); ++ void (*SetStaticByteField)(JNIEnv*, jclass, jfieldID, jbyte); ++ void (*SetStaticCharField)(JNIEnv*, jclass, jfieldID, jchar); ++ void (*SetStaticShortField)(JNIEnv*, jclass, jfieldID, jshort); ++ void (*SetStaticIntField)(JNIEnv*, jclass, jfieldID, jint); ++ void (*SetStaticLongField)(JNIEnv*, jclass, jfieldID, jlong); ++ void (*SetStaticFloatField)(JNIEnv*, jclass, jfieldID, jfloat); ++ void (*SetStaticDoubleField)(JNIEnv*, jclass, jfieldID, jdouble); ++ ++ jstring (*NewString)(JNIEnv*, const jchar*, jsize); ++ jsize (*GetStringLength)(JNIEnv*, jstring); ++ const jchar* (*GetStringChars)(JNIEnv*, jstring, jboolean*); ++ void (*ReleaseStringChars)(JNIEnv*, jstring, const jchar*); ++ jstring (*NewStringUTF)(JNIEnv*, const char*); ++ jsize (*GetStringUTFLength)(JNIEnv*, jstring); ++ /* JNI spec says this returns const jbyte*, but that's inconsistent */ ++ const char* (*GetStringUTFChars)(JNIEnv*, jstring, jboolean*); ++ void (*ReleaseStringUTFChars)(JNIEnv*, jstring, const char*); ++ jsize (*GetArrayLength)(JNIEnv*, jarray); ++ jobjectArray (*NewObjectArray)(JNIEnv*, jsize, jclass, jobject); ++ jobject (*GetObjectArrayElement)(JNIEnv*, jobjectArray, jsize); ++ void (*SetObjectArrayElement)(JNIEnv*, jobjectArray, jsize, jobject); ++ ++ jbooleanArray (*NewBooleanArray)(JNIEnv*, jsize); ++ jbyteArray (*NewByteArray)(JNIEnv*, jsize); ++ jcharArray (*NewCharArray)(JNIEnv*, jsize); ++ jshortArray (*NewShortArray)(JNIEnv*, jsize); ++ jintArray (*NewIntArray)(JNIEnv*, jsize); ++ jlongArray (*NewLongArray)(JNIEnv*, jsize); ++ jfloatArray (*NewFloatArray)(JNIEnv*, jsize); ++ jdoubleArray (*NewDoubleArray)(JNIEnv*, jsize); ++ ++ jboolean* (*GetBooleanArrayElements)(JNIEnv*, jbooleanArray, jboolean*); ++ jbyte* (*GetByteArrayElements)(JNIEnv*, jbyteArray, jboolean*); ++ jchar* (*GetCharArrayElements)(JNIEnv*, jcharArray, jboolean*); ++ jshort* (*GetShortArrayElements)(JNIEnv*, jshortArray, jboolean*); ++ jint* (*GetIntArrayElements)(JNIEnv*, jintArray, jboolean*); ++ jlong* (*GetLongArrayElements)(JNIEnv*, jlongArray, jboolean*); ++ jfloat* (*GetFloatArrayElements)(JNIEnv*, jfloatArray, jboolean*); ++ jdouble* (*GetDoubleArrayElements)(JNIEnv*, jdoubleArray, jboolean*); ++ ++ void (*ReleaseBooleanArrayElements)(JNIEnv*, jbooleanArray, jboolean*, jint); ++ void (*ReleaseByteArrayElements)(JNIEnv*, jbyteArray, jbyte*, jint); ++ void (*ReleaseCharArrayElements)(JNIEnv*, jcharArray, jchar*, jint); ++ void (*ReleaseShortArrayElements)(JNIEnv*, jshortArray, jshort*, jint); ++ void (*ReleaseIntArrayElements)(JNIEnv*, jintArray, jint*, jint); ++ void (*ReleaseLongArrayElements)(JNIEnv*, jlongArray, jlong*, jint); ++ void (*ReleaseFloatArrayElements)(JNIEnv*, jfloatArray, jfloat*, jint); ++ void (*ReleaseDoubleArrayElements)(JNIEnv*, jdoubleArray, jdouble*, jint); ++ ++ void ( ++ *GetBooleanArrayRegion)(JNIEnv*, jbooleanArray, jsize, jsize, jboolean*); ++ void (*GetByteArrayRegion)(JNIEnv*, jbyteArray, jsize, jsize, jbyte*); ++ void (*GetCharArrayRegion)(JNIEnv*, jcharArray, jsize, jsize, jchar*); ++ void (*GetShortArrayRegion)(JNIEnv*, jshortArray, jsize, jsize, jshort*); ++ void (*GetIntArrayRegion)(JNIEnv*, jintArray, jsize, jsize, jint*); ++ void (*GetLongArrayRegion)(JNIEnv*, jlongArray, jsize, jsize, jlong*); ++ void (*GetFloatArrayRegion)(JNIEnv*, jfloatArray, jsize, jsize, jfloat*); ++ void (*GetDoubleArrayRegion)(JNIEnv*, jdoubleArray, jsize, jsize, jdouble*); ++ ++ /* spec shows these without const; some jni.h do, some don't */ ++ void (*SetBooleanArrayRegion)( ++ JNIEnv*, ++ jbooleanArray, ++ jsize, ++ jsize, ++ const jboolean*); ++ void (*SetByteArrayRegion)(JNIEnv*, jbyteArray, jsize, jsize, const jbyte*); ++ void (*SetCharArrayRegion)(JNIEnv*, jcharArray, jsize, jsize, const jchar*); ++ void ( ++ *SetShortArrayRegion)(JNIEnv*, jshortArray, jsize, jsize, const jshort*); ++ void (*SetIntArrayRegion)(JNIEnv*, jintArray, jsize, jsize, const jint*); ++ void (*SetLongArrayRegion)(JNIEnv*, jlongArray, jsize, jsize, const jlong*); ++ void ( ++ *SetFloatArrayRegion)(JNIEnv*, jfloatArray, jsize, jsize, const jfloat*); ++ void (*SetDoubleArrayRegion)( ++ JNIEnv*, ++ jdoubleArray, ++ jsize, ++ jsize, ++ const jdouble*); ++ ++ jint (*RegisterNatives)(JNIEnv*, jclass, const JNINativeMethod*, jint); ++ jint (*UnregisterNatives)(JNIEnv*, jclass); ++ jint (*MonitorEnter)(JNIEnv*, jobject); ++ jint (*MonitorExit)(JNIEnv*, jobject); ++ jint (*GetJavaVM)(JNIEnv*, JavaVM**); ++ ++ void (*GetStringRegion)(JNIEnv*, jstring, jsize, jsize, jchar*); ++ void (*GetStringUTFRegion)(JNIEnv*, jstring, jsize, jsize, char*); ++ ++ void* (*GetPrimitiveArrayCritical)(JNIEnv*, jarray, jboolean*); ++ void (*ReleasePrimitiveArrayCritical)(JNIEnv*, jarray, void*, jint); ++ ++ const jchar* (*GetStringCritical)(JNIEnv*, jstring, jboolean*); ++ void (*ReleaseStringCritical)(JNIEnv*, jstring, const jchar*); ++ ++ jweak (*NewWeakGlobalRef)(JNIEnv*, jobject); ++ void (*DeleteWeakGlobalRef)(JNIEnv*, jweak); ++ ++ jboolean (*ExceptionCheck)(JNIEnv*); ++ ++ jobject (*NewDirectByteBuffer)(JNIEnv*, void*, jlong); ++ void* (*GetDirectBufferAddress)(JNIEnv*, jobject); ++ jlong (*GetDirectBufferCapacity)(JNIEnv*, jobject); ++ ++ /* added in JNI 1.6 */ ++ jobjectRefType (*GetObjectRefType)(JNIEnv*, jobject); ++}; ++ ++/* ++ * C++ object wrapper. ++ * ++ * This is usually overlaid on a C struct whose first element is a ++ * JNINativeInterface*. We rely somewhat on compiler behavior. ++ */ ++struct _JNIEnv { ++ /* do not rename this; it does not seem to be entirely opaque */ ++ const struct JNINativeInterface* functions; ++ ++#if defined(__cplusplus) ++ ++ jint GetVersion() { ++ return functions->GetVersion(this); ++ } ++ ++ jclass DefineClass( ++ const char* name, ++ jobject loader, ++ const jbyte* buf, ++ jsize bufLen) { ++ return functions->DefineClass(this, name, loader, buf, bufLen); ++ } ++ ++ jclass FindClass(const char* name) { ++ return functions->FindClass(this, name); ++ } ++ ++ jmethodID FromReflectedMethod(jobject method) { ++ return functions->FromReflectedMethod(this, method); ++ } ++ ++ jfieldID FromReflectedField(jobject field) { ++ return functions->FromReflectedField(this, field); ++ } ++ ++ jobject ToReflectedMethod(jclass cls, jmethodID methodID, jboolean isStatic) { ++ return functions->ToReflectedMethod(this, cls, methodID, isStatic); ++ } ++ ++ jclass GetSuperclass(jclass clazz) { ++ return functions->GetSuperclass(this, clazz); ++ } ++ ++ jboolean IsAssignableFrom(jclass clazz1, jclass clazz2) { ++ return functions->IsAssignableFrom(this, clazz1, clazz2); ++ } ++ ++ jobject ToReflectedField(jclass cls, jfieldID fieldID, jboolean isStatic) { ++ return functions->ToReflectedField(this, cls, fieldID, isStatic); ++ } ++ ++ jint Throw(jthrowable obj) { ++ return functions->Throw(this, obj); ++ } ++ ++ jint ThrowNew(jclass clazz, const char* message) { ++ return functions->ThrowNew(this, clazz, message); ++ } ++ ++ jthrowable ExceptionOccurred() { ++ return functions->ExceptionOccurred(this); ++ } ++ ++ void ExceptionDescribe() { ++ functions->ExceptionDescribe(this); ++ } ++ ++ void ExceptionClear() { ++ functions->ExceptionClear(this); ++ } ++ ++ void FatalError(const char* msg) { ++ functions->FatalError(this, msg); ++ } ++ ++ jint PushLocalFrame(jint capacity) { ++ return functions->PushLocalFrame(this, capacity); ++ } ++ ++ jobject PopLocalFrame(jobject result) { ++ return functions->PopLocalFrame(this, result); ++ } ++ ++ jobject NewGlobalRef(jobject obj) { ++ return functions->NewGlobalRef(this, obj); ++ } ++ ++ void DeleteGlobalRef(jobject globalRef) { ++ functions->DeleteGlobalRef(this, globalRef); ++ } ++ ++ void DeleteLocalRef(jobject localRef) { ++ functions->DeleteLocalRef(this, localRef); ++ } ++ ++ jboolean IsSameObject(jobject ref1, jobject ref2) { ++ return functions->IsSameObject(this, ref1, ref2); ++ } ++ ++ jobject NewLocalRef(jobject ref) { ++ return functions->NewLocalRef(this, ref); ++ } ++ ++ jint EnsureLocalCapacity(jint capacity) { ++ return functions->EnsureLocalCapacity(this, capacity); ++ } ++ ++ jobject AllocObject(jclass clazz) { ++ return functions->AllocObject(this, clazz); ++ } ++ ++ jobject NewObject(jclass clazz, jmethodID methodID, ...) { ++ va_list args; ++ va_start(args, methodID); ++ jobject result = functions->NewObjectV(this, clazz, methodID, args); ++ va_end(args); ++ return result; ++ } ++ ++ jobject NewObjectV(jclass clazz, jmethodID methodID, va_list args) { ++ return functions->NewObjectV(this, clazz, methodID, args); ++ } ++ ++ jobject NewObjectA(jclass clazz, jmethodID methodID, jvalue* args) { ++ return functions->NewObjectA(this, clazz, methodID, args); ++ } ++ ++ jclass GetObjectClass(jobject obj) { ++ return functions->GetObjectClass(this, obj); ++ } ++ ++ jboolean IsInstanceOf(jobject obj, jclass clazz) { ++ return functions->IsInstanceOf(this, obj, clazz); ++ } ++ ++ jmethodID GetMethodID(jclass clazz, const char* name, const char* sig) { ++ return functions->GetMethodID(this, clazz, name, sig); ++ } ++ ++#define CALL_TYPE_METHOD(_jtype, _jname) \ ++ _jtype Call##_jname##Method(jobject obj, jmethodID methodID, ...) { \ ++ _jtype result; \ ++ va_list args; \ ++ va_start(args, methodID); \ ++ result = functions->Call##_jname##MethodV(this, obj, methodID, args); \ ++ va_end(args); \ ++ return result; \ ++ } ++#define CALL_TYPE_METHODV(_jtype, _jname) \ ++ _jtype Call##_jname##MethodV( \ ++ jobject obj, jmethodID methodID, va_list args) { \ ++ return functions->Call##_jname##MethodV(this, obj, methodID, args); \ ++ } ++#define CALL_TYPE_METHODA(_jtype, _jname) \ ++ _jtype Call##_jname##MethodA( \ ++ jobject obj, jmethodID methodID, jvalue* args) { \ ++ return functions->Call##_jname##MethodA(this, obj, methodID, args); \ ++ } ++ ++#define CALL_TYPE(_jtype, _jname) \ ++ CALL_TYPE_METHOD(_jtype, _jname) \ ++ CALL_TYPE_METHODV(_jtype, _jname) \ ++ CALL_TYPE_METHODA(_jtype, _jname) ++ ++ CALL_TYPE(jobject, Object) ++ CALL_TYPE(jboolean, Boolean) ++ CALL_TYPE(jbyte, Byte) ++ CALL_TYPE(jchar, Char) ++ CALL_TYPE(jshort, Short) ++ CALL_TYPE(jint, Int) ++ CALL_TYPE(jlong, Long) ++ CALL_TYPE(jfloat, Float) ++ CALL_TYPE(jdouble, Double) ++ ++ void CallVoidMethod(jobject obj, jmethodID methodID, ...) { ++ va_list args; ++ va_start(args, methodID); ++ functions->CallVoidMethodV(this, obj, methodID, args); ++ va_end(args); ++ } ++ void CallVoidMethodV(jobject obj, jmethodID methodID, va_list args) { ++ functions->CallVoidMethodV(this, obj, methodID, args); ++ } ++ void CallVoidMethodA(jobject obj, jmethodID methodID, jvalue* args) { ++ functions->CallVoidMethodA(this, obj, methodID, args); ++ } ++ ++#define CALL_NONVIRT_TYPE_METHOD(_jtype, _jname) \ ++ _jtype CallNonvirtual##_jname##Method( \ ++ jobject obj, jclass clazz, jmethodID methodID, ...) { \ ++ _jtype result; \ ++ va_list args; \ ++ va_start(args, methodID); \ ++ result = functions->CallNonvirtual##_jname##MethodV( \ ++ this, obj, clazz, methodID, args); \ ++ va_end(args); \ ++ return result; \ ++ } ++#define CALL_NONVIRT_TYPE_METHODV(_jtype, _jname) \ ++ _jtype CallNonvirtual##_jname##MethodV( \ ++ jobject obj, jclass clazz, jmethodID methodID, va_list args) { \ ++ return functions->CallNonvirtual##_jname##MethodV( \ ++ this, obj, clazz, methodID, args); \ ++ } ++#define CALL_NONVIRT_TYPE_METHODA(_jtype, _jname) \ ++ _jtype CallNonvirtual##_jname##MethodA( \ ++ jobject obj, jclass clazz, jmethodID methodID, jvalue* args) { \ ++ return functions->CallNonvirtual##_jname##MethodA( \ ++ this, obj, clazz, methodID, args); \ ++ } ++ ++#define CALL_NONVIRT_TYPE(_jtype, _jname) \ ++ CALL_NONVIRT_TYPE_METHOD(_jtype, _jname) \ ++ CALL_NONVIRT_TYPE_METHODV(_jtype, _jname) \ ++ CALL_NONVIRT_TYPE_METHODA(_jtype, _jname) ++ ++ CALL_NONVIRT_TYPE(jobject, Object) ++ CALL_NONVIRT_TYPE(jboolean, Boolean) ++ CALL_NONVIRT_TYPE(jbyte, Byte) ++ CALL_NONVIRT_TYPE(jchar, Char) ++ CALL_NONVIRT_TYPE(jshort, Short) ++ CALL_NONVIRT_TYPE(jint, Int) ++ CALL_NONVIRT_TYPE(jlong, Long) ++ CALL_NONVIRT_TYPE(jfloat, Float) ++ CALL_NONVIRT_TYPE(jdouble, Double) ++ ++ void ++ CallNonvirtualVoidMethod(jobject obj, jclass clazz, jmethodID methodID, ...) { ++ va_list args; ++ va_start(args, methodID); ++ functions->CallNonvirtualVoidMethodV(this, obj, clazz, methodID, args); ++ va_end(args); ++ } ++ void CallNonvirtualVoidMethodV( ++ jobject obj, ++ jclass clazz, ++ jmethodID methodID, ++ va_list args) { ++ functions->CallNonvirtualVoidMethodV(this, obj, clazz, methodID, args); ++ } ++ void CallNonvirtualVoidMethodA( ++ jobject obj, ++ jclass clazz, ++ jmethodID methodID, ++ jvalue* args) { ++ functions->CallNonvirtualVoidMethodA(this, obj, clazz, methodID, args); ++ } ++ ++ jfieldID GetFieldID(jclass clazz, const char* name, const char* sig) { ++ return functions->GetFieldID(this, clazz, name, sig); ++ } ++ ++ jobject GetObjectField(jobject obj, jfieldID fieldID) { ++ return functions->GetObjectField(this, obj, fieldID); ++ } ++ jboolean GetBooleanField(jobject obj, jfieldID fieldID) { ++ return functions->GetBooleanField(this, obj, fieldID); ++ } ++ jbyte GetByteField(jobject obj, jfieldID fieldID) { ++ return functions->GetByteField(this, obj, fieldID); ++ } ++ jchar GetCharField(jobject obj, jfieldID fieldID) { ++ return functions->GetCharField(this, obj, fieldID); ++ } ++ jshort GetShortField(jobject obj, jfieldID fieldID) { ++ return functions->GetShortField(this, obj, fieldID); ++ } ++ jint GetIntField(jobject obj, jfieldID fieldID) { ++ return functions->GetIntField(this, obj, fieldID); ++ } ++ jlong GetLongField(jobject obj, jfieldID fieldID) { ++ return functions->GetLongField(this, obj, fieldID); ++ } ++ jfloat GetFloatField(jobject obj, jfieldID fieldID) { ++ return functions->GetFloatField(this, obj, fieldID); ++ } ++ jdouble GetDoubleField(jobject obj, jfieldID fieldID) { ++ return functions->GetDoubleField(this, obj, fieldID); ++ } ++ ++ void SetObjectField(jobject obj, jfieldID fieldID, jobject value) { ++ functions->SetObjectField(this, obj, fieldID, value); ++ } ++ void SetBooleanField(jobject obj, jfieldID fieldID, jboolean value) { ++ functions->SetBooleanField(this, obj, fieldID, value); ++ } ++ void SetByteField(jobject obj, jfieldID fieldID, jbyte value) { ++ functions->SetByteField(this, obj, fieldID, value); ++ } ++ void SetCharField(jobject obj, jfieldID fieldID, jchar value) { ++ functions->SetCharField(this, obj, fieldID, value); ++ } ++ void SetShortField(jobject obj, jfieldID fieldID, jshort value) { ++ functions->SetShortField(this, obj, fieldID, value); ++ } ++ void SetIntField(jobject obj, jfieldID fieldID, jint value) { ++ functions->SetIntField(this, obj, fieldID, value); ++ } ++ void SetLongField(jobject obj, jfieldID fieldID, jlong value) { ++ functions->SetLongField(this, obj, fieldID, value); ++ } ++ void SetFloatField(jobject obj, jfieldID fieldID, jfloat value) { ++ functions->SetFloatField(this, obj, fieldID, value); ++ } ++ void SetDoubleField(jobject obj, jfieldID fieldID, jdouble value) { ++ functions->SetDoubleField(this, obj, fieldID, value); ++ } ++ ++ jmethodID GetStaticMethodID(jclass clazz, const char* name, const char* sig) { ++ return functions->GetStaticMethodID(this, clazz, name, sig); ++ } ++ ++#define CALL_STATIC_TYPE_METHOD(_jtype, _jname) \ ++ _jtype CallStatic##_jname##Method(jclass clazz, jmethodID methodID, ...) { \ ++ _jtype result; \ ++ va_list args; \ ++ va_start(args, methodID); \ ++ result = \ ++ functions->CallStatic##_jname##MethodV(this, clazz, methodID, args); \ ++ va_end(args); \ ++ return result; \ ++ } ++#define CALL_STATIC_TYPE_METHODV(_jtype, _jname) \ ++ _jtype CallStatic##_jname##MethodV( \ ++ jclass clazz, jmethodID methodID, va_list args) { \ ++ return functions->CallStatic##_jname##MethodV( \ ++ this, clazz, methodID, args); \ ++ } ++#define CALL_STATIC_TYPE_METHODA(_jtype, _jname) \ ++ _jtype CallStatic##_jname##MethodA( \ ++ jclass clazz, jmethodID methodID, jvalue* args) { \ ++ return functions->CallStatic##_jname##MethodA( \ ++ this, clazz, methodID, args); \ ++ } ++ ++#define CALL_STATIC_TYPE(_jtype, _jname) \ ++ CALL_STATIC_TYPE_METHOD(_jtype, _jname) \ ++ CALL_STATIC_TYPE_METHODV(_jtype, _jname) \ ++ CALL_STATIC_TYPE_METHODA(_jtype, _jname) ++ ++ CALL_STATIC_TYPE(jobject, Object) ++ CALL_STATIC_TYPE(jboolean, Boolean) ++ CALL_STATIC_TYPE(jbyte, Byte) ++ CALL_STATIC_TYPE(jchar, Char) ++ CALL_STATIC_TYPE(jshort, Short) ++ CALL_STATIC_TYPE(jint, Int) ++ CALL_STATIC_TYPE(jlong, Long) ++ CALL_STATIC_TYPE(jfloat, Float) ++ CALL_STATIC_TYPE(jdouble, Double) ++ ++ void CallStaticVoidMethod(jclass clazz, jmethodID methodID, ...) { ++ va_list args; ++ va_start(args, methodID); ++ functions->CallStaticVoidMethodV(this, clazz, methodID, args); ++ va_end(args); ++ } ++ void CallStaticVoidMethodV(jclass clazz, jmethodID methodID, va_list args) { ++ functions->CallStaticVoidMethodV(this, clazz, methodID, args); ++ } ++ void CallStaticVoidMethodA(jclass clazz, jmethodID methodID, jvalue* args) { ++ functions->CallStaticVoidMethodA(this, clazz, methodID, args); ++ } ++ ++ jfieldID GetStaticFieldID(jclass clazz, const char* name, const char* sig) { ++ return functions->GetStaticFieldID(this, clazz, name, sig); ++ } ++ ++ jobject GetStaticObjectField(jclass clazz, jfieldID fieldID) { ++ return functions->GetStaticObjectField(this, clazz, fieldID); ++ } ++ jboolean GetStaticBooleanField(jclass clazz, jfieldID fieldID) { ++ return functions->GetStaticBooleanField(this, clazz, fieldID); ++ } ++ jbyte GetStaticByteField(jclass clazz, jfieldID fieldID) { ++ return functions->GetStaticByteField(this, clazz, fieldID); ++ } ++ jchar GetStaticCharField(jclass clazz, jfieldID fieldID) { ++ return functions->GetStaticCharField(this, clazz, fieldID); ++ } ++ jshort GetStaticShortField(jclass clazz, jfieldID fieldID) { ++ return functions->GetStaticShortField(this, clazz, fieldID); ++ } ++ jint GetStaticIntField(jclass clazz, jfieldID fieldID) { ++ return functions->GetStaticIntField(this, clazz, fieldID); ++ } ++ jlong GetStaticLongField(jclass clazz, jfieldID fieldID) { ++ return functions->GetStaticLongField(this, clazz, fieldID); ++ } ++ jfloat GetStaticFloatField(jclass clazz, jfieldID fieldID) { ++ return functions->GetStaticFloatField(this, clazz, fieldID); ++ } ++ jdouble GetStaticDoubleField(jclass clazz, jfieldID fieldID) { ++ return functions->GetStaticDoubleField(this, clazz, fieldID); ++ } ++ ++ void SetStaticObjectField(jclass clazz, jfieldID fieldID, jobject value) { ++ functions->SetStaticObjectField(this, clazz, fieldID, value); ++ } ++ void SetStaticBooleanField(jclass clazz, jfieldID fieldID, jboolean value) { ++ functions->SetStaticBooleanField(this, clazz, fieldID, value); ++ } ++ void SetStaticByteField(jclass clazz, jfieldID fieldID, jbyte value) { ++ functions->SetStaticByteField(this, clazz, fieldID, value); ++ } ++ void SetStaticCharField(jclass clazz, jfieldID fieldID, jchar value) { ++ functions->SetStaticCharField(this, clazz, fieldID, value); ++ } ++ void SetStaticShortField(jclass clazz, jfieldID fieldID, jshort value) { ++ functions->SetStaticShortField(this, clazz, fieldID, value); ++ } ++ void SetStaticIntField(jclass clazz, jfieldID fieldID, jint value) { ++ functions->SetStaticIntField(this, clazz, fieldID, value); ++ } ++ void SetStaticLongField(jclass clazz, jfieldID fieldID, jlong value) { ++ functions->SetStaticLongField(this, clazz, fieldID, value); ++ } ++ void SetStaticFloatField(jclass clazz, jfieldID fieldID, jfloat value) { ++ functions->SetStaticFloatField(this, clazz, fieldID, value); ++ } ++ void SetStaticDoubleField(jclass clazz, jfieldID fieldID, jdouble value) { ++ functions->SetStaticDoubleField(this, clazz, fieldID, value); ++ } ++ ++ jstring NewString(const jchar* unicodeChars, jsize len) { ++ return functions->NewString(this, unicodeChars, len); ++ } ++ ++ jsize GetStringLength(jstring string) { ++ return functions->GetStringLength(this, string); ++ } ++ ++ const jchar* GetStringChars(jstring string, jboolean* isCopy) { ++ return functions->GetStringChars(this, string, isCopy); ++ } ++ ++ void ReleaseStringChars(jstring string, const jchar* chars) { ++ functions->ReleaseStringChars(this, string, chars); ++ } ++ ++ jstring NewStringUTF(const char* bytes) { ++ return functions->NewStringUTF(this, bytes); ++ } ++ ++ jsize GetStringUTFLength(jstring string) { ++ return functions->GetStringUTFLength(this, string); ++ } ++ ++ const char* GetStringUTFChars(jstring string, jboolean* isCopy) { ++ return functions->GetStringUTFChars(this, string, isCopy); ++ } ++ ++ void ReleaseStringUTFChars(jstring string, const char* utf) { ++ functions->ReleaseStringUTFChars(this, string, utf); ++ } ++ ++ jsize GetArrayLength(jarray array) { ++ return functions->GetArrayLength(this, array); ++ } ++ ++ jobjectArray ++ NewObjectArray(jsize length, jclass elementClass, jobject initialElement) { ++ return functions->NewObjectArray( ++ this, length, elementClass, initialElement); ++ } ++ ++ jobject GetObjectArrayElement(jobjectArray array, jsize index) { ++ return functions->GetObjectArrayElement(this, array, index); ++ } ++ ++ void SetObjectArrayElement(jobjectArray array, jsize index, jobject value) { ++ functions->SetObjectArrayElement(this, array, index, value); ++ } ++ ++ jbooleanArray NewBooleanArray(jsize length) { ++ return functions->NewBooleanArray(this, length); ++ } ++ jbyteArray NewByteArray(jsize length) { ++ return functions->NewByteArray(this, length); ++ } ++ jcharArray NewCharArray(jsize length) { ++ return functions->NewCharArray(this, length); ++ } ++ jshortArray NewShortArray(jsize length) { ++ return functions->NewShortArray(this, length); ++ } ++ jintArray NewIntArray(jsize length) { ++ return functions->NewIntArray(this, length); ++ } ++ jlongArray NewLongArray(jsize length) { ++ return functions->NewLongArray(this, length); ++ } ++ jfloatArray NewFloatArray(jsize length) { ++ return functions->NewFloatArray(this, length); ++ } ++ jdoubleArray NewDoubleArray(jsize length) { ++ return functions->NewDoubleArray(this, length); ++ } ++ ++ jboolean* GetBooleanArrayElements(jbooleanArray array, jboolean* isCopy) { ++ return functions->GetBooleanArrayElements(this, array, isCopy); ++ } ++ jbyte* GetByteArrayElements(jbyteArray array, jboolean* isCopy) { ++ return functions->GetByteArrayElements(this, array, isCopy); ++ } ++ jchar* GetCharArrayElements(jcharArray array, jboolean* isCopy) { ++ return functions->GetCharArrayElements(this, array, isCopy); ++ } ++ jshort* GetShortArrayElements(jshortArray array, jboolean* isCopy) { ++ return functions->GetShortArrayElements(this, array, isCopy); ++ } ++ jint* GetIntArrayElements(jintArray array, jboolean* isCopy) { ++ return functions->GetIntArrayElements(this, array, isCopy); ++ } ++ jlong* GetLongArrayElements(jlongArray array, jboolean* isCopy) { ++ return functions->GetLongArrayElements(this, array, isCopy); ++ } ++ jfloat* GetFloatArrayElements(jfloatArray array, jboolean* isCopy) { ++ return functions->GetFloatArrayElements(this, array, isCopy); ++ } ++ jdouble* GetDoubleArrayElements(jdoubleArray array, jboolean* isCopy) { ++ return functions->GetDoubleArrayElements(this, array, isCopy); ++ } ++ ++ void ++ ReleaseBooleanArrayElements(jbooleanArray array, jboolean* elems, jint mode) { ++ functions->ReleaseBooleanArrayElements(this, array, elems, mode); ++ } ++ void ReleaseByteArrayElements(jbyteArray array, jbyte* elems, jint mode) { ++ functions->ReleaseByteArrayElements(this, array, elems, mode); ++ } ++ void ReleaseCharArrayElements(jcharArray array, jchar* elems, jint mode) { ++ functions->ReleaseCharArrayElements(this, array, elems, mode); ++ } ++ void ReleaseShortArrayElements(jshortArray array, jshort* elems, jint mode) { ++ functions->ReleaseShortArrayElements(this, array, elems, mode); ++ } ++ void ReleaseIntArrayElements(jintArray array, jint* elems, jint mode) { ++ functions->ReleaseIntArrayElements(this, array, elems, mode); ++ } ++ void ReleaseLongArrayElements(jlongArray array, jlong* elems, jint mode) { ++ functions->ReleaseLongArrayElements(this, array, elems, mode); ++ } ++ void ReleaseFloatArrayElements(jfloatArray array, jfloat* elems, jint mode) { ++ functions->ReleaseFloatArrayElements(this, array, elems, mode); ++ } ++ void ++ ReleaseDoubleArrayElements(jdoubleArray array, jdouble* elems, jint mode) { ++ functions->ReleaseDoubleArrayElements(this, array, elems, mode); ++ } ++ ++ void GetBooleanArrayRegion( ++ jbooleanArray array, ++ jsize start, ++ jsize len, ++ jboolean* buf) { ++ functions->GetBooleanArrayRegion(this, array, start, len, buf); ++ } ++ void ++ GetByteArrayRegion(jbyteArray array, jsize start, jsize len, jbyte* buf) { ++ functions->GetByteArrayRegion(this, array, start, len, buf); ++ } ++ void ++ GetCharArrayRegion(jcharArray array, jsize start, jsize len, jchar* buf) { ++ functions->GetCharArrayRegion(this, array, start, len, buf); ++ } ++ void ++ GetShortArrayRegion(jshortArray array, jsize start, jsize len, jshort* buf) { ++ functions->GetShortArrayRegion(this, array, start, len, buf); ++ } ++ void GetIntArrayRegion(jintArray array, jsize start, jsize len, jint* buf) { ++ functions->GetIntArrayRegion(this, array, start, len, buf); ++ } ++ void ++ GetLongArrayRegion(jlongArray array, jsize start, jsize len, jlong* buf) { ++ functions->GetLongArrayRegion(this, array, start, len, buf); ++ } ++ void ++ GetFloatArrayRegion(jfloatArray array, jsize start, jsize len, jfloat* buf) { ++ functions->GetFloatArrayRegion(this, array, start, len, buf); ++ } ++ void GetDoubleArrayRegion( ++ jdoubleArray array, ++ jsize start, ++ jsize len, ++ jdouble* buf) { ++ functions->GetDoubleArrayRegion(this, array, start, len, buf); ++ } ++ ++ void SetBooleanArrayRegion( ++ jbooleanArray array, ++ jsize start, ++ jsize len, ++ const jboolean* buf) { ++ functions->SetBooleanArrayRegion(this, array, start, len, buf); ++ } ++ void SetByteArrayRegion( ++ jbyteArray array, ++ jsize start, ++ jsize len, ++ const jbyte* buf) { ++ functions->SetByteArrayRegion(this, array, start, len, buf); ++ } ++ void SetCharArrayRegion( ++ jcharArray array, ++ jsize start, ++ jsize len, ++ const jchar* buf) { ++ functions->SetCharArrayRegion(this, array, start, len, buf); ++ } ++ void SetShortArrayRegion( ++ jshortArray array, ++ jsize start, ++ jsize len, ++ const jshort* buf) { ++ functions->SetShortArrayRegion(this, array, start, len, buf); ++ } ++ void ++ SetIntArrayRegion(jintArray array, jsize start, jsize len, const jint* buf) { ++ functions->SetIntArrayRegion(this, array, start, len, buf); ++ } ++ void SetLongArrayRegion( ++ jlongArray array, ++ jsize start, ++ jsize len, ++ const jlong* buf) { ++ functions->SetLongArrayRegion(this, array, start, len, buf); ++ } ++ void SetFloatArrayRegion( ++ jfloatArray array, ++ jsize start, ++ jsize len, ++ const jfloat* buf) { ++ functions->SetFloatArrayRegion(this, array, start, len, buf); ++ } ++ void SetDoubleArrayRegion( ++ jdoubleArray array, ++ jsize start, ++ jsize len, ++ const jdouble* buf) { ++ functions->SetDoubleArrayRegion(this, array, start, len, buf); ++ } ++ ++ jint ++ RegisterNatives(jclass clazz, const JNINativeMethod* methods, jint nMethods) { ++ return functions->RegisterNatives(this, clazz, methods, nMethods); ++ } ++ ++ jint UnregisterNatives(jclass clazz) { ++ return functions->UnregisterNatives(this, clazz); ++ } ++ ++ jint MonitorEnter(jobject obj) { ++ return functions->MonitorEnter(this, obj); ++ } ++ ++ jint MonitorExit(jobject obj) { ++ return functions->MonitorExit(this, obj); ++ } ++ ++ jint GetJavaVM(JavaVM** vm) { ++ return functions->GetJavaVM(this, vm); ++ } ++ ++ void GetStringRegion(jstring str, jsize start, jsize len, jchar* buf) { ++ functions->GetStringRegion(this, str, start, len, buf); ++ } ++ ++ void GetStringUTFRegion(jstring str, jsize start, jsize len, char* buf) { ++ return functions->GetStringUTFRegion(this, str, start, len, buf); ++ } ++ ++ void* GetPrimitiveArrayCritical(jarray array, jboolean* isCopy) { ++ return functions->GetPrimitiveArrayCritical(this, array, isCopy); ++ } ++ ++ void ReleasePrimitiveArrayCritical(jarray array, void* carray, jint mode) { ++ functions->ReleasePrimitiveArrayCritical(this, array, carray, mode); ++ } ++ ++ const jchar* GetStringCritical(jstring string, jboolean* isCopy) { ++ return functions->GetStringCritical(this, string, isCopy); ++ } ++ ++ void ReleaseStringCritical(jstring string, const jchar* carray) { ++ functions->ReleaseStringCritical(this, string, carray); ++ } ++ ++ jweak NewWeakGlobalRef(jobject obj) { ++ return functions->NewWeakGlobalRef(this, obj); ++ } ++ ++ void DeleteWeakGlobalRef(jweak obj) { ++ functions->DeleteWeakGlobalRef(this, obj); ++ } ++ ++ jboolean ExceptionCheck() { ++ return functions->ExceptionCheck(this); ++ } ++ ++ jobject NewDirectByteBuffer(void* address, jlong capacity) { ++ return functions->NewDirectByteBuffer(this, address, capacity); ++ } ++ ++ void* GetDirectBufferAddress(jobject buf) { ++ return functions->GetDirectBufferAddress(this, buf); ++ } ++ ++ jlong GetDirectBufferCapacity(jobject buf) { ++ return functions->GetDirectBufferCapacity(this, buf); ++ } ++ ++ /* added in JNI 1.6 */ ++ jobjectRefType GetObjectRefType(jobject obj) { ++ return functions->GetObjectRefType(this, obj); ++ } ++#endif /*__cplusplus*/ ++}; ++ ++/* ++ * JNI invocation interface. ++ */ ++struct JNIInvokeInterface { ++ void* reserved0; ++ void* reserved1; ++ void* reserved2; ++ ++ jint (*DestroyJavaVM)(JavaVM*); ++ jint (*AttachCurrentThread)(JavaVM*, JNIEnv**, void*); ++ jint (*DetachCurrentThread)(JavaVM*); ++ jint (*GetEnv)(JavaVM*, void**, jint); ++ jint (*AttachCurrentThreadAsDaemon)(JavaVM*, JNIEnv**, void*); ++}; ++ ++/* ++ * C++ version. ++ */ ++struct _JavaVM { ++ const struct JNIInvokeInterface* functions; ++ ++#if defined(__cplusplus) ++ jint DestroyJavaVM() { ++ return functions->DestroyJavaVM(this); ++ } ++ jint AttachCurrentThread(JNIEnv** p_env, void* thr_args) { ++ return functions->AttachCurrentThread(this, p_env, thr_args); ++ } ++ jint DetachCurrentThread() { ++ return functions->DetachCurrentThread(this); ++ } ++ jint GetEnv(void** env, jint version) { ++ return functions->GetEnv(this, env, version); ++ } ++ jint AttachCurrentThreadAsDaemon(JNIEnv** p_env, void* thr_args) { ++ return functions->AttachCurrentThreadAsDaemon(this, p_env, thr_args); ++ } ++#endif /*__cplusplus*/ ++}; ++ ++struct JavaVMAttachArgs { ++ jint version; /* must be >= JNI_VERSION_1_2 */ ++ const char* name; /* NULL or name of thread as modified UTF-8 str */ ++ jobject group; /* global ref of a ThreadGroup object, or NULL */ ++}; ++typedef struct JavaVMAttachArgs JavaVMAttachArgs; ++ ++/* ++ * JNI 1.2+ initialization. (As of 1.6, the pre-1.2 structures are no ++ * longer supported.) ++ */ ++typedef struct JavaVMOption { ++ const char* optionString; ++ void* extraInfo; ++} JavaVMOption; ++ ++typedef struct JavaVMInitArgs { ++ jint version; /* use JNI_VERSION_1_2 or later */ ++ ++ jint nOptions; ++ JavaVMOption* options; ++ jboolean ignoreUnrecognized; ++} JavaVMInitArgs; ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++/* ++ * VM initialization functions. ++ * ++ * Note these are the only symbols exported for JNI by the VM. ++ */ ++jint JNI_GetDefaultJavaVMInitArgs(void*); ++jint JNI_CreateJavaVM(JavaVM**, JNIEnv**, void*); ++jint JNI_GetCreatedJavaVMs(JavaVM**, jsize, jsize*); ++ ++#define JNIIMPORT ++#define JNIEXPORT __attribute__((visibility("default"))) ++#define JNICALL ++ ++/* ++ * Prototypes for functions exported by loadable shared libs. These are ++ * called by JNI, not provided by JNI. ++ */ ++JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved); ++JNIEXPORT void JNI_OnUnload(JavaVM* vm, void* reserved); ++ ++#ifdef __cplusplus ++} ++#endif ++ ++/* ++ * Manifest constants. ++ */ ++#define JNI_FALSE 0 ++#define JNI_TRUE 1 ++ ++#define JNI_VERSION_1_1 0x00010001 ++#define JNI_VERSION_1_2 0x00010002 ++#define JNI_VERSION_1_4 0x00010004 ++#define JNI_VERSION_1_6 0x00010006 ++ ++#define JNI_OK (0) /* no error */ ++#define JNI_ERR (-1) /* generic error */ ++#define JNI_EDETACHED (-2) /* thread detached from the VM */ ++#define JNI_EVERSION (-3) /* JNI version error */ ++ ++#define JNI_COMMIT 1 /* copy content, do not free buffer */ ++#define JNI_ABORT 2 /* free buffer w/o copying back */ ++ ++#endif /* JNI_H_ */ +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/yogajni/CMakeLists.txt b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/yogajni/CMakeLists.txt +new file mode 100644 +index 0000000..8f08a99 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/yogajni/CMakeLists.txt +@@ -0,0 +1,20 @@ ++# 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. ++ ++cmake_minimum_required(VERSION 3.13) ++set(CMAKE_VERBOSE_MAKEFILE on) ++ ++add_compile_options( ++ -fvisibility=hidden ++ -fexceptions ++ -frtti ++ -O3) ++ ++file(GLOB yoga_SRC CONFIGURE_DEPENDS jni/*.cpp) ++add_library(yoga SHARED ${yoga_SRC}) ++ ++target_include_directories(yoga PUBLIC jni) ++ ++target_link_libraries(yoga yogacore fb fbjni log android) +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/yogajni/jni/LayoutContext.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/yogajni/jni/LayoutContext.cpp +new file mode 100644 +index 0000000..970812f +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/yogajni/jni/LayoutContext.cpp +@@ -0,0 +1,34 @@ ++/* ++ * 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. ++ */ ++ ++#include ++ ++#include "LayoutContext.h" ++ ++namespace facebook::yoga::vanillajni { ++ ++namespace { ++std::stack& getContexts() { ++ static thread_local std::stack contexts; ++ return contexts; ++} ++ ++} // namespace ++ ++LayoutContext::Provider::Provider(PtrJNodeMapVanilla* data) { ++ getContexts().push(data); ++} ++ ++LayoutContext::Provider::~Provider() { ++ getContexts().pop(); ++} ++ ++/*static*/ PtrJNodeMapVanilla* LayoutContext::getNodeMap() { ++ return getContexts().empty() ? nullptr : getContexts().top(); ++} ++ ++} // namespace facebook::yoga::vanillajni +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/yogajni/jni/LayoutContext.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/yogajni/jni/LayoutContext.h +new file mode 100644 +index 0000000..70ee31a +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/yogajni/jni/LayoutContext.h +@@ -0,0 +1,29 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++#include "YGJTypesVanilla.h" ++ ++namespace facebook::yoga::vanillajni { ++ ++// TODO: This should not be exported or used outside of the JNI bindings ++class YG_EXPORT LayoutContext { ++ public: ++ // Sets a context on the current thread for the duration of the Provider's ++ // lifetime. This context should be set during the layout process to allow ++ // layout callbacks to access context-data specific to the layout pass. ++ struct Provider { ++ explicit Provider(PtrJNodeMapVanilla* data); ++ ~Provider(); ++ }; ++ ++ static PtrJNodeMapVanilla* getNodeMap(); ++}; ++ ++} // namespace facebook::yoga::vanillajni +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/yogajni/jni/ScopedGlobalRef.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/yogajni/jni/ScopedGlobalRef.h +new file mode 100644 +index 0000000..a8dcacb +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/yogajni/jni/ScopedGlobalRef.h +@@ -0,0 +1,140 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++#include ++#include ++#include "corefunctions.h" ++ ++namespace facebook::yoga::vanillajni { ++ ++/** ++ * ScopedGlobalRef is a sort of smart reference that allows us to control the ++ * lifespan of a JNI global reference. ++ * ++ * This class is designed so that when a ScopedGlobalRef goes out of scoped, its ++ * destructor will delete -JNIEnv->DeleteGlobalRef()- the underlying JNI ++ * reference. ++ * ++ * This class should be used to wrap all the global references we create during ++ * normal JNI operations if we want reference to eventually go away (in JNI it ++ * is a common operation to cache some global references throughout the lifespan ++ * of a process, in which case using this class does not really make sense). The ++ * idea behind this is that in JNI we should be very explicit about the lifespan ++ * of global references. Global references can quickly get out of control if not ++ * freed properly, and the developer should always be very aware of the lifespan ++ * of each global reference that is created in JNI so that leaks are prevented. ++ * ++ * This class is very explicit in its behavior, and it does not allow to perform ++ * unexpected conversions or unexpected ownership transfer. In practice, this ++ * class acts as a unique pointer where the underlying JNI reference can have ++ * one and just one owner. Transferring ownership is allowed but it is an ++ * explicit operation (implemented via move semantics and also via explicitly ++ * API calls). ++ * ++ * Note that this class doesn't receive an explicit JNIEnv at construction time. ++ * At destruction time it uses vanillajni::getCurrentEnv() to retrieve the ++ * JNIEnv. ++ * ++ * It is OK to cache a ScopedGlobalRef between different JNI native ++ * method calls. ++ */ ++template ++class ScopedGlobalRef { ++ static_assert( ++ std::is_same() || std::is_same() || ++ std::is_same() || std::is_same() || ++ std::is_same() || std::is_same() || ++ std::is_same() || std::is_same() || ++ std::is_same() || std::is_same() || ++ std::is_same() || std::is_same() || ++ std::is_same(), ++ "ScopedGlobalRef instantiated for invalid type"); ++ ++ public: ++ /** ++ * Constructs a ScopedGlobalRef with a JNI global reference. ++ * ++ * @param globalRef the global reference to wrap. Can be NULL. ++ */ ++ explicit ScopedGlobalRef(T globalRef) : mGlobalRef(globalRef) {} ++ ++ /** ++ * Equivalent to ScopedGlobalRef(NULL) ++ */ ++ explicit ScopedGlobalRef() : mGlobalRef(NULL) {} ++ ++ /** ++ * Move construction is allowed. ++ */ ++ ScopedGlobalRef(ScopedGlobalRef&& s) noexcept : mGlobalRef(s.release()) {} ++ ++ /** ++ * Move assignment is allowed. ++ */ ++ ScopedGlobalRef& operator=(ScopedGlobalRef&& s) noexcept { ++ reset(s.release()); ++ return *this; ++ } ++ ++ ~ScopedGlobalRef() { ++ reset(); ++ } ++ ++ /** ++ * Deletes the currently held reference and reassigns a new one to the ++ * ScopedGlobalRef. ++ */ ++ void reset(T ptr = NULL) { ++ if (ptr != mGlobalRef) { ++ if (mGlobalRef != NULL) { ++ vanillajni::getCurrentEnv()->DeleteGlobalRef(mGlobalRef); ++ } ++ mGlobalRef = ptr; ++ } ++ } ++ ++ /** ++ * Makes this ScopedGlobalRef not own the underlying JNI global reference. ++ * After calling this method, the ScopedGlobalRef will not delete the JNI ++ * global reference when the ScopedGlobalRef goes out of scope. ++ */ ++ T release() { ++ T globalRef = mGlobalRef; ++ mGlobalRef = NULL; ++ return globalRef; ++ } ++ ++ /** ++ * Returns the underlying JNI global reference. ++ */ ++ T get() const { ++ return mGlobalRef; ++ } ++ ++ /** ++ * Returns true if the underlying JNI reference is not NULL. ++ */ ++ operator bool() const { ++ return mGlobalRef != NULL; ++ } ++ ++ ScopedGlobalRef(const ScopedGlobalRef& ref) = delete; ++ ScopedGlobalRef& operator=(const ScopedGlobalRef& other) = delete; ++ ++ private: ++ T mGlobalRef; ++}; ++ ++template ++ScopedGlobalRef make_global_ref(T globalRef) { ++ return ScopedGlobalRef(globalRef); ++} ++ ++} // namespace facebook::yoga::vanillajni +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/yogajni/jni/ScopedLocalRef.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/yogajni/jni/ScopedLocalRef.h +new file mode 100644 +index 0000000..75af267 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/yogajni/jni/ScopedLocalRef.h +@@ -0,0 +1,141 @@ ++/* ++ * 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. ++ */ ++ ++/** ++ * This is a modified version of Android's ScopedLocalRef class that can be ++ * found in the Android's JNI code. ++ */ ++#pragma once ++ ++#include ++#include ++#include ++ ++namespace facebook::yoga::vanillajni { ++ ++/** ++ * ScopedLocalRef is a sort of smart reference that allows us to control the ++ * lifespan of a JNI local reference. ++ * ++ * This class is designed so that when a ScopedLocalRef goes out of scope, its ++ * destructor will delete -JNIEnv->DeleteLocalRef()- the underlying JNI ++ * reference. ++ * ++ * This class should be used to wrap all the local references that JNI ++ * gives us other than those that are passed to native methods at ++ * invocation time. The idea behind this is that in JNI we should be very ++ * explicit about the lifespan of local references. Local references can quickly ++ * get out of control, and the developer should always be very aware of the ++ * lifespan of each local reference that is created in JNI so that leaks are ++ * prevented. ++ * ++ * This class is very explicit in its behavior, and it does not allow to perform ++ * unexpected conversions or unexpected ownership transfer. In practice, this ++ * class acts as a unique pointer where the underlying JNI reference can have ++ * one and just one owner. Transferring ownership is allowed but it is an ++ * explicit operation (implemented via move semantics and also via explicitly ++ * API calls). ++ * ++ * As with standard JNI local references it is not a valid operation to keep a ++ * reference around between different native method calls. ++ */ ++template ++class ScopedLocalRef { ++ static_assert( ++ std::is_same() || std::is_same() || ++ std::is_same() || std::is_same() || ++ std::is_same() || std::is_same() || ++ std::is_same() || std::is_same() || ++ std::is_same() || std::is_same() || ++ std::is_same() || std::is_same() || ++ std::is_same(), ++ "ScopedLocalRef instantiated for invalid type"); ++ ++ public: ++ /** ++ * Constructs a ScopedLocalRef with a JNI local reference. ++ * ++ * @param localRef the local reference to wrap. Can be NULL. ++ */ ++ ScopedLocalRef(JNIEnv* env, T localRef) : mEnv(env), mLocalRef(localRef) {} ++ ++ /** ++ * Equivalent to ScopedLocalRef(env, NULL) ++ */ ++ explicit ScopedLocalRef(JNIEnv* env) : mEnv(env), mLocalRef(NULL) {} ++ ++ /** ++ * Move construction is allowed. ++ */ ++ ScopedLocalRef(ScopedLocalRef&& s) noexcept ++ : mEnv(s.mEnv), mLocalRef(s.release()) {} ++ ++ /** ++ * Move assignment is allowed. ++ */ ++ ScopedLocalRef& operator=(ScopedLocalRef&& s) noexcept { ++ reset(s.release()); ++ mEnv = s.mEnv; ++ return *this; ++ } ++ ++ ~ScopedLocalRef() { ++ reset(); ++ } ++ ++ /** ++ * Deletes the currently held reference and reassigns a new one to the ++ * ScopedLocalRef. ++ */ ++ void reset(T ptr = NULL) { ++ if (ptr != mLocalRef) { ++ if (mLocalRef != NULL) { ++ mEnv->DeleteLocalRef(mLocalRef); ++ } ++ mLocalRef = ptr; ++ } ++ } ++ ++ /** ++ * Makes this ScopedLocalRef not own the underlying JNI local reference. After ++ * calling this method, the ScopedLocalRef will not delete the JNI local ++ * reference when the ScopedLocalRef goes out of scope. ++ */ ++ T release() { ++ T localRef = mLocalRef; ++ mLocalRef = NULL; ++ return localRef; ++ } ++ ++ /** ++ * Returns the underlying JNI local reference. ++ */ ++ T get() const { ++ return mLocalRef; ++ } ++ ++ /** ++ * Returns true if the underlying JNI reference is not NULL. ++ */ ++ operator bool() const { ++ return mLocalRef != NULL; ++ } ++ ++ ScopedLocalRef(const ScopedLocalRef& ref) = delete; ++ ScopedLocalRef& operator=(const ScopedLocalRef& other) = delete; ++ ++ private: ++ JNIEnv* mEnv; ++ T mLocalRef; ++}; ++ ++template ++ScopedLocalRef make_local_ref(JNIEnv* env, T localRef) { ++ return ScopedLocalRef(env, localRef); ++} ++ ++} // namespace facebook::yoga::vanillajni +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/yogajni/jni/YGJNI.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/yogajni/jni/YGJNI.h +new file mode 100644 +index 0000000..9b26097 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/yogajni/jni/YGJNI.h +@@ -0,0 +1,77 @@ ++/* ++ * 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. ++ */ ++ ++#include ++ ++const short int LAYOUT_EDGE_SET_FLAG_INDEX = 0; ++const short int LAYOUT_WIDTH_INDEX = 1; ++const short int LAYOUT_HEIGHT_INDEX = 2; ++const short int LAYOUT_LEFT_INDEX = 3; ++const short int LAYOUT_TOP_INDEX = 4; ++const short int LAYOUT_DIRECTION_INDEX = 5; ++const short int LAYOUT_MARGIN_START_INDEX = 6; ++const short int LAYOUT_PADDING_START_INDEX = 10; ++const short int LAYOUT_BORDER_START_INDEX = 14; ++ ++namespace { ++ ++const int HAS_NEW_LAYOUT = 16; ++ ++union YGNodeContext { ++ int32_t edgesSet = 0; ++ void* asVoidPtr; ++}; ++ ++class YGNodeEdges { ++ int32_t edges_; ++ ++ public: ++ enum Edge { ++ MARGIN = 1, ++ PADDING = 2, ++ BORDER = 4, ++ }; ++ ++ explicit YGNodeEdges(YGNodeRef node) { ++ auto context = YGNodeContext{}; ++ context.asVoidPtr = YGNodeGetContext(node); ++ edges_ = context.edgesSet; ++ } ++ ++ void setOn(YGNodeRef node) { ++ auto context = YGNodeContext{}; ++ context.edgesSet = edges_; ++ YGNodeSetContext(node, context.asVoidPtr); ++ } ++ ++ bool has(Edge edge) { ++ return (edges_ & edge) == edge; ++ } ++ ++ YGNodeEdges& add(Edge edge) { ++ edges_ |= edge; ++ return *this; ++ } ++ ++ int get() { ++ return edges_; ++ } ++}; ++ ++struct YogaValue { ++ static constexpr jint NAN_BYTES = 0x7fc00000; ++ ++ static jlong asJavaLong(const YGValue& value) { ++ uint32_t valueBytes = 0; ++ memcpy(&valueBytes, &value.value, sizeof valueBytes); ++ return ((jlong)value.unit) << 32 | valueBytes; ++ } ++ constexpr static jlong undefinedAsJavaLong() { ++ return ((jlong)YGUnitUndefined) << 32 | NAN_BYTES; ++ } ++}; ++} // namespace +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/yogajni/jni/YGJNIVanilla.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/yogajni/jni/YGJNIVanilla.cpp +new file mode 100644 +index 0000000..4d01703 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/yogajni/jni/YGJNIVanilla.cpp +@@ -0,0 +1,977 @@ ++/* ++ * 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. ++ */ ++ ++#include "YGJNIVanilla.h" ++#include ++#include ++#include ++#include ++#include "LayoutContext.h" ++#include "YGJNI.h" ++#include "YGJTypesVanilla.h" ++#include "YogaJniException.h" ++#include "common.h" ++#include "jni.h" ++ ++using namespace facebook; ++using namespace facebook::yoga; ++using namespace facebook::yoga::vanillajni; ++ ++static inline ScopedLocalRef YGNodeJobject(YGNodeConstRef node) { ++ return LayoutContext::getNodeMap()->ref(node); ++} ++ ++static inline YGNodeRef _jlong2YGNodeRef(jlong addr) { ++ return reinterpret_cast(static_cast(addr)); ++} ++ ++static inline YGConfigRef _jlong2YGConfigRef(jlong addr) { ++ return reinterpret_cast(static_cast(addr)); ++} ++ ++static jlong jni_YGConfigNewJNI(JNIEnv* /*env*/, jobject /*obj*/) { ++ return reinterpret_cast(YGConfigNew()); ++} ++ ++static void ++jni_YGConfigFreeJNI(JNIEnv* /*env*/, jobject /*obj*/, jlong nativePointer) { ++ const YGConfigRef config = _jlong2YGConfigRef(nativePointer); ++ // unique_ptr will destruct the underlying global_ref, if present. ++ auto context = std::unique_ptr>{ ++ static_cast*>(YGConfigGetContext(config))}; ++ YGConfigFree(config); ++} ++ ++static void jni_YGConfigSetExperimentalFeatureEnabledJNI( ++ JNIEnv* /*env*/, ++ jobject /*obj*/, ++ jlong nativePointer, ++ jint feature, ++ jboolean enabled) { ++ const YGConfigRef config = _jlong2YGConfigRef(nativePointer); ++ YGConfigSetExperimentalFeatureEnabled( ++ config, ++ static_cast(feature), ++ static_cast(enabled)); ++} ++ ++static void jni_YGConfigSetUseWebDefaultsJNI( ++ JNIEnv* /*env*/, ++ jobject /*obj*/, ++ jlong nativePointer, ++ jboolean useWebDefaults) { ++ const YGConfigRef config = _jlong2YGConfigRef(nativePointer); ++ YGConfigSetUseWebDefaults(config, static_cast(useWebDefaults)); ++} ++ ++static void jni_YGConfigSetPointScaleFactorJNI( ++ JNIEnv* /*env*/, ++ jobject /*obj*/, ++ jlong nativePointer, ++ jfloat pixelsInPoint) { ++ const YGConfigRef config = _jlong2YGConfigRef(nativePointer); ++ YGConfigSetPointScaleFactor(config, pixelsInPoint); ++} ++ ++static void jni_YGConfigSetErrataJNI( ++ JNIEnv* /*env*/, ++ jobject /*obj*/, ++ jlong nativePointer, ++ jint errata) { ++ const YGConfigRef config = _jlong2YGConfigRef(nativePointer); ++ YGConfigSetErrata(config, static_cast(errata)); ++} ++ ++static jint jni_YGConfigGetErrataJNI( ++ JNIEnv* /*env*/, ++ jobject /*obj*/, ++ jlong nativePointer) { ++ const YGConfigRef config = _jlong2YGConfigRef(nativePointer); ++ return static_cast(YGConfigGetErrata(config)); ++} ++ ++static jlong jni_YGNodeNewJNI(JNIEnv* /*env*/, jobject /*obj*/) { ++ const YGNodeRef node = YGNodeNew(); ++ YGNodeSetContext(node, YGNodeContext{}.asVoidPtr); ++ return reinterpret_cast(node); ++} ++ ++static jlong jni_YGNodeNewWithConfigJNI( ++ JNIEnv* /*env*/, ++ jobject /*obj*/, ++ jlong configPointer) { ++ const YGNodeRef node = YGNodeNewWithConfig(_jlong2YGConfigRef(configPointer)); ++ YGNodeSetContext(node, YGNodeContext{}.asVoidPtr); ++ return reinterpret_cast(node); ++} ++ ++static int YGJNILogFunc( ++ const YGConfigConstRef config, ++ const YGNodeConstRef /*node*/, ++ YGLogLevel level, ++ const char* format, ++ va_list args) { ++ va_list argsCopy; ++ va_copy(argsCopy, args); ++ int result = vsnprintf(nullptr, 0, format, argsCopy); ++ std::vector buffer(1 + static_cast(result)); ++ vsnprintf(buffer.data(), buffer.size(), format, args); ++ ++ auto jloggerPtr = ++ static_cast*>(YGConfigGetContext(config)); ++ if (jloggerPtr != nullptr) { ++ if (*jloggerPtr) { ++ JNIEnv* env = getCurrentEnv(); ++ ++ jclass cl = env->FindClass("com/facebook/yoga/YogaLogLevel"); ++ static const jmethodID smethodId = ++ facebook::yoga::vanillajni::getStaticMethodId( ++ env, cl, "fromInt", "(I)Lcom/facebook/yoga/YogaLogLevel;"); ++ ScopedLocalRef logLevel = ++ facebook::yoga::vanillajni::callStaticObjectMethod( ++ env, cl, smethodId, level); ++ ++ auto objectClass = facebook::yoga::vanillajni::make_local_ref( ++ env, env->GetObjectClass((*jloggerPtr).get())); ++ static const jmethodID methodId = facebook::yoga::vanillajni::getMethodId( ++ env, ++ objectClass.get(), ++ "log", ++ "(Lcom/facebook/yoga/YogaLogLevel;Ljava/lang/String;)V"); ++ facebook::yoga::vanillajni::callVoidMethod( ++ env, ++ (*jloggerPtr).get(), ++ methodId, ++ logLevel.get(), ++ env->NewStringUTF(buffer.data())); ++ } ++ } ++ ++ return result; ++} ++ ++static void jni_YGConfigSetLoggerJNI( ++ JNIEnv* env, ++ jobject /*obj*/, ++ jlong nativePointer, ++ jobject logger) { ++ const YGConfigRef config = _jlong2YGConfigRef(nativePointer); ++ auto context = ++ reinterpret_cast*>(YGConfigGetContext(config)); ++ ++ if (logger != nullptr) { ++ if (context == nullptr) { ++ context = new ScopedGlobalRef(); ++ YGConfigSetContext(config, context); ++ } ++ ++ *context = newGlobalRef(env, logger); ++ YGConfigSetLogger(config, YGJNILogFunc); ++ } else { ++ if (context != nullptr) { ++ delete context; ++ YGConfigSetContext(config, nullptr); ++ } ++ YGConfigSetLogger(config, nullptr); ++ } ++} ++ ++static void ++jni_YGNodeFinalizeJNI(JNIEnv* /*env*/, jobject /*obj*/, jlong nativePointer) { ++ if (nativePointer == 0) { ++ return; ++ } ++ const YGNodeRef node = _jlong2YGNodeRef(nativePointer); ++ YGNodeFinalize(node); ++} ++ ++static void ++jni_YGNodeResetJNI(JNIEnv* /*env*/, jobject /*obj*/, jlong nativePointer) { ++ const YGNodeRef node = _jlong2YGNodeRef(nativePointer); ++ void* context = YGNodeGetContext(node); ++ YGNodeReset(node); ++ YGNodeSetContext(node, context); ++} ++ ++static void jni_YGNodeInsertChildJNI( ++ JNIEnv* /*env*/, ++ jobject /*obj*/, ++ jlong nativePointer, ++ jlong childPointer, ++ jint index) { ++ YGNodeInsertChild( ++ _jlong2YGNodeRef(nativePointer), ++ _jlong2YGNodeRef(childPointer), ++ static_cast(index)); ++} ++ ++static void jni_YGNodeSwapChildJNI( ++ JNIEnv* /*env*/, ++ jobject /*obj*/, ++ jlong nativePointer, ++ jlong childPointer, ++ jint index) { ++ YGNodeSwapChild( ++ _jlong2YGNodeRef(nativePointer), ++ _jlong2YGNodeRef(childPointer), ++ static_cast(index)); ++} ++ ++static void jni_YGNodeSetIsReferenceBaselineJNI( ++ JNIEnv* /*env*/, ++ jobject /*obj*/, ++ jlong nativePointer, ++ jboolean isReferenceBaseline) { ++ YGNodeSetIsReferenceBaseline( ++ _jlong2YGNodeRef(nativePointer), static_cast(isReferenceBaseline)); ++} ++ ++static jboolean jni_YGNodeIsReferenceBaselineJNI( ++ JNIEnv* /*env*/, ++ jobject /*obj*/, ++ jlong nativePointer) { ++ return static_cast( ++ YGNodeIsReferenceBaseline(_jlong2YGNodeRef(nativePointer))); ++} ++ ++static void jni_YGNodeRemoveAllChildrenJNI( ++ JNIEnv* /*env*/, ++ jobject /*obj*/, ++ jlong nativePointer) { ++ const YGNodeRef node = _jlong2YGNodeRef(nativePointer); ++ YGNodeRemoveAllChildren(node); ++} ++ ++static void jni_YGNodeRemoveChildJNI( ++ JNIEnv* /*env*/, ++ jobject /*obj*/, ++ jlong nativePointer, ++ jlong childPointer) { ++ YGNodeRemoveChild( ++ _jlong2YGNodeRef(nativePointer), _jlong2YGNodeRef(childPointer)); ++} ++ ++static void ++YGTransferLayoutOutputsRecursive(JNIEnv* env, jobject thiz, YGNodeRef root) { ++ if (!YGNodeGetHasNewLayout(root)) { ++ return; ++ } ++ auto obj = YGNodeJobject(root); ++ if (!obj) { ++ return; ++ } ++ ++ auto edgesSet = YGNodeEdges{root}; ++ ++ bool marginFieldSet = edgesSet.has(YGNodeEdges::MARGIN); ++ bool paddingFieldSet = edgesSet.has(YGNodeEdges::PADDING); ++ bool borderFieldSet = edgesSet.has(YGNodeEdges::BORDER); ++ ++ int fieldFlags = edgesSet.get(); ++ fieldFlags |= HAS_NEW_LAYOUT; ++ ++ const int arrSize = 6 + (marginFieldSet ? 4 : 0) + (paddingFieldSet ? 4 : 0) + ++ (borderFieldSet ? 4 : 0); ++ float arr[18]; ++ arr[LAYOUT_EDGE_SET_FLAG_INDEX] = static_cast(fieldFlags); ++ arr[LAYOUT_WIDTH_INDEX] = YGNodeLayoutGetWidth(root); ++ arr[LAYOUT_HEIGHT_INDEX] = YGNodeLayoutGetHeight(root); ++ arr[LAYOUT_LEFT_INDEX] = YGNodeLayoutGetLeft(root); ++ arr[LAYOUT_TOP_INDEX] = YGNodeLayoutGetTop(root); ++ arr[LAYOUT_DIRECTION_INDEX] = ++ static_cast(YGNodeLayoutGetDirection(root)); ++ if (marginFieldSet) { ++ arr[LAYOUT_MARGIN_START_INDEX] = YGNodeLayoutGetMargin(root, YGEdgeLeft); ++ arr[LAYOUT_MARGIN_START_INDEX + 1] = YGNodeLayoutGetMargin(root, YGEdgeTop); ++ arr[LAYOUT_MARGIN_START_INDEX + 2] = ++ YGNodeLayoutGetMargin(root, YGEdgeRight); ++ arr[LAYOUT_MARGIN_START_INDEX + 3] = ++ YGNodeLayoutGetMargin(root, YGEdgeBottom); ++ } ++ if (paddingFieldSet) { ++ int paddingStartIndex = ++ LAYOUT_PADDING_START_INDEX - (marginFieldSet ? 0 : 4); ++ arr[paddingStartIndex] = YGNodeLayoutGetPadding(root, YGEdgeLeft); ++ arr[paddingStartIndex + 1] = YGNodeLayoutGetPadding(root, YGEdgeTop); ++ arr[paddingStartIndex + 2] = YGNodeLayoutGetPadding(root, YGEdgeRight); ++ arr[paddingStartIndex + 3] = YGNodeLayoutGetPadding(root, YGEdgeBottom); ++ } ++ ++ if (borderFieldSet) { ++ int borderStartIndex = LAYOUT_BORDER_START_INDEX - ++ (marginFieldSet ? 0 : 4) - (paddingFieldSet ? 0 : 4); ++ arr[borderStartIndex] = YGNodeLayoutGetBorder(root, YGEdgeLeft); ++ arr[borderStartIndex + 1] = YGNodeLayoutGetBorder(root, YGEdgeTop); ++ arr[borderStartIndex + 2] = YGNodeLayoutGetBorder(root, YGEdgeRight); ++ arr[borderStartIndex + 3] = YGNodeLayoutGetBorder(root, YGEdgeBottom); ++ } ++ ++ // Create scope to make sure to release any local refs created here ++ { ++ // Don't change this field name without changing the name of the field in ++ // Database.java ++ auto objectClass = facebook::yoga::vanillajni::make_local_ref( ++ env, env->GetObjectClass(obj.get())); ++ static const jfieldID arrField = facebook::yoga::vanillajni::getFieldId( ++ env, objectClass.get(), "arr", "[F"); ++ ++ ScopedLocalRef arrFinal = ++ make_local_ref(env, env->NewFloatArray(arrSize)); ++ env->SetFloatArrayRegion(arrFinal.get(), 0, arrSize, arr); ++ env->SetObjectField(obj.get(), arrField, arrFinal.get()); ++ } ++ ++ YGNodeSetHasNewLayout(root, false); ++ ++ for (size_t i = 0; i < YGNodeGetChildCount(root); i++) { ++ YGTransferLayoutOutputsRecursive(env, thiz, YGNodeGetChild(root, i)); ++ } ++} ++ ++static void jni_YGNodeCalculateLayoutJNI( ++ JNIEnv* env, ++ jobject obj, ++ jlong nativePointer, ++ jfloat width, ++ jfloat height, ++ jlongArray nativePointers, ++ jobjectArray javaNodes) { ++ try { ++ PtrJNodeMapVanilla* layoutContext = nullptr; ++ auto map = PtrJNodeMapVanilla{}; ++ if (nativePointers != nullptr) { ++ map = PtrJNodeMapVanilla{nativePointers, javaNodes}; ++ layoutContext = ↦ ++ } ++ ++ LayoutContext::Provider contextProvider(layoutContext); ++ ++ const YGNodeRef root = _jlong2YGNodeRef(nativePointer); ++ YGNodeCalculateLayout( ++ root, ++ static_cast(width), ++ static_cast(height), ++ YGNodeStyleGetDirection(_jlong2YGNodeRef(nativePointer))); ++ YGTransferLayoutOutputsRecursive(env, obj, root); ++ } catch (const YogaJniException& jniException) { ++ ScopedLocalRef throwable = jniException.getThrowable(); ++ if (throwable.get() != nullptr) { ++ env->Throw(throwable.get()); ++ } ++ } catch (const std::logic_error& ex) { ++ env->ExceptionClear(); ++ jclass cl = env->FindClass("java/lang/IllegalStateException"); ++ static const jmethodID methodId = facebook::yoga::vanillajni::getMethodId( ++ env, cl, "", "(Ljava/lang/String;)V"); ++ auto throwable = env->NewObject(cl, methodId, env->NewStringUTF(ex.what())); ++ env->Throw(static_cast(throwable)); ++ } ++} ++ ++static void ++jni_YGNodeMarkDirtyJNI(JNIEnv* /*env*/, jobject /*obj*/, jlong nativePointer) { ++ YGNodeMarkDirty(_jlong2YGNodeRef(nativePointer)); ++} ++ ++static jboolean ++jni_YGNodeIsDirtyJNI(JNIEnv* /*env*/, jobject /*obj*/, jlong nativePointer) { ++ return (jboolean)YGNodeIsDirty(_jlong2YGNodeRef(nativePointer)); ++} ++ ++static void jni_YGNodeCopyStyleJNI( ++ JNIEnv* /*env*/, ++ jobject /*obj*/, ++ jlong dstNativePointer, ++ jlong srcNativePointer) { ++ YGNodeCopyStyle( ++ _jlong2YGNodeRef(dstNativePointer), _jlong2YGNodeRef(srcNativePointer)); ++} ++ ++#define YG_NODE_JNI_STYLE_PROP(javatype, type, name) \ ++ static javatype jni_YGNodeStyleGet##name##JNI( \ ++ JNIEnv* /*env*/, jobject /*obj*/, jlong nativePointer) { \ ++ return (javatype)YGNodeStyleGet##name(_jlong2YGNodeRef(nativePointer)); \ ++ } \ ++ \ ++ static void jni_YGNodeStyleSet##name##JNI( \ ++ JNIEnv* /*env*/, jobject /*obj*/, jlong nativePointer, javatype value) { \ ++ YGNodeStyleSet##name( \ ++ _jlong2YGNodeRef(nativePointer), static_cast(value)); \ ++ } ++ ++#define YG_NODE_JNI_STYLE_UNIT_PROP(name) \ ++ static jlong jni_YGNodeStyleGet##name##JNI( \ ++ JNIEnv* /*env*/, jobject /*obj*/, jlong nativePointer) { \ ++ return YogaValue::asJavaLong( \ ++ YGNodeStyleGet##name(_jlong2YGNodeRef(nativePointer))); \ ++ } \ ++ \ ++ static void jni_YGNodeStyleSet##name##JNI( \ ++ JNIEnv* /*env*/, jobject /*obj*/, jlong nativePointer, jfloat value) { \ ++ YGNodeStyleSet##name( \ ++ _jlong2YGNodeRef(nativePointer), static_cast(value)); \ ++ } \ ++ \ ++ static void jni_YGNodeStyleSet##name##PercentJNI( \ ++ JNIEnv* /*env*/, jobject /*obj*/, jlong nativePointer, jfloat value) { \ ++ YGNodeStyleSet##name##Percent( \ ++ _jlong2YGNodeRef(nativePointer), static_cast(value)); \ ++ } ++ ++#define YG_NODE_JNI_STYLE_UNIT_PROP_AUTO(name) \ ++ YG_NODE_JNI_STYLE_UNIT_PROP(name) \ ++ static void jni_YGNodeStyleSet##name##AutoJNI( \ ++ JNIEnv* /*env*/, jobject /*obj*/, jlong nativePointer) { \ ++ YGNodeStyleSet##name##Auto(_jlong2YGNodeRef(nativePointer)); \ ++ } ++ ++#define YG_NODE_JNI_STYLE_EDGE_UNIT_PROP(name) \ ++ static jlong jni_YGNodeStyleGet##name##JNI( \ ++ JNIEnv* /*env*/, jobject /*obj*/, jlong nativePointer, jint edge) { \ ++ return YogaValue::asJavaLong(YGNodeStyleGet##name( \ ++ _jlong2YGNodeRef(nativePointer), static_cast(edge))); \ ++ } \ ++ \ ++ static void jni_YGNodeStyleSet##name##JNI( \ ++ JNIEnv* /*env*/, \ ++ jobject /*obj*/, \ ++ jlong nativePointer, \ ++ jint edge, \ ++ jfloat value) { \ ++ YGNodeStyleSet##name( \ ++ _jlong2YGNodeRef(nativePointer), \ ++ static_cast(edge), \ ++ static_cast(value)); \ ++ } \ ++ \ ++ static void jni_YGNodeStyleSet##name##PercentJNI( \ ++ JNIEnv* /*env*/, \ ++ jobject /*obj*/, \ ++ jlong nativePointer, \ ++ jint edge, \ ++ jfloat value) { \ ++ YGNodeStyleSet##name##Percent( \ ++ _jlong2YGNodeRef(nativePointer), \ ++ static_cast(edge), \ ++ static_cast(value)); \ ++ } ++ ++YG_NODE_JNI_STYLE_PROP(jint, YGDirection, Direction); ++YG_NODE_JNI_STYLE_PROP(jint, YGFlexDirection, FlexDirection); ++YG_NODE_JNI_STYLE_PROP(jint, YGJustify, JustifyContent); ++YG_NODE_JNI_STYLE_PROP(jint, YGAlign, AlignItems); ++YG_NODE_JNI_STYLE_PROP(jint, YGAlign, AlignSelf); ++YG_NODE_JNI_STYLE_PROP(jint, YGAlign, AlignContent); ++YG_NODE_JNI_STYLE_PROP(jint, YGPositionType, PositionType); ++YG_NODE_JNI_STYLE_PROP(jint, YGWrap, FlexWrap); ++YG_NODE_JNI_STYLE_PROP(jint, YGOverflow, Overflow); ++YG_NODE_JNI_STYLE_PROP(jint, YGDisplay, Display); ++YG_NODE_JNI_STYLE_PROP(jfloat, float, Flex); ++YG_NODE_JNI_STYLE_PROP(jfloat, float, FlexGrow); ++YG_NODE_JNI_STYLE_PROP(jfloat, float, FlexShrink); ++ ++YG_NODE_JNI_STYLE_UNIT_PROP_AUTO(FlexBasis); ++YG_NODE_JNI_STYLE_UNIT_PROP_AUTO(Width); ++YG_NODE_JNI_STYLE_UNIT_PROP(MinWidth); ++YG_NODE_JNI_STYLE_UNIT_PROP(MaxWidth); ++YG_NODE_JNI_STYLE_UNIT_PROP_AUTO(Height); ++YG_NODE_JNI_STYLE_UNIT_PROP(MinHeight); ++YG_NODE_JNI_STYLE_UNIT_PROP(MaxHeight); ++ ++YG_NODE_JNI_STYLE_EDGE_UNIT_PROP(Position); ++ ++static jlong jni_YGNodeStyleGetMarginJNI( ++ JNIEnv* /*env*/, ++ jobject /*obj*/, ++ jlong nativePointer, ++ jint edge) { ++ YGNodeRef yogaNodeRef = _jlong2YGNodeRef(nativePointer); ++ if (!YGNodeEdges{yogaNodeRef}.has(YGNodeEdges::MARGIN)) { ++ return YogaValue::undefinedAsJavaLong(); ++ } ++ return YogaValue::asJavaLong( ++ YGNodeStyleGetMargin(yogaNodeRef, static_cast(edge))); ++} ++ ++static void jni_YGNodeStyleSetMarginJNI( ++ JNIEnv* /*env*/, ++ jobject /*obj*/, ++ jlong nativePointer, ++ jint edge, ++ jfloat margin) { ++ YGNodeRef yogaNodeRef = _jlong2YGNodeRef(nativePointer); ++ YGNodeEdges{yogaNodeRef}.add(YGNodeEdges::MARGIN).setOn(yogaNodeRef); ++ YGNodeStyleSetMargin( ++ yogaNodeRef, static_cast(edge), static_cast(margin)); ++} ++ ++static void jni_YGNodeStyleSetMarginPercentJNI( ++ JNIEnv* /*env*/, ++ jobject /*obj*/, ++ jlong nativePointer, ++ jint edge, ++ jfloat percent) { ++ YGNodeRef yogaNodeRef = _jlong2YGNodeRef(nativePointer); ++ YGNodeEdges{yogaNodeRef}.add(YGNodeEdges::MARGIN).setOn(yogaNodeRef); ++ YGNodeStyleSetMarginPercent( ++ yogaNodeRef, static_cast(edge), static_cast(percent)); ++} ++ ++static void jni_YGNodeStyleSetMarginAutoJNI( ++ JNIEnv* /*env*/, ++ jobject /*obj*/, ++ jlong nativePointer, ++ jint edge) { ++ YGNodeRef yogaNodeRef = _jlong2YGNodeRef(nativePointer); ++ YGNodeEdges{yogaNodeRef}.add(YGNodeEdges::MARGIN).setOn(yogaNodeRef); ++ YGNodeStyleSetMarginAuto(yogaNodeRef, static_cast(edge)); ++} ++ ++static jlong jni_YGNodeStyleGetPaddingJNI( ++ JNIEnv* /*env*/, ++ jobject /*obj*/, ++ jlong nativePointer, ++ jint edge) { ++ YGNodeRef yogaNodeRef = _jlong2YGNodeRef(nativePointer); ++ if (!YGNodeEdges{yogaNodeRef}.has(YGNodeEdges::PADDING)) { ++ return YogaValue::undefinedAsJavaLong(); ++ } ++ return YogaValue::asJavaLong( ++ YGNodeStyleGetPadding(yogaNodeRef, static_cast(edge))); ++} ++ ++static void jni_YGNodeStyleSetPaddingJNI( ++ JNIEnv* /*env*/, ++ jobject /*obj*/, ++ jlong nativePointer, ++ jint edge, ++ jfloat padding) { ++ YGNodeRef yogaNodeRef = _jlong2YGNodeRef(nativePointer); ++ YGNodeEdges{yogaNodeRef}.add(YGNodeEdges::PADDING).setOn(yogaNodeRef); ++ YGNodeStyleSetPadding( ++ yogaNodeRef, static_cast(edge), static_cast(padding)); ++} ++ ++static void jni_YGNodeStyleSetPaddingPercentJNI( ++ JNIEnv* /*env*/, ++ jobject /*obj*/, ++ jlong nativePointer, ++ jint edge, ++ jfloat percent) { ++ YGNodeRef yogaNodeRef = _jlong2YGNodeRef(nativePointer); ++ YGNodeEdges{yogaNodeRef}.add(YGNodeEdges::PADDING).setOn(yogaNodeRef); ++ YGNodeStyleSetPaddingPercent( ++ yogaNodeRef, static_cast(edge), static_cast(percent)); ++} ++ ++static jfloat jni_YGNodeStyleGetBorderJNI( ++ JNIEnv* /*env*/, ++ jobject /*obj*/, ++ jlong nativePointer, ++ jint edge) { ++ YGNodeRef yogaNodeRef = _jlong2YGNodeRef(nativePointer); ++ if (!YGNodeEdges{yogaNodeRef}.has(YGNodeEdges::BORDER)) { ++ return (jfloat)YGUndefined; ++ } ++ return (jfloat)YGNodeStyleGetBorder(yogaNodeRef, static_cast(edge)); ++} ++ ++static void jni_YGNodeStyleSetBorderJNI( ++ JNIEnv* /*env*/, ++ jobject /*obj*/, ++ jlong nativePointer, ++ jint edge, ++ jfloat border) { ++ YGNodeRef yogaNodeRef = _jlong2YGNodeRef(nativePointer); ++ YGNodeEdges{yogaNodeRef}.add(YGNodeEdges::BORDER).setOn(yogaNodeRef); ++ YGNodeStyleSetBorder( ++ yogaNodeRef, static_cast(edge), static_cast(border)); ++} ++ ++static void YGTransferLayoutDirection(YGNodeConstRef node, jobject javaNode) { ++ // Don't change this field name without changing the name of the field in ++ // Database.java ++ JNIEnv* env = getCurrentEnv(); ++ auto objectClass = facebook::yoga::vanillajni::make_local_ref( ++ env, env->GetObjectClass(javaNode)); ++ static const jfieldID layoutDirectionField = ++ facebook::yoga::vanillajni::getFieldId( ++ env, objectClass.get(), "mLayoutDirection", "I"); ++ env->SetIntField( ++ javaNode, ++ layoutDirectionField, ++ static_cast(YGNodeLayoutGetDirection(node))); ++} ++ ++static YGSize YGJNIMeasureFunc( ++ YGNodeConstRef node, ++ float width, ++ YGMeasureMode widthMode, ++ float height, ++ YGMeasureMode heightMode) { ++ if (auto obj = YGNodeJobject(node)) { ++ YGTransferLayoutDirection(node, obj.get()); ++ JNIEnv* env = getCurrentEnv(); ++ auto objectClass = facebook::yoga::vanillajni::make_local_ref( ++ env, env->GetObjectClass(obj.get())); ++ static const jmethodID methodId = facebook::yoga::vanillajni::getMethodId( ++ env, objectClass.get(), "measure", "(FIFI)J"); ++ const auto measureResult = facebook::yoga::vanillajni::callLongMethod( ++ env, obj.get(), methodId, width, widthMode, height, heightMode); ++ ++ static_assert( ++ sizeof(measureResult) == 8, ++ "Expected measureResult to be 8 bytes, or two 32 bit ints"); ++ ++ uint32_t wBits = 0xFFFFFFFF & (measureResult >> 32); ++ uint32_t hBits = 0xFFFFFFFF & measureResult; ++ auto measuredWidth = std::bit_cast(wBits); ++ auto measuredHeight = std::bit_cast(hBits); ++ ++ return YGSize{measuredWidth, measuredHeight}; ++ } else { ++ return YGSize{ ++ widthMode == YGMeasureModeUndefined ? 0 : width, ++ heightMode == YGMeasureModeUndefined ? 0 : height, ++ }; ++ } ++} ++ ++static void jni_YGNodeSetHasMeasureFuncJNI( ++ JNIEnv* /*env*/, ++ jobject /*obj*/, ++ jlong nativePointer, ++ jboolean hasMeasureFunc) { ++ YGNodeSetMeasureFunc( ++ _jlong2YGNodeRef(nativePointer), ++ static_cast(hasMeasureFunc) ? YGJNIMeasureFunc : nullptr); ++} ++ ++static float YGJNIBaselineFunc(YGNodeConstRef node, float width, float height) { ++ if (auto obj = YGNodeJobject(node)) { ++ JNIEnv* env = getCurrentEnv(); ++ auto objectClass = facebook::yoga::vanillajni::make_local_ref( ++ env, env->GetObjectClass(obj.get())); ++ static const jmethodID methodId = facebook::yoga::vanillajni::getMethodId( ++ env, objectClass.get(), "baseline", "(FF)F"); ++ return facebook::yoga::vanillajni::callFloatMethod( ++ env, obj.get(), methodId, width, height); ++ } else { ++ return height; ++ } ++} ++ ++static void jni_YGNodeSetHasBaselineFuncJNI( ++ JNIEnv* /*env*/, ++ jobject /*obj*/, ++ jlong nativePointer, ++ jboolean hasBaselineFunc) { ++ YGNodeSetBaselineFunc( ++ _jlong2YGNodeRef(nativePointer), ++ static_cast(hasBaselineFunc) ? YGJNIBaselineFunc : nullptr); ++} ++ ++static void jni_YGNodeSetAlwaysFormsContainingBlockJNI( ++ JNIEnv* /*env*/, ++ jobject /*obj*/, ++ jlong nativePointer, ++ jboolean alwaysFormsContainingBlock) { ++ YGNodeSetAlwaysFormsContainingBlock( ++ _jlong2YGNodeRef(nativePointer), ++ static_cast(alwaysFormsContainingBlock)); ++} ++ ++static jlong ++jni_YGNodeCloneJNI(JNIEnv* /*env*/, jobject /*obj*/, jlong nativePointer) { ++ auto node = _jlong2YGNodeRef(nativePointer); ++ const YGNodeRef clonedYogaNode = YGNodeClone(node); ++ YGNodeSetContext(clonedYogaNode, YGNodeGetContext(node)); ++ ++ return reinterpret_cast(clonedYogaNode); ++} ++ ++static jfloat jni_YGNodeStyleGetGapJNI( ++ JNIEnv* /*env*/, ++ jobject /*obj*/, ++ jlong nativePointer, ++ jint gutter) { ++ return (jfloat)YGNodeStyleGetGap( ++ _jlong2YGNodeRef(nativePointer), static_cast(gutter)); ++} ++ ++static void jni_YGNodeStyleSetGapJNI( ++ JNIEnv* /*env*/, ++ jobject /*obj*/, ++ jlong nativePointer, ++ jint gutter, ++ jfloat gapLength) { ++ YGNodeStyleSetGap( ++ _jlong2YGNodeRef(nativePointer), ++ static_cast(gutter), ++ static_cast(gapLength)); ++} ++ ++static void jni_YGNodeStyleSetGapPercentJNI( ++ JNIEnv* /*env*/, ++ jobject /*obj*/, ++ jlong nativePointer, ++ jint gutter, ++ jfloat gapLength) { ++ YGNodeStyleSetGapPercent( ++ _jlong2YGNodeRef(nativePointer), ++ static_cast(gutter), ++ static_cast(gapLength)); ++} ++ ++// Yoga specific properties, not compatible with flexbox specification ++YG_NODE_JNI_STYLE_PROP(jfloat, float, AspectRatio); ++ ++static JNINativeMethod methods[] = { ++ {"jni_YGConfigNewJNI", "()J", (void*)jni_YGConfigNewJNI}, ++ {"jni_YGConfigFreeJNI", "(J)V", (void*)jni_YGConfigFreeJNI}, ++ {"jni_YGConfigSetExperimentalFeatureEnabledJNI", ++ "(JIZ)V", ++ (void*)jni_YGConfigSetExperimentalFeatureEnabledJNI}, ++ {"jni_YGConfigSetUseWebDefaultsJNI", ++ "(JZ)V", ++ (void*)jni_YGConfigSetUseWebDefaultsJNI}, ++ {"jni_YGConfigSetPointScaleFactorJNI", ++ "(JF)V", ++ (void*)jni_YGConfigSetPointScaleFactorJNI}, ++ {"jni_YGConfigSetErrataJNI", "(JI)V", (void*)jni_YGConfigSetErrataJNI}, ++ {"jni_YGConfigGetErrataJNI", "(J)I", (void*)jni_YGConfigGetErrataJNI}, ++ {"jni_YGConfigSetLoggerJNI", ++ "(JLcom/facebook/yoga/YogaLogger;)V", ++ (void*)jni_YGConfigSetLoggerJNI}, ++ {"jni_YGNodeNewJNI", "()J", (void*)jni_YGNodeNewJNI}, ++ {"jni_YGNodeNewWithConfigJNI", "(J)J", (void*)jni_YGNodeNewWithConfigJNI}, ++ {"jni_YGNodeFinalizeJNI", "(J)V", (void*)jni_YGNodeFinalizeJNI}, ++ {"jni_YGNodeResetJNI", "(J)V", (void*)jni_YGNodeResetJNI}, ++ {"jni_YGNodeInsertChildJNI", "(JJI)V", (void*)jni_YGNodeInsertChildJNI}, ++ {"jni_YGNodeSwapChildJNI", "(JJI)V", (void*)jni_YGNodeSwapChildJNI}, ++ {"jni_YGNodeSetIsReferenceBaselineJNI", ++ "(JZ)V", ++ (void*)jni_YGNodeSetIsReferenceBaselineJNI}, ++ {"jni_YGNodeIsReferenceBaselineJNI", ++ "(J)Z", ++ (void*)jni_YGNodeIsReferenceBaselineJNI}, ++ {"jni_YGNodeRemoveAllChildrenJNI", ++ "(J)V", ++ (void*)jni_YGNodeRemoveAllChildrenJNI}, ++ {"jni_YGNodeRemoveChildJNI", "(JJ)V", (void*)jni_YGNodeRemoveChildJNI}, ++ {"jni_YGNodeCalculateLayoutJNI", ++ "(JFF[J[Lcom/facebook/yoga/YogaNodeJNIBase;)V", ++ (void*)jni_YGNodeCalculateLayoutJNI}, ++ {"jni_YGNodeMarkDirtyJNI", "(J)V", (void*)jni_YGNodeMarkDirtyJNI}, ++ {"jni_YGNodeIsDirtyJNI", "(J)Z", (void*)jni_YGNodeIsDirtyJNI}, ++ {"jni_YGNodeCopyStyleJNI", "(JJ)V", (void*)jni_YGNodeCopyStyleJNI}, ++ {"jni_YGNodeStyleGetDirectionJNI", ++ "(J)I", ++ (void*)jni_YGNodeStyleGetDirectionJNI}, ++ {"jni_YGNodeStyleSetDirectionJNI", ++ "(JI)V", ++ (void*)jni_YGNodeStyleSetDirectionJNI}, ++ {"jni_YGNodeStyleGetFlexDirectionJNI", ++ "(J)I", ++ (void*)jni_YGNodeStyleGetFlexDirectionJNI}, ++ {"jni_YGNodeStyleSetFlexDirectionJNI", ++ "(JI)V", ++ (void*)jni_YGNodeStyleSetFlexDirectionJNI}, ++ {"jni_YGNodeStyleGetJustifyContentJNI", ++ "(J)I", ++ (void*)jni_YGNodeStyleGetJustifyContentJNI}, ++ {"jni_YGNodeStyleSetJustifyContentJNI", ++ "(JI)V", ++ (void*)jni_YGNodeStyleSetJustifyContentJNI}, ++ {"jni_YGNodeStyleGetAlignItemsJNI", ++ "(J)I", ++ (void*)jni_YGNodeStyleGetAlignItemsJNI}, ++ {"jni_YGNodeStyleSetAlignItemsJNI", ++ "(JI)V", ++ (void*)jni_YGNodeStyleSetAlignItemsJNI}, ++ {"jni_YGNodeStyleGetAlignSelfJNI", ++ "(J)I", ++ (void*)jni_YGNodeStyleGetAlignSelfJNI}, ++ {"jni_YGNodeStyleSetAlignSelfJNI", ++ "(JI)V", ++ (void*)jni_YGNodeStyleSetAlignSelfJNI}, ++ {"jni_YGNodeStyleGetAlignContentJNI", ++ "(J)I", ++ (void*)jni_YGNodeStyleGetAlignContentJNI}, ++ {"jni_YGNodeStyleSetAlignContentJNI", ++ "(JI)V", ++ (void*)jni_YGNodeStyleSetAlignContentJNI}, ++ {"jni_YGNodeStyleGetPositionTypeJNI", ++ "(J)I", ++ (void*)jni_YGNodeStyleGetPositionTypeJNI}, ++ {"jni_YGNodeStyleSetPositionTypeJNI", ++ "(JI)V", ++ (void*)jni_YGNodeStyleSetPositionTypeJNI}, ++ {"jni_YGNodeStyleGetFlexWrapJNI", ++ "(J)I", ++ (void*)jni_YGNodeStyleGetFlexWrapJNI}, ++ {"jni_YGNodeStyleSetFlexWrapJNI", ++ "(JI)V", ++ (void*)jni_YGNodeStyleSetFlexWrapJNI}, ++ {"jni_YGNodeStyleGetOverflowJNI", ++ "(J)I", ++ (void*)jni_YGNodeStyleGetOverflowJNI}, ++ {"jni_YGNodeStyleSetOverflowJNI", ++ "(JI)V", ++ (void*)jni_YGNodeStyleSetOverflowJNI}, ++ {"jni_YGNodeStyleGetDisplayJNI", ++ "(J)I", ++ (void*)jni_YGNodeStyleGetDisplayJNI}, ++ {"jni_YGNodeStyleSetDisplayJNI", ++ "(JI)V", ++ (void*)jni_YGNodeStyleSetDisplayJNI}, ++ {"jni_YGNodeStyleGetFlexJNI", "(J)F", (void*)jni_YGNodeStyleGetFlexJNI}, ++ {"jni_YGNodeStyleSetFlexJNI", "(JF)V", (void*)jni_YGNodeStyleSetFlexJNI}, ++ {"jni_YGNodeStyleGetFlexGrowJNI", ++ "(J)F", ++ (void*)jni_YGNodeStyleGetFlexGrowJNI}, ++ {"jni_YGNodeStyleSetFlexGrowJNI", ++ "(JF)V", ++ (void*)jni_YGNodeStyleSetFlexGrowJNI}, ++ {"jni_YGNodeStyleGetFlexShrinkJNI", ++ "(J)F", ++ (void*)jni_YGNodeStyleGetFlexShrinkJNI}, ++ {"jni_YGNodeStyleSetFlexShrinkJNI", ++ "(JF)V", ++ (void*)jni_YGNodeStyleSetFlexShrinkJNI}, ++ {"jni_YGNodeStyleGetFlexBasisJNI", ++ "(J)J", ++ (void*)jni_YGNodeStyleGetFlexBasisJNI}, ++ {"jni_YGNodeStyleSetFlexBasisJNI", ++ "(JF)V", ++ (void*)jni_YGNodeStyleSetFlexBasisJNI}, ++ {"jni_YGNodeStyleSetFlexBasisPercentJNI", ++ "(JF)V", ++ (void*)jni_YGNodeStyleSetFlexBasisPercentJNI}, ++ {"jni_YGNodeStyleSetFlexBasisAutoJNI", ++ "(J)V", ++ (void*)jni_YGNodeStyleSetFlexBasisAutoJNI}, ++ {"jni_YGNodeStyleGetMarginJNI", ++ "(JI)J", ++ (void*)jni_YGNodeStyleGetMarginJNI}, ++ {"jni_YGNodeStyleSetMarginJNI", ++ "(JIF)V", ++ (void*)jni_YGNodeStyleSetMarginJNI}, ++ {"jni_YGNodeStyleSetMarginPercentJNI", ++ "(JIF)V", ++ (void*)jni_YGNodeStyleSetMarginPercentJNI}, ++ {"jni_YGNodeStyleSetMarginAutoJNI", ++ "(JI)V", ++ (void*)jni_YGNodeStyleSetMarginAutoJNI}, ++ {"jni_YGNodeStyleGetPaddingJNI", ++ "(JI)J", ++ (void*)jni_YGNodeStyleGetPaddingJNI}, ++ {"jni_YGNodeStyleSetPaddingJNI", ++ "(JIF)V", ++ (void*)jni_YGNodeStyleSetPaddingJNI}, ++ {"jni_YGNodeStyleSetPaddingPercentJNI", ++ "(JIF)V", ++ (void*)jni_YGNodeStyleSetPaddingPercentJNI}, ++ {"jni_YGNodeStyleGetBorderJNI", ++ "(JI)F", ++ (void*)jni_YGNodeStyleGetBorderJNI}, ++ {"jni_YGNodeStyleSetBorderJNI", ++ "(JIF)V", ++ (void*)jni_YGNodeStyleSetBorderJNI}, ++ {"jni_YGNodeStyleGetPositionJNI", ++ "(JI)J", ++ (void*)jni_YGNodeStyleGetPositionJNI}, ++ {"jni_YGNodeStyleSetPositionJNI", ++ "(JIF)V", ++ (void*)jni_YGNodeStyleSetPositionJNI}, ++ {"jni_YGNodeStyleSetPositionPercentJNI", ++ "(JIF)V", ++ (void*)jni_YGNodeStyleSetPositionPercentJNI}, ++ {"jni_YGNodeStyleGetWidthJNI", "(J)J", (void*)jni_YGNodeStyleGetWidthJNI}, ++ {"jni_YGNodeStyleSetWidthJNI", "(JF)V", (void*)jni_YGNodeStyleSetWidthJNI}, ++ {"jni_YGNodeStyleSetWidthPercentJNI", ++ "(JF)V", ++ (void*)jni_YGNodeStyleSetWidthPercentJNI}, ++ {"jni_YGNodeStyleSetWidthAutoJNI", ++ "(J)V", ++ (void*)jni_YGNodeStyleSetWidthAutoJNI}, ++ {"jni_YGNodeStyleGetHeightJNI", "(J)J", (void*)jni_YGNodeStyleGetHeightJNI}, ++ {"jni_YGNodeStyleSetHeightJNI", ++ "(JF)V", ++ (void*)jni_YGNodeStyleSetHeightJNI}, ++ {"jni_YGNodeStyleSetHeightPercentJNI", ++ "(JF)V", ++ (void*)jni_YGNodeStyleSetHeightPercentJNI}, ++ {"jni_YGNodeStyleSetHeightAutoJNI", ++ "(J)V", ++ (void*)jni_YGNodeStyleSetHeightAutoJNI}, ++ {"jni_YGNodeStyleGetMinWidthJNI", ++ "(J)J", ++ (void*)jni_YGNodeStyleGetMinWidthJNI}, ++ {"jni_YGNodeStyleSetMinWidthJNI", ++ "(JF)V", ++ (void*)jni_YGNodeStyleSetMinWidthJNI}, ++ {"jni_YGNodeStyleSetMinWidthPercentJNI", ++ "(JF)V", ++ (void*)jni_YGNodeStyleSetMinWidthPercentJNI}, ++ {"jni_YGNodeStyleGetMinHeightJNI", ++ "(J)J", ++ (void*)jni_YGNodeStyleGetMinHeightJNI}, ++ {"jni_YGNodeStyleSetMinHeightJNI", ++ "(JF)V", ++ (void*)jni_YGNodeStyleSetMinHeightJNI}, ++ {"jni_YGNodeStyleSetMinHeightPercentJNI", ++ "(JF)V", ++ (void*)jni_YGNodeStyleSetMinHeightPercentJNI}, ++ {"jni_YGNodeStyleGetMaxWidthJNI", ++ "(J)J", ++ (void*)jni_YGNodeStyleGetMaxWidthJNI}, ++ {"jni_YGNodeStyleSetMaxWidthJNI", ++ "(JF)V", ++ (void*)jni_YGNodeStyleSetMaxWidthJNI}, ++ {"jni_YGNodeStyleSetMaxWidthPercentJNI", ++ "(JF)V", ++ (void*)jni_YGNodeStyleSetMaxWidthPercentJNI}, ++ {"jni_YGNodeStyleGetMaxHeightJNI", ++ "(J)J", ++ (void*)jni_YGNodeStyleGetMaxHeightJNI}, ++ {"jni_YGNodeStyleSetMaxHeightJNI", ++ "(JF)V", ++ (void*)jni_YGNodeStyleSetMaxHeightJNI}, ++ {"jni_YGNodeStyleSetMaxHeightPercentJNI", ++ "(JF)V", ++ (void*)jni_YGNodeStyleSetMaxHeightPercentJNI}, ++ {"jni_YGNodeStyleGetAspectRatioJNI", ++ "(J)F", ++ (void*)jni_YGNodeStyleGetAspectRatioJNI}, ++ {"jni_YGNodeStyleSetAspectRatioJNI", ++ "(JF)V", ++ (void*)jni_YGNodeStyleSetAspectRatioJNI}, ++ {"jni_YGNodeSetHasMeasureFuncJNI", ++ "(JZ)V", ++ (void*)jni_YGNodeSetHasMeasureFuncJNI}, ++ {"jni_YGNodeStyleGetGapJNI", "(JI)F", (void*)jni_YGNodeStyleGetGapJNI}, ++ {"jni_YGNodeStyleSetGapJNI", "(JIF)V", (void*)jni_YGNodeStyleSetGapJNI}, ++ {"jni_YGNodeStyleSetGapPercentJNI", ++ "(JIF)V", ++ (void*)jni_YGNodeStyleSetGapPercentJNI}, ++ {"jni_YGNodeSetHasBaselineFuncJNI", ++ "(JZ)V", ++ (void*)jni_YGNodeSetHasBaselineFuncJNI}, ++ {"jni_YGNodeSetAlwaysFormsContainingBlockJNI", ++ "(JZ)V", ++ (void*)jni_YGNodeSetAlwaysFormsContainingBlockJNI}, ++ {"jni_YGNodeCloneJNI", "(J)J", (void*)jni_YGNodeCloneJNI}, ++}; ++ ++void YGJNIVanilla::registerNatives(JNIEnv* env) { ++ facebook::yoga::vanillajni::registerNatives( ++ env, ++ "com/facebook/yoga/YogaNative", ++ methods, ++ sizeof(methods) / sizeof(JNINativeMethod)); ++} +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/yogajni/jni/YGJNIVanilla.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/yogajni/jni/YGJNIVanilla.h +new file mode 100644 +index 0000000..77b8b11 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/yogajni/jni/YGJNIVanilla.h +@@ -0,0 +1,12 @@ ++/* ++ * 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. ++ */ ++ ++#include "jni.h" ++ ++namespace YGJNIVanilla { ++void registerNatives(JNIEnv* env); ++}; +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/yogajni/jni/YGJTypesVanilla.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/yogajni/jni/YGJTypesVanilla.h +new file mode 100644 +index 0000000..5d21871 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/yogajni/jni/YGJTypesVanilla.h +@@ -0,0 +1,52 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++#include ++ ++#include ++ ++#include "common.h" ++#include "jni.h" ++ ++class PtrJNodeMapVanilla { ++ std::map ptrsToIdxs_{}; ++ jobjectArray javaNodes_{}; ++ ++ public: ++ PtrJNodeMapVanilla() = default; ++ ++ PtrJNodeMapVanilla(jlongArray javaNativePointers, jobjectArray javaNodes) ++ : javaNodes_{javaNodes} { ++ using namespace facebook::yoga::vanillajni; ++ ++ JNIEnv* env = getCurrentEnv(); ++ jsize nativePointersSize = env->GetArrayLength(javaNativePointers); ++ std::vector nativePointers(static_cast(nativePointersSize)); ++ env->GetLongArrayRegion( ++ javaNativePointers, 0, nativePointersSize, nativePointers.data()); ++ ++ for (jsize i = 0; i < nativePointersSize; ++i) { ++ ptrsToIdxs_[(YGNodeConstRef)nativePointers[static_cast(i)]] = i; ++ } ++ } ++ ++ facebook::yoga::vanillajni::ScopedLocalRef ref(YGNodeConstRef node) { ++ using namespace facebook::yoga::vanillajni; ++ ++ JNIEnv* env = getCurrentEnv(); ++ auto idx = ptrsToIdxs_.find(node); ++ if (idx == ptrsToIdxs_.end()) { ++ return ScopedLocalRef(env); ++ } else { ++ return make_local_ref( ++ env, env->GetObjectArrayElement(javaNodes_, idx->second)); ++ } ++ } ++}; +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/yogajni/jni/YogaJniException.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/yogajni/jni/YogaJniException.cpp +new file mode 100644 +index 0000000..e8c6ca9 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/yogajni/jni/YogaJniException.cpp +@@ -0,0 +1,49 @@ ++/* ++ * 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. ++ */ ++ ++#include "YogaJniException.h" ++#include ++#include ++#include "common.h" ++ ++namespace facebook::yoga::vanillajni { ++ ++YogaJniException::YogaJniException() { ++ jclass cl = getCurrentEnv()->FindClass("java/lang/RuntimeException"); ++ static const jmethodID methodId = facebook::yoga::vanillajni::getMethodId( ++ getCurrentEnv(), cl, "", "()V"); ++ auto throwable = getCurrentEnv()->NewObject(cl, methodId); ++ throwable_ = ++ newGlobalRef(getCurrentEnv(), static_cast(throwable)); ++} ++ ++YogaJniException::YogaJniException(jthrowable throwable) { ++ throwable_ = newGlobalRef(getCurrentEnv(), throwable); ++} ++ ++YogaJniException::YogaJniException(YogaJniException&& rhs) noexcept ++ : throwable_(std::move(rhs.throwable_)) {} ++ ++YogaJniException::YogaJniException(const YogaJniException& rhs) { ++ throwable_ = newGlobalRef(getCurrentEnv(), rhs.throwable_.get()); ++} ++ ++YogaJniException::~YogaJniException() { ++ try { ++ throwable_.reset(); ++ } catch (...) { ++ std::terminate(); ++ } ++} ++ ++ScopedLocalRef YogaJniException::getThrowable() const noexcept { ++ return make_local_ref( ++ getCurrentEnv(), ++ static_cast(getCurrentEnv()->NewLocalRef(throwable_.get()))); ++} ++ ++} // namespace facebook::yoga::vanillajni +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/yogajni/jni/YogaJniException.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/yogajni/jni/YogaJniException.h +new file mode 100644 +index 0000000..8c53d41 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/yogajni/jni/YogaJniException.h +@@ -0,0 +1,35 @@ ++/* ++ * 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. ++ */ ++ ++#include ++#include ++#include "common.h" ++ ++namespace facebook::yoga::vanillajni { ++/** ++ * This class wraps a Java exception (jthrowable) into a C++ exception; A global ++ * reference to Java exception (jthrowable) is made so that the exception object ++ * does not gets cleared before jni call completion ++ */ ++class YogaJniException : public std::exception { ++ public: ++ YogaJniException(); ++ ~YogaJniException() override; ++ ++ explicit YogaJniException(jthrowable throwable); ++ ++ YogaJniException(YogaJniException&& rhs) noexcept; ++ ++ YogaJniException(const YogaJniException& rhs); ++ ++ ScopedLocalRef getThrowable() const noexcept; ++ ++ private: ++ ScopedGlobalRef throwable_; ++}; ++ ++} // namespace facebook::yoga::vanillajni +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/yogajni/jni/common.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/yogajni/jni/common.cpp +new file mode 100644 +index 0000000..d634b0a +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/yogajni/jni/common.cpp +@@ -0,0 +1,109 @@ ++/* ++ * 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. ++ */ ++ ++#include "common.h" ++ ++namespace facebook::yoga::vanillajni { ++ ++void registerNatives( ++ JNIEnv* env, ++ const char* className, ++ const JNINativeMethod methods[], ++ size_t numMethods) { ++ jclass clazz = env->FindClass(className); ++ ++ assertNoPendingJniExceptionIf(env, clazz == nullptr); ++ ++ auto result = ++ env->RegisterNatives(clazz, methods, static_cast(numMethods)); ++ ++ assertNoPendingJniExceptionIf(env, result != JNI_OK); ++} ++ ++jmethodID getStaticMethodId( ++ JNIEnv* env, ++ jclass clazz, ++ const char* methodName, ++ const char* methodDescriptor) { ++ jmethodID methodId = ++ env->GetStaticMethodID(clazz, methodName, methodDescriptor); ++ assertNoPendingJniExceptionIf(env, methodId == nullptr); ++ return methodId; ++} ++ ++jmethodID getMethodId( ++ JNIEnv* env, ++ jclass clazz, ++ const char* methodName, ++ const char* methodDescriptor) { ++ jmethodID methodId = env->GetMethodID(clazz, methodName, methodDescriptor); ++ assertNoPendingJniExceptionIf(env, methodId == nullptr); ++ return methodId; ++} ++ ++jfieldID getFieldId( ++ JNIEnv* env, ++ jclass clazz, ++ const char* fieldName, ++ const char* fieldSignature) { ++ jfieldID fieldId = env->GetFieldID(clazz, fieldName, fieldSignature); ++ assertNoPendingJniExceptionIf(env, fieldId == nullptr); ++ return fieldId; ++} ++ ++#define DEFINE_CALL_METHOD_FOR_PRIMITIVE_IMPLEMENTATION(jnitype, readableType) \ ++ DEFINE_CALL_METHOD_FOR_PRIMITIVE_INTERFACE(jnitype, readableType) { \ ++ va_list args; \ ++ va_start(args, methodId); \ ++ jnitype result = env->Call##readableType##MethodV(obj, methodId, args); \ ++ va_end(args); \ ++ assertNoPendingJniException(env); \ ++ return result; \ ++ } ++ ++DEFINE_CALL_METHOD_FOR_PRIMITIVE_IMPLEMENTATION(jlong, Long); ++DEFINE_CALL_METHOD_FOR_PRIMITIVE_IMPLEMENTATION(jfloat, Float); ++ ++DEFINE_CALL_METHOD_FOR_PRIMITIVE_INTERFACE(void, Void) { ++ va_list args; ++ va_start(args, methodId); ++ env->CallVoidMethodV(obj, methodId, args); ++ va_end(args); ++ assertNoPendingJniException(env); ++} ++ ++ScopedLocalRef ++callStaticObjectMethod(JNIEnv* env, jclass clazz, jmethodID methodId, ...) { ++ va_list args; ++ va_start(args, methodId); ++ jobject result = env->CallStaticObjectMethodV(clazz, methodId, args); ++ va_end(args); ++ assertNoPendingJniExceptionIf(env, result == nullptr); ++ return make_local_ref(env, result); ++} ++ ++ScopedGlobalRef newGlobalRef(JNIEnv* env, jobject obj) { ++ jobject result = env->NewGlobalRef(obj); ++ ++ if (result == nullptr) { ++ logErrorMessageAndDie("Could not obtain global reference from object"); ++ } ++ ++ return make_global_ref(result); ++} ++ ++ScopedGlobalRef newGlobalRef(JNIEnv* env, jthrowable obj) { ++ auto result = static_cast(env->NewGlobalRef(obj)); ++ ++ if (result == nullptr) { ++ logErrorMessageAndDie("Could not obtain global reference from object"); ++ } ++ ++ return make_global_ref(result); ++} ++ ++} // namespace facebook::yoga::vanillajni +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/yogajni/jni/common.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/yogajni/jni/common.h +new file mode 100644 +index 0000000..eb63554 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/yogajni/jni/common.h +@@ -0,0 +1,73 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++#include "ScopedGlobalRef.h" ++#include "ScopedLocalRef.h" ++ ++namespace facebook::yoga::vanillajni { ++ ++/** ++ * Registers a set of methods for a JNI class. Aborts if registration fails. ++ */ ++void registerNatives( ++ JNIEnv* env, ++ const char* className, ++ const JNINativeMethod methods[], ++ size_t numMethods); ++ ++/** ++ * Returns a jmethodID for a class static method. Aborts if any error happens. ++ */ ++jmethodID getStaticMethodId( ++ JNIEnv* env, ++ jclass clazz, ++ const char* methodName, ++ const char* methodDescriptor); ++ ++/** ++ * Returns a jmethodID for a class non-static method. Aborts if any error ++ * happens. ++ */ ++jmethodID getMethodId( ++ JNIEnv* env, ++ jclass clazz, ++ const char* methodName, ++ const char* methodDescriptor); ++ ++/** ++ * Returns a class non-static field ID. Aborts if any error happens. ++ */ ++jfieldID getFieldId( ++ JNIEnv* env, ++ jclass clazz, ++ const char* fieldName, ++ const char* fieldSignature); ++ ++// Helper methods to call a non-static method on an object depending on the ++// return type. Each method will abort the execution if an error ++// (such as a Java pending exception) is detected after invoking the ++// Java method. ++#define DEFINE_CALL_METHOD_FOR_PRIMITIVE_INTERFACE(jnitype, readableType) \ ++ jnitype call##readableType##Method( \ ++ JNIEnv* env, jobject obj, jmethodID methodId, ...) ++DEFINE_CALL_METHOD_FOR_PRIMITIVE_INTERFACE(void, Void); ++DEFINE_CALL_METHOD_FOR_PRIMITIVE_INTERFACE(jlong, Long); ++DEFINE_CALL_METHOD_FOR_PRIMITIVE_INTERFACE(jfloat, Float); ++ ++ScopedLocalRef ++callStaticObjectMethod(JNIEnv* env, jclass clazz, jmethodID methodId, ...); ++ ++/** ++ * Given a local or a global reference, this method creates a new global ++ * reference out of it. If any error happens, aborts the process. ++ */ ++ScopedGlobalRef newGlobalRef(JNIEnv* env, jobject obj); ++ ++ScopedGlobalRef newGlobalRef(JNIEnv* env, jthrowable obj); ++ ++} // namespace facebook::yoga::vanillajni +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/yogajni/jni/corefunctions.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/yogajni/jni/corefunctions.cpp +new file mode 100644 +index 0000000..6fcbf78 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/yogajni/jni/corefunctions.cpp +@@ -0,0 +1,91 @@ ++/* ++ * 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. ++ */ ++ ++#include "corefunctions.h" ++#include "YogaJniException.h" ++#include "macros.h" ++ ++namespace facebook::yoga::vanillajni { ++ ++namespace { ++JavaVM* globalVm = nullptr; ++struct JavaVMInitializer { ++ explicit JavaVMInitializer(JavaVM* vm) { ++ if (!vm) { ++ logErrorMessageAndDie( ++ "You cannot pass a NULL JavaVM to ensureInitialized"); ++ } ++ globalVm = vm; ++ } ++}; ++} // namespace ++ ++jint ensureInitialized(JNIEnv** env, JavaVM* vm) { ++ static JavaVMInitializer init(vm); ++ ++ if (env == nullptr) { ++ logErrorMessageAndDie( ++ "Need to pass a valid JNIEnv pointer to vanillajni initialization " ++ "routine"); ++ } ++ ++ if (vm->GetEnv(reinterpret_cast(env), JNI_VERSION_1_6) != JNI_OK) { ++ logErrorMessageAndDie( ++ "Error retrieving JNIEnv during initialization of vanillajni"); ++ } ++ ++ return JNI_VERSION_1_6; ++} ++ ++// TODO why we need JNIEXPORT for getCurrentEnv ? ++JNIEXPORT JNIEnv* getCurrentEnv() { ++ JNIEnv* env = nullptr; ++ jint ret = globalVm->GetEnv((void**)&env, JNI_VERSION_1_6); ++ if (ret != JNI_OK) { ++ logErrorMessageAndDie( ++ "There was an error retrieving the current JNIEnv. Make sure the " ++ "current thread is attached"); ++ } ++ return env; ++} ++ ++void logErrorMessageAndDie(const char* message) { ++ (void)message; ++ VANILLAJNI_LOG_ERROR( ++ "VanillaJni", ++ "Aborting due to error detected in native code: %s", ++ message); ++ VANILLAJNI_DIE(); ++} ++ ++void assertNoPendingJniException(JNIEnv* env) { ++ if (env->ExceptionCheck() == JNI_FALSE) { ++ return; ++ } ++ ++ auto throwable = env->ExceptionOccurred(); ++ if (throwable == nullptr) { ++ logErrorMessageAndDie("Unable to get pending JNI exception."); ++ } ++ env->ExceptionClear(); ++ throw YogaJniException(throwable); ++} ++ ++void assertNoPendingJniExceptionIf(JNIEnv* env, bool condition) { ++ if (!condition) { ++ return; ++ } ++ ++ if (env->ExceptionCheck() == JNI_TRUE) { ++ assertNoPendingJniException(env); ++ return; ++ } ++ ++ throw YogaJniException(); ++} ++ ++} // namespace facebook::yoga::vanillajni +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/yogajni/jni/corefunctions.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/yogajni/jni/corefunctions.h +new file mode 100644 +index 0000000..ced9480 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/yogajni/jni/corefunctions.h +@@ -0,0 +1,50 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++#include ++ ++namespace facebook::yoga::vanillajni { ++ ++/** ++ * This method has to be called before using the vanillajni library. This method ++ * is typically called when doing initialization in the "on load" JNI hook of a ++ * particular library. ++ * ++ * This method is thread safe, and after the first time it's called it has no ++ * initialization effect. ++ * ++ * @param env use this output parameter to get a JNIEnv to use for things such ++ * as registering native methods and such. ++ * @param vm the VM instance passed by JNI. This is usually the VM instance ++ * that is passed to the "on load" JNI hook. ++ * @return an integer value to return from the "on load" hook. ++ */ ++jint ensureInitialized(JNIEnv** env, JavaVM* vm); ++ ++/** ++ * Returns a JNIEnv* suitable for the current thread. If the current thread is ++ * not attached to the Java VM, this method aborts execution. ++ */ ++JNIEnv* getCurrentEnv(); ++ ++/** ++ * Logs an error message and aborts the current process. ++ */ ++void logErrorMessageAndDie(const char* message); ++ ++/** ++ * Checks whether there is a pending JNI exception. If so, it logs an error ++ * message and aborts the current process. Otherwise it does nothing. ++ */ ++void assertNoPendingJniException(JNIEnv* env); ++ ++void assertNoPendingJniExceptionIf(JNIEnv* env, bool condition); ++ ++} // namespace facebook::yoga::vanillajni +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/yogajni/jni/macros.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/yogajni/jni/macros.h +new file mode 100644 +index 0000000..2e2632d +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/yogajni/jni/macros.h +@@ -0,0 +1,23 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++ ++#ifdef __ANDROID__ ++#include ++#endif ++ ++#ifdef __ANDROID__ ++#define VANILLAJNI_LOG_ERROR(tag, format, ...) \ ++ __android_log_print(ANDROID_LOG_ERROR, tag, format, ##__VA_ARGS__) ++#else ++#define VANILLAJNI_LOG_ERROR(tag, format, ...) ++#endif ++ ++#define VANILLAJNI_DIE() std::abort() +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/yogajni/jni/yogajni.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/yogajni/jni/yogajni.cpp +new file mode 100644 +index 0000000..5bc9943 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/first-party/yogajni/jni/yogajni.cpp +@@ -0,0 +1,18 @@ ++/* ++ * 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. ++ */ ++ ++#include "YGJNIVanilla.h" ++#include "common.h" ++ ++using namespace facebook::yoga; ++ ++jint JNI_OnLoad(JavaVM* vm, void* /*unused*/) { ++ JNIEnv* env = nullptr; ++ jint ret = vanillajni::ensureInitialized(&env, vm); ++ YGJNIVanilla::registerNatives(env); ++ return ret; ++} +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/prebuilt/lib/DUMMY b/node_modules/react-native/ReactAndroid/bin/src/main/jni/prebuilt/lib/DUMMY +new file mode 100644 +index 0000000..dc29e4d +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/prebuilt/lib/DUMMY +@@ -0,0 +1 @@ ++# just a dummy temporarily to make BUCK happy about folder not present before Gradle built it +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/AsyncEventBeat.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/AsyncEventBeat.cpp +new file mode 100644 +index 0000000..4160e35 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/AsyncEventBeat.cpp +@@ -0,0 +1,69 @@ ++/* ++ * 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. ++ */ ++ ++#include ++#include ++#include ++ ++#include "AsyncEventBeat.h" ++ ++namespace facebook::react { ++ ++AsyncEventBeat::AsyncEventBeat( ++ const EventBeat::SharedOwnerBox& ownerBox, ++ EventBeatManager* eventBeatManager, ++ RuntimeExecutor runtimeExecutor, ++ jni::global_ref javaUIManager) ++ : EventBeat(ownerBox), ++ eventBeatManager_(eventBeatManager), ++ runtimeExecutor_(std::move(runtimeExecutor)), ++ javaUIManager_(std::move(javaUIManager)) { ++ eventBeatManager->addObserver(*this); ++} ++ ++AsyncEventBeat::~AsyncEventBeat() { ++ eventBeatManager_->removeObserver(*this); ++} ++ ++void AsyncEventBeat::tick() const { ++ if (!isRequested_ || isBeatCallbackScheduled_) { ++ return; ++ } ++ ++ isRequested_ = false; ++ isBeatCallbackScheduled_ = true; ++ ++ runtimeExecutor_([this, ownerBox = ownerBox_](jsi::Runtime& runtime) { ++ auto owner = ownerBox->owner.lock(); ++ if (!owner) { ++ return; ++ } ++ ++ isBeatCallbackScheduled_ = false; ++ if (beatCallback_) { ++ beatCallback_(runtime); ++ } ++ }); ++} ++ ++void AsyncEventBeat::induce() const { ++ tick(); ++} ++ ++void AsyncEventBeat::request() const { ++ bool alreadyRequested = isRequested_; ++ EventBeat::request(); ++ if (!alreadyRequested) { ++ // Notifies java side that an event will be dispatched (e.g. LayoutEvent) ++ static auto onRequestEventBeat = ++ jni::findClassStatic("com/facebook/react/fabric/FabricUIManager") ++ ->getMethod("onRequestEventBeat"); ++ onRequestEventBeat(javaUIManager_); ++ } ++} ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/AsyncEventBeat.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/AsyncEventBeat.h +new file mode 100644 +index 0000000..a45567a +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/AsyncEventBeat.h +@@ -0,0 +1,39 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++ ++#include "EventBeatManager.h" ++ ++namespace facebook::react { ++ ++class AsyncEventBeat final : public EventBeat, public EventBeatManagerObserver { ++ public: ++ AsyncEventBeat( ++ const EventBeat::SharedOwnerBox& ownerBox, ++ EventBeatManager* eventBeatManager, ++ RuntimeExecutor runtimeExecutor, ++ jni::global_ref javaUIManager); ++ ++ ~AsyncEventBeat() override; ++ ++ void tick() const override; ++ ++ void induce() const override; ++ ++ void request() const override; ++ ++ private: ++ EventBeatManager* eventBeatManager_; ++ RuntimeExecutor runtimeExecutor_; ++ jni::global_ref javaUIManager_; ++ mutable std::atomic isBeatCallbackScheduled_{false}; ++}; ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/Binding.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/Binding.cpp +new file mode 100644 +index 0000000..280ae46 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/Binding.cpp +@@ -0,0 +1,595 @@ ++/* ++ * 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. ++ */ ++ ++#include "Binding.h" ++ ++#include "AsyncEventBeat.h" ++#include "ComponentFactory.h" ++#include "EventBeatManager.h" ++#include "EventEmitterWrapper.h" ++#include "FabricMountingManager.h" ++#include "JBackgroundExecutor.h" ++#include "ReactNativeConfigHolder.h" ++#include "SurfaceHandlerBinding.h" ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++namespace facebook::react { ++ ++jni::local_ref Binding::initHybrid( ++ jni::alias_ref) { ++ return makeCxxInstance(); ++} ++ ++// Thread-safe getter ++std::shared_ptr Binding::getScheduler() { ++ std::shared_lock lock(installMutex_); ++ // Need to return a copy of the shared_ptr to make sure this is safe if called ++ // concurrently with uninstallFabricUIManager ++ return scheduler_; ++} ++ ++jni::local_ref ++Binding::getInspectorDataForInstance( ++ jni::alias_ref eventEmitterWrapper) { ++ auto scheduler = getScheduler(); ++ if (!scheduler) { ++ LOG(ERROR) << "Binding::startSurface: scheduler disappeared"; ++ return ReadableNativeMap::newObjectCxxArgs(folly::dynamic::object()); ++ } ++ ++ EventEmitterWrapper* cEventEmitter = cthis(eventEmitterWrapper); ++ InspectorData data = ++ scheduler->getInspectorDataForInstance(*cEventEmitter->eventEmitter); ++ ++ folly::dynamic result = folly::dynamic::object; ++ result["fileName"] = data.fileName; ++ result["lineNumber"] = data.lineNumber; ++ result["columnNumber"] = data.columnNumber; ++ result["selectedIndex"] = data.selectedIndex; ++ result["props"] = data.props; ++ auto hierarchy = folly::dynamic::array(); ++ for (const auto& hierarchyItem : data.hierarchy) { ++ hierarchy.push_back(hierarchyItem); ++ } ++ result["hierarchy"] = hierarchy; ++ return ReadableNativeMap::newObjectCxxArgs(result); ++} ++ ++constexpr static auto kReactFeatureFlagsJavaDescriptor = ++ "com/facebook/react/config/ReactFeatureFlags"; ++ ++static bool getFeatureFlagValue(const char* name) { ++ static const auto reactFeatureFlagsClass = ++ jni::findClassStatic(kReactFeatureFlagsJavaDescriptor); ++ const auto field = reactFeatureFlagsClass->getStaticField(name); ++ return reactFeatureFlagsClass->getStaticFieldValue(field); ++} ++ ++void Binding::setPixelDensity(float pointScaleFactor) { ++ pointScaleFactor_ = pointScaleFactor; ++} ++ ++void Binding::driveCxxAnimations() { ++ getScheduler()->animationTick(); ++} ++ ++void Binding::reportMount(SurfaceId surfaceId) { ++ auto scheduler = getScheduler(); ++ if (!scheduler) { ++ LOG(ERROR) << "Binding::reportMount: scheduler disappeared"; ++ return; ++ } ++ scheduler->reportMount(surfaceId); ++} ++ ++#pragma mark - Surface management ++ ++void Binding::startSurface( ++ jint surfaceId, ++ jni::alias_ref moduleName, ++ NativeMap* initialProps) { ++ SystraceSection s("FabricUIManagerBinding::startSurface"); ++ ++ auto scheduler = getScheduler(); ++ if (!scheduler) { ++ LOG(ERROR) << "Binding::startSurface: scheduler disappeared"; ++ return; ++ } ++ ++ auto layoutContext = LayoutContext{}; ++ layoutContext.pointScaleFactor = pointScaleFactor_; ++ ++ auto surfaceHandler = SurfaceHandler{moduleName->toStdString(), surfaceId}; ++ surfaceHandler.setContextContainer(scheduler->getContextContainer()); ++ surfaceHandler.setProps(initialProps->consume()); ++ surfaceHandler.constraintLayout({}, layoutContext); ++ ++ scheduler->registerSurface(surfaceHandler); ++ ++ surfaceHandler.start(); ++ ++ surfaceHandler.getMountingCoordinator()->setMountingOverrideDelegate( ++ animationDriver_); ++ ++ { ++ SystraceSection s2("FabricUIManagerBinding::startSurface::surfaceId::lock"); ++ std::unique_lock lock(surfaceHandlerRegistryMutex_); ++ SystraceSection s3("FabricUIManagerBinding::startSurface::surfaceId"); ++ surfaceHandlerRegistry_.emplace(surfaceId, std::move(surfaceHandler)); ++ } ++ ++ auto mountingManager = getMountingManager("startSurface"); ++ if (!mountingManager) { ++ return; ++ } ++ mountingManager->onSurfaceStart(surfaceId); ++} ++ ++void Binding::startSurfaceWithConstraints( ++ jint surfaceId, ++ jni::alias_ref moduleName, ++ NativeMap* initialProps, ++ jfloat minWidth, ++ jfloat maxWidth, ++ jfloat minHeight, ++ jfloat maxHeight, ++ jfloat offsetX, ++ jfloat offsetY, ++ jboolean isRTL, ++ jboolean doLeftAndRightSwapInRTL) { ++ SystraceSection s("FabricUIManagerBinding::startSurfaceWithConstraints"); ++ ++ if (enableFabricLogs_) { ++ LOG(WARNING) ++ << "Binding::startSurfaceWithConstraints() was called (address: " ++ << this << ", surfaceId: " << surfaceId << ")."; ++ } ++ ++ auto scheduler = getScheduler(); ++ if (!scheduler) { ++ LOG(ERROR) << "Binding::startSurfaceWithConstraints: scheduler disappeared"; ++ return; ++ } ++ ++ auto minimumSize = ++ Size{minWidth / pointScaleFactor_, minHeight / pointScaleFactor_}; ++ auto maximumSize = ++ Size{maxWidth / pointScaleFactor_, maxHeight / pointScaleFactor_}; ++ ++ LayoutContext context; ++ context.viewportOffset = ++ Point{offsetX / pointScaleFactor_, offsetY / pointScaleFactor_}; ++ context.pointScaleFactor = {pointScaleFactor_}; ++ context.swapLeftAndRightInRTL = doLeftAndRightSwapInRTL; ++ LayoutConstraints constraints = {}; ++ constraints.minimumSize = minimumSize; ++ constraints.maximumSize = maximumSize; ++ constraints.layoutDirection = ++ isRTL ? LayoutDirection::RightToLeft : LayoutDirection::LeftToRight; ++ ++ auto surfaceHandler = SurfaceHandler{moduleName->toStdString(), surfaceId}; ++ surfaceHandler.setContextContainer(scheduler->getContextContainer()); ++ surfaceHandler.setProps(initialProps->consume()); ++ surfaceHandler.constraintLayout(constraints, context); ++ ++ scheduler->registerSurface(surfaceHandler); ++ ++ surfaceHandler.start(); ++ ++ surfaceHandler.getMountingCoordinator()->setMountingOverrideDelegate( ++ animationDriver_); ++ ++ { ++ SystraceSection s2( ++ "FabricUIManagerBinding::startSurfaceWithConstraints::surfaceId::lock"); ++ std::unique_lock lock(surfaceHandlerRegistryMutex_); ++ SystraceSection s3( ++ "FabricUIManagerBinding::startSurfaceWithConstraints::surfaceId"); ++ surfaceHandlerRegistry_.emplace(surfaceId, std::move(surfaceHandler)); ++ } ++ ++ auto mountingManager = getMountingManager("startSurfaceWithConstraints"); ++ if (!mountingManager) { ++ return; ++ } ++ mountingManager->onSurfaceStart(surfaceId); ++} ++ ++void Binding::stopSurface(jint surfaceId) { ++ SystraceSection s("FabricUIManagerBinding::stopSurface"); ++ ++ if (enableFabricLogs_) { ++ LOG(WARNING) << "Binding::stopSurface() was called (address: " << this ++ << ", surfaceId: " << surfaceId << ")."; ++ } ++ ++ auto scheduler = getScheduler(); ++ if (!scheduler) { ++ LOG(ERROR) << "Binding::stopSurface: scheduler disappeared"; ++ return; ++ } ++ ++ { ++ std::unique_lock lock(surfaceHandlerRegistryMutex_); ++ ++ auto iterator = surfaceHandlerRegistry_.find(surfaceId); ++ ++ if (iterator == surfaceHandlerRegistry_.end()) { ++ LOG(ERROR) << "Binding::stopSurface: Surface with given id is not found"; ++ return; ++ } ++ ++ auto surfaceHandler = std::move(iterator->second); ++ surfaceHandlerRegistry_.erase(iterator); ++ surfaceHandler.stop(); ++ scheduler->unregisterSurface(surfaceHandler); ++ } ++ ++ auto mountingManager = getMountingManager("stopSurface"); ++ if (!mountingManager) { ++ return; ++ } ++ mountingManager->onSurfaceStop(surfaceId); ++} ++ ++void Binding::registerSurface(SurfaceHandlerBinding* surfaceHandlerBinding) { ++ const auto& surfaceHandler = surfaceHandlerBinding->getSurfaceHandler(); ++ auto scheduler = getScheduler(); ++ if (!scheduler) { ++ LOG(ERROR) << "Binding::registerSurface: scheduler disappeared"; ++ return; ++ } ++ scheduler->registerSurface(surfaceHandler); ++ ++ auto mountingManager = getMountingManager("registerSurface"); ++ if (!mountingManager) { ++ return; ++ } ++ mountingManager->onSurfaceStart(surfaceHandler.getSurfaceId()); ++} ++ ++void Binding::unregisterSurface(SurfaceHandlerBinding* surfaceHandlerBinding) { ++ const auto& surfaceHandler = surfaceHandlerBinding->getSurfaceHandler(); ++ auto scheduler = getScheduler(); ++ if (!scheduler) { ++ LOG(ERROR) << "Binding::unregisterSurface: scheduler disappeared"; ++ return; ++ } ++ scheduler->unregisterSurface(surfaceHandler); ++ ++ auto mountingManager = getMountingManager("unregisterSurface"); ++ if (!mountingManager) { ++ return; ++ } ++ mountingManager->onSurfaceStop(surfaceHandler.getSurfaceId()); ++} ++ ++void Binding::setConstraints( ++ jint surfaceId, ++ jfloat minWidth, ++ jfloat maxWidth, ++ jfloat minHeight, ++ jfloat maxHeight, ++ jfloat offsetX, ++ jfloat offsetY, ++ jboolean isRTL, ++ jboolean doLeftAndRightSwapInRTL) { ++ SystraceSection s("FabricUIManagerBinding::setConstraints"); ++ ++ auto scheduler = getScheduler(); ++ if (!scheduler) { ++ LOG(ERROR) << "Binding::setConstraints: scheduler disappeared"; ++ return; ++ } ++ ++ auto minimumSize = ++ Size{minWidth / pointScaleFactor_, minHeight / pointScaleFactor_}; ++ auto maximumSize = ++ Size{maxWidth / pointScaleFactor_, maxHeight / pointScaleFactor_}; ++ ++ LayoutContext context; ++ context.viewportOffset = ++ Point{offsetX / pointScaleFactor_, offsetY / pointScaleFactor_}; ++ context.pointScaleFactor = {pointScaleFactor_}; ++ context.swapLeftAndRightInRTL = doLeftAndRightSwapInRTL; ++ LayoutConstraints constraints = {}; ++ constraints.minimumSize = minimumSize; ++ constraints.maximumSize = maximumSize; ++ constraints.layoutDirection = ++ isRTL ? LayoutDirection::RightToLeft : LayoutDirection::LeftToRight; ++ ++ { ++ std::shared_lock lock(surfaceHandlerRegistryMutex_); ++ ++ auto iterator = surfaceHandlerRegistry_.find(surfaceId); ++ ++ if (iterator == surfaceHandlerRegistry_.end()) { ++ LOG(ERROR) ++ << "Binding::setConstraints: Surface with given id is not found"; ++ return; ++ } ++ ++ auto& surfaceHandler = iterator->second; ++ surfaceHandler.constraintLayout(constraints, context); ++ } ++} ++ ++#pragma mark - Install/uninstall java binding ++ ++void Binding::installFabricUIManager( ++ jni::alias_ref runtimeExecutorHolder, ++ jni::alias_ref runtimeSchedulerHolder, ++ jni::alias_ref javaUIManager, ++ EventBeatManager* eventBeatManager, ++ ComponentFactory* componentsRegistry, ++ jni::alias_ref reactNativeConfig) { ++ SystraceSection s("FabricUIManagerBinding::installFabricUIManager"); ++ ++ std::shared_ptr config = ++ std::make_shared(reactNativeConfig); ++ ++ enableFabricLogs_ = ++ config->getBool("react_fabric:enabled_android_fabric_logs"); ++ ++ if (enableFabricLogs_) { ++ LOG(WARNING) << "Binding::installFabricUIManager() was called (address: " ++ << this << ")."; ++ } ++ ++ std::unique_lock lock(installMutex_); ++ ++ auto globalJavaUiManager = make_global(javaUIManager); ++ mountingManager_ = ++ std::make_shared(config, globalJavaUiManager); ++ ++ ContextContainer::Shared contextContainer = ++ std::make_shared(); ++ ++ auto runtimeExecutor = runtimeExecutorHolder->cthis()->get(); ++ ++ if (runtimeSchedulerHolder) { ++ auto runtimeScheduler = runtimeSchedulerHolder->cthis()->get().lock(); ++ if (runtimeScheduler) { ++ runtimeExecutor = ++ [runtimeScheduler]( ++ std::function&& callback) { ++ runtimeScheduler->scheduleWork(std::move(callback)); ++ }; ++ contextContainer->insert( ++ "RuntimeScheduler", ++ std::weak_ptr(runtimeScheduler)); ++ } ++ } ++ ++ EventBeat::Factory asynchronousBeatFactory = ++ [eventBeatManager, runtimeExecutor, globalJavaUiManager]( ++ const EventBeat::SharedOwnerBox& ownerBox) ++ -> std::unique_ptr { ++ return std::make_unique( ++ ownerBox, eventBeatManager, runtimeExecutor, globalJavaUiManager); ++ }; ++ ++ contextContainer->insert("ReactNativeConfig", config); ++ contextContainer->insert("FabricUIManager", globalJavaUiManager); ++ ++ // Keep reference to config object and cache some feature flags here ++ reactNativeConfig_ = config; ++ ++ CoreFeatures::enablePropIteratorSetter = ++ getFeatureFlagValue("enableCppPropsIteratorSetter"); ++ CoreFeatures::excludeYogaFromRawProps = ++ getFeatureFlagValue("excludeYogaFromRawProps"); ++ ++ // RemoveDelete mega-op ++ ShadowViewMutation::PlatformSupportsRemoveDeleteTreeInstruction = ++ getFeatureFlagValue("enableRemoveDeleteTreeInstruction"); ++ ++ auto toolbox = SchedulerToolbox{}; ++ toolbox.contextContainer = contextContainer; ++ toolbox.componentRegistryFactory = componentsRegistry->buildRegistryFunction; ++ ++ // TODO: (T132338609) runtimeExecutor should execute lambdas after ++ // main bundle eval, and bindingsInstallExecutor should execute before. ++ toolbox.bridgelessBindingsExecutor = std::nullopt; ++ toolbox.runtimeExecutor = runtimeExecutor; ++ ++ toolbox.asynchronousEventBeatFactory = asynchronousBeatFactory; ++ ++ if (ReactNativeFeatureFlags::enableBackgroundExecutor()) { ++ backgroundExecutor_ = JBackgroundExecutor::create("fabric_bg"); ++ toolbox.backgroundExecutor = backgroundExecutor_; ++ } ++ ++ animationDriver_ = std::make_shared( ++ runtimeExecutor, contextContainer, this); ++ scheduler_ = ++ std::make_shared(toolbox, animationDriver_.get(), this); ++} ++ ++void Binding::uninstallFabricUIManager() { ++ if (enableFabricLogs_) { ++ LOG(WARNING) << "Binding::uninstallFabricUIManager() was called (address: " ++ << this << ")."; ++ } ++ ++ std::unique_lock lock(installMutex_); ++ animationDriver_ = nullptr; ++ scheduler_ = nullptr; ++ mountingManager_ = nullptr; ++ reactNativeConfig_ = nullptr; ++} ++ ++std::shared_ptr Binding::getMountingManager( ++ const char* locationHint) { ++ std::shared_lock lock(installMutex_); ++ if (!mountingManager_) { ++ LOG(ERROR) << "FabricMountingManager::" << locationHint ++ << " mounting manager disappeared"; ++ } ++ // Need to return a copy of the shared_ptr to make sure this is safe if called ++ // concurrently with uninstallFabricUIManager ++ return mountingManager_; ++} ++ ++void Binding::schedulerDidFinishTransaction( ++ const MountingCoordinator::Shared& mountingCoordinator) { ++ auto mountingTransaction = mountingCoordinator->pullTransaction(); ++ if (!mountingTransaction.has_value()) { ++ return; ++ } ++ ++ std::unique_lock lock(pendingTransactionsMutex_); ++ auto pendingTransaction = std::find_if( ++ pendingTransactions_.begin(), ++ pendingTransactions_.end(), ++ [&](const auto& transaction) { ++ return transaction.getSurfaceId() == ++ mountingTransaction->getSurfaceId(); ++ }); ++ ++ if (pendingTransaction != pendingTransactions_.end()) { ++ pendingTransaction->mergeWith(std::move(*mountingTransaction)); ++ } else { ++ pendingTransactions_.push_back(std::move(*mountingTransaction)); ++ } ++} ++ ++void Binding::schedulerShouldRenderTransactions( ++ const MountingCoordinator::Shared& mountingCoordinator) { ++ auto mountingManager = ++ getMountingManager("schedulerShouldRenderTransactions"); ++ if (!mountingManager) { ++ return; ++ } ++ ++ if (ReactNativeFeatureFlags:: ++ allowRecursiveCommitsWithSynchronousMountOnAndroid()) { ++ std::vector pendingTransactions; ++ ++ { ++ // Retain the lock to access the pending transactions but not to execute ++ // the mount operations because that method can call into this method ++ // again. ++ std::unique_lock lock(pendingTransactionsMutex_); ++ pendingTransactions_.swap(pendingTransactions); ++ } ++ ++ for (auto& transaction : pendingTransactions) { ++ mountingManager->executeMount(transaction); ++ } ++ } else { ++ std::unique_lock lock(pendingTransactionsMutex_); ++ for (auto& transaction : pendingTransactions_) { ++ mountingManager->executeMount(transaction); ++ } ++ pendingTransactions_.clear(); ++ } ++} ++ ++void Binding::schedulerDidRequestPreliminaryViewAllocation( ++ const ShadowNode& shadowNode) { ++ if (!shadowNode.getTraits().check(ShadowNodeTraits::Trait::FormsView)) { ++ return; ++ } ++ ++ auto mountingManager = getMountingManager("preallocateView"); ++ if (!mountingManager) { ++ return; ++ } ++ mountingManager->preallocateShadowView(shadowNode); ++} ++ ++void Binding::schedulerDidDispatchCommand( ++ const ShadowView& shadowView, ++ const std::string& commandName, ++ const folly::dynamic& args) { ++ auto mountingManager = getMountingManager("schedulerDidDispatchCommand"); ++ if (!mountingManager) { ++ return; ++ } ++ mountingManager->dispatchCommand(shadowView, commandName, args); ++} ++ ++void Binding::schedulerDidSendAccessibilityEvent( ++ const ShadowView& shadowView, ++ const std::string& eventType) { ++ auto mountingManager = ++ getMountingManager("schedulerDidSendAccessibilityEvent"); ++ if (!mountingManager) { ++ return; ++ } ++ mountingManager->sendAccessibilityEvent(shadowView, eventType); ++} ++ ++void Binding::schedulerDidSetIsJSResponder( ++ const ShadowView& shadowView, ++ bool isJSResponder, ++ bool blockNativeResponder) { ++ auto mountingManager = getMountingManager("schedulerDidSetIsJSResponder"); ++ if (!mountingManager) { ++ return; ++ } ++ mountingManager->setIsJSResponder( ++ shadowView, isJSResponder, blockNativeResponder); ++} ++ ++void Binding::onAnimationStarted() { ++ auto mountingManager = getMountingManager("onAnimationStarted"); ++ if (!mountingManager) { ++ return; ++ } ++ mountingManager->onAnimationStarted(); ++} ++ ++void Binding::onAllAnimationsComplete() { ++ auto mountingManager = getMountingManager("onAnimationComplete"); ++ if (!mountingManager) { ++ return; ++ } ++ mountingManager->onAllAnimationsComplete(); ++} ++ ++void Binding::registerNatives() { ++ registerHybrid({ ++ makeNativeMethod("initHybrid", Binding::initHybrid), ++ makeNativeMethod( ++ "installFabricUIManager", Binding::installFabricUIManager), ++ makeNativeMethod("startSurface", Binding::startSurface), ++ makeNativeMethod( ++ "getInspectorDataForInstance", Binding::getInspectorDataForInstance), ++ makeNativeMethod( ++ "startSurfaceWithConstraints", Binding::startSurfaceWithConstraints), ++ makeNativeMethod("stopSurface", Binding::stopSurface), ++ makeNativeMethod("setConstraints", Binding::setConstraints), ++ makeNativeMethod("setPixelDensity", Binding::setPixelDensity), ++ makeNativeMethod("driveCxxAnimations", Binding::driveCxxAnimations), ++ makeNativeMethod("reportMount", Binding::reportMount), ++ makeNativeMethod( ++ "uninstallFabricUIManager", Binding::uninstallFabricUIManager), ++ makeNativeMethod("registerSurface", Binding::registerSurface), ++ makeNativeMethod("unregisterSurface", Binding::unregisterSurface), ++ }); ++} ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/Binding.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/Binding.h +new file mode 100644 +index 0000000..fd3bb8a +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/Binding.h +@@ -0,0 +1,162 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "EventEmitterWrapper.h" ++#include "JFabricUIManager.h" ++ ++namespace facebook::react { ++ ++class ComponentFactory; ++class EventBeatManager; ++class FabricMountingManager; ++class Instance; ++class LayoutAnimationDriver; ++class ReactNativeConfig; ++class Scheduler; ++class SurfaceHandlerBinding; ++ ++struct JBinding : public jni::JavaClass { ++ constexpr static auto kJavaDescriptor = "Lcom/facebook/react/fabric/Binding;"; ++}; ++ ++class Binding : public jni::HybridClass, ++ public SchedulerDelegate, ++ public LayoutAnimationStatusDelegate { ++ public: ++ constexpr static const char* const kJavaDescriptor = ++ "Lcom/facebook/react/fabric/BindingImpl;"; ++ ++ static void registerNatives(); ++ ++ std::shared_ptr getScheduler(); ++ ++ private: ++ void setConstraints( ++ jint surfaceId, ++ jfloat minWidth, ++ jfloat maxWidth, ++ jfloat minHeight, ++ jfloat maxHeight, ++ jfloat offsetX, ++ jfloat offsetY, ++ jboolean isRTL, ++ jboolean doLeftAndRightSwapInRTL); ++ ++ jni::local_ref getInspectorDataForInstance( ++ jni::alias_ref eventEmitterWrapper); ++ ++ static jni::local_ref initHybrid(jni::alias_ref); ++ ++ void installFabricUIManager( ++ jni::alias_ref runtimeExecutorHolder, ++ jni::alias_ref runtimeSchedulerHolder, ++ jni::alias_ref javaUIManager, ++ EventBeatManager* eventBeatManager, ++ ComponentFactory* componentsRegistry, ++ jni::alias_ref reactNativeConfig); ++ ++ void startSurface( ++ jint surfaceId, ++ jni::alias_ref moduleName, ++ NativeMap* initialProps); ++ ++ void startSurfaceWithConstraints( ++ jint surfaceId, ++ jni::alias_ref moduleName, ++ NativeMap* initialProps, ++ jfloat minWidth, ++ jfloat maxWidth, ++ jfloat minHeight, ++ jfloat maxHeight, ++ jfloat offsetX, ++ jfloat offsetY, ++ jboolean isRTL, ++ jboolean doLeftAndRightSwapInRTL); ++ ++ void stopSurface(jint surfaceId); ++ ++ void registerSurface(SurfaceHandlerBinding* surfaceHandler); ++ ++ void unregisterSurface(SurfaceHandlerBinding* surfaceHandler); ++ ++ void schedulerDidFinishTransaction( ++ const MountingCoordinator::Shared& mountingCoordinator) override; ++ ++ void schedulerShouldRenderTransactions( ++ const MountingCoordinator::Shared& mountingCoordinator) override; ++ ++ void schedulerDidRequestPreliminaryViewAllocation( ++ const ShadowNode& shadowNode) override; ++ ++ void schedulerDidDispatchCommand( ++ const ShadowView& shadowView, ++ const std::string& commandName, ++ const folly::dynamic& args) override; ++ ++ void schedulerDidSendAccessibilityEvent( ++ const ShadowView& shadowView, ++ const std::string& eventType) override; ++ ++ void schedulerDidSetIsJSResponder( ++ const ShadowView& shadowView, ++ bool isJSResponder, ++ bool blockNativeResponder) override; ++ ++ void setPixelDensity(float pointScaleFactor); ++ ++ void driveCxxAnimations(); ++ void reportMount(SurfaceId surfaceId); ++ ++ void uninstallFabricUIManager(); ++ ++ // Private member variables ++ std::shared_mutex installMutex_; ++ std::shared_ptr mountingManager_; ++ std::shared_ptr scheduler_; ++ ++ std::shared_ptr getMountingManager( ++ const char* locationHint); ++ ++ // LayoutAnimations ++ void onAnimationStarted() override; ++ void onAllAnimationsComplete() override; ++ ++ std::shared_ptr animationDriver_; ++ ++ BackgroundExecutor backgroundExecutor_; ++ ++ std::unordered_map surfaceHandlerRegistry_{}; ++ std::shared_mutex ++ surfaceHandlerRegistryMutex_; // Protects `surfaceHandlerRegistry_`. ++ ++ // Track pending transactions, one per surfaceId ++ std::mutex pendingTransactionsMutex_; ++ std::vector pendingTransactions_; ++ ++ float pointScaleFactor_ = 1; ++ ++ std::shared_ptr reactNativeConfig_{nullptr}; ++ bool enableFabricLogs_{false}; ++}; ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/CMakeLists.txt b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/CMakeLists.txt +new file mode 100644 +index 0000000..38dfe03 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/CMakeLists.txt +@@ -0,0 +1,68 @@ ++# 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. ++ ++cmake_minimum_required(VERSION 3.13) ++ ++file(GLOB fabricjni_SRCS CONFIGURE_DEPENDS *.cpp) ++ ++add_library( ++ fabricjni ++ SHARED ++ ${fabricjni_SRCS} ++) ++ ++target_include_directories(fabricjni PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) ++ ++target_link_libraries( ++ fabricjni ++ fb ++ fbjni ++ folly_runtime ++ glog ++ glog_init ++ jsi ++ mapbufferjni ++ react_codegen_rncore ++ react_debug ++ react_featureflags ++ react_render_animations ++ react_render_attributedstring ++ react_render_componentregistry ++ react_render_core ++ react_render_debug ++ react_render_graphics ++ react_render_imagemanager ++ react_render_mapbuffer ++ react_render_mounting ++ react_render_runtimescheduler ++ react_render_scheduler ++ react_render_telemetry ++ react_render_textlayoutmanager ++ react_render_uimanager ++ react_utils ++ react_config ++ reactnativejni ++ rrc_image ++ rrc_modal ++ rrc_progressbar ++ rrc_root ++ rrc_scrollview ++ rrc_switch ++ rrc_text ++ rrc_textinput ++ rrc_unimplementedview ++ rrc_view ++ yoga ++) ++ ++target_compile_options( ++ fabricjni ++ PRIVATE ++ -DLOG_TAG=\"Fabric\" ++ -fexceptions ++ -frtti ++ -std=c++20 ++ -Wall ++) +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/ComponentFactory.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/ComponentFactory.cpp +new file mode 100644 +index 0000000..e7ecc79 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/ComponentFactory.cpp +@@ -0,0 +1,29 @@ ++/* ++ * 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. ++ */ ++ ++#include "ComponentFactory.h" ++#include ++#include ++#include ++#include ++ ++using namespace facebook::jsi; ++ ++namespace facebook::react { ++ ++jni::local_ref ComponentFactory::initHybrid( ++ jni::alias_ref) { ++ return makeCxxInstance(); ++} ++ ++void ComponentFactory::registerNatives() { ++ registerHybrid({ ++ makeNativeMethod("initHybrid", ComponentFactory::initHybrid), ++ }); ++} ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/ComponentFactory.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/ComponentFactory.h +new file mode 100644 +index 0000000..5aa76a1 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/ComponentFactory.h +@@ -0,0 +1,31 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++#include ++#include ++ ++namespace facebook::react { ++ ++class Instance; ++ ++class ComponentFactory : public jni::HybridClass { ++ public: ++ constexpr static const char* const kJavaDescriptor = ++ "Lcom/facebook/react/fabric/ComponentFactory;"; ++ ++ static void registerNatives(); ++ ++ ComponentRegistryFactory buildRegistryFunction; ++ ++ private: ++ static jni::local_ref initHybrid(jni::alias_ref); ++}; ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/CoreComponentsRegistry.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/CoreComponentsRegistry.cpp +new file mode 100644 +index 0000000..fd8e579 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/CoreComponentsRegistry.cpp +@@ -0,0 +1,112 @@ ++/* ++ * 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. ++ */ ++ ++#include "CoreComponentsRegistry.h" ++ ++#include ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++namespace facebook::react { ++ ++CoreComponentsRegistry::CoreComponentsRegistry(ComponentFactory* delegate) ++ : delegate_(delegate) {} ++ ++std::shared_ptr ++CoreComponentsRegistry::sharedProviderRegistry() { ++ static auto providerRegistry = ++ []() -> std::shared_ptr { ++ auto providerRegistry = ++ std::make_shared(); ++ ++ providerRegistry->add(concreteComponentDescriptorProvider< ++ AndroidProgressBarComponentDescriptor>()); ++ providerRegistry->add(concreteComponentDescriptorProvider< ++ AndroidSwipeRefreshLayoutComponentDescriptor>()); ++ providerRegistry->add(concreteComponentDescriptorProvider< ++ ActivityIndicatorViewComponentDescriptor>()); ++ providerRegistry->add(concreteComponentDescriptorProvider< ++ AndroidTextInputComponentDescriptor>()); ++ providerRegistry->add( ++ concreteComponentDescriptorProvider()); ++ providerRegistry->add( ++ concreteComponentDescriptorProvider()); ++ providerRegistry->add(concreteComponentDescriptorProvider< ++ ModalHostViewComponentDescriptor>()); ++ providerRegistry->add(concreteComponentDescriptorProvider< ++ AndroidSwitchComponentDescriptor>()); ++ providerRegistry->add( ++ concreteComponentDescriptorProvider()); ++ providerRegistry->add( ++ concreteComponentDescriptorProvider()); ++ providerRegistry->add( ++ concreteComponentDescriptorProvider()); ++ providerRegistry->add( ++ concreteComponentDescriptorProvider< ++ AndroidHorizontalScrollContentViewComponentDescriptor>()); ++ providerRegistry->add( ++ concreteComponentDescriptorProvider()); ++ providerRegistry->add(concreteComponentDescriptorProvider< ++ AndroidDrawerLayoutComponentDescriptor>()); ++ providerRegistry->add(concreteComponentDescriptorProvider< ++ DebuggingOverlayComponentDescriptor>()); ++ ++ return providerRegistry; ++ }(); ++ ++ return providerRegistry; ++} ++ ++jni::local_ref ++CoreComponentsRegistry::initHybrid( ++ jni::alias_ref, ++ ComponentFactory* delegate) { ++ auto instance = makeCxxInstance(delegate); ++ ++ // TODO T69453179: Codegen this file ++ auto buildRegistryFunction = ++ [](const EventDispatcher::Weak& eventDispatcher, ++ const ContextContainer::Shared& contextContainer) ++ -> ComponentDescriptorRegistry::Shared { ++ ComponentDescriptorParameters params{ ++ .eventDispatcher = eventDispatcher, ++ .contextContainer = contextContainer, ++ .flavor = nullptr}; ++ ++ auto registry = CoreComponentsRegistry::sharedProviderRegistry() ++ ->createComponentDescriptorRegistry(params); ++ auto& mutableRegistry = const_cast(*registry); ++ mutableRegistry.setFallbackComponentDescriptor( ++ std::make_shared(params)); ++ ++ return registry; ++ }; ++ ++ delegate->buildRegistryFunction = buildRegistryFunction; ++ return instance; ++} ++ ++void CoreComponentsRegistry::registerNatives() { ++ registerHybrid({ ++ makeNativeMethod("initHybrid", CoreComponentsRegistry::initHybrid), ++ }); ++} ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/CoreComponentsRegistry.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/CoreComponentsRegistry.h +new file mode 100644 +index 0000000..1f6b147 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/CoreComponentsRegistry.h +@@ -0,0 +1,40 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++#include ++#include ++#include "ComponentFactory.h" ++ ++namespace facebook::react { ++ ++class CoreComponentsRegistry ++ : public facebook::jni::HybridClass { ++ public: ++ constexpr static auto kJavaDescriptor = ++ "Lcom/facebook/react/fabric/CoreComponentsRegistry;"; ++ ++ static void registerNatives(); ++ ++ explicit CoreComponentsRegistry(ComponentFactory* delegate); ++ ++ static std::shared_ptr ++ sharedProviderRegistry(); ++ ++ private: ++ friend HybridBase; ++ ++ const ComponentFactory* delegate_; ++ ++ static jni::local_ref initHybrid( ++ jni::alias_ref, ++ ComponentFactory* delegate); ++}; ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/EventBeatManager.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/EventBeatManager.cpp +new file mode 100644 +index 0000000..04deb94 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/EventBeatManager.cpp +@@ -0,0 +1,50 @@ ++/* ++ * 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. ++ */ ++ ++#include "EventBeatManager.h" ++#include ++using namespace facebook::jni; ++ ++namespace facebook::react { ++ ++EventBeatManager::EventBeatManager( ++ jni::alias_ref jhybridobject) ++ : jhybridobject_(jhybridobject) {} ++ ++jni::local_ref EventBeatManager::initHybrid( ++ jni::alias_ref jhybridobject) { ++ return makeCxxInstance(jhybridobject); ++} ++ ++void EventBeatManager::addObserver( ++ const EventBeatManagerObserver& observer) const { ++ std::scoped_lock lock(mutex_); ++ observers_.insert(&observer); ++} ++ ++void EventBeatManager::removeObserver( ++ const EventBeatManagerObserver& observer) const { ++ std::scoped_lock lock(mutex_); ++ observers_.erase(&observer); ++} ++ ++void EventBeatManager::tick() { ++ std::scoped_lock lock(mutex_); ++ ++ for (auto observer : observers_) { ++ observer->tick(); ++ } ++} ++ ++void EventBeatManager::registerNatives() { ++ registerHybrid({ ++ makeNativeMethod("initHybrid", EventBeatManager::initHybrid), ++ makeNativeMethod("tick", EventBeatManager::tick), ++ }); ++} ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/EventBeatManager.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/EventBeatManager.h +new file mode 100644 +index 0000000..6abb69f +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/EventBeatManager.h +@@ -0,0 +1,65 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++#include ++ ++#include ++#include ++#include ++ ++namespace facebook::react { ++ ++class EventBeatManagerObserver { ++ public: ++ /* ++ * Called by `EventBeatManager` on the main thread signaling that this is a ++ * good time to flush an event queue. ++ */ ++ virtual void tick() const = 0; ++ ++ virtual ~EventBeatManagerObserver() noexcept = default; ++}; ++ ++class EventBeatManager : public jni::HybridClass { ++ public: ++ constexpr static const char* const kJavaDescriptor = ++ "Lcom/facebook/react/fabric/events/EventBeatManager;"; ++ ++ static void registerNatives(); ++ ++ explicit EventBeatManager( ++ jni::alias_ref jhybridobject); ++ ++ /* ++ * Adds (or removes) observers. ++ * `EventBeatManager` does not own/retain observers; observers must overlive ++ * the manager or be properly removed before deallocation. ++ */ ++ void addObserver(const EventBeatManagerObserver& observer) const; ++ void removeObserver(const EventBeatManagerObserver& observer) const; ++ ++ private: ++ /* ++ * Called by Java counterpart at the end of every run loop tick. ++ */ ++ void tick(); ++ ++ jni::alias_ref jhybridobject_; ++ ++ mutable std::unordered_set ++ observers_{}; // Protected by `mutex_` ++ ++ mutable std::mutex mutex_; ++ ++ static jni::local_ref initHybrid( ++ jni::alias_ref jhybridobject); ++}; ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/EventEmitterWrapper.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/EventEmitterWrapper.cpp +new file mode 100644 +index 0000000..3fc99cd +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/EventEmitterWrapper.cpp +@@ -0,0 +1,69 @@ ++/* ++ * 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. ++ */ ++ ++#include "EventEmitterWrapper.h" ++#include ++ ++using namespace facebook::jni; ++ ++namespace facebook::react { ++ ++void EventEmitterWrapper::dispatchEvent( ++ std::string eventName, ++ NativeMap* payload, ++ int category) { ++ // It is marginal, but possible for this to be constructed without a valid ++ // EventEmitter. In those cases, make sure we noop/blackhole events instead of ++ // crashing. ++ if (eventEmitter != nullptr) { ++ eventEmitter->dispatchEvent( ++ eventName, ++ payload ? payload->consume() : folly::dynamic::object(), ++ static_cast(category)); ++ } ++} ++ ++void EventEmitterWrapper::dispatchEventSynchronously( ++ std::string eventName, ++ NativeMap* params) { ++ // It is marginal, but possible for this to be constructed without a valid ++ // EventEmitter. In those cases, make sure we noop/blackhole events instead of ++ // crashing. ++ if (eventEmitter != nullptr) { ++ eventEmitter->experimental_flushSync([&]() { ++ eventEmitter->dispatchEvent( ++ std::move(eventName), ++ (params != nullptr) ? params->consume() : folly::dynamic::object(), ++ RawEvent::Category::Discrete); ++ }); ++ } ++} ++ ++void EventEmitterWrapper::dispatchUniqueEvent( ++ std::string eventName, ++ NativeMap* payload) { ++ // It is marginal, but possible for this to be constructed without a valid ++ // EventEmitter. In those cases, make sure we noop/blackhole events instead of ++ // crashing. ++ if (eventEmitter != nullptr) { ++ eventEmitter->dispatchUniqueEvent( ++ eventName, payload ? payload->consume() : folly::dynamic::object()); ++ } ++} ++ ++void EventEmitterWrapper::registerNatives() { ++ registerHybrid({ ++ makeNativeMethod("dispatchEvent", EventEmitterWrapper::dispatchEvent), ++ makeNativeMethod( ++ "dispatchUniqueEvent", EventEmitterWrapper::dispatchUniqueEvent), ++ makeNativeMethod( ++ "dispatchEventSynchronously", ++ EventEmitterWrapper::dispatchEventSynchronously), ++ }); ++} ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/EventEmitterWrapper.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/EventEmitterWrapper.h +new file mode 100644 +index 0000000..2bc6cc4 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/EventEmitterWrapper.h +@@ -0,0 +1,35 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++#include ++#include ++ ++namespace facebook::react { ++ ++class Instance; ++ ++class EventEmitterWrapper : public jni::HybridClass { ++ public: ++ constexpr static const char* const kJavaDescriptor = ++ "Lcom/facebook/react/fabric/events/EventEmitterWrapper;"; ++ ++ static void registerNatives(); ++ ++ EventEmitterWrapper(SharedEventEmitter eventEmitter) ++ : eventEmitter(std::move(eventEmitter)){}; ++ ++ SharedEventEmitter eventEmitter; ++ ++ void dispatchEvent(std::string eventName, NativeMap* params, int category); ++ void dispatchEventSynchronously(std::string eventName, NativeMap* params); ++ void dispatchUniqueEvent(std::string eventName, NativeMap* params); ++}; ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/FabricMountingManager.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/FabricMountingManager.cpp +new file mode 100644 +index 0000000..ca19376 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/FabricMountingManager.cpp +@@ -0,0 +1,916 @@ ++/* ++ * 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. ++ */ ++ ++#include "FabricMountingManager.h" ++ ++#include "EventEmitterWrapper.h" ++#include "MountItem.h" ++#include "StateWrapperImpl.h" ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++namespace facebook::react { ++ ++FabricMountingManager::FabricMountingManager( ++ std::shared_ptr& config, ++ jni::global_ref& javaUIManager) ++ : javaUIManager_(javaUIManager) {} ++ ++void FabricMountingManager::onSurfaceStart(SurfaceId surfaceId) { ++ std::lock_guard lock(allocatedViewsMutex_); ++ allocatedViewRegistry_.emplace(surfaceId, std::unordered_set{}); ++} ++ ++void FabricMountingManager::onSurfaceStop(SurfaceId surfaceId) { ++ std::lock_guard lock(allocatedViewsMutex_); ++ allocatedViewRegistry_.erase(surfaceId); ++} ++ ++static inline int getIntBufferSizeForType(CppMountItem::Type mountItemType) { ++ switch (mountItemType) { ++ case CppMountItem::Type::Create: ++ return 2; // tag, isLayoutable ++ case CppMountItem::Type::Insert: ++ case CppMountItem::Type::Remove: ++ return 3; // tag, parentTag, index ++ case CppMountItem::Type::RemoveDeleteTree: ++ return 3; // tag, parentTag, index ++ case CppMountItem::Type::Delete: ++ case CppMountItem::Type::UpdateProps: ++ case CppMountItem::Type::UpdateState: ++ case CppMountItem::Type::UpdateEventEmitter: ++ return 1; // tag ++ case CppMountItem::Type::UpdatePadding: ++ return 5; // tag, top, left, bottom, right ++ case CppMountItem::Type::UpdateLayout: ++ return ReactNativeFeatureFlags::setAndroidLayoutDirection() ++ ? 8 // tag, parentTag, x, y, w, h, DisplayType, LayoutDirection ++ : 7; // tag, parentTag, x, y, w, h, DisplayType ++ case CppMountItem::Type::UpdateOverflowInset: ++ return 5; // tag, left, top, right, bottom ++ case CppMountItem::Undefined: ++ case CppMountItem::Multiple: ++ return -1; ++ } ++} ++ ++static inline void updateBufferSizes( ++ CppMountItem::Type mountItemType, ++ size_t numInstructions, ++ int& batchMountItemIntsSize, ++ int& batchMountItemObjectsSize) { ++ if (numInstructions == 0) { ++ return; ++ } ++ ++ batchMountItemIntsSize += ++ numInstructions == 1 ? 1 : 2; // instructionType[, numInstructions] ++ batchMountItemIntsSize += ++ numInstructions * getIntBufferSizeForType(mountItemType); ++ ++ if (mountItemType == CppMountItem::Type::UpdateProps) { ++ batchMountItemObjectsSize += ++ numInstructions; // props object * numInstructions ++ } else if (mountItemType == CppMountItem::Type::UpdateState) { ++ batchMountItemObjectsSize += ++ numInstructions; // state object * numInstructions ++ } else if (mountItemType == CppMountItem::Type::UpdateEventEmitter) { ++ batchMountItemObjectsSize += ++ numInstructions; // EventEmitter object * numInstructions ++ } ++} ++ ++static inline void computeBufferSizes( ++ int& batchMountItemIntsSize, ++ int& batchMountItemObjectsSize, ++ std::vector& cppCommonMountItems, ++ std::vector& cppDeleteMountItems, ++ std::vector& cppUpdatePropsMountItems, ++ std::vector& cppUpdateStateMountItems, ++ std::vector& cppUpdatePaddingMountItems, ++ std::vector& cppUpdateLayoutMountItems, ++ std::vector& cppUpdateOverflowInsetMountItems, ++ std::vector& cppUpdateEventEmitterMountItems) { ++ CppMountItem::Type lastType = CppMountItem::Type::Undefined; ++ int numSameType = 0; ++ for (const auto& mountItem : cppCommonMountItems) { ++ const auto& mountItemType = mountItem.type; ++ ++ if (lastType == mountItemType) { ++ numSameType++; ++ if (numSameType == 2) { ++ batchMountItemIntsSize += 1; // numInstructions ++ } ++ } else { ++ numSameType = 1; ++ lastType = mountItemType; ++ batchMountItemIntsSize += 1; // instructionType ++ } ++ ++ batchMountItemIntsSize += getIntBufferSizeForType(mountItemType); ++ if (mountItemType == CppMountItem::Type::Create) { ++ batchMountItemObjectsSize += ++ 4; // component name, props, state, event emitter ++ } ++ } ++ ++ updateBufferSizes( ++ CppMountItem::Type::UpdateProps, ++ cppUpdatePropsMountItems.size(), ++ batchMountItemIntsSize, ++ batchMountItemObjectsSize); ++ updateBufferSizes( ++ CppMountItem::Type::UpdateState, ++ cppUpdateStateMountItems.size(), ++ batchMountItemIntsSize, ++ batchMountItemObjectsSize); ++ updateBufferSizes( ++ CppMountItem::Type::UpdatePadding, ++ cppUpdatePaddingMountItems.size(), ++ batchMountItemIntsSize, ++ batchMountItemObjectsSize); ++ updateBufferSizes( ++ CppMountItem::Type::UpdateLayout, ++ cppUpdateLayoutMountItems.size(), ++ batchMountItemIntsSize, ++ batchMountItemObjectsSize); ++ updateBufferSizes( ++ CppMountItem::Type::UpdateOverflowInset, ++ cppUpdateOverflowInsetMountItems.size(), ++ batchMountItemIntsSize, ++ batchMountItemObjectsSize); ++ updateBufferSizes( ++ CppMountItem::Type::UpdateEventEmitter, ++ cppUpdateEventEmitterMountItems.size(), ++ batchMountItemIntsSize, ++ batchMountItemObjectsSize); ++ updateBufferSizes( ++ CppMountItem::Type::Delete, ++ cppDeleteMountItems.size(), ++ batchMountItemIntsSize, ++ batchMountItemObjectsSize); ++} ++ ++static inline void writeIntBufferTypePreamble( ++ int mountItemType, ++ size_t numItems, ++ _JNIEnv* env, ++ jintArray& intBufferArray, ++ int& intBufferPosition) { ++ jint temp[2]; ++ if (numItems == 1) { ++ temp[0] = mountItemType; ++ env->SetIntArrayRegion(intBufferArray, intBufferPosition, 1, temp); ++ intBufferPosition += 1; ++ } else { ++ temp[0] = mountItemType | CppMountItem::Type::Multiple; ++ temp[1] = static_cast(numItems); ++ env->SetIntArrayRegion(intBufferArray, intBufferPosition, 2, temp); ++ intBufferPosition += 2; ++ } ++} ++ ++// TODO: this method will be removed when binding for components are code-gen ++jni::local_ref getPlatformComponentName(const ShadowView& shadowView) { ++ static std::string scrollViewComponentName = std::string("ScrollView"); ++ if (scrollViewComponentName == shadowView.componentName) { ++ const auto& newViewProps = ++ static_cast(*shadowView.props); ++ if (newViewProps.getProbablyMoreHorizontalThanVertical_DEPRECATED()) { ++ return jni::make_jstring("AndroidHorizontalScrollView"); ++ } ++ } ++ return jni::make_jstring(shadowView.componentName); ++} ++ ++static inline float scale(Float value, Float pointScaleFactor) { ++ std::feclearexcept(FE_ALL_EXCEPT); ++ float result = value * pointScaleFactor; ++ if (std::fetestexcept(FE_OVERFLOW)) { ++ LOG(ERROR) << "Binding::scale - FE_OVERFLOW - value: " << value ++ << " pointScaleFactor: " << pointScaleFactor ++ << " result: " << result; ++ } ++ if (std::fetestexcept(FE_UNDERFLOW)) { ++ LOG(ERROR) << "Binding::scale - FE_UNDERFLOW - value: " << value ++ << " pointScaleFactor: " << pointScaleFactor ++ << " result: " << result; ++ } ++ return result; ++} ++ ++jni::local_ref FabricMountingManager::getProps( ++ const ShadowView& oldShadowView, ++ const ShadowView& newShadowView) { ++ return ReadableNativeMap::newObjectCxxArgs(newShadowView.props->rawProps); ++} ++ ++void FabricMountingManager::executeMount( ++ const MountingTransaction& transaction) { ++ SystraceSection section("FabricMountingManager::executeMount"); ++ ++ std::scoped_lock lock(commitMutex_); ++ auto finishTransactionStartTime = telemetryTimePointNow(); ++ ++ auto env = jni::Environment::current(); ++ ++ auto telemetry = transaction.getTelemetry(); ++ auto surfaceId = transaction.getSurfaceId(); ++ auto& mutations = transaction.getMutations(); ++ ++ auto revisionNumber = telemetry.getRevisionNumber(); ++ ++ std::vector cppCommonMountItems; ++ std::vector cppDeleteMountItems; ++ std::vector cppUpdatePropsMountItems; ++ std::vector cppUpdateStateMountItems; ++ std::vector cppUpdatePaddingMountItems; ++ std::vector cppUpdateLayoutMountItems; ++ std::vector cppUpdateOverflowInsetMountItems; ++ std::vector cppUpdateEventEmitterMountItems; ++ ++ { ++ std::lock_guard allocatedViewsLock(allocatedViewsMutex_); ++ ++ auto allocatedViewsIterator = allocatedViewRegistry_.find(surfaceId); ++ auto defaultAllocatedViews = std::unordered_set{}; ++ // Do not remove `defaultAllocatedViews` or initialize ++ // `std::unordered_set{}` inline in below ternary expression - if falsy ++ // operand is a value type, the compiler will decide the expression to be a ++ // value type, an unnecessary (sometimes expensive) copy will happen as a ++ // result. ++ const auto& allocatedViewTags = ++ allocatedViewsIterator != allocatedViewRegistry_.end() ++ ? allocatedViewsIterator->second ++ : defaultAllocatedViews; ++ if (allocatedViewsIterator == allocatedViewRegistry_.end()) { ++ LOG(ERROR) << "Executing commit after surface was stopped!"; ++ } ++ ++ for (const auto& mutation : mutations) { ++ const auto& parentShadowView = mutation.parentShadowView; ++ const auto& oldChildShadowView = mutation.oldChildShadowView; ++ const auto& newChildShadowView = mutation.newChildShadowView; ++ auto& mutationType = mutation.type; ++ auto& index = mutation.index; ++ ++ bool isVirtual = mutation.mutatedViewIsVirtual(); ++ switch (mutationType) { ++ case ShadowViewMutation::Create: { ++ bool shouldCreateView = ++ !allocatedViewTags.contains(newChildShadowView.tag); ++ ++ if (shouldCreateView) { ++ cppCommonMountItems.push_back( ++ CppMountItem::CreateMountItem(newChildShadowView)); ++ } ++ break; ++ } ++ case ShadowViewMutation::Remove: { ++ if (!isVirtual && !mutation.isRedundantOperation) { ++ cppCommonMountItems.push_back(CppMountItem::RemoveMountItem( ++ parentShadowView, oldChildShadowView, index)); ++ } ++ break; ++ } ++ case ShadowViewMutation::RemoveDeleteTree: { ++ if (!isVirtual) { ++ cppCommonMountItems.push_back( ++ CppMountItem::RemoveDeleteTreeMountItem( ++ parentShadowView, oldChildShadowView, index)); ++ } ++ break; ++ } ++ case ShadowViewMutation::Delete: { ++ if (!mutation.isRedundantOperation) { ++ cppDeleteMountItems.push_back( ++ CppMountItem::DeleteMountItem(oldChildShadowView)); ++ } ++ break; ++ } ++ case ShadowViewMutation::Update: { ++ if (!isVirtual) { ++ if (oldChildShadowView.props != newChildShadowView.props) { ++ cppUpdatePropsMountItems.push_back( ++ CppMountItem::UpdatePropsMountItem( ++ oldChildShadowView, newChildShadowView)); ++ } ++ if (oldChildShadowView.state != newChildShadowView.state) { ++ cppUpdateStateMountItems.push_back( ++ CppMountItem::UpdateStateMountItem(newChildShadowView)); ++ } ++ ++ // Padding: padding mountItems must be executed before layout props ++ // are updated in the view. This is necessary to ensure that events ++ // (resulting from layout changes) are dispatched with the correct ++ // padding information. ++ if (oldChildShadowView.layoutMetrics.contentInsets != ++ newChildShadowView.layoutMetrics.contentInsets) { ++ cppUpdatePaddingMountItems.push_back( ++ CppMountItem::UpdatePaddingMountItem(newChildShadowView)); ++ } ++ ++ if (oldChildShadowView.layoutMetrics != ++ newChildShadowView.layoutMetrics) { ++ cppUpdateLayoutMountItems.push_back( ++ CppMountItem::UpdateLayoutMountItem( ++ mutation.newChildShadowView, parentShadowView)); ++ } ++ ++ // OverflowInset: This is the values indicating boundaries including ++ // children of the current view. The layout of current view may not ++ // change, and we separate this part from layout mount items to not ++ // pack too much data there. ++ if ((oldChildShadowView.layoutMetrics.overflowInset != ++ newChildShadowView.layoutMetrics.overflowInset)) { ++ cppUpdateOverflowInsetMountItems.push_back( ++ CppMountItem::UpdateOverflowInsetMountItem( ++ newChildShadowView)); ++ } ++ } ++ ++ if (oldChildShadowView.eventEmitter != ++ newChildShadowView.eventEmitter) { ++ cppUpdateEventEmitterMountItems.push_back( ++ CppMountItem::UpdateEventEmitterMountItem( ++ mutation.newChildShadowView)); ++ } ++ break; ++ } ++ case ShadowViewMutation::Insert: { ++ if (!isVirtual) { ++ // Insert item ++ cppCommonMountItems.push_back(CppMountItem::InsertMountItem( ++ parentShadowView, newChildShadowView, index)); ++ ++ bool allocationCheck = ++ allocatedViewTags.find(newChildShadowView.tag) == ++ allocatedViewTags.end(); ++ bool shouldCreateView = allocationCheck; ++ if (shouldCreateView) { ++ cppUpdatePropsMountItems.push_back( ++ CppMountItem::UpdatePropsMountItem({}, newChildShadowView)); ++ } ++ ++ // State ++ if (newChildShadowView.state) { ++ cppUpdateStateMountItems.push_back( ++ CppMountItem::UpdateStateMountItem(newChildShadowView)); ++ } ++ ++ // Padding: padding mountItems must be executed before layout props ++ // are updated in the view. This is necessary to ensure that events ++ // (resulting from layout changes) are dispatched with the correct ++ // padding information. ++ if (newChildShadowView.layoutMetrics.contentInsets != ++ EdgeInsets::ZERO) { ++ cppUpdatePaddingMountItems.push_back( ++ CppMountItem::UpdatePaddingMountItem(newChildShadowView)); ++ } ++ ++ // Layout ++ cppUpdateLayoutMountItems.push_back( ++ CppMountItem::UpdateLayoutMountItem( ++ newChildShadowView, parentShadowView)); ++ ++ // OverflowInset: This is the values indicating boundaries including ++ // children of the current view. The layout of current view may not ++ // change, and we separate this part from layout mount items to not ++ // pack too much data there. ++ if (newChildShadowView.layoutMetrics.overflowInset != ++ EdgeInsets::ZERO) { ++ cppUpdateOverflowInsetMountItems.push_back( ++ CppMountItem::UpdateOverflowInsetMountItem( ++ newChildShadowView)); ++ } ++ } ++ ++ // EventEmitter ++ cppUpdateEventEmitterMountItems.push_back( ++ CppMountItem::UpdateEventEmitterMountItem( ++ mutation.newChildShadowView)); ++ ++ break; ++ } ++ default: { ++ break; ++ } ++ } ++ } ++ ++ if (allocatedViewsIterator != allocatedViewRegistry_.end()) { ++ auto& views = allocatedViewsIterator->second; ++ for (const auto& mutation : mutations) { ++ switch (mutation.type) { ++ case ShadowViewMutation::Create: ++ views.insert(mutation.newChildShadowView.tag); ++ break; ++ case ShadowViewMutation::Delete: ++ views.erase(mutation.oldChildShadowView.tag); ++ break; ++ default: ++ break; ++ } ++ } ++ } ++ } ++ ++ // We now have all the information we need, including ordering of mount items, ++ // to know exactly how much space must be allocated ++ int batchMountItemIntsSize = 0; ++ int batchMountItemObjectsSize = 0; ++ computeBufferSizes( ++ batchMountItemIntsSize, ++ batchMountItemObjectsSize, ++ cppCommonMountItems, ++ cppDeleteMountItems, ++ cppUpdatePropsMountItems, ++ cppUpdateStateMountItems, ++ cppUpdatePaddingMountItems, ++ cppUpdateLayoutMountItems, ++ cppUpdateOverflowInsetMountItems, ++ cppUpdateEventEmitterMountItems); ++ ++ static auto createMountItemsIntBufferBatchContainer = ++ JFabricUIManager::javaClassStatic() ++ ->getMethod( ++ jint, jintArray, jni::jtypeArray, jint)>( ++ "createIntBufferBatchMountItem"); ++ ++ static auto scheduleMountItem = JFabricUIManager::javaClassStatic() ++ ->getMethod("scheduleMountItem"); ++ ++ if (batchMountItemIntsSize == 0) { ++ auto finishTransactionEndTime = telemetryTimePointNow(); ++ ++ scheduleMountItem( ++ javaUIManager_, ++ nullptr, ++ telemetry.getRevisionNumber(), ++ telemetryTimePointToMilliseconds(telemetry.getCommitStartTime()), ++ telemetryTimePointToMilliseconds(telemetry.getDiffStartTime()), ++ telemetryTimePointToMilliseconds(telemetry.getDiffEndTime()), ++ telemetryTimePointToMilliseconds(telemetry.getLayoutStartTime()), ++ telemetryTimePointToMilliseconds(telemetry.getLayoutEndTime()), ++ telemetryTimePointToMilliseconds(finishTransactionStartTime), ++ telemetryTimePointToMilliseconds(finishTransactionEndTime), ++ telemetry.getAffectedLayoutNodesCount()); ++ return; ++ } ++ ++ // Allocate the intBuffer and object array, now that we know exact sizes ++ // necessary ++ jintArray intBufferArray = env->NewIntArray(batchMountItemIntsSize); ++ auto objBufferArray = ++ jni::JArrayClass::newArray(batchMountItemObjectsSize); ++ ++ // Fill in arrays ++ int intBufferPosition = 0; ++ int objBufferPosition = 0; ++ int prevMountItemType = -1; ++ jint temp[8]; ++ for (int i = 0; i < cppCommonMountItems.size(); i++) { ++ const auto& mountItem = cppCommonMountItems[i]; ++ const auto& mountItemType = mountItem.type; ++ ++ // Get type here, and count forward how many items of this type are in a ++ // row. Write preamble to any common type here. ++ if (prevMountItemType != mountItemType) { ++ int numSameItemTypes = 1; ++ for (int j = i + 1; j < cppCommonMountItems.size() && ++ cppCommonMountItems[j].type == mountItemType; ++ j++) { ++ numSameItemTypes++; ++ } ++ ++ writeIntBufferTypePreamble( ++ mountItemType, ++ numSameItemTypes, ++ env, ++ intBufferArray, ++ intBufferPosition); ++ } ++ prevMountItemType = mountItemType; ++ ++ // TODO: multi-create, multi-insert, etc ++ if (mountItemType == CppMountItem::Type::Create) { ++ auto componentName = ++ getPlatformComponentName(mountItem.newChildShadowView); ++ ++ int isLayoutable = ++ mountItem.newChildShadowView.layoutMetrics != EmptyLayoutMetrics ? 1 ++ : 0; ++ jni::local_ref props = ++ getProps(mountItem.oldChildShadowView, mountItem.newChildShadowView); ++ ++ // Do not hold onto Java object from C ++ // We DO want to hold onto C object from Java, since we don't know the ++ // lifetime of the Java object ++ jni::local_ref javaStateWrapper = nullptr; ++ if (mountItem.newChildShadowView.state != nullptr) { ++ javaStateWrapper = StateWrapperImpl::newObjectJavaArgs(); ++ StateWrapperImpl* cStateWrapper = cthis(javaStateWrapper); ++ cStateWrapper->state_ = mountItem.newChildShadowView.state; ++ } ++ ++ // Do not hold a reference to javaEventEmitter from the C++ side. ++ auto javaEventEmitter = EventEmitterWrapper::newObjectCxxArgs( ++ mountItem.newChildShadowView.eventEmitter); ++ temp[0] = mountItem.newChildShadowView.tag; ++ temp[1] = isLayoutable; ++ env->SetIntArrayRegion(intBufferArray, intBufferPosition, 2, temp); ++ intBufferPosition += 2; ++ ++ (*objBufferArray)[objBufferPosition++] = componentName.get(); ++ (*objBufferArray)[objBufferPosition++] = props.get(); ++ (*objBufferArray)[objBufferPosition++] = ++ javaStateWrapper != nullptr ? javaStateWrapper.get() : nullptr; ++ (*objBufferArray)[objBufferPosition++] = javaEventEmitter.get(); ++ } else if (mountItemType == CppMountItem::Type::Insert) { ++ temp[0] = mountItem.newChildShadowView.tag; ++ temp[1] = mountItem.parentShadowView.tag; ++ temp[2] = mountItem.index; ++ env->SetIntArrayRegion(intBufferArray, intBufferPosition, 3, temp); ++ intBufferPosition += 3; ++ } else if (mountItemType == CppMountItem::Remove) { ++ temp[0] = mountItem.oldChildShadowView.tag; ++ temp[1] = mountItem.parentShadowView.tag; ++ temp[2] = mountItem.index; ++ env->SetIntArrayRegion(intBufferArray, intBufferPosition, 3, temp); ++ intBufferPosition += 3; ++ } else if (mountItemType == CppMountItem::RemoveDeleteTree) { ++ temp[0] = mountItem.oldChildShadowView.tag; ++ temp[1] = mountItem.parentShadowView.tag; ++ temp[2] = mountItem.index; ++ env->SetIntArrayRegion(intBufferArray, intBufferPosition, 3, temp); ++ intBufferPosition += 3; ++ } else { ++ LOG(ERROR) << "Unexpected CppMountItem type"; ++ } ++ } ++ if (!cppUpdatePropsMountItems.empty()) { ++ writeIntBufferTypePreamble( ++ CppMountItem::Type::UpdateProps, ++ cppUpdatePropsMountItems.size(), ++ env, ++ intBufferArray, ++ intBufferPosition); ++ ++ for (const auto& mountItem : cppUpdatePropsMountItems) { ++ temp[0] = mountItem.newChildShadowView.tag; ++ env->SetIntArrayRegion(intBufferArray, intBufferPosition, 1, temp); ++ intBufferPosition += 1; ++ (*objBufferArray)[objBufferPosition++] = ++ getProps(mountItem.oldChildShadowView, mountItem.newChildShadowView); ++ } ++ } ++ if (!cppUpdateStateMountItems.empty()) { ++ writeIntBufferTypePreamble( ++ CppMountItem::Type::UpdateState, ++ cppUpdateStateMountItems.size(), ++ env, ++ intBufferArray, ++ intBufferPosition); ++ ++ for (const auto& mountItem : cppUpdateStateMountItems) { ++ temp[0] = mountItem.newChildShadowView.tag; ++ env->SetIntArrayRegion(intBufferArray, intBufferPosition, 1, temp); ++ intBufferPosition += 1; ++ ++ auto state = mountItem.newChildShadowView.state; ++ // Do not hold onto Java object from C ++ // We DO want to hold onto C object from Java, since we don't know the ++ // lifetime of the Java object ++ jni::local_ref javaStateWrapper = nullptr; ++ if (state != nullptr) { ++ javaStateWrapper = StateWrapperImpl::newObjectJavaArgs(); ++ StateWrapperImpl* cStateWrapper = cthis(javaStateWrapper); ++ cStateWrapper->state_ = state; ++ } ++ ++ (*objBufferArray)[objBufferPosition++] = ++ (javaStateWrapper != nullptr ? javaStateWrapper.get() : nullptr); ++ } ++ } ++ if (!cppUpdatePaddingMountItems.empty()) { ++ writeIntBufferTypePreamble( ++ CppMountItem::Type::UpdatePadding, ++ cppUpdatePaddingMountItems.size(), ++ env, ++ intBufferArray, ++ intBufferPosition); ++ ++ for (const auto& mountItem : cppUpdatePaddingMountItems) { ++ auto layoutMetrics = mountItem.newChildShadowView.layoutMetrics; ++ auto pointScaleFactor = layoutMetrics.pointScaleFactor; ++ auto contentInsets = layoutMetrics.contentInsets; ++ ++ int left = floor(scale(contentInsets.left, pointScaleFactor)); ++ int top = floor(scale(contentInsets.top, pointScaleFactor)); ++ int right = floor(scale(contentInsets.right, pointScaleFactor)); ++ int bottom = floor(scale(contentInsets.bottom, pointScaleFactor)); ++ ++ temp[0] = mountItem.newChildShadowView.tag; ++ temp[1] = left; ++ temp[2] = top; ++ temp[3] = right; ++ temp[4] = bottom; ++ env->SetIntArrayRegion(intBufferArray, intBufferPosition, 5, temp); ++ intBufferPosition += 5; ++ } ++ } ++ if (!cppUpdateLayoutMountItems.empty()) { ++ writeIntBufferTypePreamble( ++ CppMountItem::Type::UpdateLayout, ++ cppUpdateLayoutMountItems.size(), ++ env, ++ intBufferArray, ++ intBufferPosition); ++ ++ for (const auto& mountItem : cppUpdateLayoutMountItems) { ++ const auto& layoutMetrics = mountItem.newChildShadowView.layoutMetrics; ++ auto pointScaleFactor = layoutMetrics.pointScaleFactor; ++ auto frame = layoutMetrics.frame; ++ ++ int x = round(scale(frame.origin.x, pointScaleFactor)); ++ int y = round(scale(frame.origin.y, pointScaleFactor)); ++ int w = round(scale(frame.size.width, pointScaleFactor)); ++ int h = round(scale(frame.size.height, pointScaleFactor)); ++ int displayType = toInt(layoutMetrics.displayType); ++ int layoutDirection = toInt(layoutMetrics.layoutDirection); ++ ++ temp[0] = mountItem.newChildShadowView.tag; ++ temp[1] = mountItem.parentShadowView.tag; ++ temp[2] = x; ++ temp[3] = y; ++ temp[4] = w; ++ temp[5] = h; ++ temp[6] = displayType; ++ ++ if (ReactNativeFeatureFlags::setAndroidLayoutDirection()) { ++ temp[7] = layoutDirection; ++ env->SetIntArrayRegion(intBufferArray, intBufferPosition, 8, temp); ++ intBufferPosition += 8; ++ } else { ++ env->SetIntArrayRegion(intBufferArray, intBufferPosition, 7, temp); ++ intBufferPosition += 7; ++ } ++ } ++ } ++ if (!cppUpdateOverflowInsetMountItems.empty()) { ++ writeIntBufferTypePreamble( ++ CppMountItem::Type::UpdateOverflowInset, ++ cppUpdateOverflowInsetMountItems.size(), ++ env, ++ intBufferArray, ++ intBufferPosition); ++ ++ for (const auto& mountItem : cppUpdateOverflowInsetMountItems) { ++ auto layoutMetrics = mountItem.newChildShadowView.layoutMetrics; ++ auto pointScaleFactor = layoutMetrics.pointScaleFactor; ++ auto overflowInset = layoutMetrics.overflowInset; ++ ++ int overflowInsetLeft = ++ round(scale(overflowInset.left, pointScaleFactor)); ++ int overflowInsetTop = round(scale(overflowInset.top, pointScaleFactor)); ++ int overflowInsetRight = ++ round(scale(overflowInset.right, pointScaleFactor)); ++ int overflowInsetBottom = ++ round(scale(overflowInset.bottom, pointScaleFactor)); ++ ++ temp[0] = mountItem.newChildShadowView.tag; ++ temp[1] = overflowInsetLeft; ++ temp[2] = overflowInsetTop; ++ temp[3] = overflowInsetRight; ++ temp[4] = overflowInsetBottom; ++ env->SetIntArrayRegion(intBufferArray, intBufferPosition, 5, temp); ++ intBufferPosition += 5; ++ } ++ } ++ if (!cppUpdateEventEmitterMountItems.empty()) { ++ writeIntBufferTypePreamble( ++ CppMountItem::Type::UpdateEventEmitter, ++ cppUpdateEventEmitterMountItems.size(), ++ env, ++ intBufferArray, ++ intBufferPosition); ++ ++ for (const auto& mountItem : cppUpdateEventEmitterMountItems) { ++ temp[0] = mountItem.newChildShadowView.tag; ++ env->SetIntArrayRegion(intBufferArray, intBufferPosition, 1, temp); ++ intBufferPosition += 1; ++ ++ // Do not hold a reference to javaEventEmitter from the C++ side. ++ auto javaEventEmitter = EventEmitterWrapper::newObjectCxxArgs( ++ mountItem.newChildShadowView.eventEmitter); ++ (*objBufferArray)[objBufferPosition++] = javaEventEmitter.get(); ++ } ++ } ++ ++ // Write deletes last - so that all prop updates, etc, for the tag in the same ++ // batch don't fail. Without additional machinery, moving deletes here ++ // requires that the differ never produces "DELETE...CREATE" in that order for ++ // the same tag. It's nice to be able to batch all similar operations together ++ // for space efficiency. ++ if (!cppDeleteMountItems.empty()) { ++ writeIntBufferTypePreamble( ++ CppMountItem::Type::Delete, ++ cppDeleteMountItems.size(), ++ env, ++ intBufferArray, ++ intBufferPosition); ++ ++ for (const auto& mountItem : cppDeleteMountItems) { ++ temp[0] = mountItem.oldChildShadowView.tag; ++ env->SetIntArrayRegion(intBufferArray, intBufferPosition, 1, temp); ++ intBufferPosition += 1; ++ } ++ } ++ ++ // If there are no items, we pass a nullptr instead of passing the object ++ // through the JNI ++ auto batch = createMountItemsIntBufferBatchContainer( ++ javaUIManager_, ++ surfaceId, ++ batchMountItemIntsSize == 0 ? nullptr : intBufferArray, ++ batchMountItemObjectsSize == 0 ? nullptr : objBufferArray.get(), ++ revisionNumber); ++ ++ auto finishTransactionEndTime = telemetryTimePointNow(); ++ ++ scheduleMountItem( ++ javaUIManager_, ++ batch.get(), ++ telemetry.getRevisionNumber(), ++ telemetryTimePointToMilliseconds(telemetry.getCommitStartTime()), ++ telemetryTimePointToMilliseconds(telemetry.getDiffStartTime()), ++ telemetryTimePointToMilliseconds(telemetry.getDiffEndTime()), ++ telemetryTimePointToMilliseconds(telemetry.getLayoutStartTime()), ++ telemetryTimePointToMilliseconds(telemetry.getLayoutEndTime()), ++ telemetryTimePointToMilliseconds(finishTransactionStartTime), ++ telemetryTimePointToMilliseconds(finishTransactionEndTime), ++ telemetry.getAffectedLayoutNodesCount()); ++ ++ env->DeleteLocalRef(intBufferArray); ++} ++ ++void FabricMountingManager::preallocateShadowView( ++ const ShadowNode& shadowNode) { ++ { ++ std::lock_guard lock(allocatedViewsMutex_); ++ auto allocatedViewsIterator = ++ allocatedViewRegistry_.find(shadowNode.getSurfaceId()); ++ if (allocatedViewsIterator == allocatedViewRegistry_.end()) { ++ return; ++ } ++ auto& allocatedViews = allocatedViewsIterator->second; ++ if (allocatedViews.find(shadowNode.getTag()) != allocatedViews.end()) { ++ return; ++ } ++ allocatedViews.insert(shadowNode.getTag()); ++ } ++ ++ auto shadowView = ShadowView(shadowNode); ++ ++ bool isLayoutableShadowNode = shadowView.layoutMetrics != EmptyLayoutMetrics; ++ ++ static auto preallocateView = ++ JFabricUIManager::javaClassStatic() ++ ->getMethod( ++ "preallocateView"); ++ ++ // Do not hold onto Java object from C ++ // We DO want to hold onto C object from Java, since we don't know the ++ // lifetime of the Java object ++ jni::local_ref javaStateWrapper = nullptr; ++ if (shadowView.state != nullptr) { ++ javaStateWrapper = StateWrapperImpl::newObjectJavaArgs(); ++ StateWrapperImpl* cStateWrapper = cthis(javaStateWrapper); ++ cStateWrapper->state_ = shadowView.state; ++ } ++ ++ // Do not hold a reference to javaEventEmitter from the C++ side. ++ jni::local_ref javaEventEmitter = nullptr; ++ ++ jni::local_ref props = getProps({}, shadowView); ++ ++ auto component = getPlatformComponentName(shadowView); ++ ++ preallocateView( ++ javaUIManager_, ++ shadowNode.getSurfaceId(), ++ shadowView.tag, ++ component.get(), ++ props.get(), ++ (javaStateWrapper != nullptr ? javaStateWrapper.get() : nullptr), ++ (javaEventEmitter != nullptr ? javaEventEmitter.get() : nullptr), ++ isLayoutableShadowNode); ++} ++ ++void FabricMountingManager::dispatchCommand( ++ const ShadowView& shadowView, ++ const std::string& commandName, ++ const folly::dynamic& args) { ++ static auto dispatchCommand = ++ JFabricUIManager::javaClassStatic() ++ ->getMethod( ++ "dispatchCommand"); ++ auto command = jni::make_jstring(commandName); ++ auto argsArray = jni::adopt_local(reinterpret_cast( ++ ReadableNativeArray::newObjectCxxArgs(args).release())); ++ dispatchCommand( ++ javaUIManager_, ++ shadowView.surfaceId, ++ shadowView.tag, ++ command.get(), ++ argsArray.get()); ++} ++ ++void FabricMountingManager::sendAccessibilityEvent( ++ const ShadowView& shadowView, ++ const std::string& eventType) { ++ static auto sendAccessibilityEventFromJS = ++ JFabricUIManager::javaClassStatic()->getMethod( ++ "sendAccessibilityEventFromJS"); ++ ++ auto eventTypeStr = jni::make_jstring(eventType); ++ sendAccessibilityEventFromJS( ++ javaUIManager_, shadowView.surfaceId, shadowView.tag, eventTypeStr.get()); ++} ++ ++void FabricMountingManager::setIsJSResponder( ++ const ShadowView& shadowView, ++ bool isJSResponder, ++ bool blockNativeResponder) { ++ static auto setJSResponder = ++ JFabricUIManager::javaClassStatic() ++ ->getMethod("setJSResponder"); ++ ++ static auto clearJSResponder = ++ JFabricUIManager::javaClassStatic()->getMethod( ++ "clearJSResponder"); ++ ++ if (isJSResponder) { ++ setJSResponder( ++ javaUIManager_, ++ shadowView.surfaceId, ++ shadowView.tag, ++ // The closest non-flattened ancestor of the same value if the node is ++ // not flattened. For now, we don't support the case when the node can ++ // be flattened because the only component that uses this feature - ++ // ScrollView - cannot be flattened. ++ shadowView.tag, ++ (jboolean)blockNativeResponder); ++ } else { ++ clearJSResponder(javaUIManager_); ++ } ++} ++ ++void FabricMountingManager::onAnimationStarted() { ++ static auto layoutAnimationsStartedJNI = ++ JFabricUIManager::javaClassStatic()->getMethod( ++ "onAnimationStarted"); ++ ++ layoutAnimationsStartedJNI(javaUIManager_); ++} ++ ++void FabricMountingManager::onAllAnimationsComplete() { ++ static auto allAnimationsCompleteJNI = ++ JFabricUIManager::javaClassStatic()->getMethod( ++ "onAllAnimationsComplete"); ++ ++ allAnimationsCompleteJNI(javaUIManager_); ++} ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/FabricMountingManager.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/FabricMountingManager.h +new file mode 100644 +index 0000000..03457b4 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/FabricMountingManager.h +@@ -0,0 +1,71 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++namespace facebook::react { ++ ++class MountingTransaction; ++class ReactNativeConfig; ++struct ShadowView; ++ ++class FabricMountingManager final { ++ public: ++ FabricMountingManager( ++ std::shared_ptr& config, ++ jni::global_ref& javaUIManager); ++ FabricMountingManager(const FabricMountingManager&) = delete; ++ ++ void onSurfaceStart(SurfaceId surfaceId); ++ ++ void onSurfaceStop(SurfaceId surfaceId); ++ ++ void preallocateShadowView(const ShadowNode& shadowNode); ++ ++ void executeMount(const MountingTransaction& transaction); ++ ++ void dispatchCommand( ++ const ShadowView& shadowView, ++ const std::string& commandName, ++ const folly::dynamic& args); ++ ++ void sendAccessibilityEvent( ++ const ShadowView& shadowView, ++ const std::string& eventType); ++ ++ void setIsJSResponder( ++ const ShadowView& shadowView, ++ bool isJSResponder, ++ bool blockNativeResponder); ++ ++ void onAnimationStarted(); ++ ++ void onAllAnimationsComplete(); ++ ++ private: ++ jni::global_ref javaUIManager_; ++ ++ std::recursive_mutex commitMutex_; ++ ++ std::unordered_map> ++ allocatedViewRegistry_{}; ++ std::recursive_mutex allocatedViewsMutex_; ++ ++ jni::local_ref getProps( ++ const ShadowView& oldShadowView, ++ const ShadowView& newShadowView); ++}; ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/JBackgroundExecutor.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/JBackgroundExecutor.cpp +new file mode 100644 +index 0000000..5f48d61 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/JBackgroundExecutor.cpp +@@ -0,0 +1,28 @@ ++/* ++ * 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. ++ */ ++ ++#include "JBackgroundExecutor.h" ++ ++#include ++#include ++ ++namespace facebook::react { ++ ++using namespace facebook::jni; ++ ++BackgroundExecutor JBackgroundExecutor::create(const std::string& name) { ++ auto instance = make_global(newInstance(name)); ++ return [instance = std::move(instance)](std::function&& runnable) { ++ static auto method = ++ javaClassStatic()->getMethod( ++ "queueRunnable"); ++ auto jrunnable = JNativeRunnable::newObjectCxxArgs(std::move(runnable)); ++ method(instance, jrunnable.get()); ++ }; ++} ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/JBackgroundExecutor.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/JBackgroundExecutor.h +new file mode 100644 +index 0000000..1224ec7 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/JBackgroundExecutor.h +@@ -0,0 +1,23 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++#include ++ ++namespace facebook::react { ++ ++class JBackgroundExecutor : public jni::JavaClass { ++ public: ++ static auto constexpr kJavaDescriptor = ++ "Lcom/facebook/react/bridge/BackgroundExecutor;"; ++ ++ static BackgroundExecutor create(const std::string& name); ++}; ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/JFabricUIManager.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/JFabricUIManager.cpp +new file mode 100644 +index 0000000..48326b9 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/JFabricUIManager.cpp +@@ -0,0 +1,21 @@ ++/* ++ * 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. ++ */ ++ ++#include "JFabricUIManager.h" ++ ++#include "Binding.h" ++ ++namespace facebook::react { ++ ++Binding* JFabricUIManager::getBinding() { ++ static const auto bindingField = ++ javaClassStatic()->getField("mBinding"); ++ ++ return jni::static_ref_cast(getFieldValue(bindingField)) ++ ->cthis(); ++} ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/JFabricUIManager.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/JFabricUIManager.h +new file mode 100644 +index 0000000..5134ed5 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/JFabricUIManager.h +@@ -0,0 +1,24 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++ ++namespace facebook::react { ++ ++class Binding; ++ ++class JFabricUIManager : public jni::JavaClass { ++ public: ++ static constexpr auto kJavaDescriptor = ++ "Lcom/facebook/react/fabric/FabricUIManager;"; ++ ++ Binding* getBinding(); ++}; ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/MountItem.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/MountItem.cpp +new file mode 100644 +index 0000000..b1f20f8 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/MountItem.cpp +@@ -0,0 +1,64 @@ ++/* ++ * 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. ++ */ ++ ++#include "MountItem.h" ++ ++namespace facebook::react { ++ ++CppMountItem CppMountItem::CreateMountItem(const ShadowView& shadowView) { ++ return {CppMountItem::Type::Create, {}, {}, shadowView, -1}; ++} ++CppMountItem CppMountItem::DeleteMountItem(const ShadowView& shadowView) { ++ return {CppMountItem::Type::Delete, {}, shadowView, {}, -1}; ++} ++CppMountItem CppMountItem::InsertMountItem( ++ const ShadowView& parentView, ++ const ShadowView& shadowView, ++ int index) { ++ return {CppMountItem::Type::Insert, parentView, {}, shadowView, index}; ++} ++CppMountItem CppMountItem::RemoveMountItem( ++ const ShadowView& parentView, ++ const ShadowView& shadowView, ++ int index) { ++ return {CppMountItem::Type::Remove, parentView, shadowView, {}, index}; ++} ++CppMountItem CppMountItem::RemoveDeleteTreeMountItem( ++ const ShadowView& parentView, ++ const ShadowView& shadowView, ++ int index) { ++ return { ++ CppMountItem::Type::RemoveDeleteTree, parentView, shadowView, {}, index}; ++} ++CppMountItem CppMountItem::UpdatePropsMountItem( ++ const ShadowView& oldShadowView, ++ const ShadowView& newShadowView) { ++ return { ++ CppMountItem::Type::UpdateProps, {}, oldShadowView, newShadowView, -1}; ++} ++CppMountItem CppMountItem::UpdateStateMountItem(const ShadowView& shadowView) { ++ return {CppMountItem::Type::UpdateState, {}, {}, shadowView, -1}; ++} ++CppMountItem CppMountItem::UpdateLayoutMountItem( ++ const ShadowView& shadowView, ++ const ShadowView& parentView) { ++ return {CppMountItem::Type::UpdateLayout, parentView, {}, shadowView, -1}; ++} ++CppMountItem CppMountItem::UpdateEventEmitterMountItem( ++ const ShadowView& shadowView) { ++ return {CppMountItem::Type::UpdateEventEmitter, {}, {}, shadowView, -1}; ++} ++CppMountItem CppMountItem::UpdatePaddingMountItem( ++ const ShadowView& shadowView) { ++ return {CppMountItem::Type::UpdatePadding, {}, {}, shadowView, -1}; ++} ++CppMountItem CppMountItem::UpdateOverflowInsetMountItem( ++ const ShadowView& shadowView) { ++ return {CppMountItem::Type::UpdateOverflowInset, {}, {}, shadowView, -1}; ++} ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/MountItem.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/MountItem.h +new file mode 100644 +index 0000000..d3b65a7 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/MountItem.h +@@ -0,0 +1,86 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++#include ++ ++namespace facebook::react { ++ ++struct JMountItem : public jni::JavaClass { ++ static constexpr auto kJavaDescriptor = ++ "Lcom/facebook/react/fabric/mounting/mountitems/MountItem;"; ++}; ++ ++struct CppMountItem final { ++#pragma mark - Designated Initializers ++ ++ static CppMountItem CreateMountItem(const ShadowView& shadowView); ++ ++ static CppMountItem DeleteMountItem(const ShadowView& shadowView); ++ ++ static CppMountItem InsertMountItem( ++ const ShadowView& parentView, ++ const ShadowView& shadowView, ++ int index); ++ ++ static CppMountItem RemoveMountItem( ++ const ShadowView& parentView, ++ const ShadowView& shadowView, ++ int index); ++ ++ static CppMountItem RemoveDeleteTreeMountItem( ++ const ShadowView& parentView, ++ const ShadowView& shadowView, ++ int index); ++ ++ static CppMountItem UpdatePropsMountItem( ++ const ShadowView& oldShadowView, ++ const ShadowView& newShadowView); ++ ++ static CppMountItem UpdateStateMountItem(const ShadowView& shadowView); ++ ++ static CppMountItem UpdateLayoutMountItem( ++ const ShadowView& shadowView, ++ const ShadowView& parentView); ++ ++ static CppMountItem UpdateEventEmitterMountItem(const ShadowView& shadowView); ++ ++ static CppMountItem UpdatePaddingMountItem(const ShadowView& shadowView); ++ ++ static CppMountItem UpdateOverflowInsetMountItem( ++ const ShadowView& shadowView); ++ ++#pragma mark - Type ++ ++ enum Type { ++ Undefined = -1, ++ Multiple = 1, ++ Create = 2, ++ Delete = 4, ++ Insert = 8, ++ Remove = 16, ++ UpdateProps = 32, ++ UpdateState = 64, ++ UpdateLayout = 128, ++ UpdateEventEmitter = 256, ++ UpdatePadding = 512, ++ UpdateOverflowInset = 1024, ++ RemoveDeleteTree = 2048 ++ }; ++ ++#pragma mark - Fields ++ ++ Type type = {Create}; ++ ShadowView parentShadowView = {}; ++ ShadowView oldChildShadowView = {}; ++ ShadowView newChildShadowView = {}; ++ int index = {}; ++}; ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/OnLoad.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/OnLoad.cpp +new file mode 100644 +index 0000000..1e4ab75 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/OnLoad.cpp +@@ -0,0 +1,30 @@ ++/* ++ * 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. ++ */ ++ ++#include ++ ++#include "Binding.h" ++#include "ComponentFactory.h" ++#include "CoreComponentsRegistry.h" ++#include "EventBeatManager.h" ++#include "EventEmitterWrapper.h" ++#include "JEmptyReactNativeConfig.h" ++#include "StateWrapperImpl.h" ++#include "SurfaceHandlerBinding.h" ++ ++JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*) { ++ return facebook::jni::initialize(vm, [] { ++ facebook::react::Binding::registerNatives(); ++ facebook::react::EventBeatManager::registerNatives(); ++ facebook::react::EventEmitterWrapper::registerNatives(); ++ facebook::react::StateWrapperImpl::registerNatives(); ++ facebook::react::ComponentFactory::registerNatives(); ++ facebook::react::CoreComponentsRegistry::registerNatives(); ++ facebook::react::SurfaceHandlerBinding::registerNatives(); ++ facebook::react::JEmptyReactNativeConfig::registerNatives(); ++ }); ++} +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/ReactNativeConfigHolder.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/ReactNativeConfigHolder.cpp +new file mode 100644 +index 0000000..84c3ae5 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/ReactNativeConfigHolder.cpp +@@ -0,0 +1,41 @@ ++/* ++ * 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. ++ */ ++ ++#include "ReactNativeConfigHolder.h" ++ ++#include ++ ++using namespace facebook::react; ++ ++bool ReactNativeConfigHolder::getBool(const std::string& param) const { ++ static const auto method = facebook::jni::findClassStatic( ++ "com/facebook/react/fabric/ReactNativeConfig") ++ ->getMethod("getBool"); ++ return method(reactNativeConfig_, facebook::jni::make_jstring(param).get()); ++} ++ ++std::string ReactNativeConfigHolder::getString(const std::string& param) const { ++ static const auto method = facebook::jni::findClassStatic( ++ "com/facebook/react/fabric/ReactNativeConfig") ++ ->getMethod("getString"); ++ return method(reactNativeConfig_, facebook::jni::make_jstring(param).get()) ++ ->toString(); ++} ++ ++int64_t ReactNativeConfigHolder::getInt64(const std::string& param) const { ++ static const auto method = facebook::jni::findClassStatic( ++ "com/facebook/react/fabric/ReactNativeConfig") ++ ->getMethod("getInt64"); ++ return method(reactNativeConfig_, facebook::jni::make_jstring(param).get()); ++} ++ ++double ReactNativeConfigHolder::getDouble(const std::string& param) const { ++ static const auto method = facebook::jni::findClassStatic( ++ "com/facebook/react/fabric/ReactNativeConfig") ++ ->getMethod("getDouble"); ++ return method(reactNativeConfig_, facebook::jni::make_jstring(param).get()); ++} +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/ReactNativeConfigHolder.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/ReactNativeConfigHolder.h +new file mode 100644 +index 0000000..a169235 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/ReactNativeConfigHolder.h +@@ -0,0 +1,35 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++#include ++#include ++#include ++ ++namespace facebook::react { ++ ++/** ++ * Implementation of ReactNativeConfig that wraps a ReactNativeConfig Java ++ * object. ++ */ ++class ReactNativeConfigHolder : public ReactNativeConfig { ++ public: ++ explicit ReactNativeConfigHolder(jni::alias_ref reactNativeConfig) ++ : reactNativeConfig_(make_global(reactNativeConfig)){}; ++ ++ bool getBool(const std::string& param) const override; ++ std::string getString(const std::string& param) const override; ++ int64_t getInt64(const std::string& param) const override; ++ double getDouble(const std::string& param) const override; ++ ++ private: ++ jni::global_ref reactNativeConfig_; ++}; ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/StateWrapperImpl.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/StateWrapperImpl.cpp +new file mode 100644 +index 0000000..bf5c18e +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/StateWrapperImpl.cpp +@@ -0,0 +1,66 @@ ++/* ++ * 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. ++ */ ++ ++#include "StateWrapperImpl.h" ++#include ++#include ++#include ++#include ++ ++using namespace facebook::jni; ++ ++namespace facebook::react { ++ ++/** ++ * Called from Java constructor through the JNI. ++ */ ++jni::local_ref StateWrapperImpl::initHybrid( ++ jni::alias_ref) { ++ return makeCxxInstance(); ++} ++ ++jni::local_ref ++StateWrapperImpl::getStateDataImpl() { ++ if (auto state = state_.lock()) { ++ folly::dynamic map = state->getDynamic(); ++ return ReadableNativeMap::newObjectCxxArgs(std::move(map)); ++ } else { ++ return nullptr; ++ } ++} ++ ++jni::local_ref ++StateWrapperImpl::getStateMapBufferDataImpl() { ++ if (auto state = state_.lock()) { ++ MapBuffer map = state->getMapBuffer(); ++ return JReadableMapBuffer::createWithContents(std::move(map)); ++ } else { ++ return nullptr; ++ } ++} ++ ++void StateWrapperImpl::updateStateImpl(NativeMap* map) { ++ if (auto state = state_.lock()) { ++ // Get folly::dynamic from map ++ auto dynamicMap = map->consume(); ++ // Set state ++ state->updateState(std::move(dynamicMap)); ++ } ++} ++ ++void StateWrapperImpl::registerNatives() { ++ registerHybrid({ ++ makeNativeMethod("initHybrid", StateWrapperImpl::initHybrid), ++ makeNativeMethod("getStateDataImpl", StateWrapperImpl::getStateDataImpl), ++ makeNativeMethod("updateStateImpl", StateWrapperImpl::updateStateImpl), ++ makeNativeMethod( ++ "getStateMapBufferDataImpl", ++ StateWrapperImpl::getStateMapBufferDataImpl), ++ }); ++} ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/StateWrapperImpl.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/StateWrapperImpl.h +new file mode 100644 +index 0000000..3aac2e0 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/StateWrapperImpl.h +@@ -0,0 +1,40 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++#include ++#include ++#include ++ ++namespace facebook::react { ++ ++class Instance; ++ ++class StateWrapperImpl : public jni::HybridClass { ++ public: ++ constexpr static const char* const kJavaDescriptor = ++ "Lcom/facebook/react/fabric/StateWrapperImpl;"; ++ constexpr static auto StateWrapperImplJavaDescriptor = ++ "com/facebook/react/fabric/StateWrapperImpl"; ++ ++ static void registerNatives(); ++ ++ jni::local_ref getStateMapBufferDataImpl(); ++ jni::local_ref getStateDataImpl(); ++ void updateStateImpl(NativeMap* map); ++ ++ std::weak_ptr state_; ++ ++ private: ++ jni::alias_ref jhybridobject_; ++ ++ static jni::local_ref initHybrid(jni::alias_ref); ++}; ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/SurfaceHandlerBinding.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/SurfaceHandlerBinding.cpp +new file mode 100644 +index 0000000..dd0efec +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/SurfaceHandlerBinding.cpp +@@ -0,0 +1,115 @@ ++/* ++ * 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. ++ */ ++ ++#include "SurfaceHandlerBinding.h" ++#include ++ ++namespace facebook::react { ++ ++SurfaceHandlerBinding::SurfaceHandlerBinding( ++ SurfaceId surfaceId, ++ const std::string& moduleName) ++ : surfaceHandler_(moduleName, surfaceId) {} ++ ++void SurfaceHandlerBinding::setDisplayMode(jint mode) { ++ surfaceHandler_.setDisplayMode(static_cast(mode)); ++} ++ ++void SurfaceHandlerBinding::start() { ++ std::unique_lock lock(lifecycleMutex_); ++ ++ if (surfaceHandler_.getStatus() != SurfaceHandler::Status::Running) { ++ surfaceHandler_.start(); ++ } ++} ++ ++void SurfaceHandlerBinding::stop() { ++ std::unique_lock lock(lifecycleMutex_); ++ ++ if (surfaceHandler_.getStatus() == SurfaceHandler::Status::Running) { ++ surfaceHandler_.stop(); ++ } ++} ++ ++jint SurfaceHandlerBinding::getSurfaceId() { ++ return surfaceHandler_.getSurfaceId(); ++} ++ ++void SurfaceHandlerBinding::setSurfaceId(jint surfaceId) { ++ surfaceHandler_.setSurfaceId(surfaceId); ++} ++ ++jboolean SurfaceHandlerBinding::isRunning() { ++ return surfaceHandler_.getStatus() == SurfaceHandler::Status::Running; ++} ++ ++jni::local_ref SurfaceHandlerBinding::getModuleName() { ++ return jni::make_jstring(surfaceHandler_.getModuleName()); ++} ++ ++jni::local_ref ++SurfaceHandlerBinding::initHybrid( ++ jni::alias_ref, ++ jint surfaceId, ++ jni::alias_ref moduleName) { ++ return makeCxxInstance(surfaceId, moduleName->toStdString()); ++} ++ ++void SurfaceHandlerBinding::setLayoutConstraints( ++ jfloat minWidth, ++ jfloat maxWidth, ++ jfloat minHeight, ++ jfloat maxHeight, ++ jfloat offsetX, ++ jfloat offsetY, ++ jboolean doLeftAndRightSwapInRTL, ++ jboolean isRTL, ++ jfloat pixelDensity) { ++ LayoutConstraints constraints = {}; ++ constraints.minimumSize = {minWidth, minHeight}; ++ constraints.maximumSize = {maxWidth, maxHeight}; ++ constraints.layoutDirection = ++ isRTL ? LayoutDirection::RightToLeft : LayoutDirection::LeftToRight; ++ ++ LayoutContext context = {}; ++ context.swapLeftAndRightInRTL = doLeftAndRightSwapInRTL; ++ context.pointScaleFactor = pixelDensity; ++ context.viewportOffset = {offsetX, offsetY}; ++ ++ surfaceHandler_.constraintLayout(constraints, context); ++} ++ ++void SurfaceHandlerBinding::setProps(NativeMap* props) { ++ surfaceHandler_.setProps(props->consume()); ++} ++ ++const SurfaceHandler& SurfaceHandlerBinding::getSurfaceHandler() { ++ return surfaceHandler_; ++} ++ ++void SurfaceHandlerBinding::registerNatives() { ++ registerHybrid({ ++ makeNativeMethod("initHybrid", SurfaceHandlerBinding::initHybrid), ++ makeNativeMethod( ++ "getSurfaceIdNative", SurfaceHandlerBinding::getSurfaceId), ++ makeNativeMethod( ++ "setSurfaceIdNative", SurfaceHandlerBinding::setSurfaceId), ++ makeNativeMethod("isRunningNative", SurfaceHandlerBinding::isRunning), ++ makeNativeMethod( ++ "getModuleNameNative", SurfaceHandlerBinding::getModuleName), ++ makeNativeMethod("startNative", SurfaceHandlerBinding::start), ++ makeNativeMethod("stopNative", SurfaceHandlerBinding::stop), ++ makeNativeMethod( ++ "setLayoutConstraintsNative", ++ SurfaceHandlerBinding::setLayoutConstraints), ++ makeNativeMethod("setPropsNative", SurfaceHandlerBinding::setProps), ++ makeNativeMethod( ++ "setDisplayModeNative", SurfaceHandlerBinding::setDisplayMode), ++ }); ++} ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/SurfaceHandlerBinding.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/SurfaceHandlerBinding.h +new file mode 100644 +index 0000000..f8693cd +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/fabric/SurfaceHandlerBinding.h +@@ -0,0 +1,65 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++ ++#include ++#include ++#include ++ ++namespace facebook::react { ++ ++class SurfaceHandlerBinding : public jni::HybridClass { ++ public: ++ constexpr static const char* const kJavaDescriptor = ++ "Lcom/facebook/react/fabric/SurfaceHandlerBinding;"; ++ ++ static void registerNatives(); ++ ++ SurfaceHandlerBinding(SurfaceId surfaceId, const std::string& moduleName); ++ ++ void start(); ++ void stop(); ++ ++ void setDisplayMode(jint mode); ++ ++ jint getSurfaceId(); ++ void setSurfaceId(jint surfaceId); ++ jni::local_ref getModuleName(); ++ ++ jboolean isRunning(); ++ ++ void setLayoutConstraints( ++ jfloat minWidth, ++ jfloat maxWidth, ++ jfloat minHeight, ++ jfloat maxHeight, ++ jfloat offsetX, ++ jfloat offsetY, ++ jboolean doLeftAndRightSwapInRTL, ++ jboolean isRTL, ++ jfloat pixelDensity); ++ ++ void setProps(NativeMap* props); ++ ++ const SurfaceHandler& getSurfaceHandler(); ++ ++ private: ++ mutable std::shared_mutex lifecycleMutex_; ++ const SurfaceHandler surfaceHandler_; ++ ++ jni::alias_ref jhybridobject_; ++ ++ static jni::local_ref initHybrid( ++ jni::alias_ref, ++ jint surfaceId, ++ jni::alias_ref moduleName); ++}; ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/hermes/instrumentation/CMakeLists.txt b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/hermes/instrumentation/CMakeLists.txt +new file mode 100644 +index 0000000..525d86a +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/hermes/instrumentation/CMakeLists.txt +@@ -0,0 +1,31 @@ ++# 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. ++ ++cmake_minimum_required(VERSION 3.13) ++set(CMAKE_VERBOSE_MAKEFILE on) ++ ++file(GLOB_RECURSE jsijniprofiler_SRC CONFIGURE_DEPENDS *.cpp) ++ ++add_library( ++ jsijniprofiler ++ SHARED ++ ${jsijniprofiler_SRC} ++) ++target_compile_options( ++ jsijniprofiler ++ PRIVATE ++ -fexceptions ++) ++target_include_directories(jsijniprofiler PRIVATE .) ++target_link_libraries( ++ jsijniprofiler ++ fb ++ fbjni ++ jsireact ++ folly_runtime ++ hermes-engine::libhermes ++ jsi ++ reactnativejni ++) +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/hermes/instrumentation/HermesMemoryDumper.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/hermes/instrumentation/HermesMemoryDumper.h +new file mode 100644 +index 0000000..b1bd308 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/hermes/instrumentation/HermesMemoryDumper.h +@@ -0,0 +1,49 @@ ++/* ++ * 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. ++ */ ++ ++#include ++#include ++ ++namespace facebook { ++namespace jsi { ++namespace jni { ++ ++namespace jni = ::facebook::jni; ++ ++class HermesMemoryDumper : public jni::JavaClass { ++ public: ++ constexpr static auto kJavaDescriptor = ++ "Lcom/facebook/hermes/instrumentation/HermesMemoryDumper;"; ++ ++ bool shouldSaveSnapshot() { ++ static auto shouldSaveSnapshotMethod = ++ javaClassStatic()->getMethod("shouldSaveSnapshot"); ++ return shouldSaveSnapshotMethod(self()); ++ } ++ ++ std::string getInternalStorage() { ++ static auto getInternalStorageMethod = ++ javaClassStatic()->getMethod("getInternalStorage"); ++ return getInternalStorageMethod(self())->toStdString(); ++ } ++ ++ std::string getId() { ++ static auto getInternalStorageMethod = ++ javaClassStatic()->getMethod("getId"); ++ return getInternalStorageMethod(self())->toStdString(); ++ } ++ ++ void setMetaData(std::string crashId) { ++ static auto getIdMethod = ++ javaClassStatic()->getMethod("setMetaData"); ++ getIdMethod(self(), crashId); ++ } ++}; ++ ++} // namespace jni ++} // namespace jsi ++} // namespace facebook +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/hermes/instrumentation/HermesSamplingProfiler.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/hermes/instrumentation/HermesSamplingProfiler.cpp +new file mode 100644 +index 0000000..d10f857 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/hermes/instrumentation/HermesSamplingProfiler.cpp +@@ -0,0 +1,42 @@ ++/* ++ * 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. ++ */ ++ ++#include "HermesSamplingProfiler.h" ++ ++#include ++ ++namespace facebook { ++namespace jsi { ++namespace jni { ++ ++void HermesSamplingProfiler::enable(jni::alias_ref) { ++ hermes::HermesRuntime::enableSamplingProfiler(); ++} ++ ++void HermesSamplingProfiler::disable(jni::alias_ref) { ++ hermes::HermesRuntime::disableSamplingProfiler(); ++} ++ ++void HermesSamplingProfiler::dumpSampledTraceToFile( ++ jni::alias_ref, ++ std::string filename) { ++ hermes::HermesRuntime::dumpSampledTraceToFile(filename); ++} ++ ++void HermesSamplingProfiler::registerNatives() { ++ javaClassLocal()->registerNatives({ ++ makeNativeMethod("enable", HermesSamplingProfiler::enable), ++ makeNativeMethod("disable", HermesSamplingProfiler::enable), ++ makeNativeMethod( ++ "dumpSampledTraceToFile", ++ HermesSamplingProfiler::dumpSampledTraceToFile), ++ }); ++} ++ ++} // namespace jni ++} // namespace jsi ++} // namespace facebook +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/hermes/instrumentation/HermesSamplingProfiler.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/hermes/instrumentation/HermesSamplingProfiler.h +new file mode 100644 +index 0000000..0c6a2e3 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/hermes/instrumentation/HermesSamplingProfiler.h +@@ -0,0 +1,40 @@ ++/* ++ * 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. ++ */ ++ ++#ifndef HERMESSAMPLINGPROFILER_H_ ++#define HERMESSAMPLINGPROFILER_H_ ++ ++#include ++#include ++ ++namespace facebook { ++namespace jsi { ++namespace jni { ++ ++namespace jni = ::facebook::jni; ++ ++class HermesSamplingProfiler : public jni::JavaClass { ++ public: ++ constexpr static auto kJavaDescriptor = ++ "Lcom/facebook/hermes/instrumentation/HermesSamplingProfiler;"; ++ static void enable(jni::alias_ref); ++ static void disable(jni::alias_ref); ++ static void dumpSampledTraceToFile( ++ jni::alias_ref, ++ std::string filename); ++ ++ static void registerNatives(); ++ ++ private: ++ HermesSamplingProfiler(); ++}; ++ ++} // namespace jni ++} // namespace jsi ++} // namespace facebook ++ ++#endif /* HERMESSAMPLINGPROFILER_H_ */ +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/hermes/instrumentation/OnLoad.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/hermes/instrumentation/OnLoad.cpp +new file mode 100644 +index 0000000..f46e500 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/hermes/instrumentation/OnLoad.cpp +@@ -0,0 +1,14 @@ ++/* ++ * 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. ++ */ ++ ++#include "HermesSamplingProfiler.h" ++ ++JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) { ++ return facebook::jni::initialize(vm, [] { ++ facebook::jsi::jni::HermesSamplingProfiler::registerNatives(); ++ }); ++} +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/hermes/reactexecutor/CMakeLists.txt b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/hermes/reactexecutor/CMakeLists.txt +new file mode 100644 +index 0000000..0a7f253 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/hermes/reactexecutor/CMakeLists.txt +@@ -0,0 +1,33 @@ ++# 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. ++ ++cmake_minimum_required(VERSION 3.13) ++set(CMAKE_VERBOSE_MAKEFILE on) ++ ++file(GLOB_RECURSE hermes_executor_SRC CONFIGURE_DEPENDS *.cpp) ++ ++add_library(hermes_executor ++ SHARED ++ ${hermes_executor_SRC} ++) ++target_compile_options( ++ hermes_executor ++ PRIVATE ++ $<$:-DHERMES_ENABLE_DEBUGGER=1> ++ -std=c++20 ++ -fexceptions ++) ++target_include_directories(hermes_executor PRIVATE .) ++target_link_libraries( ++ hermes_executor ++ hermes_executor_common ++ jsireact ++ fb ++ fbjni ++ folly_runtime ++ hermes-engine::libhermes ++ jsi ++ reactnativejni ++) +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/hermes/reactexecutor/OnLoad.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/hermes/reactexecutor/OnLoad.cpp +new file mode 100644 +index 0000000..035b511 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/hermes/reactexecutor/OnLoad.cpp +@@ -0,0 +1,111 @@ ++/* ++ * 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. ++ */ ++ ++#include <../instrumentation/HermesMemoryDumper.h> ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++namespace facebook::react { ++ ++static void hermesFatalHandler(const std::string& reason) { ++ LOG(ERROR) << "Hermes Fatal: " << reason << "\n"; ++ __android_log_assert(nullptr, "Hermes", "%s", reason.c_str()); ++} ++ ++static std::once_flag flag; ++ ++static ::hermes::vm::RuntimeConfig makeRuntimeConfig(jlong heapSizeMB) { ++ namespace vm = ::hermes::vm; ++ auto gcConfigBuilder = vm::GCConfig::Builder().withName("RN"); ++ if (heapSizeMB > 0) { ++ gcConfigBuilder.withMaxHeapSize(heapSizeMB << 20); ++ } ++ ++ return vm::RuntimeConfig::Builder() ++ .withGCConfig(gcConfigBuilder.build()) ++ .withEnableSampleProfiling(true) ++ .build(); ++} ++ ++static void installBindings(jsi::Runtime& runtime) { ++ react::Logger androidLogger = ++ static_cast( ++ &reactAndroidLoggingHook); ++ react::bindNativeLogger(runtime, androidLogger); ++} ++ ++class HermesExecutorHolder ++ : public jni::HybridClass { ++ public: ++ static constexpr auto kJavaDescriptor = ++ "Lcom/facebook/hermes/reactexecutor/HermesExecutor;"; ++ ++ static jni::local_ref initHybridDefaultConfig( ++ jni::alias_ref, ++ bool enableDebugger, ++ std::string debuggerName) { ++ JReactMarker::setLogPerfMarkerIfNeeded(); ++ ++ std::call_once(flag, []() { ++ facebook::hermes::HermesRuntime::setFatalHandler(hermesFatalHandler); ++ }); ++ auto factory = std::make_unique(installBindings); ++ factory->setEnableDebugger(enableDebugger); ++ if (!debuggerName.empty()) { ++ factory->setDebuggerName(debuggerName); ++ } ++ return makeCxxInstance(std::move(factory)); ++ } ++ ++ static jni::local_ref initHybrid( ++ jni::alias_ref, ++ bool enableDebugger, ++ std::string debuggerName, ++ jlong heapSizeMB) { ++ JReactMarker::setLogPerfMarkerIfNeeded(); ++ auto runtimeConfig = makeRuntimeConfig(heapSizeMB); ++ std::call_once(flag, []() { ++ facebook::hermes::HermesRuntime::setFatalHandler(hermesFatalHandler); ++ }); ++ auto factory = std::make_unique( ++ installBindings, JSIExecutor::defaultTimeoutInvoker, runtimeConfig); ++ factory->setEnableDebugger(enableDebugger); ++ if (!debuggerName.empty()) { ++ factory->setDebuggerName(debuggerName); ++ } ++ return makeCxxInstance(std::move(factory)); ++ } ++ ++ static void registerNatives() { ++ registerHybrid( ++ {makeNativeMethod("initHybrid", HermesExecutorHolder::initHybrid), ++ makeNativeMethod( ++ "initHybridDefaultConfig", ++ HermesExecutorHolder::initHybridDefaultConfig)}); ++ } ++ ++ private: ++ friend HybridBase; ++ using HybridBase::HybridBase; ++}; ++ ++} // namespace facebook::react ++ ++JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) { ++ return facebook::jni::initialize( ++ vm, [] { facebook::react::HermesExecutorHolder::registerNatives(); }); ++} +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/CMakeLists.txt b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/CMakeLists.txt +new file mode 100644 +index 0000000..e503374 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/CMakeLists.txt +@@ -0,0 +1,42 @@ ++# 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. ++ ++cmake_minimum_required(VERSION 3.13) ++set(CMAKE_VERBOSE_MAKEFILE on) ++ ++file(GLOB reactnativejni_SRC CONFIGURE_DEPENDS *.cpp) ++ ++add_compile_options( ++ -fexceptions ++ -Wno-unused-lambda-capture ++ -std=c++20) ++ ++###################### ++### reactnativejni ### ++###################### ++ ++ ++add_library( ++ reactnativejni ++ SHARED ++ ${reactnativejni_SRC} ++) ++ ++# TODO This should not be ../../ ++target_include_directories(reactnativejni PUBLIC ../../) ++ ++target_link_libraries(reactnativejni ++ android ++ callinvokerholder ++ fb ++ fbjni ++ folly_runtime ++ glog_init ++ logger ++ react_cxxreact ++ react_render_runtimescheduler ++ runtimeexecutor ++ yoga ++ ) +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/CatalystInstanceImpl.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/CatalystInstanceImpl.cpp +new file mode 100644 +index 0000000..8dccfab +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/CatalystInstanceImpl.cpp +@@ -0,0 +1,422 @@ ++/* ++ * 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. ++ */ ++ ++#include "CatalystInstanceImpl.h" ++#include "ReactInstanceManagerInspectorTarget.h" ++ ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include "JReactCxxErrorHandler.h" ++#include "JReactSoftExceptionLogger.h" ++#include "JavaScriptExecutorHolder.h" ++#include "JniJSModulesUnbundle.h" ++#include "NativeArray.h" ++ ++using namespace facebook::jni; ++ ++namespace facebook::react { ++ ++namespace { ++ ++class InstanceCallbackImpl : public InstanceCallback { ++ public: ++ explicit InstanceCallbackImpl(alias_ref jobj) ++ : jobj_(make_global(jobj)) {} ++ ++ void onBatchComplete() override { ++ jni::ThreadScope guard; ++ static auto method = ++ JInstanceCallback::javaClassStatic()->getMethod( ++ "onBatchComplete"); ++ method(jobj_); ++ } ++ ++ void incrementPendingJSCalls() override { ++ // For C++ modules, this can be called from an arbitrary thread ++ // managed by the module, via callJSCallback or callJSFunction. So, ++ // we ensure that it is registered with the JVM. ++ jni::ThreadScope guard; ++ static auto method = ++ JInstanceCallback::javaClassStatic()->getMethod( ++ "incrementPendingJSCalls"); ++ method(jobj_); ++ } ++ ++ void decrementPendingJSCalls() override { ++ jni::ThreadScope guard; ++ static auto method = ++ JInstanceCallback::javaClassStatic()->getMethod( ++ "decrementPendingJSCalls"); ++ method(jobj_); ++ } ++ ++ private: ++ global_ref jobj_; ++}; ++ ++} // namespace ++ ++jni::local_ref ++CatalystInstanceImpl::initHybrid(jni::alias_ref) { ++ return makeCxxInstance(); ++} ++ ++CatalystInstanceImpl::CatalystInstanceImpl() ++ : instance_(std::make_unique()) {} ++ ++void CatalystInstanceImpl::registerNatives() { ++ registerHybrid({ ++ makeNativeMethod("initHybrid", CatalystInstanceImpl::initHybrid), ++ makeNativeMethod( ++ "initializeBridge", CatalystInstanceImpl::initializeBridge), ++ makeNativeMethod( ++ "jniExtendNativeModules", CatalystInstanceImpl::extendNativeModules), ++ makeNativeMethod( ++ "jniSetSourceURL", CatalystInstanceImpl::jniSetSourceURL), ++ makeNativeMethod( ++ "jniRegisterSegment", CatalystInstanceImpl::jniRegisterSegment), ++ makeNativeMethod( ++ "jniLoadScriptFromAssets", ++ CatalystInstanceImpl::jniLoadScriptFromAssets), ++ makeNativeMethod( ++ "jniLoadScriptFromFile", CatalystInstanceImpl::jniLoadScriptFromFile), ++ makeNativeMethod( ++ "jniCallJSFunction", CatalystInstanceImpl::jniCallJSFunction), ++ makeNativeMethod( ++ "jniCallJSCallback", CatalystInstanceImpl::jniCallJSCallback), ++ makeNativeMethod( ++ "setGlobalVariable", CatalystInstanceImpl::setGlobalVariable), ++ makeNativeMethod( ++ "getJavaScriptContext", CatalystInstanceImpl::getJavaScriptContext), ++ makeNativeMethod( ++ "getJSCallInvokerHolder", ++ CatalystInstanceImpl::getJSCallInvokerHolder), ++ makeNativeMethod( ++ "getNativeMethodCallInvokerHolder", ++ CatalystInstanceImpl::getNativeMethodCallInvokerHolder), ++ makeNativeMethod( ++ "jniHandleMemoryPressure", ++ CatalystInstanceImpl::handleMemoryPressure), ++ makeNativeMethod( ++ "getRuntimeExecutor", CatalystInstanceImpl::getRuntimeExecutor), ++ makeNativeMethod( ++ "getRuntimeScheduler", CatalystInstanceImpl::getRuntimeScheduler), ++ makeNativeMethod( ++ "unregisterFromInspector", ++ CatalystInstanceImpl::unregisterFromInspector), ++ }); ++} ++ ++void log(ReactNativeLogLevel level, const char* message) { ++ switch (level) { ++ case ReactNativeLogLevelInfo: ++ LOG(INFO) << message; ++ break; ++ case ReactNativeLogLevelWarning: ++ LOG(WARNING) << message; ++ JReactSoftExceptionLogger::logNoThrowSoftExceptionWithMessage( ++ "react_native_log#warning", message); ++ break; ++ case ReactNativeLogLevelError: ++ LOG(ERROR) << message; ++ JReactCxxErrorHandler::handleError(message); ++ break; ++ case ReactNativeLogLevelFatal: ++ LOG(FATAL) << message; ++ break; ++ } ++} ++ ++void CatalystInstanceImpl::initializeBridge( ++ jni::alias_ref callback, ++ // This executor is actually a factory holder. ++ JavaScriptExecutorHolder* jseh, ++ jni::alias_ref jsQueue, ++ jni::alias_ref nativeModulesQueue, ++ jni::alias_ref::javaobject> ++ javaModules, ++ jni::alias_ref::javaobject> ++ cxxModules, ++ jni::alias_ref ++ inspectorTarget) { ++ set_react_native_logfunc(&log); ++ ++ // TODO mhorowitz: how to assert here? ++ // Assertions.assertCondition(mBridge == null, "initializeBridge should be ++ // called once"); ++ moduleMessageQueue_ = ++ std::make_shared(nativeModulesQueue); ++ ++ // This used to be: ++ // ++ // Java CatalystInstanceImpl -> C++ CatalystInstanceImpl -> Bridge -> ++ // Bridge::Callback ++ // --weak--> ReactCallback -> Java CatalystInstanceImpl ++ // ++ // Now the weak ref is a global ref. So breaking the loop depends on ++ // CatalystInstanceImpl#destroy() calling mHybridData.resetNative(), which ++ // should cause all the C++ pointers to be cleaned up (except C++ ++ // CatalystInstanceImpl might be kept alive for a short time by running ++ // callbacks). This also means that all native calls need to be pre-checked ++ // to avoid NPE. ++ ++ // See the comment in callJSFunction. Once js calls switch to strings, we ++ // don't need jsModuleDescriptions any more, all the way up and down the ++ // stack. ++ ++ moduleRegistry_ = std::make_shared(buildNativeModuleList( ++ std::weak_ptr(instance_), ++ javaModules, ++ cxxModules, ++ moduleMessageQueue_)); ++ ++ instance_->initializeBridge( ++ std::make_unique(callback), ++ jseh->getExecutorFactory(), ++ std::make_unique(jsQueue), ++ moduleRegistry_, ++ inspectorTarget != nullptr ++ ? inspectorTarget->cthis()->getInspectorTarget() ++ : nullptr); ++} ++ ++void CatalystInstanceImpl::extendNativeModules( ++ jni::alias_ref::javaobject> ++ javaModules, ++ jni::alias_ref::javaobject> ++ cxxModules) { ++ moduleRegistry_->registerModules(buildNativeModuleList( ++ std::weak_ptr(instance_), ++ javaModules, ++ cxxModules, ++ moduleMessageQueue_)); ++} ++ ++void CatalystInstanceImpl::jniSetSourceURL(const std::string& sourceURL) { ++ instance_->setSourceURL(sourceURL); ++} ++ ++void CatalystInstanceImpl::jniRegisterSegment( ++ int segmentId, ++ const std::string& path) { ++ instance_->registerBundle((uint32_t)segmentId, path); ++} ++ ++static ScriptTag getScriptTagFromFile(const char* sourcePath) { ++ std::ifstream bundle_stream(sourcePath, std::ios_base::in); ++ BundleHeader header; ++ if (bundle_stream && ++ bundle_stream.read(reinterpret_cast(&header), sizeof(header))) { ++ return parseTypeFromHeader(header); ++ } else { ++ return ScriptTag::String; ++ } ++} ++ ++static bool isIndexedRAMBundle(std::unique_ptr* script) { ++ BundleHeader header; ++ strncpy( ++ reinterpret_cast(&header), script->get()->c_str(), sizeof(header)); ++ return parseTypeFromHeader(header) == ScriptTag::RAMBundle; ++} ++ ++void CatalystInstanceImpl::jniLoadScriptFromAssets( ++ jni::alias_ref assetManager, ++ const std::string& assetURL, ++ bool loadSynchronously) { ++ const int kAssetsLength = 9; // strlen("assets://"); ++ auto sourceURL = assetURL.substr(kAssetsLength); ++ ++ auto manager = extractAssetManager(assetManager); ++ auto script = loadScriptFromAssets(manager, sourceURL); ++ if (JniJSModulesUnbundle::isUnbundle(manager, sourceURL)) { ++ auto bundle = JniJSModulesUnbundle::fromEntryFile(manager, sourceURL); ++ auto registry = RAMBundleRegistry::singleBundleRegistry(std::move(bundle)); ++ instance_->loadRAMBundle( ++ std::move(registry), std::move(script), sourceURL, loadSynchronously); ++ return; ++ } else if (isIndexedRAMBundle(&script)) { ++ instance_->loadRAMBundleFromString(std::move(script), sourceURL); ++ } else { ++ instance_->loadScriptFromString( ++ std::move(script), sourceURL, loadSynchronously); ++ } ++} ++ ++void CatalystInstanceImpl::jniLoadScriptFromFile( ++ const std::string& fileName, ++ const std::string& sourceURL, ++ bool loadSynchronously) { ++ auto reactInstance = instance_; ++ if (!reactInstance) { ++ return; ++ } ++ ++ switch (getScriptTagFromFile(fileName.c_str())) { ++ case ScriptTag::RAMBundle: ++ instance_->loadRAMBundleFromFile(fileName, sourceURL, loadSynchronously); ++ break; ++ case ScriptTag::String: ++ default: { ++ std::unique_ptr script; ++ RecoverableError::runRethrowingAsRecoverable( ++ [&fileName, &script]() { ++ script = JSBigFileString::fromPath(fileName); ++ }); ++ instance_->loadScriptFromString( ++ std::move(script), sourceURL, loadSynchronously); ++ } ++ } ++} ++ ++void CatalystInstanceImpl::jniCallJSFunction( ++ std::string module, ++ std::string method, ++ NativeArray* arguments) { ++ // We want to share the C++ code, and on iOS, modules pass module/method ++ // names as strings all the way through to JS, and there's no way to do ++ // string -> id mapping on the objc side. So on Android, we convert the ++ // number to a string, here which gets passed as-is to JS. There, they they ++ // used as ids if isFinite(), which handles this case, and looked up as ++ // strings otherwise. Eventually, we'll probably want to modify the stack ++ // from the JS proxy through here to use strings, too. ++ instance_->callJSFunction( ++ std::move(module), std::move(method), arguments->consume()); ++} ++ ++void CatalystInstanceImpl::jniCallJSCallback( ++ jint callbackId, ++ NativeArray* arguments) { ++ instance_->callJSCallback(callbackId, arguments->consume()); ++} ++ ++void CatalystInstanceImpl::setGlobalVariable( ++ std::string propName, ++ std::string&& jsonValue) { ++ // This is only ever called from Java with short strings, and only ++ // for testing, so no need to try hard for zero-copy here. ++ ++ instance_->setGlobalVariable( ++ std::move(propName), ++ std::make_unique(std::move(jsonValue))); ++} ++ ++jlong CatalystInstanceImpl::getJavaScriptContext() { ++ return (jlong)(intptr_t)instance_->getJavaScriptContext(); ++} ++ ++void CatalystInstanceImpl::handleMemoryPressure(int pressureLevel) { ++ instance_->handleMemoryPressure(pressureLevel); ++} ++ ++jni::alias_ref ++CatalystInstanceImpl::getJSCallInvokerHolder() { ++ if (!jsCallInvokerHolder_) { ++ auto runtimeScheduler = getRuntimeScheduler(); ++ auto runtimeSchedulerCallInvoker = ++ std::make_shared( ++ runtimeScheduler->cthis()->get()); ++ jsCallInvokerHolder_ = jni::make_global( ++ CallInvokerHolder::newObjectCxxArgs(runtimeSchedulerCallInvoker)); ++ } ++ return jsCallInvokerHolder_; ++} ++ ++jni::alias_ref ++CatalystInstanceImpl::getNativeMethodCallInvokerHolder() { ++ if (!nativeMethodCallInvokerHolder_) { ++ class NativeMethodCallInvokerImpl : public NativeMethodCallInvoker { ++ private: ++ std::shared_ptr messageQueueThread_; ++ ++ public: ++ NativeMethodCallInvokerImpl( ++ std::shared_ptr messageQueueThread) ++ : messageQueueThread_(messageQueueThread) {} ++ void invokeAsync( ++ const std::string& methodName, ++ std::function&& work) noexcept override { ++ messageQueueThread_->runOnQueue(std::move(work)); ++ } ++ void invokeSync( ++ const std::string& methodName, ++ std::function&& work) override { ++ messageQueueThread_->runOnQueueSync(std::move(work)); ++ } ++ }; ++ ++ std::shared_ptr nativeMethodCallInvoker = ++ std::make_shared(moduleMessageQueue_); ++ ++ std::shared_ptr decoratedNativeMethodCallInvoker = ++ instance_->getDecoratedNativeMethodCallInvoker(nativeMethodCallInvoker); ++ ++ nativeMethodCallInvokerHolder_ = ++ jni::make_global(NativeMethodCallInvokerHolder::newObjectCxxArgs( ++ decoratedNativeMethodCallInvoker)); ++ } ++ ++ return nativeMethodCallInvokerHolder_; ++} ++ ++jni::alias_ref ++CatalystInstanceImpl::getRuntimeExecutor() { ++ if (!runtimeExecutor_) { ++ auto executor = instance_->getRuntimeExecutor(); ++ if (executor) { ++ runtimeExecutor_ = ++ jni::make_global(JRuntimeExecutor::newObjectCxxArgs(executor)); ++ } ++ } ++ return runtimeExecutor_; ++} ++ ++jni::alias_ref ++CatalystInstanceImpl::getRuntimeScheduler() { ++ if (!runtimeScheduler_) { ++ auto runtimeExecutor = instance_->getRuntimeExecutor(); ++ if (runtimeExecutor) { ++ auto runtimeScheduler = ++ std::make_shared(runtimeExecutor); ++ runtimeScheduler_ = jni::make_global( ++ JRuntimeScheduler::newObjectCxxArgs(runtimeScheduler)); ++ runtimeExecutor([scheduler = ++ std::move(runtimeScheduler)](jsi::Runtime& runtime) { ++ RuntimeSchedulerBinding::createAndInstallIfNeeded(runtime, scheduler); ++ }); ++ } ++ } ++ ++ return runtimeScheduler_; ++} ++ ++void CatalystInstanceImpl::unregisterFromInspector() { ++ instance_->unregisterFromInspector(); ++} ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/CatalystInstanceImpl.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/CatalystInstanceImpl.h +new file mode 100644 +index 0000000..a81b3f6 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/CatalystInstanceImpl.h +@@ -0,0 +1,127 @@ ++/* ++ * 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. ++ */ ++ ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#include "JMessageQueueThread.h" ++#include "JRuntimeExecutor.h" ++#include "JRuntimeScheduler.h" ++#include "JSLoader.h" ++#include "JavaModuleWrapper.h" ++#include "ModuleRegistryBuilder.h" ++#include "ReactInstanceManagerInspectorTarget.h" ++ ++namespace facebook::react { ++ ++class Instance; ++class JavaScriptExecutorHolder; ++class NativeArray; ++ ++struct JInstanceCallback : public jni::JavaClass { ++ static constexpr auto kJavaDescriptor = ++ "Lcom/facebook/react/bridge/CatalystInstanceImpl$InstanceCallback;"; ++}; ++ ++class CatalystInstanceImpl : public jni::HybridClass { ++ public: ++ static constexpr auto kJavaDescriptor = ++ "Lcom/facebook/react/bridge/CatalystInstanceImpl;"; ++ ++ static jni::local_ref initHybrid(jni::alias_ref); ++ ++ static void registerNatives(); ++ ++ std::shared_ptr getInstance() { ++ return instance_; ++ } ++ ++ private: ++ friend HybridBase; ++ ++ CatalystInstanceImpl(); ++ ++ void initializeBridge( ++ jni::alias_ref callback, ++ // This executor is actually a factory holder. ++ JavaScriptExecutorHolder* jseh, ++ jni::alias_ref jsQueue, ++ jni::alias_ref moduleQueue, ++ jni::alias_ref< ++ jni::JCollection::javaobject> ++ javaModules, ++ jni::alias_ref::javaobject> ++ cxxModules, ++ jni::alias_ref ++ inspectorTarget); ++ ++ void extendNativeModules( ++ jni::alias_ref::javaobject> javaModules, ++ jni::alias_ref::javaobject> ++ cxxModules); ++ ++ /** ++ * Sets the source URL of the underlying bridge without loading any JS code. ++ */ ++ void jniSetSourceURL(const std::string& sourceURL); ++ ++ /** ++ * Registers the file path of an additional JS segment by its ID. ++ * ++ */ ++ void jniRegisterSegment(int segmentId, const std::string& path); ++ ++ void jniLoadScriptFromAssets( ++ jni::alias_ref assetManager, ++ const std::string& assetURL, ++ bool loadSynchronously); ++ void jniLoadScriptFromFile( ++ const std::string& fileName, ++ const std::string& sourceURL, ++ bool loadSynchronously); ++ void jniCallJSFunction( ++ std::string module, ++ std::string method, ++ NativeArray* arguments); ++ void jniCallJSCallback(jint callbackId, NativeArray* arguments); ++ jni::alias_ref getJSCallInvokerHolder(); ++ jni::alias_ref ++ getNativeMethodCallInvokerHolder(); ++ jni::alias_ref getRuntimeExecutor(); ++ jni::alias_ref getRuntimeScheduler(); ++ void setGlobalVariable(std::string propName, std::string&& jsonValue); ++ jlong getJavaScriptContext(); ++ void handleMemoryPressure(int pressureLevel); ++ ++ void createAndInstallRuntimeSchedulerIfNecessary(); ++ ++ /** ++ * Unregisters the instance from the inspector. This method must be called ++ * on the main thread, after initializeBridge has finished executing and ++ * before the destructor for Instance has started. ++ */ ++ void unregisterFromInspector(); ++ ++ // This should be the only long-lived strong reference, but every C++ class ++ // will have a weak reference. ++ std::shared_ptr instance_; ++ std::shared_ptr moduleRegistry_; ++ std::shared_ptr moduleMessageQueue_; ++ jni::global_ref jsCallInvokerHolder_; ++ jni::global_ref ++ nativeMethodCallInvokerHolder_; ++ jni::global_ref runtimeExecutor_; ++ jni::global_ref runtimeScheduler_; ++}; ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/CxxModuleWrapper.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/CxxModuleWrapper.h +new file mode 100644 +index 0000000..80747e1 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/CxxModuleWrapper.h +@@ -0,0 +1,38 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include "CxxModuleWrapperBase.h" ++ ++namespace facebook::react { ++ ++class CxxModuleWrapper ++ : public jni::HybridClass { ++ public: ++ constexpr static const char* const kJavaDescriptor = ++ "Lcom/facebook/react/bridge/CxxModuleWrapper;"; ++ ++ std::string getName() override { ++ return module_->getName(); ++ } ++ ++ // This steals ownership of the underlying module for use by the C++ bridge ++ std::unique_ptr getModule() override { ++ return std::move(module_); ++ } ++ ++ protected: ++ friend HybridBase; ++ ++ explicit CxxModuleWrapper(std::unique_ptr module) ++ : module_(std::move(module)) {} ++ ++ std::unique_ptr module_; ++}; ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/CxxModuleWrapperBase.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/CxxModuleWrapperBase.h +new file mode 100644 +index 0000000..dc1954f +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/CxxModuleWrapperBase.h +@@ -0,0 +1,45 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++#include ++ ++#include ++#include ++ ++namespace facebook::react { ++ ++struct JNativeModule : jni::JavaClass { ++ constexpr static const char* const kJavaDescriptor = ++ "Lcom/facebook/react/bridge/NativeModule;"; ++}; ++ ++/** ++ * The C++ part of a CxxModuleWrapper is not a unique class, but it ++ * must extend this base class. ++ */ ++class CxxModuleWrapperBase ++ : public jni::HybridClass { ++ public: ++ constexpr static const char* const kJavaDescriptor = ++ "Lcom/facebook/react/bridge/CxxModuleWrapperBase;"; ++ ++ static void registerNatives() { ++ registerHybrid( ++ {makeNativeMethod("getName", CxxModuleWrapperBase::getName)}); ++ } ++ ++ // JNI method ++ virtual std::string getName() = 0; ++ ++ // Called by ModuleRegistryBuilder ++ virtual std::unique_ptr getModule() = 0; ++}; ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/CxxSharedModuleWrapper.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/CxxSharedModuleWrapper.h +new file mode 100644 +index 0000000..8d6dd71 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/CxxSharedModuleWrapper.h +@@ -0,0 +1,37 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++ ++#include "CxxModuleWrapperBase.h" ++ ++namespace facebook::react { ++ ++class CxxSharedModuleWrapper : public CxxModuleWrapperBase { ++ public: ++ std::string getName() override { ++ return shared_->getName(); ++ } ++ ++ std::unique_ptr getModule() override { ++ // Instead of just moving out the stored CxxModule, this creates a ++ // proxy which passes calls to the shared stored CxxModule. ++ ++ return std::make_unique(shared_); ++ } ++ ++ protected: ++ explicit CxxSharedModuleWrapper( ++ std::unique_ptr module) ++ : shared_(std::move(module)) {} ++ ++ std::shared_ptr shared_; ++}; ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JCallback.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JCallback.h +new file mode 100644 +index 0000000..0220f80 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JCallback.h +@@ -0,0 +1,50 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++ ++#include ++#include ++ ++#include "NativeArray.h" ++ ++namespace facebook::react { ++ ++class Instance; ++ ++struct JCallback : public jni::JavaClass { ++ constexpr static auto kJavaDescriptor = ++ "Lcom/facebook/react/bridge/Callback;"; ++}; ++ ++class JCxxCallbackImpl : public jni::HybridClass { ++ public: ++ constexpr static auto kJavaDescriptor = ++ "Lcom/facebook/react/bridge/CxxCallbackImpl;"; ++ ++ static void registerNatives() { ++ javaClassStatic()->registerNatives({ ++ makeNativeMethod("nativeInvoke", JCxxCallbackImpl::invoke), ++ }); ++ } ++ ++ private: ++ friend HybridBase; ++ ++ using Callback = std::function; ++ JCxxCallbackImpl(Callback callback) : callback_(std::move(callback)) {} ++ ++ void invoke(NativeArray* arguments) { ++ callback_(arguments->consume()); ++ } ++ ++ Callback callback_; ++}; ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JInspector.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JInspector.cpp +new file mode 100644 +index 0000000..41e5c8f +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JInspector.cpp +@@ -0,0 +1,112 @@ ++/* ++ * 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. ++ */ ++ ++#include "JInspector.h" ++ ++#include ++ ++namespace facebook::react { ++ ++namespace { ++ ++class RemoteConnection : public jsinspector_modern::IRemoteConnection { ++ public: ++ RemoteConnection(jni::alias_ref connection) ++ : connection_(jni::make_global(connection)) {} ++ ++ virtual void onMessage(std::string message) override { ++ connection_->onMessage(message); ++ } ++ ++ virtual void onDisconnect() override { ++ connection_->onDisconnect(); ++ } ++ ++ private: ++ jni::global_ref connection_; ++}; ++ ++} // namespace ++ ++jni::local_ref ++JPage::create(int id, const std::string& title, const std::string& vm) { ++ static auto constructor = javaClassStatic() ++ ->getConstructor, ++ jni::local_ref)>(); ++ return javaClassStatic()->newObject( ++ constructor, id, jni::make_jstring(title), jni::make_jstring(vm)); ++} ++ ++void JRemoteConnection::onMessage(const std::string& message) const { ++ static auto method = ++ javaClassStatic()->getMethod)>("onMessage"); ++ method(self(), jni::make_jstring(message)); ++} ++ ++void JRemoteConnection::onDisconnect() const { ++ static auto method = javaClassStatic()->getMethod("onDisconnect"); ++ method(self()); ++} ++ ++JLocalConnection::JLocalConnection( ++ std::unique_ptr connection) ++ : connection_(std::move(connection)) {} ++ ++void JLocalConnection::sendMessage(std::string message) { ++ connection_->sendMessage(std::move(message)); ++} ++ ++void JLocalConnection::disconnect() { ++ connection_->disconnect(); ++} ++ ++void JLocalConnection::registerNatives() { ++ javaClassStatic()->registerNatives({ ++ makeNativeMethod("sendMessage", JLocalConnection::sendMessage), ++ makeNativeMethod("disconnect", JLocalConnection::disconnect), ++ }); ++} ++ ++jni::global_ref JInspector::instance( ++ jni::alias_ref) { ++ static auto instance = jni::make_global( ++ newObjectCxxArgs(&jsinspector_modern::getInspectorInstance())); ++ return instance; ++} ++ ++jni::local_ref> JInspector::getPages() { ++ std::vector pages = ++ inspector_->getPages(); ++ auto array = jni::JArrayClass::newArray(pages.size()); ++ for (size_t i = 0; i < pages.size(); i++) { ++ (*array)[i] = JPage::create(pages[i].id, pages[i].title, pages[i].vm); ++ } ++ return array; ++} ++ ++jni::local_ref JInspector::connect( ++ int pageId, ++ jni::alias_ref remote) { ++ auto localConnection = inspector_->connect( ++ pageId, std::make_unique(std::move(remote))); ++ return localConnection ++ ? JLocalConnection::newObjectCxxArgs(std::move(localConnection)) ++ : nullptr; ++} ++ ++void JInspector::registerNatives() { ++ JLocalConnection::registerNatives(); ++ javaClassStatic()->registerNatives({ ++ makeNativeMethod("instance", JInspector::instance), ++ makeNativeMethod("getPagesNative", JInspector::getPages), ++ makeNativeMethod("connectNative", JInspector::connect), ++ }); ++} ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JInspector.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JInspector.h +new file mode 100644 +index 0000000..897976e +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JInspector.h +@@ -0,0 +1,77 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++ ++#include ++ ++#include ++ ++namespace facebook::react { ++ ++class JPage : public jni::JavaClass { ++ public: ++ static constexpr auto kJavaDescriptor = ++ "Lcom/facebook/react/bridge/Inspector$Page;"; ++ ++ static jni::local_ref ++ create(int id, const std::string& title, const std::string& vm); ++}; ++ ++class JRemoteConnection : public jni::JavaClass { ++ public: ++ static constexpr auto kJavaDescriptor = ++ "Lcom/facebook/react/bridge/Inspector$RemoteConnection;"; ++ ++ void onMessage(const std::string& message) const; ++ void onDisconnect() const; ++}; ++ ++class JLocalConnection : public jni::HybridClass { ++ public: ++ static constexpr auto kJavaDescriptor = ++ "Lcom/facebook/react/bridge/Inspector$LocalConnection;"; ++ ++ JLocalConnection( ++ std::unique_ptr connection); ++ ++ void sendMessage(std::string message); ++ void disconnect(); ++ ++ static void registerNatives(); ++ ++ private: ++ std::unique_ptr connection_; ++}; ++ ++class JInspector : public jni::HybridClass { ++ public: ++ static constexpr auto kJavaDescriptor = ++ "Lcom/facebook/react/bridge/Inspector;"; ++ ++ static jni::global_ref instance( ++ jni::alias_ref); ++ ++ jni::local_ref> getPages(); ++ jni::local_ref connect( ++ int pageId, ++ jni::alias_ref remote); ++ ++ static void registerNatives(); ++ ++ private: ++ friend HybridBase; ++ ++ JInspector(jsinspector_modern::IInspector* inspector) ++ : inspector_(inspector) {} ++ ++ jsinspector_modern::IInspector* inspector_; ++}; ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JMessageQueueThread.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JMessageQueueThread.cpp +new file mode 100644 +index 0000000..e945c01 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JMessageQueueThread.cpp +@@ -0,0 +1,99 @@ ++/* ++ * 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. ++ */ ++ ++#include "JMessageQueueThread.h" ++ ++#include ++#include ++ ++#include ++#include ++#include ++ ++namespace facebook::react { ++ ++using namespace jni; ++ ++namespace { ++ ++std::function wrapRunnable(std::function&& runnable) { ++ return [runnable = std::move(runnable)]() mutable { ++ if (!runnable) { ++ // Runnable is empty, nothing to run. ++ return; ++ } ++ ++ auto localRunnable = std::move(runnable); ++ ++ // Clearing `runnable` to free all associated resources that stored lambda ++ // might retain. ++ runnable = nullptr; ++ ++ try { ++ localRunnable(); ++ } catch (const jsi::JSError& ex) { ++ // We can't do as much parsing here as we do in ExceptionManager.js ++ std::string message = ex.getMessage() + ", stack:\n" + ex.getStack(); ++ throwNewJavaException( ++ "com/facebook/react/common/JavascriptException", message.c_str()); ++ } ++ }; ++} ++ ++} // namespace ++ ++JMessageQueueThread::JMessageQueueThread( ++ alias_ref jobj) ++ : m_jobj(make_global(jobj)) {} ++ ++void JMessageQueueThread::runOnQueue(std::function&& runnable) { ++ // For C++ modules, this can be called from an arbitrary thread ++ // managed by the module, via callJSCallback or callJSFunction. So, ++ // we ensure that it is registered with the JVM. ++ jni::ThreadScope guard; ++ static auto method = ++ JavaMessageQueueThread::javaClassStatic() ++ ->getMethod("runOnQueue"); ++ auto jrunnable = ++ JNativeRunnable::newObjectCxxArgs(wrapRunnable(std::move(runnable))); ++ method(m_jobj, jrunnable.get()); ++} ++ ++void JMessageQueueThread::runOnQueueSync(std::function&& runnable) { ++ static auto jIsOnThread = ++ JavaMessageQueueThread::javaClassStatic()->getMethod( ++ "isOnThread"); ++ ++ if (jIsOnThread(m_jobj)) { ++ wrapRunnable(std::move(runnable))(); ++ } else { ++ std::mutex signalMutex; ++ std::condition_variable signalCv; ++ bool runnableComplete = false; ++ ++ runOnQueue([&]() mutable { ++ std::scoped_lock lock(signalMutex); ++ ++ runnable(); ++ runnableComplete = true; ++ ++ signalCv.notify_one(); ++ }); ++ ++ std::unique_lock lock(signalMutex); ++ signalCv.wait(lock, [&runnableComplete] { return runnableComplete; }); ++ } ++} ++ ++void JMessageQueueThread::quitSynchronous() { ++ static auto method = ++ JavaMessageQueueThread::javaClassStatic()->getMethod( ++ "quitSynchronous"); ++ method(m_jobj); ++} ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JMessageQueueThread.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JMessageQueueThread.h +new file mode 100644 +index 0000000..716e58b +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JMessageQueueThread.h +@@ -0,0 +1,49 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++ ++#include ++#include ++ ++namespace facebook::react { ++ ++class JavaMessageQueueThread : public jni::JavaClass { ++ public: ++ static constexpr auto kJavaDescriptor = ++ "Lcom/facebook/react/bridge/queue/MessageQueueThread;"; ++}; ++ ++class JMessageQueueThread : public MessageQueueThread { ++ public: ++ JMessageQueueThread(jni::alias_ref jobj); ++ ++ /** ++ * Enqueues the given function to run on this MessageQueueThread. ++ */ ++ void runOnQueue(std::function&& runnable) override; ++ ++ /** ++ * Synchronously executes the given function to run on this ++ * MessageQueueThread, waiting until it completes. Can be called from any ++ * thread, but will block if not called on this MessageQueueThread. ++ */ ++ void runOnQueueSync(std::function&& runnable) override; ++ ++ /** ++ * Synchronously quits the current MessageQueueThread. Can be called from any ++ * thread, but will block if not called on this MessageQueueThread. ++ */ ++ void quitSynchronous() override; ++ ++ private: ++ jni::global_ref m_jobj; ++}; ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JReactCxxErrorHandler.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JReactCxxErrorHandler.cpp +new file mode 100644 +index 0000000..8aff63d +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JReactCxxErrorHandler.cpp +@@ -0,0 +1,18 @@ ++/* ++ * 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. ++ */ ++ ++#include "JReactCxxErrorHandler.h" ++ ++using namespace facebook::react; ++ ++void JReactCxxErrorHandler::handleError(std::string message) { ++ static const auto handleError = ++ javaClassStatic()->getStaticMethod( ++ "handleError"); ++ ++ return handleError(javaClassStatic(), message); ++} +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JReactCxxErrorHandler.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JReactCxxErrorHandler.h +new file mode 100644 +index 0000000..e54dbde +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JReactCxxErrorHandler.h +@@ -0,0 +1,23 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++#include ++ ++namespace facebook::react { ++ ++class JReactCxxErrorHandler : public jni::JavaClass { ++ public: ++ static constexpr const char* kJavaDescriptor = ++ "Lcom/facebook/react/bridge/ReactCxxErrorHandler;"; ++ ++ static void handleError(std::string message); ++}; ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JReactMarker.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JReactMarker.cpp +new file mode 100644 +index 0000000..131237c +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JReactMarker.cpp +@@ -0,0 +1,171 @@ ++/* ++ * 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. ++ */ ++ ++#include "JReactMarker.h" ++#include ++#include ++#include ++#include ++ ++namespace facebook::react { ++ ++void JReactMarker::setLogPerfMarkerIfNeeded() { ++ static std::once_flag flag{}; ++ std::call_once(flag, []() { ++ ReactMarker::logTaggedMarkerImpl = JReactMarker::logPerfMarker; ++ ReactMarker::logTaggedMarkerBridgelessImpl = ++ JReactMarker::logPerfMarkerBridgeless; ++ }); ++} ++ ++void JReactMarker::logMarker(const std::string& marker) { ++ static auto cls = javaClassStatic(); ++ static auto meth = cls->getStaticMethod("logMarker"); ++ meth(cls, marker); ++} ++ ++void JReactMarker::logMarker( ++ const std::string& marker, ++ const std::string& tag) { ++ static auto cls = javaClassStatic(); ++ static auto meth = ++ cls->getStaticMethod("logMarker"); ++ meth(cls, marker, tag); ++} ++ ++void JReactMarker::logMarker( ++ const std::string& marker, ++ const std::string& tag, ++ const int instanceKey) { ++ static auto cls = javaClassStatic(); ++ static auto meth = ++ cls->getStaticMethod("logMarker"); ++ meth(cls, marker, tag, instanceKey); ++} ++ ++void JReactMarker::logPerfMarker( ++ const ReactMarker::ReactMarkerId markerId, ++ const char* tag) { ++ const int bridgeInstanceKey = 0; ++ logPerfMarkerWithInstanceKey(markerId, tag, bridgeInstanceKey); ++} ++ ++void JReactMarker::logPerfMarkerBridgeless( ++ const ReactMarker::ReactMarkerId markerId, ++ const char* tag) { ++ const int bridgelessInstanceKey = 1; ++ logPerfMarkerWithInstanceKey(markerId, tag, bridgelessInstanceKey); ++} ++ ++void JReactMarker::logPerfMarkerWithInstanceKey( ++ const ReactMarker::ReactMarkerId markerId, ++ const char* tag, ++ const int instanceKey) { ++ switch (markerId) { ++ case ReactMarker::APP_STARTUP_START: ++ JReactMarker::logMarker("APP_STARTUP_START"); ++ break; ++ case ReactMarker::APP_STARTUP_STOP: ++ JReactMarker::logMarker("APP_STARTUP_END"); ++ break; ++ case ReactMarker::INIT_REACT_RUNTIME_START: ++ JReactMarker::logMarker("INIT_REACT_RUNTIME_START"); ++ break; ++ case ReactMarker::INIT_REACT_RUNTIME_STOP: ++ JReactMarker::logMarker("INIT_REACT_RUNTIME_END"); ++ break; ++ case ReactMarker::RUN_JS_BUNDLE_START: ++ JReactMarker::logMarker("RUN_JS_BUNDLE_START", tag, instanceKey); ++ break; ++ case ReactMarker::RUN_JS_BUNDLE_STOP: ++ JReactMarker::logMarker("RUN_JS_BUNDLE_END", tag, instanceKey); ++ break; ++ case ReactMarker::CREATE_REACT_CONTEXT_STOP: ++ JReactMarker::logMarker("CREATE_REACT_CONTEXT_END"); ++ break; ++ case ReactMarker::JS_BUNDLE_STRING_CONVERT_START: ++ JReactMarker::logMarker("loadApplicationScript_startStringConvert"); ++ break; ++ case ReactMarker::JS_BUNDLE_STRING_CONVERT_STOP: ++ JReactMarker::logMarker("loadApplicationScript_endStringConvert"); ++ break; ++ case ReactMarker::NATIVE_MODULE_SETUP_START: ++ JReactMarker::logMarker("NATIVE_MODULE_SETUP_START", tag, instanceKey); ++ break; ++ case ReactMarker::NATIVE_MODULE_SETUP_STOP: ++ JReactMarker::logMarker("NATIVE_MODULE_SETUP_END", tag, instanceKey); ++ break; ++ case ReactMarker::REGISTER_JS_SEGMENT_START: ++ JReactMarker::logMarker("REGISTER_JS_SEGMENT_START", tag, instanceKey); ++ break; ++ case ReactMarker::REGISTER_JS_SEGMENT_STOP: ++ JReactMarker::logMarker("REGISTER_JS_SEGMENT_STOP", tag, instanceKey); ++ break; ++ case ReactMarker::NATIVE_REQUIRE_START: ++ case ReactMarker::NATIVE_REQUIRE_STOP: ++ case ReactMarker::REACT_INSTANCE_INIT_START: ++ case ReactMarker::REACT_INSTANCE_INIT_STOP: ++ // These are not used on Android. ++ break; ++ } ++} ++ ++void JReactMarker::nativeLogMarker( ++ jni::alias_ref /* unused */, ++ std::string markerNameStr, ++ jlong markerTime) { ++ // TODO: refactor this to a bidirectional map along with ++ // logPerfMarkerWithInstanceKey ++ if (markerNameStr == "APP_STARTUP_START") { ++ ReactMarker::logMarkerDone( ++ ReactMarker::APP_STARTUP_START, (double)markerTime); ++ } else if (markerNameStr == "APP_STARTUP_END") { ++ ReactMarker::logMarkerDone( ++ ReactMarker::APP_STARTUP_STOP, (double)markerTime); ++ } else if (markerNameStr == "INIT_REACT_RUNTIME_START") { ++ ReactMarker::logMarkerDone( ++ ReactMarker::INIT_REACT_RUNTIME_START, (double)markerTime); ++ } else if (markerNameStr == "INIT_REACT_RUNTIME_END") { ++ ReactMarker::logMarkerDone( ++ ReactMarker::INIT_REACT_RUNTIME_STOP, (double)markerTime); ++ } else if (markerNameStr == "RUN_JS_BUNDLE_START") { ++ ReactMarker::logMarkerDone( ++ ReactMarker::RUN_JS_BUNDLE_START, (double)markerTime); ++ } else if (markerNameStr == "RUN_JS_BUNDLE_END") { ++ ReactMarker::logMarkerDone( ++ ReactMarker::RUN_JS_BUNDLE_STOP, (double)markerTime); ++ } else if (markerNameStr == "CREATE_REACT_CONTEXT_END") { ++ ReactMarker::logMarkerDone( ++ ReactMarker::CREATE_REACT_CONTEXT_STOP, (double)markerTime); ++ } else if (markerNameStr == "loadApplicationScript_startStringConvert") { ++ ReactMarker::logMarkerDone( ++ ReactMarker::JS_BUNDLE_STRING_CONVERT_START, (double)markerTime); ++ } else if (markerNameStr == "loadApplicationScript_endStringConvert") { ++ ReactMarker::logMarkerDone( ++ ReactMarker::JS_BUNDLE_STRING_CONVERT_STOP, (double)markerTime); ++ } else if (markerNameStr == "NATIVE_MODULE_SETUP_START") { ++ ReactMarker::logMarkerDone( ++ ReactMarker::NATIVE_MODULE_SETUP_START, (double)markerTime); ++ } else if (markerNameStr == "NATIVE_MODULE_SETUP_END") { ++ ReactMarker::logMarkerDone( ++ ReactMarker::NATIVE_MODULE_SETUP_STOP, (double)markerTime); ++ } else if (markerNameStr == "REGISTER_JS_SEGMENT_START") { ++ ReactMarker::logMarkerDone( ++ ReactMarker::REGISTER_JS_SEGMENT_START, (double)markerTime); ++ } else if (markerNameStr == "REGISTER_JS_SEGMENT_STOP") { ++ ReactMarker::logMarkerDone( ++ ReactMarker::REGISTER_JS_SEGMENT_STOP, (double)markerTime); ++ } ++} ++ ++void JReactMarker::registerNatives() { ++ javaClassLocal()->registerNatives({ ++ makeNativeMethod("nativeLogMarker", JReactMarker::nativeLogMarker), ++ }); ++} ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JReactMarker.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JReactMarker.h +new file mode 100644 +index 0000000..5094b01 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JReactMarker.h +@@ -0,0 +1,47 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++#include ++ ++#include ++ ++namespace facebook::react { ++ ++class JReactMarker : public facebook::jni::JavaClass { ++ public: ++ static constexpr auto kJavaDescriptor = ++ "Lcom/facebook/react/bridge/ReactMarker;"; ++ static void registerNatives(); ++ static void setLogPerfMarkerIfNeeded(); ++ ++ private: ++ static void logMarker(const std::string& marker); ++ static void logMarker(const std::string& marker, const std::string& tag); ++ static void logMarker( ++ const std::string& marker, ++ const std::string& tag, ++ const int instanceKey); ++ static void logPerfMarker( ++ const ReactMarker::ReactMarkerId markerId, ++ const char* tag); ++ static void logPerfMarkerBridgeless( ++ const ReactMarker::ReactMarkerId markerId, ++ const char* tag); ++ static void logPerfMarkerWithInstanceKey( ++ const ReactMarker::ReactMarkerId markerId, ++ const char* tag, ++ const int instanceKey); ++ static void nativeLogMarker( ++ jni::alias_ref /* unused */, ++ std::string markerNameStr, ++ jlong markerTime); ++}; ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JReactSoftExceptionLogger.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JReactSoftExceptionLogger.cpp +new file mode 100644 +index 0000000..7f1cf1d +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JReactSoftExceptionLogger.cpp +@@ -0,0 +1,21 @@ ++/* ++ * 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. ++ */ ++ ++#include "JReactSoftExceptionLogger.h" ++ ++using namespace facebook::react; ++ ++void JReactSoftExceptionLogger::logNoThrowSoftExceptionWithMessage( ++ std::string tag, ++ std::string message) { ++ static const auto logNoThrowSoftExceptionWithMessage = ++ javaClassStatic() ++ ->getStaticMethod( ++ "logNoThrowSoftExceptionWithMessage"); ++ ++ return logNoThrowSoftExceptionWithMessage(javaClassStatic(), tag, message); ++} +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JReactSoftExceptionLogger.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JReactSoftExceptionLogger.h +new file mode 100644 +index 0000000..c8ea6e1 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JReactSoftExceptionLogger.h +@@ -0,0 +1,26 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++#include ++ ++namespace facebook::react { ++ ++class JReactSoftExceptionLogger ++ : public jni::JavaClass { ++ public: ++ static constexpr const char* kJavaDescriptor = ++ "Lcom/facebook/react/bridge/ReactSoftExceptionLogger;"; ++ ++ static void logNoThrowSoftExceptionWithMessage( ++ std::string tag, ++ std::string message); ++}; ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JRuntimeExecutor.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JRuntimeExecutor.cpp +new file mode 100644 +index 0000000..433e6ed +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JRuntimeExecutor.cpp +@@ -0,0 +1,19 @@ ++/* ++ * 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. ++ */ ++ ++#include "JRuntimeExecutor.h" ++ ++namespace facebook::react { ++ ++JRuntimeExecutor::JRuntimeExecutor(RuntimeExecutor runtimeExecutor) ++ : runtimeExecutor_(runtimeExecutor) {} ++ ++RuntimeExecutor JRuntimeExecutor::get() { ++ return runtimeExecutor_; ++} ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JRuntimeExecutor.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JRuntimeExecutor.h +new file mode 100644 +index 0000000..b614ad1 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JRuntimeExecutor.h +@@ -0,0 +1,28 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++#include ++ ++namespace facebook::react { ++ ++class JRuntimeExecutor : public jni::HybridClass { ++ public: ++ static auto constexpr kJavaDescriptor = ++ "Lcom/facebook/react/bridge/RuntimeExecutor;"; ++ ++ RuntimeExecutor get(); ++ ++ private: ++ friend HybridBase; ++ JRuntimeExecutor(RuntimeExecutor runtimeExecutor); ++ RuntimeExecutor runtimeExecutor_; ++}; ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JRuntimeScheduler.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JRuntimeScheduler.cpp +new file mode 100644 +index 0000000..587c324 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JRuntimeScheduler.cpp +@@ -0,0 +1,20 @@ ++/* ++ * 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. ++ */ ++ ++#include "JRuntimeScheduler.h" ++ ++namespace facebook::react { ++ ++JRuntimeScheduler::JRuntimeScheduler( ++ std::weak_ptr runtimeScheduler) ++ : runtimeScheduler_(runtimeScheduler) {} ++ ++std::weak_ptr JRuntimeScheduler::get() { ++ return runtimeScheduler_; ++} ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JRuntimeScheduler.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JRuntimeScheduler.h +new file mode 100644 +index 0000000..6220cce +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JRuntimeScheduler.h +@@ -0,0 +1,28 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++#include ++ ++namespace facebook::react { ++ ++class JRuntimeScheduler : public jni::HybridClass { ++ public: ++ static auto constexpr kJavaDescriptor = ++ "Lcom/facebook/react/bridge/RuntimeScheduler;"; ++ ++ std::weak_ptr get(); ++ ++ private: ++ friend HybridBase; ++ JRuntimeScheduler(std::weak_ptr runtimeScheduler); ++ std::weak_ptr runtimeScheduler_; ++}; ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JSLoader.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JSLoader.cpp +new file mode 100644 +index 0000000..03921b5 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JSLoader.cpp +@@ -0,0 +1,97 @@ ++/* ++ * 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. ++ */ ++ ++#include "JSLoader.h" ++ ++#include ++#include ++#include ++#include ++#include ++ ++#ifdef WITH_FBSYSTRACE ++#include ++using fbsystrace::FbSystraceSection; ++#endif ++ ++using namespace facebook::jni; ++ ++namespace facebook::react { ++ ++class AssetManagerString : public JSBigString { ++ public: ++ AssetManagerString(AAsset* asset) : asset_(asset){}; ++ ++ virtual ~AssetManagerString() { ++ AAsset_close(asset_); ++ } ++ ++ bool isAscii() const override { ++ return false; ++ } ++ ++ const char* c_str() const override { ++ return (const char*)AAsset_getBuffer(asset_); ++ } ++ ++ // Length of the c_str without the NULL byte. ++ size_t size() const override { ++ return AAsset_getLength(asset_); ++ } ++ ++ private: ++ AAsset* asset_; ++}; ++ ++__attribute__((visibility("default"))) AAssetManager* extractAssetManager( ++ alias_ref assetManager) { ++ auto env = Environment::current(); ++ return AAssetManager_fromJava(env, assetManager.get()); ++} ++ ++__attribute__((visibility("default"))) std::unique_ptr ++loadScriptFromAssets(AAssetManager* manager, const std::string& assetName) { ++#ifdef WITH_FBSYSTRACE ++ FbSystraceSection s( ++ TRACE_TAG_REACT_CXX_BRIDGE, ++ "reactbridge_jni_loadScriptFromAssets", ++ "assetName", ++ assetName); ++#endif ++ if (manager) { ++ auto asset = AAssetManager_open( ++ manager, ++ assetName.c_str(), ++ AASSET_MODE_STREAMING); // Optimized for sequential read: see ++ // AssetManager.java for docs ++ if (asset) { ++ auto script = std::make_unique(asset); ++ if (script->size() >= sizeof(BundleHeader)) { ++ // When using bytecode, it's safe for the underlying buffer to not be \0 ++ // terminated. In all other scenarios, we will force a copy of the ++ // script to ensure we have a terminator. ++ const BundleHeader* header = ++ reinterpret_cast(script->c_str()); ++ if (isHermesBytecodeBundle(*header)) { ++ return script; ++ } ++ } ++ ++ auto buf = std::make_unique(script->size()); ++ memcpy(buf->data(), script->c_str(), script->size()); ++ return buf; ++ } ++ } ++ ++ throw std::runtime_error(folly::to( ++ "Unable to load script. Make sure you're " ++ "either running Metro (run 'npx react-native start') or that your bundle '", ++ assetName, ++ "' is packaged correctly for release.")); ++} ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JSLoader.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JSLoader.h +new file mode 100644 +index 0000000..1d18db4 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JSLoader.h +@@ -0,0 +1,32 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++ ++#include ++#include ++#include ++ ++namespace facebook::react { ++ ++struct JAssetManager : jni::JavaClass { ++ static constexpr auto kJavaDescriptor = "Landroid/content/res/AssetManager;"; ++}; ++ ++/** ++ * Helper method for loading JS script from android asset ++ */ ++AAssetManager* extractAssetManager( ++ jni::alias_ref assetManager); ++ ++std::unique_ptr loadScriptFromAssets( ++ AAssetManager* assetManager, ++ const std::string& assetName); ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JSLogging.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JSLogging.cpp +new file mode 100644 +index 0000000..243b41f +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JSLogging.cpp +@@ -0,0 +1,27 @@ ++/* ++ * 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. ++ */ ++ ++#include "JSLogging.h" ++ ++#include ++ ++namespace facebook::react { ++ ++void reactAndroidLoggingHook( ++ const std::string& message, ++ android_LogPriority logLevel) { ++ FBLOG_PRI(logLevel, "ReactNativeJS", "%s", message.c_str()); ++} ++ ++void reactAndroidLoggingHook( ++ const std::string& message, ++ unsigned int logLevel) { ++ reactAndroidLoggingHook( ++ message, static_cast(logLevel + ANDROID_LOG_DEBUG)); ++} ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JSLogging.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JSLogging.h +new file mode 100644 +index 0000000..d236f24 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JSLogging.h +@@ -0,0 +1,20 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++#include ++ ++namespace facebook::react { ++ ++void reactAndroidLoggingHook( ++ const std::string& message, ++ android_LogPriority logLevel); ++void reactAndroidLoggingHook(const std::string& message, unsigned int logLevel); ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JavaModuleWrapper.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JavaModuleWrapper.cpp +new file mode 100644 +index 0000000..1f4b7c1 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JavaModuleWrapper.cpp +@@ -0,0 +1,161 @@ ++/* ++ * 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. ++ */ ++ ++#include "JavaModuleWrapper.h" ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#ifdef WITH_FBSYSTRACE ++#include ++#endif ++ ++#include "CatalystInstanceImpl.h" ++#include "ReadableNativeArray.h" ++ ++using facebook::xplat::module::CxxModule; ++ ++namespace facebook::react { ++ ++std::string JMethodDescriptor::getSignature() const { ++ static auto signature = javaClassStatic()->getField("signature"); ++ return getFieldValue(signature)->toStdString(); ++} ++ ++std::string JMethodDescriptor::getName() const { ++ static auto name = javaClassStatic()->getField("name"); ++ return getFieldValue(name)->toStdString(); ++} ++ ++std::string JMethodDescriptor::getType() const { ++ static auto type = javaClassStatic()->getField("type"); ++ return getFieldValue(type)->toStdString(); ++} ++ ++std::string JavaNativeModule::getName() { ++ static auto getNameMethod = ++ wrapper_->getClass()->getMethod("getName"); ++ return getNameMethod(wrapper_)->toStdString(); ++} ++ ++std::string JavaNativeModule::getSyncMethodName(unsigned int reactMethodId) { ++ if (reactMethodId >= syncMethods_.size()) { ++ throw std::invalid_argument(folly::to( ++ "methodId ", ++ reactMethodId, ++ " out of range [0..", ++ syncMethods_.size(), ++ "]")); ++ } ++ ++ auto& methodInvoker = syncMethods_[reactMethodId]; ++ ++ if (!methodInvoker.has_value()) { ++ throw std::invalid_argument(folly::to( ++ "methodId ", reactMethodId, " is not a recognized sync method")); ++ } ++ ++ return methodInvoker->getMethodName(); ++} ++ ++std::vector JavaNativeModule::getMethods() { ++ std::vector ret; ++ syncMethods_.clear(); ++ auto descs = wrapper_->getMethodDescriptors(); ++ for (const auto& desc : *descs) { ++ auto methodName = desc->getName(); ++ auto methodType = desc->getType(); ++ ++ if (methodType == "sync") { ++ // allow for the sync methods vector to have empty values, resize on ++ // demand ++ size_t methodIndex = ret.size(); ++ if (methodIndex >= syncMethods_.size()) { ++ syncMethods_.resize(methodIndex + 1); ++ } ++ syncMethods_.insert( ++ syncMethods_.begin() + methodIndex, ++ MethodInvoker( ++ desc->getMethod(), ++ methodName, ++ desc->getSignature(), ++ getName() + "." + methodName, ++ true)); ++ } ++ ++ ret.emplace_back(std::move(methodName), std::move(methodType)); ++ } ++ return ret; ++} ++ ++folly::dynamic JavaNativeModule::getConstants() { ++ static auto constantsMethod = ++ wrapper_->getClass()->getMethod("getConstants"); ++ auto constants = constantsMethod(wrapper_); ++ if (!constants) { ++ return nullptr; ++ } else { ++ return cthis(constants)->consume(); ++ } ++} ++ ++void JavaNativeModule::invoke( ++ unsigned int reactMethodId, ++ folly::dynamic&& params, ++ int callId) { ++ messageQueueThread_->runOnQueue( ++ [this, reactMethodId, params = std::move(params), callId] { ++ static auto invokeMethod = ++ wrapper_->getClass() ++ ->getMethod( ++ "invoke"); ++#ifdef WITH_FBSYSTRACE ++ if (callId != -1) { ++ fbsystrace_end_async_flow(TRACE_TAG_REACT_APPS, "native", callId); ++ } ++#endif ++ invokeMethod( ++ wrapper_, ++ static_cast(reactMethodId), ++ ReadableNativeArray::newObjectCxxArgs(std::move(params)).get()); ++ }); ++} ++ ++MethodCallResult JavaNativeModule::callSerializableNativeHook( ++ unsigned int reactMethodId, ++ folly::dynamic&& params) { ++ // TODO: evaluate whether calling through invoke is potentially faster ++ if (reactMethodId >= syncMethods_.size()) { ++ throw std::invalid_argument(folly::to( ++ "methodId ", ++ reactMethodId, ++ " out of range [0..", ++ syncMethods_.size(), ++ "]")); ++ } ++ ++ auto& method = syncMethods_[reactMethodId]; ++ CHECK(method.has_value() && method->isSyncHook()) ++ << "Trying to invoke a asynchronous method as synchronous hook"; ++ return method->invoke(instance_, wrapper_->getModule(), params); ++} ++ ++jni::local_ref JMethodDescriptor::getMethod() ++ const { ++ static auto method = ++ javaClassStatic()->getField("method"); ++ return getFieldValue(method); ++} ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JavaModuleWrapper.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JavaModuleWrapper.h +new file mode 100644 +index 0000000..1e3929a +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JavaModuleWrapper.h +@@ -0,0 +1,87 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++#include ++#include ++ ++#include "MethodInvoker.h" ++ ++namespace facebook::react { ++ ++class Instance; ++class MessageQueueThread; ++ ++struct JMethodDescriptor : public jni::JavaClass { ++ static constexpr auto kJavaDescriptor = ++ "Lcom/facebook/react/bridge/JavaModuleWrapper$MethodDescriptor;"; ++ ++ jni::local_ref getMethod() const; ++ std::string getSignature() const; ++ std::string getName() const; ++ std::string getType() const; ++}; ++ ++struct JavaModuleWrapper : jni::JavaClass { ++ static constexpr auto kJavaDescriptor = ++ "Lcom/facebook/react/bridge/JavaModuleWrapper;"; ++ ++ jni::local_ref getModule() { ++ // This is the call which causes a lazy Java module to actually be ++ // created. ++ static auto getModule = ++ javaClassStatic()->getMethod( ++ "getModule"); ++ return getModule(self()); ++ } ++ ++ std::string getName() const { ++ static auto getName = javaClassStatic()->getMethod("getName"); ++ return getName(self())->toStdString(); ++ } ++ ++ jni::local_ref::javaobject> ++ getMethodDescriptors() { ++ static auto getMethods = ++ getClass() ++ ->getMethod< ++ jni::JList::javaobject()>( ++ "getMethodDescriptors"); ++ return getMethods(self()); ++ } ++}; ++ ++class JavaNativeModule : public NativeModule { ++ public: ++ JavaNativeModule( ++ std::weak_ptr instance, ++ jni::alias_ref wrapper, ++ std::shared_ptr messageQueueThread) ++ : instance_(std::move(instance)), ++ wrapper_(make_global(wrapper)), ++ messageQueueThread_(std::move(messageQueueThread)) {} ++ ++ std::string getName() override; ++ std::string getSyncMethodName(unsigned int reactMethodId) override; ++ folly::dynamic getConstants() override; ++ std::vector getMethods() override; ++ void invoke(unsigned int reactMethodId, folly::dynamic&& params, int callId) ++ override; ++ MethodCallResult callSerializableNativeHook( ++ unsigned int reactMethodId, ++ folly::dynamic&& params) override; ++ ++ private: ++ std::weak_ptr instance_; ++ jni::global_ref wrapper_; ++ std::shared_ptr messageQueueThread_; ++ std::vector> syncMethods_; ++}; ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JavaScriptExecutorHolder.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JavaScriptExecutorHolder.h +new file mode 100644 +index 0000000..55cbc3e +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JavaScriptExecutorHolder.h +@@ -0,0 +1,33 @@ ++/* ++ * 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. ++ */ ++ ++#include ++ ++#include ++#include ++ ++namespace facebook::react { ++ ++class JavaScriptExecutorHolder ++ : public jni::HybridClass { ++ public: ++ static constexpr auto kJavaDescriptor = ++ "Lcom/facebook/react/bridge/JavaScriptExecutor;"; ++ ++ std::shared_ptr getExecutorFactory() { ++ return mExecutorFactory; ++ } ++ ++ protected: ++ JavaScriptExecutorHolder(std::shared_ptr factory) ++ : mExecutorFactory(factory) {} ++ ++ private: ++ std::shared_ptr mExecutorFactory; ++}; ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JniJSModulesUnbundle.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JniJSModulesUnbundle.cpp +new file mode 100644 +index 0000000..f192010 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JniJSModulesUnbundle.cpp +@@ -0,0 +1,96 @@ ++/* ++ * 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. ++ */ ++ ++#include "JniJSModulesUnbundle.h" ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++using magic_number_t = uint32_t; ++const magic_number_t MAGIC_FILE_HEADER = 0xFB0BD1E5; ++const char* MAGIC_FILE_NAME = "UNBUNDLE"; ++ ++namespace facebook::react { ++ ++using asset_ptr = ++ std::unique_ptr>; ++ ++static std::string jsModulesDir(const std::string& entryFile) { ++ std::string dir = dirname(entryFile.c_str()); ++ ++ // android's asset manager does not work with paths that start with a dot ++ return dir == "." ? "js-modules/" : dir + "/js-modules/"; ++} ++ ++static asset_ptr openAsset( ++ AAssetManager* manager, ++ const std::string& fileName, ++ int mode = AASSET_MODE_STREAMING) { ++ return asset_ptr( ++ AAssetManager_open(manager, fileName.c_str(), mode), AAsset_close); ++} ++ ++std::unique_ptr JniJSModulesUnbundle::fromEntryFile( ++ AAssetManager* assetManager, ++ const std::string& entryFile) { ++ return std::make_unique( ++ assetManager, jsModulesDir(entryFile)); ++} ++ ++JniJSModulesUnbundle::JniJSModulesUnbundle( ++ AAssetManager* assetManager, ++ const std::string& moduleDirectory) ++ : m_assetManager(assetManager), m_moduleDirectory(moduleDirectory) {} ++ ++bool JniJSModulesUnbundle::isUnbundle( ++ AAssetManager* assetManager, ++ const std::string& assetName) { ++ if (!assetManager) { ++ return false; ++ } ++ ++ auto magicFileName = jsModulesDir(assetName) + MAGIC_FILE_NAME; ++ auto asset = openAsset(assetManager, magicFileName.c_str()); ++ if (asset == nullptr) { ++ return false; ++ } ++ ++ magic_number_t fileHeader = 0; ++ AAsset_read(asset.get(), &fileHeader, sizeof(fileHeader)); ++ return fileHeader == htole32(MAGIC_FILE_HEADER); ++} ++ ++JSModulesUnbundle::Module JniJSModulesUnbundle::getModule( ++ uint32_t moduleId) const { ++ // can be nullptr for default constructor. ++ FBASSERTMSGF( ++ m_assetManager != nullptr, ++ "Unbundle has not been initialized with an asset manager"); ++ ++ std::ostringstream sourceUrlBuilder; ++ sourceUrlBuilder << moduleId << ".js"; ++ auto sourceUrl = sourceUrlBuilder.str(); ++ ++ auto fileName = m_moduleDirectory + sourceUrl; ++ auto asset = openAsset(m_assetManager, fileName, AASSET_MODE_BUFFER); ++ ++ const char* buffer = nullptr; ++ if (asset != nullptr) { ++ buffer = static_cast(AAsset_getBuffer(asset.get())); ++ } ++ if (buffer == nullptr) { ++ throw ModuleNotFound(moduleId); ++ } ++ return {sourceUrl, std::string(buffer, AAsset_getLength(asset.get()))}; ++} ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JniJSModulesUnbundle.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JniJSModulesUnbundle.h +new file mode 100644 +index 0000000..51578df +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/JniJSModulesUnbundle.h +@@ -0,0 +1,43 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++ ++#include ++#include ++ ++namespace facebook::react { ++ ++class JniJSModulesUnbundle : public JSModulesUnbundle { ++ /** ++ * This implementation reads modules as single file from the assets of an apk. ++ */ ++ public: ++ JniJSModulesUnbundle() = default; ++ JniJSModulesUnbundle( ++ AAssetManager* assetManager, ++ const std::string& moduleDirectory); ++ JniJSModulesUnbundle(JniJSModulesUnbundle&& other) = delete; ++ JniJSModulesUnbundle& operator=(JSModulesUnbundle&& other) = delete; ++ ++ static std::unique_ptr fromEntryFile( ++ AAssetManager* assetManager, ++ const std::string& entryFile); ++ ++ static bool isUnbundle( ++ AAssetManager* assetManager, ++ const std::string& assetName); ++ virtual Module getModule(uint32_t moduleId) const override; ++ ++ private: ++ AAssetManager* m_assetManager = nullptr; ++ std::string m_moduleDirectory; ++}; ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/MethodInvoker.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/MethodInvoker.cpp +new file mode 100644 +index 0000000..8c0e3ba +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/MethodInvoker.cpp +@@ -0,0 +1,314 @@ ++/* ++ * 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. ++ */ ++ ++#include "MethodInvoker.h" ++ ++#ifdef WITH_FBSYSTRACE ++#include ++#endif ++ ++#include ++ ++#include ++#include ++ ++#include "JCallback.h" ++#include "ReadableNativeArray.h" ++#include "ReadableNativeMap.h" ++#include "WritableNativeArray.h" ++#include "WritableNativeMap.h" ++ ++using namespace facebook::jni; ++ ++namespace facebook::react { ++ ++namespace { ++ ++using dynamic_iterator = folly::dynamic::const_iterator; ++ ++struct JPromiseImpl : public JavaClass { ++ constexpr static auto kJavaDescriptor = ++ "Lcom/facebook/react/bridge/PromiseImpl;"; ++ ++ static local_ref create( ++ local_ref resolve, ++ local_ref reject) { ++ return newInstance(resolve, reject); ++ } ++}; ++ ++// HACK: Exposes constructor ++struct ExposedReadableNativeArray : public ReadableNativeArray { ++ explicit ExposedReadableNativeArray(folly::dynamic array) ++ : ReadableNativeArray(std::move(array)) {} ++}; ++ ++jdouble extractDouble(const folly::dynamic& value) { ++ if (value.isInt()) { ++ return static_cast(value.getInt()); ++ } else { ++ return static_cast(value.getDouble()); ++ } ++} ++ ++jint extractInteger(const folly::dynamic& value) { ++ // The logic here is taken from convertDynamicIfIntegral, but the ++ // return type and exception are different. ++ if (value.isInt()) { ++ // TODO: this truncates 64 bit ints, valid in JS ++ return static_cast(value.getInt()); ++ } ++ double dbl = value.getDouble(); ++ jint result = static_cast(dbl); ++ if (dbl != result) { ++ throw std::invalid_argument(folly::to( ++ "Tried to convert jint argument, but got a non-integral double: ", ++ dbl)); ++ } ++ return result; ++} ++ ++local_ref extractCallback( ++ std::weak_ptr& instance, ++ const folly::dynamic& value) { ++ if (value.isNull()) { ++ return local_ref(nullptr); ++ } else { ++ return JCxxCallbackImpl::newObjectCxxArgs(makeCallback(instance, value)); ++ } ++} ++ ++local_ref extractPromise( ++ std::weak_ptr& instance, ++ dynamic_iterator& it, ++ dynamic_iterator& end) { ++ auto resolve = extractCallback(instance, *it++); ++ CHECK(it != end); ++ auto reject = extractCallback(instance, *it++); ++ return JPromiseImpl::create(resolve, reject); ++} ++ ++bool isNullable(char type) { ++ switch (type) { ++ case 'Z': ++ case 'I': ++ case 'F': ++ case 'S': ++ case 'A': ++ case 'M': ++ case 'X': ++ return true; ++ default: ++ return false; ++ ; ++ } ++} ++ ++jvalue extract( ++ std::weak_ptr& instance, ++ char type, ++ dynamic_iterator& it, ++ dynamic_iterator& end) { ++ CHECK(it != end); ++ jvalue value; ++ if (type == 'P') { ++ value.l = extractPromise(instance, it, end).release(); ++ return value; ++ } ++ ++ const auto& arg = *it++; ++ if (isNullable(type) && arg.isNull()) { ++ value.l = nullptr; ++ return value; ++ } ++ ++ switch (type) { ++ case 'z': ++ value.z = static_cast(arg.getBool()); ++ break; ++ case 'Z': ++ value.l = ++ JBoolean::valueOf(static_cast(arg.getBool())).release(); ++ break; ++ case 'i': ++ value.i = extractInteger(arg); ++ break; ++ case 'I': ++ value.l = JInteger::valueOf(extractInteger(arg)).release(); ++ break; ++ case 'f': ++ value.f = static_cast(extractDouble(arg)); ++ break; ++ case 'F': ++ value.l = ++ JFloat::valueOf(static_cast(extractDouble(arg))).release(); ++ break; ++ case 'd': ++ value.d = extractDouble(arg); ++ break; ++ case 'D': ++ value.l = JDouble::valueOf(extractDouble(arg)).release(); ++ break; ++ case 'S': ++ value.l = make_jstring(arg.getString().c_str()).release(); ++ break; ++ case 'A': ++ value.l = ReadableNativeArray::newObjectCxxArgs(arg).release(); ++ break; ++ case 'M': ++ value.l = ReadableNativeMap::newObjectCxxArgs(arg).release(); ++ break; ++ case 'X': ++ value.l = extractCallback(instance, arg).release(); ++ break; ++ default: ++ LOG(FATAL) << "Unknown param type: " << type; ++ } ++ return value; ++} ++ ++std::size_t countJsArgs(const std::string& signature) { ++ std::size_t count = 0; ++ for (char c : signature) { ++ switch (c) { ++ case 'P': ++ count += 2; ++ break; ++ default: ++ count += 1; ++ break; ++ } ++ } ++ return count; ++} ++ ++} // namespace ++ ++MethodInvoker::MethodInvoker( ++ alias_ref method, ++ std::string methodName, ++ std::string signature, ++ std::string traceName, ++ bool isSync) ++ : method_(method->getMethodID()), ++ methodName_(methodName), ++ signature_(signature), ++ jsArgCount_(countJsArgs(signature) - 2), ++ traceName_(std::move(traceName)), ++ isSync_(isSync) { ++ CHECK(signature_.at(1) == '.') << "Improper module method signature"; ++ CHECK(isSync_ || signature_.at(0) == 'v') ++ << "Non-sync hooks cannot have a non-void return type"; ++} ++ ++std::string MethodInvoker::getMethodName() const { ++ return methodName_; ++} ++ ++MethodCallResult MethodInvoker::invoke( ++ std::weak_ptr& instance, ++ alias_ref module, ++ const folly::dynamic& params) { ++#ifdef WITH_FBSYSTRACE ++ fbsystrace::FbSystraceSection s( ++ TRACE_TAG_REACT_CXX_BRIDGE, ++ isSync_ ? "callJavaSyncHook" : "callJavaModuleMethod", ++ "method", ++ traceName_); ++#endif ++ ++ if (params.size() != jsArgCount_) { ++ throw std::invalid_argument(folly::to( ++ "expected ", jsArgCount_, " arguments, got ", params.size())); ++ } ++ ++ auto env = Environment::current(); ++ auto argCount = signature_.size() - 2; ++ JniLocalScope scope(env, static_cast(argCount)); ++ jvalue args[argCount]; ++ std::transform( ++ signature_.begin() + 2, ++ signature_.end(), ++ args, ++ [&instance, it = params.begin(), end = params.end()](char type) mutable { ++ return extract(instance, type, it, end); ++ }); ++ ++#define PRIMITIVE_CASE(METHOD) \ ++ { \ ++ auto result = env->Call##METHOD##MethodA(module.get(), method_, args); \ ++ throwPendingJniExceptionAsCppException(); \ ++ return folly::dynamic(result); \ ++ } ++ ++#define PRIMITIVE_CASE_CASTING(METHOD, RESULT_TYPE) \ ++ { \ ++ auto result = env->Call##METHOD##MethodA(module.get(), method_, args); \ ++ throwPendingJniExceptionAsCppException(); \ ++ return folly::dynamic(static_cast(result)); \ ++ } ++ ++#define OBJECT_CASE(JNI_CLASS, ACTIONS) \ ++ { \ ++ auto jobject = env->CallObjectMethodA(module.get(), method_, args); \ ++ throwPendingJniExceptionAsCppException(); \ ++ if (!jobject) { \ ++ return folly::dynamic(nullptr); \ ++ } \ ++ auto result = adopt_local(static_cast(jobject)); \ ++ return folly::dynamic(result->ACTIONS()); \ ++ } ++ ++#define OBJECT_CASE_CASTING(JNI_CLASS, ACTIONS, RESULT_TYPE) \ ++ { \ ++ auto jobject = env->CallObjectMethodA(module.get(), method_, args); \ ++ throwPendingJniExceptionAsCppException(); \ ++ if (!jobject) { \ ++ return folly::dynamic(nullptr); \ ++ } \ ++ auto result = adopt_local(static_cast(jobject)); \ ++ return folly::dynamic(static_cast(result->ACTIONS())); \ ++ } ++ ++ char returnType = signature_.at(0); ++ switch (returnType) { ++ case 'v': ++ env->CallVoidMethodA(module.get(), method_, args); ++ throwPendingJniExceptionAsCppException(); ++ return std::nullopt; ++ ++ case 'z': ++ PRIMITIVE_CASE_CASTING(Boolean, bool) ++ case 'Z': ++ OBJECT_CASE_CASTING(JBoolean, value, bool) ++ case 'i': ++ PRIMITIVE_CASE(Int) ++ case 'I': ++ OBJECT_CASE(JInteger, value) ++ case 'd': ++ PRIMITIVE_CASE(Double) ++ case 'D': ++ OBJECT_CASE(JDouble, value) ++ case 'f': ++ PRIMITIVE_CASE(Float) ++ case 'F': ++ OBJECT_CASE(JFloat, value) ++ ++ case 'S': ++ OBJECT_CASE(JString, toStdString) ++ case 'M': ++ OBJECT_CASE(WritableNativeMap, cthis()->consume) ++ case 'A': ++ OBJECT_CASE(WritableNativeArray, cthis()->consume) ++ ++ default: ++ LOG(FATAL) << "Unknown return type: " << returnType; ++ return std::nullopt; ++ } ++} ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/MethodInvoker.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/MethodInvoker.h +new file mode 100644 +index 0000000..2c5cfb8 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/MethodInvoker.h +@@ -0,0 +1,64 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++ ++#include ++#include ++#include ++ ++namespace facebook::react { ++ ++class Instance; ++ ++struct JReflectMethod : public jni::JavaClass { ++ static constexpr auto kJavaDescriptor = "Ljava/lang/reflect/Method;"; ++ ++ jmethodID getMethodID() { ++ auto id = jni::Environment::current()->FromReflectedMethod(self()); ++ jni::throwPendingJniExceptionAsCppException(); ++ return id; ++ } ++}; ++ ++struct JBaseJavaModule : public jni::JavaClass { ++ static constexpr auto kJavaDescriptor = ++ "Lcom/facebook/react/bridge/BaseJavaModule;"; ++}; ++ ++class MethodInvoker { ++ public: ++ MethodInvoker( ++ jni::alias_ref method, ++ std::string methodName, ++ std::string signature, ++ std::string traceName, ++ bool isSync); ++ ++ MethodCallResult invoke( ++ std::weak_ptr& instance, ++ jni::alias_ref module, ++ const folly::dynamic& params); ++ ++ std::string getMethodName() const; ++ ++ bool isSyncHook() const { ++ return isSync_; ++ } ++ ++ private: ++ jmethodID method_; ++ std::string methodName_; ++ std::string signature_; ++ std::size_t jsArgCount_; ++ std::string traceName_; ++ bool isSync_; ++}; ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/ModuleRegistryBuilder.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/ModuleRegistryBuilder.cpp +new file mode 100644 +index 0000000..71de6e6 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/ModuleRegistryBuilder.cpp +@@ -0,0 +1,70 @@ ++/* ++ * 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. ++ */ ++ ++#include "ModuleRegistryBuilder.h" ++ ++#include ++#include ++#include ++ ++#include ++ ++namespace facebook::react { ++ ++std::string ModuleHolder::getName() const { ++ static auto method = getClass()->getMethod("getName"); ++ return method(self())->toStdString(); ++} ++ ++xplat::module::CxxModule::Provider ModuleHolder::getProvider( ++ const std::string& moduleName) const { ++ return [self = jni::make_global(self()), moduleName] { ++ static auto getModule = ++ ModuleHolder::javaClassStatic()->getMethod( ++ "getModule"); ++ // This is the call which uses the lazy Java Provider to instantiate the ++ // Java CxxModuleWrapper which contains the CxxModule. ++ auto module = getModule(self); ++ ++ CHECK(module->isInstanceOf(CxxModuleWrapperBase::javaClassStatic())) ++ << "NativeModule '" << moduleName << "' isn't a C++ module"; ++ ++ auto cxxModule = ++ jni::static_ref_cast(module); ++ // Then, we grab the CxxModule from the wrapper, which is no longer needed. ++ return cxxModule->cthis()->getModule(); ++ }; ++} ++ ++std::vector> buildNativeModuleList( ++ std::weak_ptr winstance, ++ jni::alias_ref::javaobject> ++ javaModules, ++ jni::alias_ref::javaobject> ++ cxxModules, ++ std::shared_ptr moduleMessageQueue) { ++ std::vector> modules; ++ if (javaModules) { ++ for (const auto& jm : *javaModules) { ++ modules.emplace_back(std::make_unique( ++ winstance, jm, moduleMessageQueue)); ++ } ++ } ++ if (cxxModules) { ++ for (const auto& cm : *cxxModules) { ++ std::string moduleName = cm->getName(); ++ modules.emplace_back(std::make_unique( ++ winstance, ++ moduleName, ++ cm->getProvider(moduleName), ++ moduleMessageQueue)); ++ } ++ } ++ return modules; ++} ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/ModuleRegistryBuilder.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/ModuleRegistryBuilder.h +new file mode 100644 +index 0000000..ec18985 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/ModuleRegistryBuilder.h +@@ -0,0 +1,38 @@ ++/* ++ * 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. ++ */ ++ ++#include ++ ++#include ++#include ++#include ++ ++#include "CxxModuleWrapper.h" ++#include "JavaModuleWrapper.h" ++ ++namespace facebook::react { ++ ++class MessageQueueThread; ++ ++class ModuleHolder : public jni::JavaClass { ++ public: ++ static auto constexpr kJavaDescriptor = ++ "Lcom/facebook/react/bridge/ModuleHolder;"; ++ ++ std::string getName() const; ++ xplat::module::CxxModule::Provider getProvider( ++ const std::string& moduleName) const; ++}; ++ ++std::vector> buildNativeModuleList( ++ std::weak_ptr winstance, ++ jni::alias_ref::javaobject> ++ javaModules, ++ jni::alias_ref::javaobject> ++ cxxModules, ++ std::shared_ptr moduleMessageQueue); ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/NativeArray.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/NativeArray.cpp +new file mode 100644 +index 0000000..179cd0a +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/NativeArray.cpp +@@ -0,0 +1,46 @@ ++/* ++ * 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. ++ */ ++ ++#include "NativeArray.h" ++ ++#include ++ ++using namespace facebook::jni; ++ ++namespace facebook::react { ++ ++void NativeArray::assertInternalType() { ++ if (!array_.isArray()) { ++ throwNewJavaException( ++ exceptions::gUnexpectedNativeTypeExceptionClass, ++ "expected Array, got a %s", ++ array_.typeName()); ++ } ++} ++ ++local_ref NativeArray::toString() { ++ throwIfConsumed(); ++ return make_jstring(folly::toJson(array_).c_str()); ++} ++ ++void NativeArray::registerNatives() { ++ registerHybrid({ ++ makeNativeMethod("toString", NativeArray::toString), ++ }); ++} ++ ++folly::dynamic NativeArray::consume() { ++ throwIfConsumed(); ++ isConsumed = true; ++ return std::move(array_); ++} ++ ++void NativeArray::throwIfConsumed() { ++ exceptions::throwIfObjectAlreadyConsumed(this, "Array already consumed"); ++} ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/NativeArray.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/NativeArray.h +new file mode 100644 +index 0000000..c708748 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/NativeArray.h +@@ -0,0 +1,50 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++#include ++ ++#include "NativeCommon.h" ++ ++namespace facebook::react { ++ ++class NativeArray : public jni::HybridClass { ++ public: ++ static auto constexpr* kJavaDescriptor = ++ "Lcom/facebook/react/bridge/NativeArray;"; ++ ++ jni::local_ref toString(); ++ ++ RN_EXPORT folly::dynamic consume(); ++ ++ // Whether this array has been added to another array or map and no longer ++ // has a valid array value. ++ bool isConsumed; ++ ++ static void registerNatives(); ++ ++ protected: ++ folly::dynamic array_; ++ ++ friend HybridBase; ++ ++ template ++ explicit NativeArray(Dyn&& array) ++ : isConsumed(false), array_(std::forward(array)) { ++ assertInternalType(); ++ } ++ ++ void assertInternalType(); ++ void throwIfConsumed(); ++ ++ NativeArray(const NativeArray&) = delete; ++ NativeArray& operator=(const NativeArray&) = delete; ++}; ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/NativeCommon.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/NativeCommon.cpp +new file mode 100644 +index 0000000..04078f1 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/NativeCommon.cpp +@@ -0,0 +1,63 @@ ++/* ++ * 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. ++ */ ++ ++#include "NativeCommon.h" ++ ++using namespace facebook::jni; ++ ++namespace facebook::react { ++ ++namespace exceptions { ++const char* gUnexpectedNativeTypeExceptionClass = ++ "com/facebook/react/bridge/UnexpectedNativeTypeException"; ++} ++ ++namespace { ++ ++// Returns a leaked global_ref. ++alias_ref getTypeField(const char* fieldName) { ++ static auto cls = ReadableType::javaClassStatic(); ++ auto field = cls->getStaticField(fieldName); ++ return make_global(cls->getStaticFieldValue(field)).release(); ++} ++ ++} // namespace ++ ++local_ref ReadableType::getType(folly::dynamic::Type type) { ++ switch (type) { ++ case folly::dynamic::Type::NULLT: { ++ static alias_ref val = getTypeField("Null"); ++ return make_local(val); ++ } ++ case folly::dynamic::Type::BOOL: { ++ static alias_ref val = getTypeField("Boolean"); ++ return make_local(val); ++ } ++ case folly::dynamic::Type::DOUBLE: ++ case folly::dynamic::Type::INT64: { ++ static alias_ref val = getTypeField("Number"); ++ return make_local(val); ++ } ++ case folly::dynamic::Type::STRING: { ++ static alias_ref val = getTypeField("String"); ++ return make_local(val); ++ } ++ case folly::dynamic::Type::OBJECT: { ++ static alias_ref val = getTypeField("Map"); ++ return make_local(val); ++ } ++ case folly::dynamic::Type::ARRAY: { ++ static alias_ref val = getTypeField("Array"); ++ return make_local(val); ++ } ++ default: ++ throwNewJavaException( ++ exceptions::gUnexpectedNativeTypeExceptionClass, "Unknown type"); ++ } ++} ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/NativeCommon.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/NativeCommon.h +new file mode 100644 +index 0000000..b3b7bc0 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/NativeCommon.h +@@ -0,0 +1,40 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++#include ++ ++#ifndef RN_EXPORT ++#define RN_EXPORT __attribute__((visibility("default"))) ++#endif ++ ++namespace facebook::react { ++ ++struct ReadableType : public jni::JavaClass { ++ static auto constexpr kJavaDescriptor = ++ "Lcom/facebook/react/bridge/ReadableType;"; ++ ++ static jni::local_ref getType(folly::dynamic::Type type); ++}; ++ ++namespace exceptions { ++ ++extern const char* gUnexpectedNativeTypeExceptionClass; ++ ++template ++void throwIfObjectAlreadyConsumed(const T& t, const char* msg) { ++ if (t->isConsumed) { ++ jni::throwNewJavaException( ++ "com/facebook/react/bridge/ObjectAlreadyConsumedException", msg); ++ } ++} ++ ++} // namespace exceptions ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/NativeMap.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/NativeMap.cpp +new file mode 100644 +index 0000000..31a01a1 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/NativeMap.cpp +@@ -0,0 +1,37 @@ ++/* ++ * 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. ++ */ ++ ++#include "NativeMap.h" ++ ++#include ++ ++using namespace facebook::jni; ++ ++namespace facebook::react { ++ ++local_ref NativeMap::toString() { ++ throwIfConsumed(); ++ return make_jstring(folly::toJson(map_).c_str()); ++} ++ ++void NativeMap::registerNatives() { ++ registerHybrid({ ++ makeNativeMethod("toString", NativeMap::toString), ++ }); ++} ++ ++folly::dynamic NativeMap::consume() { ++ throwIfConsumed(); ++ isConsumed = true; ++ return std::move(map_); ++} ++ ++void NativeMap::throwIfConsumed() { ++ exceptions::throwIfObjectAlreadyConsumed(this, "Map already consumed"); ++} ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/NativeMap.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/NativeMap.h +new file mode 100644 +index 0000000..a451c41 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/NativeMap.h +@@ -0,0 +1,47 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++#include ++ ++#include "NativeCommon.h" ++ ++namespace facebook::react { ++ ++class NativeMap : public jni::HybridClass { ++ public: ++ static auto constexpr kJavaDescriptor = ++ "Lcom/facebook/react/bridge/NativeMap;"; ++ ++ jni::local_ref toString(); ++ ++ RN_EXPORT folly::dynamic consume(); ++ ++ // Whether this map has been added to another array or map and no longer ++ // has a valid map value. ++ bool isConsumed; ++ ++ static void registerNatives(); ++ ++ protected: ++ folly::dynamic map_; ++ ++ friend HybridBase; ++ ++ template ++ explicit NativeMap(Dyn&& map) ++ : isConsumed(false), map_(std::forward(map)) {} ++ ++ void throwIfConsumed(); ++ ++ NativeMap(const NativeMap&) = delete; ++ NativeMap& operator=(const NativeMap&) = delete; ++}; ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/OnLoad.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/OnLoad.cpp +new file mode 100644 +index 0000000..a2077e8 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/OnLoad.cpp +@@ -0,0 +1,100 @@ ++/* ++ * 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. ++ */ ++ ++#include ++ ++#include ++ ++#include ++#include ++ ++#include "CatalystInstanceImpl.h" ++#include "CxxModuleWrapperBase.h" ++#include "JCallback.h" ++#include "JDynamicNative.h" ++#include "JInspector.h" ++#include "JReactMarker.h" ++#include "JavaScriptExecutorHolder.h" ++#include "ProxyExecutor.h" ++#include "ReactInstanceManagerInspectorTarget.h" ++#include "WritableNativeArray.h" ++#include "WritableNativeMap.h" ++ ++#ifndef WITH_GLOGINIT ++#define WITH_GLOGINIT 1 ++#endif ++ ++#ifdef WITH_XPLATINIT ++#include ++#endif ++ ++namespace facebook::react { ++ ++namespace { ++ ++struct JavaJSExecutor : public jni::JavaClass { ++ static constexpr auto kJavaDescriptor = ++ "Lcom/facebook/react/bridge/JavaJSExecutor;"; ++}; ++ ++class ProxyJavaScriptExecutorHolder ++ : public jni:: ++ HybridClass { ++ public: ++ static constexpr auto kJavaDescriptor = ++ "Lcom/facebook/react/bridge/ProxyJavaScriptExecutor;"; ++ ++ static jni::local_ref initHybrid( ++ jni::alias_ref, ++ jni::alias_ref executorInstance) { ++ return makeCxxInstance(std::make_shared( ++ make_global(executorInstance))); ++ } ++ ++ static void registerNatives() { ++ registerHybrid({ ++ makeNativeMethod( ++ "initHybrid", ProxyJavaScriptExecutorHolder::initHybrid), ++ }); ++ } ++ ++ private: ++ friend HybridBase; ++ using HybridBase::HybridBase; ++}; ++ ++} // namespace ++ ++extern "C" JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) { ++#ifdef WITH_XPLATINIT ++ return facebook::xplat::initialize(vm, [] { ++#else ++ return jni::initialize(vm, [] { ++#endif ++#if WITH_GLOGINIT ++ gloginit::initialize(); ++ FLAGS_minloglevel = 0; ++#endif ++ ++ ProxyJavaScriptExecutorHolder::registerNatives(); ++ CatalystInstanceImpl::registerNatives(); ++ CxxModuleWrapperBase::registerNatives(); ++ JCxxCallbackImpl::registerNatives(); ++ NativeArray::registerNatives(); ++ ReadableNativeArray::registerNatives(); ++ WritableNativeArray::registerNatives(); ++ NativeMap::registerNatives(); ++ ReadableNativeMap::registerNatives(); ++ WritableNativeMap::registerNatives(); ++ JDynamicNative::registerNatives(); ++ JReactMarker::registerNatives(); ++ JInspector::registerNatives(); ++ ReactInstanceManagerInspectorTarget::registerNatives(); ++ }); ++} ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/ProxyExecutor.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/ProxyExecutor.cpp +new file mode 100644 +index 0000000..68a121f +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/ProxyExecutor.cpp +@@ -0,0 +1,139 @@ ++/* ++ * 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. ++ */ ++ ++#include "ProxyExecutor.h" ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++namespace facebook::react { ++ ++const auto EXECUTOR_BASECLASS = "com/facebook/react/bridge/JavaJSExecutor"; ++ ++static std::string executeJSCallWithProxy( ++ jobject executor, ++ const std::string& methodName, ++ const folly::dynamic& arguments) { ++ static auto executeJSCall = ++ jni::findClassStatic(EXECUTOR_BASECLASS) ++ ->getMethod("executeJSCall"); ++ ++ auto result = executeJSCall( ++ executor, ++ jni::make_jstring(methodName).get(), ++ jni::make_jstring(folly::toJson(arguments).c_str()).get()); ++ return result->toString(); ++} ++ ++std::unique_ptr ProxyExecutorOneTimeFactory::createJSExecutor( ++ std::shared_ptr delegate, ++ std::shared_ptr) { ++ return std::make_unique(std::move(m_executor), delegate); ++} ++ ++ProxyExecutor::ProxyExecutor( ++ jni::global_ref&& executorInstance, ++ std::shared_ptr delegate) ++ : m_executor(std::move(executorInstance)), m_delegate(delegate) {} ++ ++ProxyExecutor::~ProxyExecutor() { ++ m_executor.reset(); ++} ++ ++void ProxyExecutor::initializeRuntime() { ++ folly::dynamic nativeModuleConfig = folly::dynamic::array; ++ ++ { ++ SystraceSection s("collectNativeModuleDescriptions"); ++ auto moduleRegistry = m_delegate->getModuleRegistry(); ++ for (const auto& name : moduleRegistry->moduleNames()) { ++ auto config = moduleRegistry->getConfig(name); ++ nativeModuleConfig.push_back(config ? config->config : nullptr); ++ } ++ } ++ ++ folly::dynamic config = folly::dynamic::object( ++ "remoteModuleConfig", std::move(nativeModuleConfig)); ++ ++ { ++ SystraceSection t("setGlobalVariable"); ++ setGlobalVariable( ++ "__fbBatchedBridgeConfig", ++ std::make_unique(folly::toJson(config))); ++ } ++} ++ ++void ProxyExecutor::loadBundle( ++ std::unique_ptr, ++ std::string sourceURL) { ++ static auto loadBundle = jni::findClassStatic(EXECUTOR_BASECLASS) ++ ->getMethod("loadBundle"); ++ ++ // The proxy ignores the script data passed in. ++ ++ loadBundle(m_executor.get(), jni::make_jstring(sourceURL).get()); ++ // We can get pending calls here to native but the queue will be drained when ++ // we launch the application. ++} ++ ++void ProxyExecutor::setBundleRegistry(std::unique_ptr) { ++ jni::throwNewJavaException( ++ "java/lang/UnsupportedOperationException", ++ "Loading application RAM bundles is not supported for proxy executors"); ++} ++ ++void ProxyExecutor::registerBundle( ++ uint32_t bundleId, ++ const std::string& bundlePath) { ++ jni::throwNewJavaException( ++ "java/lang/UnsupportedOperationException", ++ "Loading application RAM bundles is not supported for proxy executors"); ++} ++ ++void ProxyExecutor::callFunction( ++ const std::string& moduleId, ++ const std::string& methodId, ++ const folly::dynamic& arguments) { ++ auto call = folly::dynamic::array(moduleId, methodId, std::move(arguments)); ++ ++ std::string result = executeJSCallWithProxy( ++ m_executor.get(), "callFunctionReturnFlushedQueue", std::move(call)); ++ m_delegate->callNativeModules(*this, folly::parseJson(result), true); ++} ++ ++void ProxyExecutor::invokeCallback( ++ const double callbackId, ++ const folly::dynamic& arguments) { ++ auto call = folly::dynamic::array(callbackId, std::move(arguments)); ++ std::string result = executeJSCallWithProxy( ++ m_executor.get(), "invokeCallbackAndReturnFlushedQueue", std::move(call)); ++ m_delegate->callNativeModules(*this, folly::parseJson(result), true); ++} ++ ++void ProxyExecutor::setGlobalVariable( ++ std::string propName, ++ std::unique_ptr jsonValue) { ++ static auto setGlobalVariable = ++ jni::findClassStatic(EXECUTOR_BASECLASS) ++ ->getMethod("setGlobalVariable"); ++ ++ setGlobalVariable( ++ m_executor.get(), ++ jni::make_jstring(propName).get(), ++ jni::make_jstring(jsonValue->c_str()).get()); ++} ++ ++std::string ProxyExecutor::getDescription() { ++ return "Chrome"; ++} ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/ProxyExecutor.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/ProxyExecutor.h +new file mode 100644 +index 0000000..7bf7342 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/ProxyExecutor.h +@@ -0,0 +1,64 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++#include ++#include ++#include ++ ++namespace facebook::react { ++ ++/** ++ * This executor factory can only create a single executor instance because it ++ * moves executorInstance global reference to the executor instance it creates. ++ */ ++class ProxyExecutorOneTimeFactory : public JSExecutorFactory { ++ public: ++ ProxyExecutorOneTimeFactory(jni::global_ref&& executorInstance) ++ : m_executor(std::move(executorInstance)) {} ++ virtual std::unique_ptr createJSExecutor( ++ std::shared_ptr delegate, ++ std::shared_ptr queue) override; ++ ++ private: ++ jni::global_ref m_executor; ++}; ++ ++class ProxyExecutor : public JSExecutor { ++ public: ++ ProxyExecutor( ++ jni::global_ref&& executorInstance, ++ std::shared_ptr delegate); ++ virtual ~ProxyExecutor() override; ++ virtual void initializeRuntime() override; ++ virtual void loadBundle( ++ std::unique_ptr script, ++ std::string sourceURL) override; ++ virtual void setBundleRegistry( ++ std::unique_ptr bundle) override; ++ virtual void registerBundle(uint32_t bundleId, const std::string& bundlePath) ++ override; ++ virtual void callFunction( ++ const std::string& moduleId, ++ const std::string& methodId, ++ const folly::dynamic& arguments) override; ++ virtual void invokeCallback( ++ const double callbackId, ++ const folly::dynamic& arguments) override; ++ virtual void setGlobalVariable( ++ std::string propName, ++ std::unique_ptr jsonValue) override; ++ virtual std::string getDescription() override; ++ ++ private: ++ jni::global_ref m_executor; ++ std::shared_ptr m_delegate; ++}; ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/ReadableNativeArray.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/ReadableNativeArray.cpp +new file mode 100644 +index 0000000..9add683 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/ReadableNativeArray.cpp +@@ -0,0 +1,50 @@ ++/* ++ * 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. ++ */ ++ ++#include "ReadableNativeArray.h" ++ ++#include "ReadableNativeMap.h" ++ ++using namespace facebook::jni; ++ ++namespace facebook::react { ++ ++void ReadableNativeArray::mapException(std::exception_ptr ex) { ++ try { ++ std::rethrow_exception(ex); ++ } catch (const folly::TypeError& err) { ++ throwNewJavaException( ++ exceptions::gUnexpectedNativeTypeExceptionClass, err.what()); ++ } ++} ++ ++local_ref> ReadableNativeArray::importArray() { ++ auto size = static_cast(array_.size()); ++ auto jarray = JArrayClass::newArray(size); ++ for (jint ii = 0; ii < size; ii++) { ++ addDynamicToJArray(jarray, ii, array_.at(ii)); ++ } ++ return jarray; ++} ++ ++local_ref> ReadableNativeArray::importTypeArray() { ++ auto size = static_cast(array_.size()); ++ auto jarray = JArrayClass::newArray(size); ++ for (jint ii = 0; ii < size; ii++) { ++ (*jarray)[ii] = ReadableType::getType(array_.at(ii).type()); ++ } ++ return jarray; ++} ++ ++void ReadableNativeArray::registerNatives() { ++ registerHybrid({ ++ makeNativeMethod("importArray", ReadableNativeArray::importArray), ++ makeNativeMethod("importTypeArray", ReadableNativeArray::importTypeArray), ++ }); ++} ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/ReadableNativeArray.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/ReadableNativeArray.h +new file mode 100644 +index 0000000..02d9445 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/ReadableNativeArray.h +@@ -0,0 +1,42 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include "NativeArray.h" ++ ++#include "NativeCommon.h" ++#include "NativeMap.h" ++ ++namespace facebook::react { ++ ++struct ReadableArray : jni::JavaClass { ++ static auto constexpr kJavaDescriptor = ++ "Lcom/facebook/react/bridge/ReadableArray;"; ++}; ++ ++class ReadableNativeArray ++ : public jni::HybridClass { ++ protected: ++ friend HybridBase; ++ ++ template ++ explicit ReadableNativeArray(Dyn&& array) ++ : HybridBase(std::forward(array)) {} ++ ++ public: ++ static constexpr const char* kJavaDescriptor = ++ "Lcom/facebook/react/bridge/ReadableNativeArray;"; ++ ++ static void mapException(std::exception_ptr ex); ++ static void registerNatives(); ++ ++ jni::local_ref> importArray(); ++ jni::local_ref> importTypeArray(); ++}; ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/ReadableNativeMap.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/ReadableNativeMap.cpp +new file mode 100644 +index 0000000..08f2b0b +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/ReadableNativeMap.cpp +@@ -0,0 +1,128 @@ ++/* ++ * 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. ++ */ ++ ++#include "ReadableNativeMap.h" ++ ++using namespace facebook::jni; ++ ++namespace facebook::react { ++ ++void ReadableNativeMap::mapException(std::exception_ptr ex) { ++ try { ++ std::rethrow_exception(ex); ++ } catch (const folly::TypeError& err) { ++ throwNewJavaException( ++ exceptions::gUnexpectedNativeTypeExceptionClass, err.what()); ++ } ++} ++ ++void addDynamicToJArray( ++ local_ref> jarray, ++ jint index, ++ const folly::dynamic& dyn) { ++ switch (dyn.type()) { ++ case folly::dynamic::Type::NULLT: { ++ jarray->setElement(index, nullptr); ++ break; ++ } ++ case folly::dynamic::Type::BOOL: { ++ (*jarray)[index] = JBoolean::valueOf(dyn.getBool()); ++ break; ++ } ++ case folly::dynamic::Type::INT64: { ++ (*jarray)[index] = JDouble::valueOf(dyn.getInt()); ++ break; ++ } ++ case folly::dynamic::Type::DOUBLE: { ++ (*jarray)[index] = JDouble::valueOf(dyn.getDouble()); ++ break; ++ } ++ case folly::dynamic::Type::STRING: { ++ (*jarray)[index] = make_jstring(dyn.getString()); ++ break; ++ } ++ case folly::dynamic::Type::OBJECT: { ++ (*jarray)[index] = ReadableNativeMap::newObjectCxxArgs(dyn); ++ break; ++ } ++ case folly::dynamic::Type::ARRAY: { ++ (*jarray)[index] = ReadableNativeArray::newObjectCxxArgs(dyn); ++ break; ++ } ++ default: ++ jarray->setElement(index, nullptr); ++ break; ++ } ++} ++ ++local_ref> ReadableNativeMap::importKeys() { ++ throwIfConsumed(); ++ ++ keys_ = folly::dynamic::array(); ++ if (map_ == nullptr) { ++ return JArrayClass::newArray(0); ++ } ++ auto jarray = JArrayClass::newArray(map_.size()); ++ jint i = 0; ++ for (auto& pair : map_.items()) { ++ auto value = pair.first.asString(); ++ (*keys_).push_back(value); ++ (*jarray)[i++] = make_jstring(value); ++ } ++ ++ return jarray; ++} ++ ++local_ref> ReadableNativeMap::importValues() { ++ throwIfConsumed(); ++ ++ auto size = static_cast(keys_.value().size()); ++ auto jarray = JArrayClass::newArray(size); ++ for (jint ii = 0; ii < size; ii++) { ++ const std::string& key = (*keys_)[ii].getString(); ++ addDynamicToJArray(jarray, ii, map_.at(key)); ++ } ++ return jarray; ++} ++ ++local_ref> ReadableNativeMap::importTypes() { ++ throwIfConsumed(); ++ ++ auto size = static_cast(keys_.value().size()); ++ auto jarray = JArrayClass::newArray(size); ++ for (jint ii = 0; ii < size; ii++) { ++ const std::string& key = (*keys_)[ii].getString(); ++ (*jarray)[ii] = ReadableType::getType(map_.at(key).type()); ++ } ++ return jarray; ++} ++ ++local_ref ++ReadableNativeMap::createWithContents(folly::dynamic&& map) { ++ if (map.isNull()) { ++ return local_ref(nullptr); ++ } ++ ++ if (!map.isObject()) { ++ throwNewJavaException( ++ exceptions::gUnexpectedNativeTypeExceptionClass, ++ "expected Map, got a %s", ++ map.typeName()); ++ } ++ ++ return newObjectCxxArgs(std::move(map)); ++} ++ ++void ReadableNativeMap::registerNatives() { ++ registerHybrid({ ++ makeNativeMethod("importKeys", ReadableNativeMap::importKeys), ++ makeNativeMethod("importValues", ReadableNativeMap::importValues), ++ makeNativeMethod("importTypes", ReadableNativeMap::importTypes), ++ }); ++} ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/ReadableNativeMap.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/ReadableNativeMap.h +new file mode 100644 +index 0000000..16ff720 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/ReadableNativeMap.h +@@ -0,0 +1,51 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++#include ++#include ++#include ++ ++#include "NativeCommon.h" ++#include "NativeMap.h" ++#include "ReadableNativeArray.h" ++ ++namespace facebook::react { ++ ++struct WritableNativeMap; ++ ++struct ReadableMap : jni::JavaClass { ++ static auto constexpr kJavaDescriptor = ++ "Lcom/facebook/react/bridge/ReadableMap;"; ++}; ++ ++void addDynamicToJArray( ++ jni::local_ref> jarray, ++ jint index, ++ const folly::dynamic& dyn); ++ ++struct ReadableNativeMap : jni::HybridClass { ++ static auto constexpr kJavaDescriptor = ++ "Lcom/facebook/react/bridge/ReadableNativeMap;"; ++ ++ jni::local_ref> importKeys(); ++ jni::local_ref> importValues(); ++ jni::local_ref> importTypes(); ++ std::optional keys_; ++ static jni::local_ref createWithContents(folly::dynamic&& map); ++ ++ static void mapException(std::exception_ptr ex); ++ static void registerNatives(); ++ ++ using HybridBase::HybridBase; ++ friend HybridBase; ++ friend struct WritableNativeMap; ++}; ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/WritableNativeArray.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/WritableNativeArray.cpp +new file mode 100644 +index 0000000..c6ca317 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/WritableNativeArray.cpp +@@ -0,0 +1,91 @@ ++/* ++ * 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. ++ */ ++ ++#include "WritableNativeArray.h" ++ ++#include "ReadableNativeMap.h" ++ ++using namespace facebook::jni; ++ ++namespace facebook::react { ++ ++WritableNativeArray::WritableNativeArray() ++ : HybridBase(folly::dynamic::array()) {} ++ ++WritableNativeArray::WritableNativeArray(folly::dynamic&& val) ++ : HybridBase(std::move(val)) { ++ if (!array_.isArray()) { ++ throw std::runtime_error("WritableNativeArray value must be an array."); ++ } ++} ++ ++local_ref WritableNativeArray::initHybrid( ++ alias_ref) { ++ return makeCxxInstance(); ++} ++ ++void WritableNativeArray::pushNull() { ++ throwIfConsumed(); ++ array_.push_back(nullptr); ++} ++ ++void WritableNativeArray::pushBoolean(jboolean value) { ++ throwIfConsumed(); ++ array_.push_back(value == JNI_TRUE); ++} ++ ++void WritableNativeArray::pushDouble(jdouble value) { ++ throwIfConsumed(); ++ array_.push_back(value); ++} ++ ++void WritableNativeArray::pushInt(jint value) { ++ throwIfConsumed(); ++ array_.push_back(value); ++} ++ ++void WritableNativeArray::pushString(jstring value) { ++ if (value == NULL) { ++ pushNull(); ++ return; ++ } ++ throwIfConsumed(); ++ array_.push_back(wrap_alias(value)->toStdString()); ++} ++ ++void WritableNativeArray::pushNativeArray(ReadableNativeArray* otherArray) { ++ if (otherArray == NULL) { ++ pushNull(); ++ return; ++ } ++ throwIfConsumed(); ++ array_.push_back(otherArray->consume()); ++} ++ ++void WritableNativeArray::pushNativeMap(ReadableNativeMap* map) { ++ if (map == NULL) { ++ pushNull(); ++ return; ++ } ++ throwIfConsumed(); ++ array_.push_back(map->consume()); ++} ++ ++void WritableNativeArray::registerNatives() { ++ registerHybrid({ ++ makeNativeMethod("initHybrid", WritableNativeArray::initHybrid), ++ makeNativeMethod("pushNull", WritableNativeArray::pushNull), ++ makeNativeMethod("pushBoolean", WritableNativeArray::pushBoolean), ++ makeNativeMethod("pushDouble", WritableNativeArray::pushDouble), ++ makeNativeMethod("pushInt", WritableNativeArray::pushInt), ++ makeNativeMethod("pushString", WritableNativeArray::pushString), ++ makeNativeMethod("pushNativeArray", WritableNativeArray::pushNativeArray), ++ makeNativeMethod("pushNativeMap", WritableNativeArray::pushNativeMap), ++ }); ++} ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/WritableNativeArray.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/WritableNativeArray.h +new file mode 100644 +index 0000000..559beef +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/WritableNativeArray.h +@@ -0,0 +1,46 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++#include ++#include ++ ++#include "ReadableNativeArray.h" ++ ++namespace facebook::react { ++ ++struct ReadableNativeMap; ++ ++struct WritableArray : jni::JavaClass { ++ static auto constexpr kJavaDescriptor = ++ "Lcom/facebook/react/bridge/WritableArray;"; ++}; ++ ++struct WritableNativeArray ++ : public jni::HybridClass { ++ static constexpr const char* kJavaDescriptor = ++ "Lcom/facebook/react/bridge/WritableNativeArray;"; ++ ++ WritableNativeArray(); ++ WritableNativeArray(folly::dynamic&& val); ++ ++ static jni::local_ref initHybrid(jni::alias_ref); ++ ++ void pushNull(); ++ void pushBoolean(jboolean value); ++ void pushDouble(jdouble value); ++ void pushInt(jint value); ++ void pushString(jstring value); ++ void pushNativeArray(ReadableNativeArray* otherArray); ++ void pushNativeMap(ReadableNativeMap* map); ++ ++ static void registerNatives(); ++}; ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/WritableNativeMap.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/WritableNativeMap.cpp +new file mode 100644 +index 0000000..9c53c5c +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/WritableNativeMap.cpp +@@ -0,0 +1,102 @@ ++/* ++ * 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. ++ */ ++ ++#include "WritableNativeMap.h" ++ ++using namespace facebook::jni; ++ ++namespace facebook::react { ++ ++WritableNativeMap::WritableNativeMap() : HybridBase(folly::dynamic::object()) {} ++ ++WritableNativeMap::WritableNativeMap(folly::dynamic&& val) ++ : HybridBase(std::move(val)) { ++ if (!map_.isObject()) { ++ throw std::runtime_error("WritableNativeMap value must be an object."); ++ } ++} ++ ++local_ref WritableNativeMap::initHybrid( ++ alias_ref) { ++ return makeCxxInstance(); ++} ++ ++void WritableNativeMap::putNull(std::string key) { ++ throwIfConsumed(); ++ map_.insert(std::move(key), nullptr); ++} ++ ++void WritableNativeMap::putBoolean(std::string key, bool val) { ++ throwIfConsumed(); ++ map_.insert(std::move(key), val); ++} ++ ++void WritableNativeMap::putDouble(std::string key, double val) { ++ throwIfConsumed(); ++ map_.insert(std::move(key), val); ++} ++ ++void WritableNativeMap::putInt(std::string key, int val) { ++ throwIfConsumed(); ++ map_.insert(std::move(key), val); ++} ++ ++void WritableNativeMap::putString(std::string key, alias_ref val) { ++ if (!val) { ++ putNull(std::move(key)); ++ return; ++ } ++ throwIfConsumed(); ++ map_.insert(std::move(key), val->toString()); ++} ++ ++void WritableNativeMap::putNativeArray( ++ std::string key, ++ ReadableNativeArray* otherArray) { ++ if (!otherArray) { ++ putNull(std::move(key)); ++ return; ++ } ++ throwIfConsumed(); ++ map_.insert(key, otherArray->consume()); ++} ++ ++void WritableNativeMap::putNativeMap( ++ std::string key, ++ ReadableNativeMap* otherMap) { ++ if (!otherMap) { ++ putNull(std::move(key)); ++ return; ++ } ++ throwIfConsumed(); ++ map_.insert(std::move(key), otherMap->consume()); ++} ++ ++void WritableNativeMap::mergeNativeMap(ReadableNativeMap* other) { ++ throwIfConsumed(); ++ other->throwIfConsumed(); ++ ++ for (auto sourceIt : other->map_.items()) { ++ map_[sourceIt.first] = sourceIt.second; ++ } ++} ++ ++void WritableNativeMap::registerNatives() { ++ registerHybrid({ ++ makeNativeMethod("putNull", WritableNativeMap::putNull), ++ makeNativeMethod("putBoolean", WritableNativeMap::putBoolean), ++ makeNativeMethod("putDouble", WritableNativeMap::putDouble), ++ makeNativeMethod("putInt", WritableNativeMap::putInt), ++ makeNativeMethod("putString", WritableNativeMap::putString), ++ makeNativeMethod("putNativeArray", WritableNativeMap::putNativeArray), ++ makeNativeMethod("putNativeMap", WritableNativeMap::putNativeMap), ++ makeNativeMethod("mergeNativeMap", WritableNativeMap::mergeNativeMap), ++ makeNativeMethod("initHybrid", WritableNativeMap::initHybrid), ++ }); ++} ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/WritableNativeMap.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/WritableNativeMap.h +new file mode 100644 +index 0000000..d20f007 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jni/WritableNativeMap.h +@@ -0,0 +1,48 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++#include ++#include ++ ++#include "ReadableNativeArray.h" ++#include "ReadableNativeMap.h" ++ ++namespace facebook::react { ++ ++struct WritableMap : jni::JavaClass { ++ static auto constexpr kJavaDescriptor = ++ "Lcom/facebook/react/bridge/WritableMap;"; ++}; ++ ++struct WritableNativeMap ++ : jni::HybridClass { ++ static auto constexpr kJavaDescriptor = ++ "Lcom/facebook/react/bridge/WritableNativeMap;"; ++ ++ WritableNativeMap(); ++ WritableNativeMap(folly::dynamic&& val); ++ ++ static jni::local_ref initHybrid(jni::alias_ref); ++ ++ void putNull(std::string key); ++ void putBoolean(std::string key, bool val); ++ void putDouble(std::string key, double val); ++ void putInt(std::string key, int val); ++ void putString(std::string key, jni::alias_ref val); ++ void putNativeArray(std::string key, ReadableNativeArray* val); ++ void putNativeMap(std::string key, ReadableNativeMap* val); ++ void mergeNativeMap(ReadableNativeMap* other); ++ ++ static void registerNatives(); ++ ++ friend HybridBase; ++}; ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jscexecutor/CMakeLists.txt b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jscexecutor/CMakeLists.txt +new file mode 100644 +index 0000000..6785880 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jscexecutor/CMakeLists.txt +@@ -0,0 +1,36 @@ ++# 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. ++ ++cmake_minimum_required(VERSION 3.13) ++set(CMAKE_VERBOSE_MAKEFILE on) ++ ++add_compile_options(-fvisibility=hidden -fexceptions -frtti) ++ ++file(GLOB jscexecutor_SRC CONFIGURE_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) ++add_library(jscexecutor SHARED ${jscexecutor_SRC}) ++ ++target_include_directories(jscexecutor PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) ++ ++# Patch from Expo: https://github.com/expo/react-native/blob/02714ab44d1e206fa80e81aef618e61017cccdc1/ReactAndroid/src/main/java/com/facebook/react/jscexecutor/CMakeLists.txt#L16-L25 ++# Explicitly link libgcc.a to prevent undefined `_Unwind_Resume` symbol and crash from throwing c++ exceptions even someone tries to catch the exceptions. ++# according to https://android.googlesource.com/platform/ndk/+/master/docs/BuildSystemMaintainers.md#unwinding, ++# we should put the unwinder between static libs and shared libs. ++# ++# TODO(ncor): we don't need this patch anymore after upgrading to ndk r23 ++if(ANDROID_NDK_REVISION VERSION_LESS "23.0.0") ++ set(LIB_UNWIND gcc) ++else() ++ set(LIB_UNWIND unwind) ++endif() ++ ++target_link_libraries(jscexecutor ++ jsireact ++ jscruntime ++ ${LIB_UNWIND} ++ fb ++ fbjni ++ folly_runtime ++ jsi ++ reactnativejni) +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jscexecutor/OnLoad.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jscexecutor/OnLoad.cpp +new file mode 100644 +index 0000000..f9a4649 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/jscexecutor/OnLoad.cpp +@@ -0,0 +1,78 @@ ++/* ++ * 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. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++namespace facebook::react { ++ ++namespace { ++ ++class JSCExecutorFactory : public JSExecutorFactory { ++ public: ++ std::unique_ptr createJSExecutor( ++ std::shared_ptr delegate, ++ std::shared_ptr jsQueue) override { ++ auto installBindings = [](jsi::Runtime& runtime) { ++ react::Logger androidLogger = ++ static_cast( ++ &reactAndroidLoggingHook); ++ react::bindNativeLogger(runtime, androidLogger); ++ }; ++ return std::make_unique( ++ jsc::makeJSCRuntime(), ++ delegate, ++ JSIExecutor::defaultTimeoutInvoker, ++ installBindings); ++ } ++}; ++ ++} // namespace ++ ++// This is not like JSCJavaScriptExecutor, which calls JSC directly. This uses ++// JSIExecutor with JSCRuntime. ++class JSCExecutorHolder ++ : public jni::HybridClass { ++ public: ++ static constexpr auto kJavaDescriptor = ++ "Lcom/facebook/react/jscexecutor/JSCExecutor;"; ++ ++ static jni::local_ref initHybrid( ++ jni::alias_ref, ++ ReadableNativeMap*) { ++ // This is kind of a weird place for stuff, but there's no other ++ // good place for initialization which is specific to JSC on ++ // Android. ++ JReactMarker::setLogPerfMarkerIfNeeded(); ++ // TODO mhorowitz T28461666 fill in some missing nice to have glue ++ return makeCxxInstance(std::make_unique()); ++ } ++ ++ static void registerNatives() { ++ registerHybrid({ ++ makeNativeMethod("initHybrid", JSCExecutorHolder::initHybrid), ++ }); ++ } ++ ++ private: ++ friend HybridBase; ++ using HybridBase::HybridBase; ++}; ++ ++} // namespace facebook::react ++ ++JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) { ++ return facebook::jni::initialize( ++ vm, [] { facebook::react::JSCExecutorHolder::registerNatives(); }); ++} +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/mapbuffer/CMakeLists.txt b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/mapbuffer/CMakeLists.txt +new file mode 100644 +index 0000000..2694a9c +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/mapbuffer/CMakeLists.txt +@@ -0,0 +1,34 @@ ++# 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. ++ ++cmake_minimum_required(VERSION 3.13) ++set(CMAKE_VERBOSE_MAKEFILE on) ++ ++add_compile_options(-fexceptions -frtti -std=c++20 -Wall -DLOG_TAG=\"Fabric\") ++ ++file(GLOB mapbuffer_SRC CONFIGURE_DEPENDS ++ ${CMAKE_CURRENT_SOURCE_DIR}/react/common/mapbuffer/*.cpp) ++ ++add_library(mapbufferjni SHARED ${mapbuffer_SRC}) ++ ++target_include_directories(mapbufferjni ++ PUBLIC ++ ${CMAKE_CURRENT_SOURCE_DIR} ++ PRIVATE ++ ${CMAKE_CURRENT_SOURCE_DIR}/react/common/mapbuffer/ ++) ++ ++target_link_libraries(mapbufferjni ++ fb ++ fbjni ++ folly_runtime ++ glog ++ glog_init ++ react_debug ++ react_render_mapbuffer ++ react_utils ++ react_config ++ yoga ++) +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/mapbuffer/react/common/mapbuffer/JReadableMapBuffer.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/mapbuffer/react/common/mapbuffer/JReadableMapBuffer.cpp +new file mode 100644 +index 0000000..49b07b7 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/mapbuffer/react/common/mapbuffer/JReadableMapBuffer.cpp +@@ -0,0 +1,41 @@ ++/* ++ * 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. ++ */ ++ ++#include "JReadableMapBuffer.h" ++ ++namespace facebook::react { ++ ++void JReadableMapBuffer::registerNatives() { ++ registerHybrid({ ++ makeNativeMethod( ++ "importByteBuffer", JReadableMapBuffer::importByteBuffer), ++ }); ++} ++ ++jni::local_ref JReadableMapBuffer::importByteBuffer() { ++ // TODO T83483191: Reevaluate what's the best approach here (allocateDirect vs ++ // DirectByteBuffer). ++ return jni::JByteBuffer::wrapBytes( ++ serializedData_.data(), serializedData_.size()); ++} ++ ++std::vector JReadableMapBuffer::data() const { ++ return serializedData_; ++} ++ ++jni::local_ref ++JReadableMapBuffer::createWithContents(MapBuffer&& map) { ++ return newObjectCxxArgs(std::move(map)); ++} ++ ++JReadableMapBuffer::JReadableMapBuffer(MapBuffer&& map) ++ : serializedData_(std::move(map.bytes_)) { ++ react_native_assert( ++ (serializedData_.size() != 0) && "Error no content in map"); ++} ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/mapbuffer/react/common/mapbuffer/JReadableMapBuffer.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/mapbuffer/react/common/mapbuffer/JReadableMapBuffer.h +new file mode 100644 +index 0000000..5949ca5 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/mapbuffer/react/common/mapbuffer/JReadableMapBuffer.h +@@ -0,0 +1,38 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++#include ++#include ++ ++#include ++ ++namespace facebook::react { ++ ++class JReadableMapBuffer : public jni::HybridClass { ++ public: ++ static auto constexpr kJavaDescriptor = ++ "Lcom/facebook/react/common/mapbuffer/ReadableMapBuffer;"; ++ ++ static void registerNatives(); ++ ++ static jni::local_ref createWithContents( ++ MapBuffer&& map); ++ ++ explicit JReadableMapBuffer(MapBuffer&& map); ++ ++ jni::local_ref importByteBuffer(); ++ ++ std::vector data() const; ++ ++ private: ++ std::vector serializedData_; ++}; ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/mapbuffer/react/common/mapbuffer/JWritableMapBuffer.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/mapbuffer/react/common/mapbuffer/JWritableMapBuffer.cpp +new file mode 100644 +index 0000000..46ed21c +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/mapbuffer/react/common/mapbuffer/JWritableMapBuffer.cpp +@@ -0,0 +1,65 @@ ++/* ++ * 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. ++ */ ++ ++#include "JWritableMapBuffer.h" ++#include ++ ++namespace facebook::react { ++ ++MapBuffer JWritableMapBuffer::getMapBuffer() { ++ static const auto getKeys = ++ javaClassStatic()->getMethod("getKeys"); ++ static const auto getValues = ++ javaClassStatic()->getMethod()>( ++ "getValues"); ++ ++ auto keyArray = getKeys(self()); ++ auto values = getValues(self()); ++ ++ auto keys = keyArray->pin(); ++ ++ MapBufferBuilder builder; ++ ++ auto size = keys.size(); ++ for (int i = 0; i < size; i++) { ++ auto key = keys[i]; ++ jni::local_ref value = values->getElement(i); ++ ++ static const auto booleanClass = jni::JBoolean::javaClassStatic(); ++ static const auto integerClass = jni::JInteger::javaClassStatic(); ++ static const auto doubleClass = jni::JDouble::javaClassStatic(); ++ static const auto stringClass = jni::JString::javaClassStatic(); ++ static const auto readableMapClass = JReadableMapBuffer::javaClassStatic(); ++ static const auto writableMapClass = JWritableMapBuffer::javaClassStatic(); ++ ++ if (value->isInstanceOf(booleanClass)) { ++ auto element = jni::static_ref_cast(value); ++ builder.putBool(key, element->value()); ++ } else if (value->isInstanceOf(integerClass)) { ++ auto element = jni::static_ref_cast(value); ++ builder.putInt(key, element->value()); ++ } else if (value->isInstanceOf(doubleClass)) { ++ auto element = jni::static_ref_cast(value); ++ builder.putDouble(key, element->value()); ++ } else if (value->isInstanceOf(stringClass)) { ++ auto element = jni::static_ref_cast(value); ++ builder.putString(key, element->toStdString()); ++ } else if (value->isInstanceOf(readableMapClass)) { ++ auto element = ++ jni::static_ref_cast(value); ++ builder.putMapBuffer(key, MapBuffer(element->cthis()->data())); ++ } else if (value->isInstanceOf(writableMapClass)) { ++ auto element = ++ jni::static_ref_cast(value); ++ builder.putMapBuffer(key, element->getMapBuffer()); ++ } ++ } ++ ++ return builder.build(); ++} ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/mapbuffer/react/common/mapbuffer/JWritableMapBuffer.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/mapbuffer/react/common/mapbuffer/JWritableMapBuffer.h +new file mode 100644 +index 0000000..e076b28 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/mapbuffer/react/common/mapbuffer/JWritableMapBuffer.h +@@ -0,0 +1,23 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++#include ++ ++namespace facebook::react { ++ ++class JWritableMapBuffer : public jni::JavaClass { ++ public: ++ static auto constexpr kJavaDescriptor = ++ "Lcom/facebook/react/common/mapbuffer/WritableMapBuffer;"; ++ ++ MapBuffer getMapBuffer(); ++}; ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/mapbuffer/react/common/mapbuffer/OnLoad.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/mapbuffer/react/common/mapbuffer/OnLoad.cpp +new file mode 100644 +index 0000000..3a1ec41 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/mapbuffer/react/common/mapbuffer/OnLoad.cpp +@@ -0,0 +1,16 @@ ++/* ++ * 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. ++ */ ++ ++#include ++ ++#include "JReadableMapBuffer.h" ++#include "JWritableMapBuffer.h" ++ ++JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*) { ++ return facebook::jni::initialize( ++ vm, [] { facebook::react::JReadableMapBuffer::registerNatives(); }); ++} +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/newarchdefaults/CMakeLists.txt b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/newarchdefaults/CMakeLists.txt +new file mode 100644 +index 0000000..932157a +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/newarchdefaults/CMakeLists.txt +@@ -0,0 +1,29 @@ ++# 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. ++ ++cmake_minimum_required(VERSION 3.13) ++set(CMAKE_VERBOSE_MAKEFILE on) ++ ++add_compile_options(-fexceptions -frtti -std=c++20 -Wall -DLOG_TAG=\"ReactNative\") ++ ++file(GLOB react_newarchdefaults_SRC CONFIGURE_DEPENDS *.cpp) ++ ++add_library(react_newarchdefaults SHARED ${react_newarchdefaults_SRC}) ++ ++target_include_directories(react_newarchdefaults PUBLIC .) ++ ++target_link_libraries(react_newarchdefaults ++ fbjni ++ fabricjni ++ react_featureflagsjni ++ react_nativemodule_core ++ react_codegen_rncore ++ react_cxxreactpackage ++ react_nativemodule_defaults ++ react_nativemodule_dom ++ react_nativemodule_featureflags ++ react_nativemodule_microtasks ++ react_nativemodule_idlecallbacks ++ jsi) +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/newarchdefaults/DefaultComponentsRegistry.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/newarchdefaults/DefaultComponentsRegistry.cpp +new file mode 100644 +index 0000000..386d2ff +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/newarchdefaults/DefaultComponentsRegistry.cpp +@@ -0,0 +1,74 @@ ++/* ++ * 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. ++ */ ++ ++#include "DefaultComponentsRegistry.h" ++ ++#include ++#include ++#include ++#include ++#include ++ ++namespace facebook::react { ++ ++std::function)> ++ DefaultComponentsRegistry::registerComponentDescriptorsFromEntryPoint{}; ++ ++DefaultComponentsRegistry::DefaultComponentsRegistry(ComponentFactory* delegate) ++ : delegate_(delegate) {} ++ ++std::shared_ptr ++DefaultComponentsRegistry::sharedProviderRegistry() { ++ auto providerRegistry = CoreComponentsRegistry::sharedProviderRegistry(); ++ ++ if (DefaultComponentsRegistry::registerComponentDescriptorsFromEntryPoint) { ++ (DefaultComponentsRegistry::registerComponentDescriptorsFromEntryPoint)( ++ providerRegistry); ++ } else { ++ LOG(WARNING) ++ << "Custom component descriptors were not configured from JNI_OnLoad"; ++ } ++ ++ return providerRegistry; ++} ++ ++jni::local_ref ++DefaultComponentsRegistry::initHybrid( ++ jni::alias_ref, ++ ComponentFactory* delegate) { ++ auto instance = makeCxxInstance(delegate); ++ ++ auto buildRegistryFunction = ++ [](const EventDispatcher::Weak& eventDispatcher, ++ const ContextContainer::Shared& contextContainer) ++ -> ComponentDescriptorRegistry::Shared { ++ ComponentDescriptorParameters params{ ++ .eventDispatcher = eventDispatcher, ++ .contextContainer = contextContainer, ++ .flavor = nullptr}; ++ ++ auto registry = DefaultComponentsRegistry::sharedProviderRegistry() ++ ->createComponentDescriptorRegistry(params); ++ ++ auto& mutableRegistry = const_cast(*registry); ++ mutableRegistry.setFallbackComponentDescriptor( ++ std::make_shared(params)); ++ ++ return registry; ++ }; ++ ++ delegate->buildRegistryFunction = buildRegistryFunction; ++ return instance; ++} ++ ++void DefaultComponentsRegistry::registerNatives() { ++ registerHybrid({ ++ makeNativeMethod("initHybrid", DefaultComponentsRegistry::initHybrid), ++ }); ++} ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/newarchdefaults/DefaultComponentsRegistry.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/newarchdefaults/DefaultComponentsRegistry.h +new file mode 100644 +index 0000000..d1950e8 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/newarchdefaults/DefaultComponentsRegistry.h +@@ -0,0 +1,45 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++#include ++#include ++#include ++#include ++ ++namespace facebook::react { ++ ++class DefaultComponentsRegistry ++ : public facebook::jni::HybridClass { ++ public: ++ constexpr static auto kJavaDescriptor = ++ "Lcom/facebook/react/defaults/DefaultComponentsRegistry;"; ++ ++ static void registerNatives(); ++ ++ static std::function)> ++ registerComponentDescriptorsFromEntryPoint; ++ ++ DefaultComponentsRegistry(ComponentFactory* delegate); ++ ++ private: ++ friend HybridBase; ++ ++ static std::shared_ptr ++ sharedProviderRegistry(); ++ ++ const ComponentFactory* delegate_; ++ ++ static jni::local_ref initHybrid( ++ jni::alias_ref, ++ ComponentFactory* delegate); ++}; ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/newarchdefaults/DefaultTurboModuleManagerDelegate.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/newarchdefaults/DefaultTurboModuleManagerDelegate.cpp +new file mode 100644 +index 0000000..e2f8771 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/newarchdefaults/DefaultTurboModuleManagerDelegate.cpp +@@ -0,0 +1,92 @@ ++/* ++ * 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. ++ */ ++ ++#include "DefaultTurboModuleManagerDelegate.h" ++ ++#include ++ ++#include ++ ++namespace facebook::react { ++ ++DefaultTurboModuleManagerDelegate::DefaultTurboModuleManagerDelegate( ++ jni::alias_ref::javaobject> ++ cxxReactPackages) ++ : cxxReactPackages_() { ++ cxxReactPackages_.reserve(cxxReactPackages->size()); ++ std::transform( ++ cxxReactPackages->begin(), ++ cxxReactPackages->end(), ++ std::back_inserter(cxxReactPackages_), ++ [](jni::alias_ref elem) { ++ return jni::make_global(elem); ++ }); ++}; ++ ++std::function( ++ const std::string&, ++ const std::shared_ptr&)> ++ DefaultTurboModuleManagerDelegate::cxxModuleProvider{nullptr}; ++ ++std::function( ++ const std::string&, ++ const JavaTurboModule::InitParams&)> ++ DefaultTurboModuleManagerDelegate::javaModuleProvider{nullptr}; ++ ++jni::local_ref ++DefaultTurboModuleManagerDelegate::initHybrid( ++ jni::alias_ref jClass, ++ jni::alias_ref::javaobject> ++ cxxReactPackages) { ++ return makeCxxInstance(cxxReactPackages); ++} ++ ++void DefaultTurboModuleManagerDelegate::registerNatives() { ++ registerHybrid({ ++ makeNativeMethod( ++ "initHybrid", DefaultTurboModuleManagerDelegate::initHybrid), ++ }); ++} ++ ++std::shared_ptr DefaultTurboModuleManagerDelegate::getTurboModule( ++ const std::string& name, ++ const std::shared_ptr& jsInvoker) { ++ for (const auto& cxxReactPackage : cxxReactPackages_) { ++ auto cppPart = cxxReactPackage->cthis(); ++ if (cppPart) { ++ auto module = cppPart->getModule(name, jsInvoker); ++ if (module) { ++ return module; ++ } ++ } ++ } ++ ++ auto moduleProvider = DefaultTurboModuleManagerDelegate::cxxModuleProvider; ++ if (moduleProvider) { ++ auto module = moduleProvider(name, jsInvoker); ++ if (module) { ++ return module; ++ } ++ } ++ ++ return DefaultTurboModules::getTurboModule(name, jsInvoker); ++} ++ ++std::shared_ptr DefaultTurboModuleManagerDelegate::getTurboModule( ++ const std::string& name, ++ const JavaTurboModule::InitParams& params) { ++ auto moduleProvider = DefaultTurboModuleManagerDelegate::javaModuleProvider; ++ if (moduleProvider) { ++ if (auto resolvedModule = moduleProvider(name, params)) { ++ return resolvedModule; ++ } ++ } ++ ++ return nullptr; ++} ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/newarchdefaults/DefaultTurboModuleManagerDelegate.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/newarchdefaults/DefaultTurboModuleManagerDelegate.h +new file mode 100644 +index 0000000..099c245 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/newarchdefaults/DefaultTurboModuleManagerDelegate.h +@@ -0,0 +1,61 @@ ++/* ++ * 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. ++ */ ++ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++namespace facebook::react { ++ ++class DefaultTurboModuleManagerDelegate : public jni::HybridClass< ++ DefaultTurboModuleManagerDelegate, ++ TurboModuleManagerDelegate> { ++ public: ++ static constexpr auto kJavaDescriptor = ++ "Lcom/facebook/react/defaults/DefaultTurboModuleManagerDelegate;"; ++ ++ static jni::local_ref initHybrid( ++ jni::alias_ref, ++ jni::alias_ref::javaobject>); ++ ++ static void registerNatives(); ++ ++ static std::function( ++ const std::string&, ++ const std::shared_ptr&)> ++ cxxModuleProvider; ++ ++ static std::function( ++ const std::string&, ++ const JavaTurboModule::InitParams&)> ++ javaModuleProvider; ++ ++ std::shared_ptr getTurboModule( ++ const std::string& name, ++ const std::shared_ptr& jsInvoker) override; ++ std::shared_ptr getTurboModule( ++ const std::string& name, ++ const JavaTurboModule::InitParams& params) override; ++ ++ private: ++ friend HybridBase; ++ using HybridBase::HybridBase; ++ ++ std::vector> cxxReactPackages_; ++ ++ DefaultTurboModuleManagerDelegate( ++ jni::alias_ref::javaobject> ++ cxxReactPackage); ++}; ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/newarchdefaults/OnLoad.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/newarchdefaults/OnLoad.cpp +new file mode 100644 +index 0000000..a666756 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/newarchdefaults/OnLoad.cpp +@@ -0,0 +1,18 @@ ++/* ++ * 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. ++ */ ++ ++#include ++ ++#include "DefaultComponentsRegistry.h" ++#include "DefaultTurboModuleManagerDelegate.h" ++ ++JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*) { ++ return facebook::jni::initialize(vm, [] { ++ facebook::react::DefaultTurboModuleManagerDelegate::registerNatives(); ++ facebook::react::DefaultComponentsRegistry::registerNatives(); ++ }); ++} +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/perftests/OnLoad.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/perftests/OnLoad.cpp +new file mode 100644 +index 0000000..bd5341c +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/perftests/OnLoad.cpp +@@ -0,0 +1,243 @@ ++/* ++ * 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. ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++namespace facebook::react { ++ ++using facebook::jni::alias_ref; ++ ++namespace { ++ ++// This is a wrapper around the Java proxy to the javascript module. This ++// allows us to call functions on the js module from c++. Are you seeing ++// crashes in this class? Android 6+ crashes when you try to call a ++// method on a Proxy. Switch to an older version of Android. If you're ++// really desperate, you can fix this by using ToReflectedMethod on the ++// underlying jmethodid and invoking that. ++class JavaJSModule : public jni::JavaClass { ++ public: ++ static constexpr auto kJavaDescriptor = ++ "Lcom/facebook/react/CatalystBridgeBenchmarks$BridgeBenchmarkModule;"; ++ ++ static void bounceCxx(alias_ref obj, int iters) { ++ static auto method = javaClassLocal()->getMethod("bounceCxx"); ++ method(obj, iters); ++ } ++ ++ static void bounceArgsCxx( ++ alias_ref obj, ++ int iters, ++ int a, ++ int b, ++ double x, ++ double y, ++ const std::string& s, ++ const std::string& t) { ++ static auto method = ++ javaClassLocal() ++ ->getMethod( ++ "bounceArgsCxx"); ++ method( ++ obj, ++ iters, ++ a, ++ b, ++ x, ++ y, ++ jni::make_jstring(s).get(), ++ jni::make_jstring(t).get()); ++ } ++}; ++ ++// This is just the test instance itself. Used only to countdown the latch. ++class CatalystBridgeBenchmarks ++ : public jni::JavaClass { ++ public: ++ static constexpr auto kJavaDescriptor = ++ "Lcom/facebook/react/CatalystBridgeBenchmarks;"; ++ ++ static void countDown(alias_ref obj) { ++ static auto method = javaClassLocal()->getMethod("countDown"); ++ method(obj); ++ } ++}; ++ ++// This is the shared data for two cxx bounce threads. ++struct Data { ++ std::mutex m; ++ std::condition_variable cv; ++ bool leftActive; ++ Data() : leftActive(true) {} ++}; ++Data data; ++ ++void runBounce(jni::alias_ref, bool isLeft, int iters) { ++ for (int i = 0; i < iters; i++) { ++ std::unique_lock lk(data.m); ++ data.cv.wait(lk, [&] { return data.leftActive == isLeft; }); ++ data.leftActive = !isLeft; ++ data.cv.notify_one(); ++ } ++} ++ ++static jni::global_ref jsModule; ++static jni::global_ref javaTestInstance; ++ ++class CxxBenchmarkModule : public xplat::module::CxxModule { ++ public: ++ virtual std::string getName() override { ++ return "CxxBenchmarkModule"; ++ } ++ ++ virtual auto getConstants() ++ -> std::map override { ++ return std::map(); ++ } ++ ++ virtual auto getMethods() -> std::vector override { ++ return std::vector{ ++ Method( ++ "bounce", ++ [this](folly::dynamic args) { ++ this->bounce(xplat::jsArgAsInt(args, 0)); ++ }), ++ Method( ++ "bounceArgs", ++ [this](folly::dynamic args) { ++ this->bounceArgs( ++ xplat::jsArgAsInt(args, 0), ++ xplat::jsArgAsInt(args, 1), ++ xplat::jsArgAsInt(args, 2), ++ xplat::jsArgAsDouble(args, 3), ++ xplat::jsArgAsDouble(args, 4), ++ xplat::jsArgAsString(args, 5), ++ xplat::jsArgAsString(args, 6)); ++ }), ++ }; ++ } ++ ++ void bounce(int iters) { ++ if (iters == 0) { ++ CatalystBridgeBenchmarks::countDown(javaTestInstance); ++ } else { ++ JavaJSModule::bounceCxx(jsModule, iters - 1); ++ } ++ } ++ ++ void bounceArgs( ++ int iters, ++ int a, ++ int b, ++ double x, ++ double y, ++ const std::string& s, ++ const std::string& t) { ++ if (iters == 0) { ++ CatalystBridgeBenchmarks::countDown(javaTestInstance); ++ } else { ++ JavaJSModule::bounceArgsCxx(jsModule, iters - 1, a, b, x, y, s, t); ++ } ++ } ++}; ++ ++void setUp( ++ alias_ref obj, ++ alias_ref mod) { ++ javaTestInstance = jni::make_global(obj); ++ jsModule = jni::make_global(mod); ++} ++ ++void tearDown(alias_ref) { ++ javaTestInstance.reset(); ++ jsModule.reset(); ++} ++ ++namespace logwatcher { ++ ++static std::string gMessageToLookFor; ++static int gMessagePriorityToLookFor; ++static bool gHasSeenMessage = false; ++ ++/** ++ * NB: Don't put JNI logic (or anything else that could trigger a log) here! ++ */ ++static void stubLogHandler(int pri, const char* tag, const char* msg) { ++ if (gMessageToLookFor.empty()) { ++ return; ++ } ++ ++ bool priorityMatches = pri == gMessagePriorityToLookFor; ++ bool substringFound = strstr(msg, gMessageToLookFor.c_str()) != NULL; ++ gHasSeenMessage |= priorityMatches && substringFound; ++} ++ ++static jboolean hasSeenExpectedLogMessage(JNIEnv*, jclass) { ++ return gHasSeenMessage ? JNI_TRUE : JNI_FALSE; ++} ++ ++static void stopWatchingLogMessages(JNIEnv*, jclass) { ++ gMessageToLookFor = ""; ++ gHasSeenMessage = false; ++ setLogHandler(NULL); ++} ++ ++static void startWatchingForLogMessage( ++ JNIEnv* env, ++ jclass loggerClass, ++ jstring jmsg, ++ jint priority) { ++ stopWatchingLogMessages(env, loggerClass); ++ gMessageToLookFor = jni::wrap_alias(jmsg)->toStdString(); ++ gMessagePriorityToLookFor = priority; ++ setLogHandler(&stubLogHandler); ++} ++ ++} // namespace logwatcher ++} // namespace ++} // namespace facebook::react ++ ++using namespace facebook::react; ++ ++extern "C" facebook::xplat::module::CxxModule* CxxBenchmarkModule() { ++ return new facebook::react::CxxBenchmarkModule(); ++} ++ ++extern "C" jint JNI_OnLoad(JavaVM* vm, void*) { ++ return facebook::jni::initialize(vm, [] { ++ facebook::jni::registerNatives( ++ "com/facebook/catalyst/testing/LogWatcher", ++ { ++ makeNativeMethod( ++ "startWatchingForLogMessage", ++ "(Ljava/lang/String;I)V", ++ logwatcher::startWatchingForLogMessage), ++ makeNativeMethod( ++ "stopWatchingLogMessages", ++ "()V", ++ logwatcher::stopWatchingLogMessages), ++ makeNativeMethod( ++ "hasSeenExpectedLogMessage", ++ "()Z", ++ logwatcher::hasSeenExpectedLogMessage), ++ }); ++ facebook::jni::registerNatives( ++ "com/facebook/react/CatalystBridgeBenchmarks", ++ { ++ makeNativeMethod("runNativeBounce", runBounce), ++ makeNativeMethod("nativeSetUp", setUp), ++ makeNativeMethod("nativeTearDown", tearDown), ++ }); ++ }); ++} +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/reactnativeblob/BlobCollector.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/reactnativeblob/BlobCollector.cpp +new file mode 100644 +index 0000000..9b8f80c +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/reactnativeblob/BlobCollector.cpp +@@ -0,0 +1,77 @@ ++/* ++ * 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. ++ */ ++ ++#include "BlobCollector.h" ++ ++#include ++#include ++#include ++ ++using namespace facebook; ++ ++namespace facebook::react { ++ ++static constexpr auto kBlobModuleJavaDescriptor = ++ "com/facebook/react/modules/blob/BlobModule"; ++ ++BlobCollector::BlobCollector( ++ jni::global_ref blobModule, ++ const std::string& blobId) ++ : blobModule_(blobModule), blobId_(blobId) {} ++ ++BlobCollector::~BlobCollector() { ++ jni::ThreadScope::WithClassLoader([&] { ++ static auto removeMethod = jni::findClassStatic(kBlobModuleJavaDescriptor) ++ ->getMethod("remove"); ++ removeMethod(blobModule_, jni::make_jstring(blobId_).get()); ++ blobModule_.reset(); ++ }); ++} ++ ++size_t BlobCollector::getBlobLength() { ++ static auto getLengthMethod = ++ jni::findClassStatic(kBlobModuleJavaDescriptor) ++ ->getMethod("getLengthOfBlob"); ++ auto length = getLengthMethod(blobModule_, jni::make_jstring(blobId_).get()); ++ return static_cast(length); ++} ++ ++void BlobCollector::nativeInstall( ++ jni::alias_ref, ++ jni::alias_ref blobModule, ++ jlong jsContextNativePointer) { ++ auto& runtime = *((jsi::Runtime*)jsContextNativePointer); ++ auto blobModuleRef = jni::make_global(blobModule); ++ runtime.global().setProperty( ++ runtime, ++ "__blobCollectorProvider", ++ jsi::Function::createFromHostFunction( ++ runtime, ++ jsi::PropNameID::forAscii(runtime, "__blobCollectorProvider"), ++ 1, ++ [blobModuleRef]( ++ jsi::Runtime& rt, ++ const jsi::Value& thisVal, ++ const jsi::Value* args, ++ size_t count) { ++ auto blobId = args[0].asString(rt).utf8(rt); ++ auto blobCollector = ++ std::make_shared(blobModuleRef, blobId); ++ auto blobCollectorJsObject = ++ jsi::Object::createFromHostObject(rt, blobCollector); ++ blobCollectorJsObject.setExternalMemoryPressure( ++ rt, blobCollector->getBlobLength()); ++ return blobCollectorJsObject; ++ })); ++} ++ ++void BlobCollector::registerNatives() { ++ registerHybrid( ++ {makeNativeMethod("nativeInstall", BlobCollector::nativeInstall)}); ++} ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/reactnativeblob/BlobCollector.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/reactnativeblob/BlobCollector.h +new file mode 100644 +index 0000000..17046b4 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/reactnativeblob/BlobCollector.h +@@ -0,0 +1,40 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++#include ++ ++namespace facebook::react { ++ ++class BlobCollector : public jni::HybridClass, ++ public jsi::HostObject { ++ public: ++ BlobCollector(jni::global_ref blobModule, const std::string& blobId); ++ ~BlobCollector(); ++ ++ size_t getBlobLength(); ++ ++ static constexpr auto kJavaDescriptor = ++ "Lcom/facebook/react/modules/blob/BlobCollector;"; ++ ++ static void nativeInstall( ++ jni::alias_ref, ++ jni::alias_ref blobModule, ++ jlong jsContextNativePointer); ++ ++ static void registerNatives(); ++ ++ private: ++ friend HybridBase; ++ ++ jni::global_ref blobModule_; ++ const std::string blobId_; ++}; ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/reactnativeblob/CMakeLists.txt b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/reactnativeblob/CMakeLists.txt +new file mode 100644 +index 0000000..d28871f +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/reactnativeblob/CMakeLists.txt +@@ -0,0 +1,22 @@ ++# 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. ++ ++cmake_minimum_required(VERSION 3.13) ++set(CMAKE_VERBOSE_MAKEFILE on) ++ ++add_compile_options(-fvisibility=hidden -fexceptions -frtti) ++ ++file(GLOB reactnativeblob_SRC CONFIGURE_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) ++add_library(reactnativeblob SHARED ${reactnativeblob_SRC}) ++ ++target_include_directories(reactnativeblob PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) ++ ++target_link_libraries(reactnativeblob ++ jsireact ++ fb ++ fbjni ++ folly_runtime ++ jsi ++ reactnativejni) +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/reactnativeblob/OnLoad.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/reactnativeblob/OnLoad.cpp +new file mode 100644 +index 0000000..ded8547 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/reactnativeblob/OnLoad.cpp +@@ -0,0 +1,15 @@ ++/* ++ * 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. ++ */ ++ ++#include ++ ++#include "BlobCollector.h" ++ ++JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) { ++ return facebook::jni::initialize( ++ vm, [] { facebook::react::BlobCollector::registerNatives(); }); ++} +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/reactperflogger/CMakeLists.txt b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/reactperflogger/CMakeLists.txt +new file mode 100644 +index 0000000..d65bb29 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/reactperflogger/CMakeLists.txt +@@ -0,0 +1,23 @@ ++# 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. ++ ++cmake_minimum_required(VERSION 3.13) ++set(CMAKE_VERBOSE_MAKEFILE on) ++ ++add_compile_options(-fexceptions -frtti -std=c++20 -Wall) ++ ++add_library(reactperfloggerjni INTERFACE) ++ ++target_include_directories(reactperfloggerjni ++ INTERFACE ++ ${CMAKE_CURRENT_SOURCE_DIR} ++) ++ ++target_link_libraries(reactperfloggerjni ++ INTERFACE ++ fb ++ fbjni ++ android ++ reactperflogger) +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/reactperflogger/reactperflogger/JNativeModulePerfLogger.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/reactperflogger/reactperflogger/JNativeModulePerfLogger.h +new file mode 100644 +index 0000000..3081409 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/reactperflogger/reactperflogger/JNativeModulePerfLogger.h +@@ -0,0 +1,28 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++#include ++#include ++ ++namespace facebook::react { ++ ++class JNativeModulePerfLogger ++ : public jni::HybridClass { ++ public: ++ static auto constexpr kJavaDescriptor = ++ "Lcom/facebook/react/reactperflogger/NativeModulePerfLogger;"; ++ ++ virtual std::unique_ptr get() = 0; ++ ++ private: ++ friend HybridBase; ++}; ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/runtime/hermes/jni/CMakeLists.txt b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/runtime/hermes/jni/CMakeLists.txt +new file mode 100644 +index 0000000..1848f35 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/runtime/hermes/jni/CMakeLists.txt +@@ -0,0 +1,29 @@ ++# 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. ++ ++cmake_minimum_required(VERSION 3.13) ++set(CMAKE_VERBOSE_MAKEFILE on) ++ ++file(GLOB_RECURSE hermes_instance_jni_SRC CONFIGURE_DEPENDS *.cpp) ++ ++add_library(hermesinstancejni ++ SHARED ++ ${hermes_instance_jni_SRC} ++) ++target_compile_options( ++ hermesinstancejni ++ PRIVATE ++ $<$:-DHERMES_ENABLE_DEBUGGER=1> ++ -std=c++20 ++ -fexceptions ++) ++target_include_directories(hermesinstancejni PRIVATE .) ++target_link_libraries( ++ hermesinstancejni ++ hermes-engine::libhermes ++ rninstance ++ fbjni ++ bridgelesshermes ++) +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/runtime/hermes/jni/JHermesInstance.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/runtime/hermes/jni/JHermesInstance.cpp +new file mode 100644 +index 0000000..deabc52 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/runtime/hermes/jni/JHermesInstance.cpp +@@ -0,0 +1,37 @@ ++/* ++ * 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. ++ */ ++ ++#include "JHermesInstance.h" ++ ++#include ++#include ++ ++namespace facebook::react { ++ ++jni::local_ref JHermesInstance::initHybrid( ++ jni::alias_ref /* unused */, ++ jni::alias_ref reactNativeConfig) { ++ std::shared_ptr config = reactNativeConfig != nullptr ++ ? std::make_shared(reactNativeConfig) ++ : nullptr; ++ ++ return makeCxxInstance(config); ++} ++ ++void JHermesInstance::registerNatives() { ++ registerHybrid({ ++ makeNativeMethod("initHybrid", JHermesInstance::initHybrid), ++ }); ++} ++ ++std::unique_ptr JHermesInstance::createJSRuntime( ++ std::shared_ptr msgQueueThread) noexcept { ++ return HermesInstance::createJSRuntime( ++ reactNativeConfig_, nullptr, msgQueueThread); ++} ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/runtime/hermes/jni/JHermesInstance.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/runtime/hermes/jni/JHermesInstance.h +new file mode 100644 +index 0000000..5ee3450 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/runtime/hermes/jni/JHermesInstance.h +@@ -0,0 +1,49 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "../../jni/JJSRuntimeFactory.h" ++ ++namespace facebook::react { ++ ++class JHermesInstance ++ : public jni::HybridClass { ++ public: ++ static constexpr auto kJavaDescriptor = ++ "Lcom/facebook/react/runtime/hermes/HermesInstance;"; ++ ++ static jni::local_ref initHybrid( ++ jni::alias_ref /* unused */, ++ jni::alias_ref reactNativeConfig); ++ ++ static void registerNatives(); ++ ++ JHermesInstance(std::shared_ptr reactNativeConfig) ++ : reactNativeConfig_(reactNativeConfig){}; ++ ++ std::unique_ptr createJSRuntime( ++ std::shared_ptr msgQueueThread) noexcept; ++ ++ ~JHermesInstance() {} ++ ++ private: ++ friend HybridBase; ++ ++ std::shared_ptr reactNativeConfig_; ++}; ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/runtime/hermes/jni/OnLoad.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/runtime/hermes/jni/OnLoad.cpp +new file mode 100644 +index 0000000..7dd0dd1 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/runtime/hermes/jni/OnLoad.cpp +@@ -0,0 +1,15 @@ ++/* ++ * 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. ++ */ ++ ++#include ++ ++#include "JHermesInstance.h" ++ ++JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*) { ++ return facebook::jni::initialize( ++ vm, [] { facebook::react::JHermesInstance::registerNatives(); }); ++} +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/runtime/jni/CMakeLists.txt b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/runtime/jni/CMakeLists.txt +new file mode 100644 +index 0000000..f618197 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/runtime/jni/CMakeLists.txt +@@ -0,0 +1,32 @@ ++# 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. ++ ++cmake_minimum_required(VERSION 3.13) ++set(CMAKE_VERBOSE_MAKEFILE on) ++ ++file(GLOB_RECURSE bridgeless_jni_SRC CONFIGURE_DEPENDS *.cpp) ++ ++add_library(rninstance ++ SHARED ++ ${bridgeless_jni_SRC} ++) ++target_compile_options( ++ rninstance ++ PRIVATE ++ $<$:-DHERMES_ENABLE_DEBUGGER=1> ++ -std=c++20 ++ -fexceptions ++) ++target_include_directories(rninstance PUBLIC .) ++target_link_libraries( ++ rninstance ++ fabricjni ++ react_featureflagsjni ++ turbomodulejsijni ++ fb ++ jsi ++ fbjni ++ bridgeless ++) +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/runtime/jni/JBindingsInstaller.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/runtime/jni/JBindingsInstaller.h +new file mode 100644 +index 0000000..fb83833 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/runtime/jni/JBindingsInstaller.h +@@ -0,0 +1,32 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++#include ++#include ++#include ++#include ++ ++namespace facebook { ++namespace react { ++ ++class JBindingsInstaller : public jni::HybridClass, ++ public BindingsInstaller { ++ public: ++ static constexpr auto kJavaDescriptor = ++ "Lcom/facebook/react/runtime/BindingsInstaller;"; ++ ++ ~JBindingsInstaller() {} ++ ++ private: ++ friend HybridBase; ++}; ++ ++} // namespace react ++} // namespace facebook +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/runtime/jni/JJSTimerExecutor.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/runtime/jni/JJSTimerExecutor.cpp +new file mode 100644 +index 0000000..0e2a390 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/runtime/jni/JJSTimerExecutor.cpp +@@ -0,0 +1,34 @@ ++/* ++ * 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. ++ */ ++ ++#include "JJSTimerExecutor.h" ++ ++#include ++#include ++ ++namespace facebook::react { ++ ++void JJSTimerExecutor::setTimerManager( ++ std::weak_ptr timerManager) { ++ timerManager_ = timerManager; ++} ++ ++void JJSTimerExecutor::callTimers(WritableNativeArray* timerIDs) { ++ if (auto timerManager = timerManager_.lock()) { ++ for (const auto& timerID : timerIDs->consume()) { ++ timerManager->callTimer((uint32_t)timerID.asInt()); ++ } ++ } ++} ++ ++void JJSTimerExecutor::registerNatives() { ++ registerHybrid({ ++ makeNativeMethod("callTimers", JJSTimerExecutor::callTimers), ++ }); ++} ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/runtime/jni/JJSTimerExecutor.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/runtime/jni/JJSTimerExecutor.h +new file mode 100644 +index 0000000..cc7d938 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/runtime/jni/JJSTimerExecutor.h +@@ -0,0 +1,37 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++#include ++#include ++#include ++#include ++ ++namespace facebook::react { ++ ++class JJSTimerExecutor : public jni::HybridClass { ++ public: ++ JJSTimerExecutor() = default; ++ ++ constexpr static auto kJavaDescriptor = ++ "Lcom/facebook/react/runtime/JSTimerExecutor;"; ++ ++ static void registerNatives(); ++ ++ void setTimerManager(std::weak_ptr timerManager); ++ ++ void callTimers(WritableNativeArray* timerIDs); ++ ++ private: ++ friend HybridBase; ++ ++ std::weak_ptr timerManager_; ++}; ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/runtime/jni/JJavaTimerManager.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/runtime/jni/JJavaTimerManager.cpp +new file mode 100644 +index 0000000..b54da9b +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/runtime/jni/JJavaTimerManager.cpp +@@ -0,0 +1,30 @@ ++/* ++ * 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. ++ */ ++ ++#include "JJavaTimerManager.h" ++ ++#include ++#include ++ ++namespace facebook::react { ++ ++void JJavaTimerManager::createTimer( ++ uint32_t timerID, ++ double duration, ++ bool repeat) { ++ static const auto method = ++ javaClassStatic()->getMethod("createTimer"); ++ method(self(), timerID, (long)duration, static_cast(repeat)); ++} ++ ++void JJavaTimerManager::deleteTimer(uint32_t timerID) { ++ static const auto method = ++ javaClassStatic()->getMethod("deleteTimer"); ++ method(self(), timerID); ++} ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/runtime/jni/JJavaTimerManager.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/runtime/jni/JJavaTimerManager.h +new file mode 100644 +index 0000000..e576a1f +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/runtime/jni/JJavaTimerManager.h +@@ -0,0 +1,26 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++ ++#include ++#include ++ ++namespace facebook::react { ++ ++struct JJavaTimerManager : jni::JavaClass { ++ static auto constexpr kJavaDescriptor = ++ "Lcom/facebook/react/modules/core/JavaTimerManager;"; ++ ++ void createTimer(uint32_t timerID, double duration, bool repeat); ++ ++ void deleteTimer(uint32_t timerID); ++}; ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/runtime/jni/JReactExceptionManager.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/runtime/jni/JReactExceptionManager.cpp +new file mode 100644 +index 0000000..157c3eb +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/runtime/jni/JReactExceptionManager.cpp +@@ -0,0 +1,66 @@ ++/* ++ * 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. ++ */ ++ ++#include "JReactExceptionManager.h" ++#include ++#include ++#include ++ ++namespace facebook::react { ++ ++namespace { ++class ParsedError : public facebook::jni::JavaClass { ++ public: ++ static auto constexpr kJavaDescriptor = ++ "Lcom/facebook/react/interfaces/exceptionmanager/ReactJsExceptionHandler$ParsedError;"; ++}; ++ ++class ParsedStackFrameImpl ++ : public facebook::jni::JavaClass { ++ public: ++ static auto constexpr kJavaDescriptor = ++ "Lcom/facebook/react/interfaces/exceptionmanager/ReactJsExceptionHandler$ParsedStackFrameImpl;"; ++ ++ static facebook::jni::local_ref create( ++ const JsErrorHandler::ParsedError::StackFrame& frame) { ++ return newInstance( ++ frame.fileName, frame.methodName, frame.lineNumber, frame.columnNumber); ++ } ++}; ++ ++class ParsedErrorImpl ++ : public facebook::jni::JavaClass { ++ public: ++ static auto constexpr kJavaDescriptor = ++ "Lcom/facebook/react/interfaces/exceptionmanager/ReactJsExceptionHandler$ParsedErrorImpl;"; ++ ++ static facebook::jni::local_ref create( ++ const JsErrorHandler::ParsedError& error) { ++ auto stackFrames = ++ facebook::jni::JArrayList::create(); ++ for (const auto& frame : error.frames) { ++ stackFrames->add(ParsedStackFrameImpl::create(frame)); ++ } ++ ++ return newInstance( ++ stackFrames, error.message, error.exceptionId, error.isFatal); ++ } ++}; ++ ++} // namespace ++ ++void JReactExceptionManager::reportJsException( ++ const JsErrorHandler::ParsedError& error) { ++ static const auto method = ++ javaClassStatic()->getMethod)>( ++ "reportJsException"); ++ if (self() != nullptr) { ++ method(self(), ParsedErrorImpl::create(error)); ++ } ++} ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/runtime/jni/JReactExceptionManager.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/runtime/jni/JReactExceptionManager.h +new file mode 100644 +index 0000000..3261545 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/runtime/jni/JReactExceptionManager.h +@@ -0,0 +1,25 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++#include ++#include ++ ++namespace facebook::react { ++ ++class JReactExceptionManager ++ : public facebook::jni::JavaClass { ++ public: ++ static auto constexpr kJavaDescriptor = ++ "Lcom/facebook/react/interfaces/exceptionmanager/ReactJsExceptionHandler;"; ++ ++ void reportJsException(const JsErrorHandler::ParsedError& error); ++}; ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/runtime/jni/JReactInstance.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/runtime/jni/JReactInstance.cpp +new file mode 100644 +index 0000000..8bd5ebc +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/runtime/jni/JReactInstance.cpp +@@ -0,0 +1,253 @@ ++/* ++ * 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. ++ */ ++ ++#include "JReactInstance.h" ++ ++#ifdef WITH_FBSYSTRACE ++#include ++#endif ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "JavaTimerRegistry.h" ++ ++namespace facebook::react { ++ ++JReactInstance::JReactInstance( ++ jni::alias_ref jsRuntimeFactory, ++ jni::alias_ref jsMessageQueueThread, ++ jni::alias_ref nativeMessageQueueThread, ++ jni::alias_ref javaTimerManager, ++ jni::alias_ref jsTimerExecutor, ++ jni::alias_ref jReactExceptionManager, ++ jni::alias_ref jBindingsInstaller, ++ bool isProfiling, ++ jni::alias_ref ++ jReactHostInspectorTarget) noexcept { ++ // TODO(janzer): Lazily create runtime ++ auto sharedJSMessageQueueThread = ++ std::make_shared(jsMessageQueueThread); ++ auto sharedNativeMessageQueueThread = ++ std::make_shared(nativeMessageQueueThread); ++ ++ // Create the timer manager (for JS timers) ++ auto timerRegistry = ++ std::make_unique(jni::make_global(javaTimerManager)); ++ auto timerManager = std::make_shared(std::move(timerRegistry)); ++ jsTimerExecutor->cthis()->setTimerManager(timerManager); ++ ++ jReactExceptionManager_ = jni::make_global(jReactExceptionManager); ++ auto onJsError = ++ [weakJReactExceptionManager = jni::make_weak(jReactExceptionManager)]( ++ const JsErrorHandler::ParsedError& error) mutable noexcept { ++ if (auto jReactExceptionManager = ++ weakJReactExceptionManager.lockLocal()) { ++ jReactExceptionManager->reportJsException(error); ++ } ++ }; ++ ++ jBindingsInstaller_ = jni::make_global(jBindingsInstaller); ++ ++ instance_ = std::make_unique( ++ jsRuntimeFactory->cthis()->createJSRuntime(sharedJSMessageQueueThread), ++ sharedJSMessageQueueThread, ++ timerManager, ++ std::move(onJsError), ++ jReactHostInspectorTarget ++ ? jReactHostInspectorTarget->cthis()->getInspectorTarget() ++ : nullptr); ++ ++ auto bufferedRuntimeExecutor = instance_->getBufferedRuntimeExecutor(); ++ timerManager->setRuntimeExecutor(bufferedRuntimeExecutor); ++ ++ ReactInstance::JSRuntimeFlags options = {.isProfiling = isProfiling}; ++ instance_->initializeRuntime(options, [this](jsi::Runtime& runtime) { ++ react::Logger androidLogger = ++ static_cast( ++ &reactAndroidLoggingHook); ++ react::bindNativeLogger(runtime, androidLogger); ++ if (jBindingsInstaller_ != nullptr) { ++ auto appBindingInstaller = ++ jBindingsInstaller_->cthis()->getBindingsInstallFunc(); ++ if (appBindingInstaller != nullptr) { ++ appBindingInstaller(runtime); ++ } ++ } ++ }); ++ ++ auto unbufferedRuntimeExecutor = instance_->getUnbufferedRuntimeExecutor(); ++ // Set up the JS and native modules call invokers (for TurboModules) ++ auto jsInvoker = std::make_unique( ++ instance_->getRuntimeScheduler()); ++ jsCallInvokerHolder_ = jni::make_global( ++ CallInvokerHolder::newObjectCxxArgs(std::move(jsInvoker))); ++ auto nativeMethodCallInvoker = ++ std::make_unique( ++ sharedNativeMessageQueueThread); ++ nativeMethodCallInvokerHolder_ = ++ jni::make_global(NativeMethodCallInvokerHolder::newObjectCxxArgs( ++ std::move(nativeMethodCallInvoker))); ++ ++ // Storing this here to make sure the Java reference doesn't get destroyed ++ unbufferedRuntimeExecutor_ = jni::make_global( ++ JRuntimeExecutor::newObjectCxxArgs(unbufferedRuntimeExecutor)); ++ bufferedRuntimeExecutor_ = jni::make_global( ++ JRuntimeExecutor::newObjectCxxArgs(bufferedRuntimeExecutor)); ++ runtimeScheduler_ = jni::make_global( ++ JRuntimeScheduler::newObjectCxxArgs(instance_->getRuntimeScheduler())); ++} ++ ++jni::local_ref JReactInstance::initHybrid( ++ jni::alias_ref /* unused */, ++ jni::alias_ref jsRuntimeFactory, ++ jni::alias_ref jsMessageQueueThread, ++ jni::alias_ref nativeMessageQueueThread, ++ jni::alias_ref javaTimerManager, ++ jni::alias_ref jsTimerExecutor, ++ jni::alias_ref jReactExceptionManager, ++ jni::alias_ref jBindingsInstaller, ++ bool isProfiling, ++ jni::alias_ref ++ jReactHostInspectorTarget) { ++ return makeCxxInstance( ++ jsRuntimeFactory, ++ jsMessageQueueThread, ++ nativeMessageQueueThread, ++ javaTimerManager, ++ jsTimerExecutor, ++ jReactExceptionManager, ++ jBindingsInstaller, ++ isProfiling, ++ jReactHostInspectorTarget); ++} ++ ++void JReactInstance::loadJSBundleFromAssets( ++ jni::alias_ref assetManager, ++ const std::string& assetURL) { ++ const int kAssetsLength = 9; // strlen("assets://"); ++ auto sourceURL = assetURL.substr(kAssetsLength); ++ ++ auto manager = extractAssetManager(assetManager); ++ auto script = loadScriptFromAssets(manager, sourceURL); ++ instance_->loadScript(std::move(script), sourceURL); ++} ++ ++void JReactInstance::loadJSBundleFromFile( ++ const std::string& fileName, ++ const std::string& sourceURL) { ++ std::unique_ptr script; ++ RecoverableError::runRethrowingAsRecoverable( ++ [&fileName, &script]() { script = JSBigFileString::fromPath(fileName); }); ++ instance_->loadScript(std::move(script), sourceURL); ++} ++ ++/** ++ * This is needed to initialize TurboModules; in the future this will be ++ * replaced with something similar to runtimeExecutor, which we'll use for ++ * Fabric as well. ++ * TODO T44251068 Replace with runtimeExecutor ++ */ ++jni::alias_ref ++JReactInstance::getJSCallInvokerHolder() { ++ return jsCallInvokerHolder_; ++} ++ ++jni::alias_ref ++JReactInstance::getNativeMethodCallInvokerHolder() { ++ return nativeMethodCallInvokerHolder_; ++} ++ ++jni::global_ref ++JReactInstance::createJSTimerExecutor( ++ jni::alias_ref /* unused */) { ++ return jni::make_global(JJSTimerExecutor::newObjectCxxArgs()); ++} ++ ++void JReactInstance::callFunctionOnModule( ++ const std::string& moduleName, ++ const std::string& methodName, ++ NativeArray* args) { ++ instance_->callFunctionOnModule(moduleName, methodName, args->consume()); ++} ++ ++jni::alias_ref ++JReactInstance::getUnbufferedRuntimeExecutor() noexcept { ++ return unbufferedRuntimeExecutor_; ++} ++ ++jni::alias_ref ++JReactInstance::getBufferedRuntimeExecutor() noexcept { ++ return bufferedRuntimeExecutor_; ++} ++ ++jni::alias_ref ++JReactInstance::getRuntimeScheduler() noexcept { ++ return runtimeScheduler_; ++} ++ ++void JReactInstance::registerSegment( ++ int segmentId, ++ const std::string& segmentPath) noexcept { ++ instance_->registerSegment((uint32_t)segmentId, segmentPath); ++} ++ ++void JReactInstance::handleMemoryPressureJs(jint level) { ++ instance_->handleMemoryPressureJs(level); ++} ++ ++jlong JReactInstance::getJavaScriptContext() { ++ return (jlong)(intptr_t)instance_->getJavaScriptContext(); ++} ++ ++void JReactInstance::unregisterFromInspector() { ++ instance_->unregisterFromInspector(); ++} ++ ++void JReactInstance::registerNatives() { ++ registerHybrid({ ++ makeNativeMethod("initHybrid", JReactInstance::initHybrid), ++ makeNativeMethod( ++ "createJSTimerExecutor", JReactInstance::createJSTimerExecutor), ++ makeNativeMethod( ++ "loadJSBundleFromAssets", JReactInstance::loadJSBundleFromAssets), ++ makeNativeMethod( ++ "loadJSBundleFromFile", JReactInstance::loadJSBundleFromFile), ++ makeNativeMethod( ++ "getJSCallInvokerHolder", JReactInstance::getJSCallInvokerHolder), ++ makeNativeMethod( ++ "getNativeMethodCallInvokerHolder", ++ JReactInstance::getNativeMethodCallInvokerHolder), ++ makeNativeMethod( ++ "callFunctionOnModule", JReactInstance::callFunctionOnModule), ++ makeNativeMethod( ++ "getUnbufferedRuntimeExecutor", ++ JReactInstance::getUnbufferedRuntimeExecutor), ++ makeNativeMethod( ++ "getBufferedRuntimeExecutor", ++ JReactInstance::getBufferedRuntimeExecutor), ++ makeNativeMethod( ++ "getRuntimeScheduler", JReactInstance::getRuntimeScheduler), ++ makeNativeMethod( ++ "registerSegmentNative", JReactInstance::registerSegment), ++ makeNativeMethod( ++ "handleMemoryPressureJs", JReactInstance::handleMemoryPressureJs), ++ makeNativeMethod( ++ "getJavaScriptContext", JReactInstance::getJavaScriptContext), ++ makeNativeMethod( ++ "unregisterFromInspector", JReactInstance::unregisterFromInspector), ++ }); ++} ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/runtime/jni/JReactInstance.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/runtime/jni/JReactInstance.h +new file mode 100644 +index 0000000..d6552a8 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/runtime/jni/JReactInstance.h +@@ -0,0 +1,119 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "JBindingsInstaller.h" ++#include "JJSRuntimeFactory.h" ++#include "JJSTimerExecutor.h" ++#include "JJavaTimerManager.h" ++#include "JReactExceptionManager.h" ++#include "JReactHostInspectorTarget.h" ++ ++namespace facebook::react { ++ ++class JReactInstance : public jni::HybridClass { ++ public: ++ constexpr static auto kJavaDescriptor = ++ "Lcom/facebook/react/runtime/ReactInstance;"; ++ ++ static jni::local_ref initHybrid( ++ jni::alias_ref, ++ jni::alias_ref jsRuntimeFactory, ++ jni::alias_ref jsMessageQueueThread, ++ jni::alias_ref ++ nativeMessageQueueThread, ++ jni::alias_ref javaTimerManager, ++ jni::alias_ref jsTimerExecutor, ++ jni::alias_ref jReactExceptionManager, ++ jni::alias_ref jBindingsInstaller, ++ bool isProfiling, ++ jni::alias_ref ++ jReactHostInspectorTarget); ++ ++ /* ++ * Instantiates and returns an instance of `JSTimerExecutor`. ++ */ ++ static jni::global_ref createJSTimerExecutor( ++ jni::alias_ref /* unused */); ++ ++ static void registerNatives(); ++ ++ void loadJSBundleFromAssets( ++ jni::alias_ref assetManager, ++ const std::string& assetURL); ++ ++ void loadJSBundleFromFile( ++ const std::string& fileName, ++ const std::string& sourceURL); ++ ++ void callFunctionOnModule( ++ const std::string& moduleName, ++ const std::string& methodName, ++ NativeArray* args); ++ ++ jni::alias_ref ++ getUnbufferedRuntimeExecutor() noexcept; ++ jni::alias_ref ++ getBufferedRuntimeExecutor() noexcept; ++ jni::alias_ref getRuntimeScheduler() noexcept; ++ ++ void registerSegment(int segmentId, const std::string& segmentPath) noexcept; ++ ++ void handleMemoryPressureJs(jint level); ++ ++ void unregisterFromInspector(); ++ ++ private: ++ friend HybridBase; ++ ++ explicit JReactInstance( ++ jni::alias_ref jsRuntimeFactory, ++ jni::alias_ref jsMessageQueueThread, ++ jni::alias_ref ++ nativeMessageQueueThread, ++ jni::alias_ref javaTimerManager, ++ jni::alias_ref jsTimerExecutor, ++ jni::alias_ref jReactExceptionManager, ++ jni::alias_ref jBindingsInstaller, ++ bool isProfiling, ++ jni::alias_ref ++ jReactHostInspectorTarget) noexcept; ++ ++ jni::alias_ref getJSCallInvokerHolder(); ++ jni::alias_ref ++ getNativeMethodCallInvokerHolder(); ++ ++ std::unique_ptr instance_; ++ jni::global_ref unbufferedRuntimeExecutor_; ++ jni::global_ref bufferedRuntimeExecutor_; ++ jni::global_ref runtimeScheduler_; ++ jni::global_ref jsCallInvokerHolder_; ++ jni::global_ref ++ nativeMethodCallInvokerHolder_; ++ jni::global_ref jReactExceptionManager_; ++ jni::global_ref jBindingsInstaller_; ++ ++ jlong getJavaScriptContext(); ++}; ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/runtime/jni/JavaTimerRegistry.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/runtime/jni/JavaTimerRegistry.cpp +new file mode 100644 +index 0000000..842cade +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/runtime/jni/JavaTimerRegistry.cpp +@@ -0,0 +1,28 @@ ++/* ++ * 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. ++ */ ++ ++#include "JavaTimerRegistry.h" ++ ++namespace facebook::react { ++ ++JavaTimerRegistry::JavaTimerRegistry( ++ jni::global_ref javaTimerManager) ++ : javaTimerManager_(javaTimerManager) {} ++ ++void JavaTimerRegistry::createTimer(uint32_t timerID, double delayMS) { ++ javaTimerManager_->createTimer(timerID, delayMS, /* repeat */ false); ++} ++ ++void JavaTimerRegistry::createRecurringTimer(uint32_t timerID, double delayMS) { ++ javaTimerManager_->createTimer(timerID, delayMS, /* repeat */ true); ++} ++ ++void JavaTimerRegistry::deleteTimer(uint32_t timerID) { ++ javaTimerManager_->deleteTimer(timerID); ++} ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/runtime/jni/JavaTimerRegistry.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/runtime/jni/JavaTimerRegistry.h +new file mode 100644 +index 0000000..06670e1 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/runtime/jni/JavaTimerRegistry.h +@@ -0,0 +1,38 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++ ++#include ++#include ++ ++#include "JJavaTimerManager.h" ++ ++namespace facebook::react { ++ ++/** ++ * Call into JavaTimerManager.java to schedule and delete timers ++ * with the Platform. ++ */ ++class JavaTimerRegistry : public PlatformTimerRegistry { ++ public: ++ JavaTimerRegistry( ++ jni::global_ref javaTimerManager); ++ ++#pragma mark - PlatformTimerRegistry ++ ++ void createTimer(uint32_t timerID, double delayMS) override; ++ void createRecurringTimer(uint32_t timerID, double delayMS) override; ++ void deleteTimer(uint32_t timerID) override; ++ ++ private: ++ jni::global_ref javaTimerManager_; ++}; ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/runtime/jni/OnLoad.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/runtime/jni/OnLoad.cpp +new file mode 100644 +index 0000000..f4dcbfa +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/runtime/jni/OnLoad.cpp +@@ -0,0 +1,22 @@ ++/* ++ * 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. ++ */ ++ ++#include ++#include ++ ++#include "JJSTimerExecutor.h" ++#include "JReactHostInspectorTarget.h" ++#include "JReactInstance.h" ++ ++JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* /*unused*/) { ++ return facebook::jni::initialize(vm, [] { ++ facebook::react::JReactMarker::setLogPerfMarkerIfNeeded(); ++ facebook::react::JReactInstance::registerNatives(); ++ facebook::react::JJSTimerExecutor::registerNatives(); ++ facebook::react::JReactHostInspectorTarget::registerNatives(); ++ }); ++} +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/runtime/jsc/jni/CMakeLists.txt b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/runtime/jsc/jni/CMakeLists.txt +new file mode 100644 +index 0000000..fed3a3c +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/runtime/jsc/jni/CMakeLists.txt +@@ -0,0 +1,22 @@ ++# 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. ++ ++cmake_minimum_required(VERSION 3.13) ++set(CMAKE_VERBOSE_MAKEFILE on) ++ ++add_compile_options(-fvisibility=hidden -fexceptions -frtti) ++ ++file(GLOB jscinstance_SRC CONFIGURE_DEPENDS "*.cpp") ++add_library(jscinstance SHARED ${jscinstance_SRC}) ++ ++target_include_directories(jscinstance PUBLIC .) ++ ++target_link_libraries( ++ jscinstance ++ bridgeless ++ jscruntime ++ fbjni ++ reactnativejni ++) +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/runtime/jsc/jni/OnLoad.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/runtime/jsc/jni/OnLoad.cpp +new file mode 100644 +index 0000000..e49a55d +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/runtime/jsc/jni/OnLoad.cpp +@@ -0,0 +1,48 @@ ++/* ++ * 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. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++namespace facebook::react { ++ ++class JSCInstance : public jni::HybridClass { ++ public: ++ static constexpr auto kJavaDescriptor = ++ "Lcom/facebook/react/runtime/JSCInstance;"; ++ ++ static jni::local_ref initHybrid(jni::alias_ref) { ++ return makeCxxInstance(); ++ } ++ ++ static void registerNatives() { ++ registerHybrid({ ++ makeNativeMethod("initHybrid", JSCInstance::initHybrid), ++ }); ++ } ++ ++ std::unique_ptr createJSRuntime( ++ std::shared_ptr msgQueueThread) noexcept { ++ return std::make_unique(jsc::makeJSCRuntime()); ++ } ++ ++ private: ++ friend HybridBase; ++ using HybridBase::HybridBase; ++}; ++ ++} // namespace facebook::react ++ ++JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) { ++ return facebook::jni::initialize( ++ vm, [] { facebook::react::JSCInstance::registerNatives(); }); ++} +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/turbomodule/CMakeLists.txt b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/turbomodule/CMakeLists.txt +new file mode 100644 +index 0000000..4c7aeb1 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/turbomodule/CMakeLists.txt +@@ -0,0 +1,65 @@ ++# 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. ++ ++cmake_minimum_required(VERSION 3.13) ++set(CMAKE_VERBOSE_MAKEFILE on) ++ ++add_compile_options( ++ -fexceptions ++ -frtti ++ -Wno-unused-lambda-capture ++ -std=c++20) ++ ++######################### ++### callinvokerholder ### ++######################### ++ ++# TODO This should be exported to its own folder hierarchy ++add_library( ++ callinvokerholder ++ STATIC ++ ReactCommon/CallInvokerHolder.cpp ++ ReactCommon/NativeMethodCallInvokerHolder.cpp ++) ++ ++target_include_directories(callinvokerholder ++ PUBLIC ++ ${CMAKE_CURRENT_SOURCE_DIR} ++ ) ++ ++target_link_libraries(callinvokerholder ++ fb ++ fbjni ++ runtimeexecutor ++ callinvoker ++ reactperfloggerjni) ++ ++################################## ++### react_nativemodule_manager ### ++################################## ++ ++# TODO: rename to react_nativemodule_manager ++add_library( ++ turbomodulejsijni ++ SHARED ++ ReactCommon/BindingsInstallerHolder.cpp ++ ReactCommon/CompositeTurboModuleManagerDelegate.cpp ++ ReactCommon/OnLoad.cpp ++ ReactCommon/TurboModuleManager.cpp ++) ++ ++target_include_directories( ++ turbomodulejsijni ++ PUBLIC ++ ${CMAKE_CURRENT_SOURCE_DIR} ++) ++ ++target_link_libraries(turbomodulejsijni ++ fb ++ fbjni ++ jsi ++ react_nativemodule_core ++ callinvokerholder ++ reactperfloggerjni) +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/turbomodule/ReactCommon/CallInvokerHolder.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/turbomodule/ReactCommon/CallInvokerHolder.cpp +new file mode 100644 +index 0000000..9b44821 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/turbomodule/ReactCommon/CallInvokerHolder.cpp +@@ -0,0 +1,21 @@ ++/* ++ * 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. ++ */ ++ ++#include "CallInvokerHolder.h" ++ ++namespace facebook::react { ++ ++CallInvokerHolder::CallInvokerHolder(std::shared_ptr callInvoker) ++ : _callInvoker(callInvoker) {} ++ ++std::shared_ptr CallInvokerHolder::getCallInvoker() { ++ return _callInvoker; ++} ++ ++void CallInvokerHolder::registerNatives() {} ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/turbomodule/ReactCommon/CallInvokerHolder.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/turbomodule/ReactCommon/CallInvokerHolder.h +new file mode 100644 +index 0000000..3e4b4f8 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/turbomodule/ReactCommon/CallInvokerHolder.h +@@ -0,0 +1,30 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++#include ++#include ++ ++namespace facebook::react { ++ ++class CallInvokerHolder : public jni::HybridClass { ++ public: ++ static auto constexpr kJavaDescriptor = ++ "Lcom/facebook/react/turbomodule/core/CallInvokerHolderImpl;"; ++ ++ static void registerNatives(); ++ std::shared_ptr getCallInvoker(); ++ ++ private: ++ friend HybridBase; ++ CallInvokerHolder(std::shared_ptr callInvoker); ++ std::shared_ptr _callInvoker; ++}; ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/turbomodule/ReactCommon/CompositeTurboModuleManagerDelegate.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/turbomodule/ReactCommon/CompositeTurboModuleManagerDelegate.cpp +new file mode 100644 +index 0000000..a8e37e7 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/turbomodule/ReactCommon/CompositeTurboModuleManagerDelegate.cpp +@@ -0,0 +1,58 @@ ++/* ++ * 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. ++ */ ++ ++#include "CompositeTurboModuleManagerDelegate.h" ++ ++namespace facebook::react { ++ ++jni::local_ref ++CompositeTurboModuleManagerDelegate::initHybrid(jni::alias_ref) { ++ return makeCxxInstance(); ++} ++ ++void CompositeTurboModuleManagerDelegate::registerNatives() { ++ registerHybrid({ ++ makeNativeMethod( ++ "initHybrid", CompositeTurboModuleManagerDelegate::initHybrid), ++ makeNativeMethod( ++ "addTurboModuleManagerDelegate", ++ CompositeTurboModuleManagerDelegate::addTurboModuleManagerDelegate), ++ }); ++} ++ ++std::shared_ptr ++CompositeTurboModuleManagerDelegate::getTurboModule( ++ const std::string& moduleName, ++ const std::shared_ptr& jsInvoker) { ++ for (auto delegate : mDelegates_) { ++ if (auto turboModule = ++ delegate->cthis()->getTurboModule(moduleName, jsInvoker)) { ++ return turboModule; ++ } ++ } ++ return nullptr; ++} ++ ++std::shared_ptr ++CompositeTurboModuleManagerDelegate::getTurboModule( ++ const std::string& moduleName, ++ const JavaTurboModule::InitParams& params) { ++ for (auto delegate : mDelegates_) { ++ if (auto turboModule = ++ delegate->cthis()->getTurboModule(moduleName, params)) { ++ return turboModule; ++ } ++ } ++ return nullptr; ++} ++ ++void CompositeTurboModuleManagerDelegate::addTurboModuleManagerDelegate( ++ jni::alias_ref delegate) { ++ mDelegates_.push_back(jni::make_global(delegate)); ++} ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/turbomodule/ReactCommon/CompositeTurboModuleManagerDelegate.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/turbomodule/ReactCommon/CompositeTurboModuleManagerDelegate.h +new file mode 100644 +index 0000000..52b24cc +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/turbomodule/ReactCommon/CompositeTurboModuleManagerDelegate.h +@@ -0,0 +1,48 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++#include ++#include ++#include ++#include ++ ++namespace facebook::react { ++ ++class CompositeTurboModuleManagerDelegate ++ : public jni::HybridClass< ++ CompositeTurboModuleManagerDelegate, ++ TurboModuleManagerDelegate> { ++ public: ++ static auto constexpr kJavaDescriptor = ++ "Lcom/facebook/react/CompositeReactPackageTurboModuleManagerDelegate;"; ++ ++ static jni::local_ref initHybrid(jni::alias_ref); ++ ++ static void registerNatives(); ++ ++ std::shared_ptr getTurboModule( ++ const std::string& moduleName, ++ const std::shared_ptr& jsInvoker) override; ++ ++ std::shared_ptr getTurboModule( ++ const std::string& moduleName, ++ const JavaTurboModule::InitParams& params) override; ++ ++ private: ++ friend HybridBase; ++ using HybridBase::HybridBase; ++ std::vector> ++ mDelegates_; ++ ++ void addTurboModuleManagerDelegate( ++ jni::alias_ref delegate); ++}; ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/turbomodule/ReactCommon/NativeMethodCallInvokerHolder.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/turbomodule/ReactCommon/NativeMethodCallInvokerHolder.cpp +new file mode 100644 +index 0000000..62d9b0d +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/turbomodule/ReactCommon/NativeMethodCallInvokerHolder.cpp +@@ -0,0 +1,23 @@ ++/* ++ * 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. ++ */ ++ ++#include "NativeMethodCallInvokerHolder.h" ++ ++namespace facebook::react { ++ ++NativeMethodCallInvokerHolder::NativeMethodCallInvokerHolder( ++ std::shared_ptr nativeMethodCallInvoker) ++ : _nativeMethodCallInvoker(nativeMethodCallInvoker) {} ++ ++std::shared_ptr ++NativeMethodCallInvokerHolder::getNativeMethodCallInvoker() { ++ return _nativeMethodCallInvoker; ++} ++ ++void NativeMethodCallInvokerHolder::registerNatives() {} ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/turbomodule/ReactCommon/NativeMethodCallInvokerHolder.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/turbomodule/ReactCommon/NativeMethodCallInvokerHolder.h +new file mode 100644 +index 0000000..ef8fa3b +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/turbomodule/ReactCommon/NativeMethodCallInvokerHolder.h +@@ -0,0 +1,32 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++#include ++#include ++ ++namespace facebook::react { ++ ++class NativeMethodCallInvokerHolder ++ : public jni::HybridClass { ++ public: ++ static auto constexpr kJavaDescriptor = ++ "Lcom/facebook/react/turbomodule/core/NativeMethodCallInvokerHolderImpl;"; ++ ++ static void registerNatives(); ++ std::shared_ptr getNativeMethodCallInvoker(); ++ ++ private: ++ friend HybridBase; ++ NativeMethodCallInvokerHolder( ++ std::shared_ptr nativeMethodCallInvoker); ++ std::shared_ptr _nativeMethodCallInvoker; ++}; ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/turbomodule/ReactCommon/OnLoad.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/turbomodule/ReactCommon/OnLoad.cpp +new file mode 100644 +index 0000000..013e2ca +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/turbomodule/ReactCommon/OnLoad.cpp +@@ -0,0 +1,35 @@ ++/* ++ * 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. ++ */ ++ ++#include ++#include ++#include ++ ++#include "CompositeTurboModuleManagerDelegate.h" ++#include "TurboModuleManager.h" ++ ++void jniEnableCppLogging( ++ facebook::jni::alias_ref cls, ++ facebook::jni::alias_ref< ++ facebook::react::JNativeModulePerfLogger::javaobject> perfLogger) { ++ facebook::react::TurboModulePerfLogger::enableLogging( ++ perfLogger->cthis()->get()); ++} ++ ++JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*) { ++ return facebook::jni::initialize(vm, [] { ++ // TODO: dvacca ramanpreet unify this with the way ++ // "ComponentDescriptorFactory" is defined in Fabric ++ facebook::react::TurboModuleManager::registerNatives(); ++ ++ facebook::react::CompositeTurboModuleManagerDelegate::registerNatives(); ++ ++ facebook::jni::registerNatives( ++ "com/facebook/react/internal/turbomodule/core/TurboModulePerfLogger", ++ {makeNativeMethod("jniEnableCppLogging", jniEnableCppLogging)}); ++ }); ++} +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/turbomodule/ReactCommon/TurboModuleManager.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/turbomodule/ReactCommon/TurboModuleManager.cpp +new file mode 100644 +index 0000000..d18685d +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/turbomodule/ReactCommon/TurboModuleManager.cpp +@@ -0,0 +1,351 @@ ++/* ++ * 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. ++ */ ++ ++#include ++#include ++#include ++ ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "TurboModuleManager.h" ++ ++namespace facebook::react { ++ ++namespace { ++ ++class JMethodDescriptor : public jni::JavaClass { ++ public: ++ static auto constexpr kJavaDescriptor = ++ "Lcom/facebook/react/internal/turbomodule/core/TurboModuleInteropUtils$MethodDescriptor;"; ++ ++ JavaInteropTurboModule::MethodDescriptor toMethodDescriptor() { ++ return JavaInteropTurboModule::MethodDescriptor{ ++ .methodName = getMethodName(), ++ .jniSignature = getJNISignature(), ++ .jsiReturnKind = getJSIReturnKind(), ++ .jsArgCount = getJSArgCount(), ++ }; ++ } ++ ++ private: ++ std::string getMethodName() { ++ static const auto field = ++ javaClassStatic()->getField("methodName"); ++ return getFieldValue(field)->toStdString(); ++ } ++ ++ std::string getJNISignature() { ++ static const auto field = ++ javaClassStatic()->getField("jniSignature"); ++ return getFieldValue(field)->toStdString(); ++ } ++ ++ TurboModuleMethodValueKind getJSIReturnKind() { ++ static const auto field = ++ javaClassStatic()->getField("jsiReturnKind"); ++ const std::string jsiReturnKind = getFieldValue(field)->toStdString(); ++ if (jsiReturnKind == "VoidKind") { ++ return VoidKind; ++ } ++ if (jsiReturnKind == "BooleanKind") { ++ return BooleanKind; ++ } ++ if (jsiReturnKind == "NumberKind") { ++ return NumberKind; ++ } ++ if (jsiReturnKind == "StringKind") { ++ return StringKind; ++ } ++ if (jsiReturnKind == "ObjectKind") { ++ return ObjectKind; ++ } ++ if (jsiReturnKind == "ArrayKind") { ++ return ArrayKind; ++ } ++ if (jsiReturnKind == "FunctionKind") { ++ return FunctionKind; ++ } ++ if (jsiReturnKind == "PromiseKind") { ++ return PromiseKind; ++ } ++ ++ throw new std::runtime_error( ++ std::string("Failed to convert jsiReturnKind \"") + jsiReturnKind + ++ "\" to TurboModuleMethodValueKind"); ++ } ++ ++ int getJSArgCount() { ++ static const auto field = javaClassStatic()->getField("jsArgCount"); ++ return getFieldValue(field); ++ } ++}; ++} // namespace ++ ++TurboModuleManager::TurboModuleManager( ++ RuntimeExecutor runtimeExecutor, ++ std::shared_ptr jsCallInvoker, ++ std::shared_ptr nativeMethodCallInvoker, ++ jni::alias_ref delegate) ++ : runtimeExecutor_(std::move(runtimeExecutor)), ++ jsCallInvoker_(std::move(jsCallInvoker)), ++ nativeMethodCallInvoker_(std::move(nativeMethodCallInvoker)), ++ delegate_(jni::make_global(delegate)), ++ turboModuleCache_(std::make_shared()), ++ legacyModuleCache_(std::make_shared()) {} ++ ++jni::local_ref TurboModuleManager::initHybrid( ++ jni::alias_ref /* unused */, ++ jni::alias_ref runtimeExecutor, ++ jni::alias_ref jsCallInvokerHolder, ++ jni::alias_ref ++ nativeMethodCallInvokerHolder, ++ jni::alias_ref delegate) { ++ return makeCxxInstance( ++ runtimeExecutor->cthis()->get(), ++ jsCallInvokerHolder->cthis()->getCallInvoker(), ++ nativeMethodCallInvokerHolder->cthis()->getNativeMethodCallInvoker(), ++ delegate); ++} ++ ++void TurboModuleManager::registerNatives() { ++ registerHybrid({ ++ makeNativeMethod("initHybrid", TurboModuleManager::initHybrid), ++ makeNativeMethod( ++ "installJSIBindings", TurboModuleManager::installJSIBindings), ++ }); ++} ++ ++TurboModuleProviderFunctionType TurboModuleManager::createTurboModuleProvider( ++ jni::alias_ref javaPart, ++ jsi::Runtime* runtime, ++ bool enableSyncVoidMethods) { ++ return [turboModuleCache_ = std::weak_ptr(turboModuleCache_), ++ runtime, ++ jsCallInvoker_ = std::weak_ptr(jsCallInvoker_), ++ nativeMethodCallInvoker_ = ++ std::weak_ptr(nativeMethodCallInvoker_), ++ weakDelegate = jni::make_weak(delegate_), ++ weakJavaPart = jni::make_weak(javaPart), ++ enableSyncVoidMethods]( ++ const std::string& name) -> std::shared_ptr { ++ auto turboModuleCache = turboModuleCache_.lock(); ++ auto jsCallInvoker = jsCallInvoker_.lock(); ++ auto nativeMethodCallInvoker = nativeMethodCallInvoker_.lock(); ++ auto delegate = weakDelegate.lockLocal(); ++ auto javaPart = weakJavaPart.lockLocal(); ++ ++ if (!turboModuleCache || !jsCallInvoker || !nativeMethodCallInvoker || ++ !delegate || !javaPart) { ++ return nullptr; ++ } ++ ++ const char* moduleName = name.c_str(); ++ ++ TurboModulePerfLogger::moduleJSRequireBeginningStart(moduleName); ++ ++ auto turboModuleLookup = turboModuleCache->find(name); ++ if (turboModuleLookup != turboModuleCache->end()) { ++ TurboModulePerfLogger::moduleJSRequireBeginningCacheHit(moduleName); ++ TurboModulePerfLogger::moduleJSRequireBeginningEnd(moduleName); ++ return turboModuleLookup->second; ++ } ++ ++ TurboModulePerfLogger::moduleJSRequireBeginningEnd(moduleName); ++ ++ auto cxxModule = delegate->cthis()->getTurboModule(name, jsCallInvoker); ++ if (cxxModule) { ++ turboModuleCache->insert({name, cxxModule}); ++ return cxxModule; ++ } ++ ++ auto& cxxTurboModuleMapProvider = globalExportedCxxTurboModuleMap(); ++ auto it = cxxTurboModuleMapProvider.find(name); ++ if (it != cxxTurboModuleMapProvider.end()) { ++ auto turboModule = it->second(jsCallInvoker); ++ turboModuleCache->insert({name, turboModule}); ++ return turboModule; ++ } ++ ++ static auto getTurboLegacyCxxModule = ++ javaPart->getClass() ++ ->getMethod( ++ const std::string&)>("getTurboLegacyCxxModule"); ++ auto legacyCxxModule = getTurboLegacyCxxModule(javaPart.get(), name); ++ ++ if (legacyCxxModule) { ++ TurboModulePerfLogger::moduleJSRequireEndingStart(moduleName); ++ ++ auto turboModule = std::make_shared( ++ legacyCxxModule->cthis()->getModule(), jsCallInvoker); ++ turboModuleCache->insert({name, turboModule}); ++ ++ TurboModulePerfLogger::moduleJSRequireEndingEnd(moduleName); ++ return turboModule; ++ } ++ ++ static auto getTurboJavaModule = ++ javaPart->getClass() ++ ->getMethod(const std::string&)>( ++ "getTurboJavaModule"); ++ auto moduleInstance = getTurboJavaModule(javaPart.get(), name); ++ ++ if (moduleInstance) { ++ TurboModulePerfLogger::moduleJSRequireEndingStart(moduleName); ++ JavaTurboModule::InitParams params = { ++ .moduleName = name, ++ .instance = moduleInstance, ++ .jsInvoker = jsCallInvoker, ++ .nativeMethodCallInvoker = nativeMethodCallInvoker, ++ .shouldVoidMethodsExecuteSync = enableSyncVoidMethods}; ++ ++ auto turboModule = delegate->cthis()->getTurboModule(name, params); ++ if (moduleInstance->isInstanceOf( ++ JTurboModuleWithJSIBindings::javaClassStatic())) { ++ static auto getBindingsInstaller = ++ JTurboModuleWithJSIBindings::javaClassStatic() ++ ->getMethod( ++ "getBindingsInstaller"); ++ auto installer = getBindingsInstaller(moduleInstance); ++ if (installer) { ++ installer->cthis()->installBindings(*runtime); ++ } ++ } ++ ++ turboModuleCache->insert({name, turboModule}); ++ TurboModulePerfLogger::moduleJSRequireEndingEnd(moduleName); ++ return turboModule; ++ } ++ ++ return nullptr; ++ }; ++} ++ ++TurboModuleProviderFunctionType TurboModuleManager::createLegacyModuleProvider( ++ jni::alias_ref javaPart) { ++ return [legacyModuleCache_ = std::weak_ptr(legacyModuleCache_), ++ jsCallInvoker_ = std::weak_ptr(jsCallInvoker_), ++ nativeMethodCallInvoker_ = ++ std::weak_ptr(nativeMethodCallInvoker_), ++ weakDelegate = jni::make_weak(delegate_), ++ weakJavaPart = jni::make_weak(javaPart)]( ++ const std::string& name) -> std::shared_ptr { ++ auto legacyModuleCache = legacyModuleCache_.lock(); ++ auto jsCallInvoker = jsCallInvoker_.lock(); ++ auto nativeMethodCallInvoker = nativeMethodCallInvoker_.lock(); ++ auto delegate = weakDelegate.lockLocal(); ++ auto javaPart = weakJavaPart.lockLocal(); ++ ++ if (!legacyModuleCache || !jsCallInvoker || !nativeMethodCallInvoker || ++ !delegate || !javaPart) { ++ return nullptr; ++ } ++ ++ const char* moduleName = name.c_str(); ++ ++ TurboModulePerfLogger::moduleJSRequireBeginningStart(moduleName); ++ ++ auto legacyModuleLookup = legacyModuleCache->find(name); ++ if (legacyModuleLookup != legacyModuleCache->end()) { ++ TurboModulePerfLogger::moduleJSRequireBeginningCacheHit(moduleName); ++ TurboModulePerfLogger::moduleJSRequireBeginningEnd(moduleName); ++ return legacyModuleLookup->second; ++ } ++ ++ TurboModulePerfLogger::moduleJSRequireBeginningEnd(moduleName); ++ ++ static auto getLegacyCxxModule = ++ javaPart->getClass() ++ ->getMethod( ++ const std::string&)>("getLegacyCxxModule"); ++ auto legacyCxxModule = getLegacyCxxModule(javaPart.get(), name); ++ ++ if (legacyCxxModule) { ++ TurboModulePerfLogger::moduleJSRequireEndingStart(moduleName); ++ ++ auto turboModule = std::make_shared( ++ legacyCxxModule->cthis()->getModule(), jsCallInvoker); ++ legacyModuleCache->insert({name, turboModule}); ++ ++ TurboModulePerfLogger::moduleJSRequireEndingEnd(moduleName); ++ return turboModule; ++ } ++ ++ static auto getLegacyJavaModule = ++ javaPart->getClass() ++ ->getMethod(const std::string&)>( ++ "getLegacyJavaModule"); ++ auto moduleInstance = getLegacyJavaModule(javaPart.get(), name); ++ ++ if (moduleInstance) { ++ TurboModulePerfLogger::moduleJSRequireEndingStart(moduleName); ++ JavaTurboModule::InitParams params = { ++ .moduleName = name, ++ .instance = moduleInstance, ++ .jsInvoker = jsCallInvoker, ++ .nativeMethodCallInvoker = nativeMethodCallInvoker, ++ .shouldVoidMethodsExecuteSync = false}; ++ ++ static auto getMethodDescriptorsFromModule = ++ javaPart->getClass() ++ ->getStaticMethod::javaobject>( ++ jni::alias_ref)>( ++ "getMethodDescriptorsFromModule"); ++ ++ auto javaMethodDescriptors = ++ getMethodDescriptorsFromModule(javaPart->getClass(), moduleInstance); ++ ++ std::vector methodDescriptors; ++ for (jni::alias_ref javaMethodDescriptor : ++ *javaMethodDescriptors) { ++ methodDescriptors.push_back(javaMethodDescriptor->toMethodDescriptor()); ++ } ++ ++ auto turboModule = ++ std::make_shared(params, methodDescriptors); ++ ++ legacyModuleCache->insert({name, turboModule}); ++ TurboModulePerfLogger::moduleJSRequireEndingEnd(moduleName); ++ return turboModule; ++ } ++ ++ return nullptr; ++ }; ++} ++ ++void TurboModuleManager::installJSIBindings( ++ jni::alias_ref javaPart, ++ bool shouldCreateLegacyModules, ++ bool enableSyncVoidMethods) { ++ auto cxxPart = javaPart->cthis(); ++ if (cxxPart == nullptr || !cxxPart->jsCallInvoker_) { ++ return; // Runtime doesn't exist when attached to Chrome debugger. ++ } ++ ++ cxxPart->runtimeExecutor_([cxxPart, ++ javaPart = jni::make_global(javaPart), ++ shouldCreateLegacyModules, ++ enableSyncVoidMethods](jsi::Runtime& runtime) { ++ TurboModuleBinding::install( ++ runtime, ++ cxxPart->createTurboModuleProvider( ++ javaPart, &runtime, enableSyncVoidMethods), ++ shouldCreateLegacyModules ++ ? cxxPart->createLegacyModuleProvider(javaPart) ++ : nullptr); ++ }); ++} ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/turbomodule/ReactCommon/TurboModuleManager.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/turbomodule/ReactCommon/TurboModuleManager.h +new file mode 100644 +index 0000000..49f28da +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/turbomodule/ReactCommon/TurboModuleManager.h +@@ -0,0 +1,76 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++namespace facebook::react { ++ ++class TurboModuleManager : public jni::HybridClass { ++ public: ++ static auto constexpr kJavaDescriptor = ++ "Lcom/facebook/react/internal/turbomodule/core/TurboModuleManager;"; ++ static jni::local_ref initHybrid( ++ jni::alias_ref /* unused */, ++ jni::alias_ref runtimeExecutor, ++ jni::alias_ref jsCallInvokerHolder, ++ jni::alias_ref ++ nativeMethodCallInvokerHolder, ++ jni::alias_ref delegate); ++ static void registerNatives(); ++ ++ private: ++ friend HybridBase; ++ RuntimeExecutor runtimeExecutor_; ++ std::shared_ptr jsCallInvoker_; ++ std::shared_ptr nativeMethodCallInvoker_; ++ jni::global_ref delegate_; ++ ++ using ModuleCache = ++ std::unordered_map>; ++ ++ /** ++ * TODO(T48018690): ++ * All modules are currently long-lived. ++ * We need to come up with a mechanism to allow modules to specify whether ++ * they want to be long-lived or short-lived. ++ */ ++ std::shared_ptr turboModuleCache_; ++ std::shared_ptr legacyModuleCache_; ++ ++ static void installJSIBindings( ++ jni::alias_ref javaPart, ++ bool shouldCreateLegacyModules, ++ bool enableSyncVoidMethods); ++ explicit TurboModuleManager( ++ RuntimeExecutor runtimeExecutor, ++ std::shared_ptr jsCallInvoker, ++ std::shared_ptr nativeMethodCallInvoker, ++ jni::alias_ref delegate); ++ ++ TurboModuleProviderFunctionType createTurboModuleProvider( ++ jni::alias_ref javaPart, ++ jsi::Runtime* runtime, ++ bool enableSyncVoidMethods); ++ TurboModuleProviderFunctionType createLegacyModuleProvider( ++ jni::alias_ref javaPart); ++}; ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/turbomodule/ReactCommon/TurboModuleManagerDelegate.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/turbomodule/ReactCommon/TurboModuleManagerDelegate.h +new file mode 100644 +index 0000000..0c38700 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/turbomodule/ReactCommon/TurboModuleManagerDelegate.h +@@ -0,0 +1,35 @@ ++/* ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++#include ++#include ++#include ++#include ++ ++namespace facebook::react { ++ ++class TurboModuleManagerDelegate ++ : public jni::HybridClass { ++ public: ++ static auto constexpr kJavaDescriptor = ++ "Lcom/facebook/react/internal/turbomodule/core/TurboModuleManagerDelegate;"; ++ ++ virtual std::shared_ptr getTurboModule( ++ const std::string& name, ++ const JavaTurboModule::InitParams& params) = 0; ++ virtual std::shared_ptr getTurboModule( ++ const std::string& name, ++ const std::shared_ptr& jsInvoker) = 0; ++ ++ private: ++ friend HybridBase; ++}; ++ ++} // namespace facebook::react +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/uimanager/CMakeLists.txt b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/uimanager/CMakeLists.txt +new file mode 100644 +index 0000000..ca7c6e0 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/uimanager/CMakeLists.txt +@@ -0,0 +1,27 @@ ++# 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. ++ ++cmake_minimum_required(VERSION 3.13) ++set(CMAKE_VERBOSE_MAKEFILE on) ++ ++add_compile_options(-fexceptions -frtti -std=c++20 -Wall -DLOG_TAG=\"ReactNative\") ++ ++file(GLOB uimanagerjni_SRC CONFIGURE_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) ++add_library(uimanagerjni SHARED ${uimanagerjni_SRC}) ++ ++target_include_directories(uimanagerjni PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) ++ ++target_link_libraries(uimanagerjni ++ fb ++ fbjni ++ folly_runtime ++ glog ++ glog_init ++ bridgelessnativeviewconfig ++ rrc_native ++ yoga ++ callinvokerholder ++ reactnativejni ++ react_render_componentregistry) +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/uimanager/OnLoad.cpp b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/uimanager/OnLoad.cpp +new file mode 100644 +index 0000000..d3aa672 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/react/uimanager/OnLoad.cpp +@@ -0,0 +1,18 @@ ++/* ++ * 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. ++ */ ++ ++#include ++ ++#include "ComponentNameResolverBinding.h" ++#include "UIConstantsProviderBinding.h" ++ ++JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*) { ++ return facebook::jni::initialize(vm, [] { ++ facebook::react::ComponentNameResolverBinding::registerNatives(); ++ facebook::react::UIConstantsProviderBinding::registerNatives(); ++ }); ++} +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/third-party/boost/CMakeLists.txt b/node_modules/react-native/ReactAndroid/bin/src/main/jni/third-party/boost/CMakeLists.txt +new file mode 100644 +index 0000000..2868624 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/third-party/boost/CMakeLists.txt +@@ -0,0 +1,22 @@ ++# 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. ++ ++cmake_minimum_required(VERSION 3.13) ++set(CMAKE_VERBOSE_MAKEFILE on) ++ ++# These ASM files are picked from the boost release separately, ++# because the react native version does not include anything outside of headers. ++# They are required for Folly futures to compile successfully. ++ENABLE_LANGUAGE(ASM) ++file(GLOB_RECURSE ++ boostasm_SRC ++ CONFIGURE_DEPENDS ++ ${CMAKE_CURRENT_SOURCE_DIR}/asm/${ANDROID_ABI}/*.S) ++add_library(boost STATIC ${boostasm_SRC}) ++ ++set_target_properties(boost PROPERTIES LINKER_LANGUAGE CXX) ++ ++target_include_directories(boost PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/boost_1_83_0) ++ +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/third-party/boost/asm/arm64-v8a/jump_arm64_aapcs_elf_gas.S b/node_modules/react-native/ReactAndroid/bin/src/main/jni/third-party/boost/asm/arm64-v8a/jump_arm64_aapcs_elf_gas.S +new file mode 100644 +index 0000000..7c0c2fa +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/third-party/boost/asm/arm64-v8a/jump_arm64_aapcs_elf_gas.S +@@ -0,0 +1,114 @@ ++/* ++ Copyright Edward Nevill + Oliver Kowalke 2015 ++ Distributed under the Boost Software License, Version 1.0. ++ (See accompanying file LICENSE_1_0.txt or copy at ++ http://www.boost.org/LICENSE_1_0.txt) ++*/ ++/******************************************************* ++ * * ++ * ------------------------------------------------- * ++ * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * ++ * ------------------------------------------------- * ++ * | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| * ++ * ------------------------------------------------- * ++ * | d8 | d9 | d10 | d11 | * ++ * ------------------------------------------------- * ++ * ------------------------------------------------- * ++ * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * ++ * ------------------------------------------------- * ++ * | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| * ++ * ------------------------------------------------- * ++ * | d12 | d13 | d14 | d15 | * ++ * ------------------------------------------------- * ++ * ------------------------------------------------- * ++ * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * ++ * ------------------------------------------------- * ++ * | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| * ++ * ------------------------------------------------- * ++ * | x19 | x20 | x21 | x22 | * ++ * ------------------------------------------------- * ++ * ------------------------------------------------- * ++ * | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | * ++ * ------------------------------------------------- * ++ * | 0x60| 0x64| 0x68| 0x6c| 0x70| 0x74| 0x78| 0x7c| * ++ * ------------------------------------------------- * ++ * | x23 | x24 | x25 | x26 | * ++ * ------------------------------------------------- * ++ * ------------------------------------------------- * ++ * | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | * ++ * ------------------------------------------------- * ++ * | 0x80| 0x84| 0x88| 0x8c| 0x90| 0x94| 0x98| 0x9c| * ++ * ------------------------------------------------- * ++ * | x27 | x28 | FP | LR | * ++ * ------------------------------------------------- * ++ * ------------------------------------------------- * ++ * | 40 | 41 | 42 | 43 | | | * ++ * ------------------------------------------------- * ++ * | 0xa0| 0xa4| 0xa8| 0xac| | | * ++ * ------------------------------------------------- * ++ * | PC | align | | | * ++ * ------------------------------------------------- * ++ * * ++ *******************************************************/ ++ ++.cpu generic+fp+simd ++.text ++.align 2 ++.global jump_fcontext ++.type jump_fcontext, %function ++jump_fcontext: ++ # prepare stack for GP + FPU ++ sub sp, sp, #0xb0 ++ ++ # save d8 - d15 ++ stp d8, d9, [sp, #0x00] ++ stp d10, d11, [sp, #0x10] ++ stp d12, d13, [sp, #0x20] ++ stp d14, d15, [sp, #0x30] ++ ++ # save x19-x30 ++ stp x19, x20, [sp, #0x40] ++ stp x21, x22, [sp, #0x50] ++ stp x23, x24, [sp, #0x60] ++ stp x25, x26, [sp, #0x70] ++ stp x27, x28, [sp, #0x80] ++ stp x29, x30, [sp, #0x90] ++ ++ # save LR as PC ++ str x30, [sp, #0xa0] ++ ++ # store RSP (pointing to context-data) in X0 ++ mov x4, sp ++ ++ # restore RSP (pointing to context-data) from X1 ++ mov sp, x0 ++ ++ # load d8 - d15 ++ ldp d8, d9, [sp, #0x00] ++ ldp d10, d11, [sp, #0x10] ++ ldp d12, d13, [sp, #0x20] ++ ldp d14, d15, [sp, #0x30] ++ ++ # load x19-x30 ++ ldp x19, x20, [sp, #0x40] ++ ldp x21, x22, [sp, #0x50] ++ ldp x23, x24, [sp, #0x60] ++ ldp x25, x26, [sp, #0x70] ++ ldp x27, x28, [sp, #0x80] ++ ldp x29, x30, [sp, #0x90] ++ ++ # return transfer_t from jump ++ # pass transfer_t as first arg in context function ++ # X0 == FCTX, X1 == DATA ++ mov x0, x4 ++ ++ # load pc ++ ldr x4, [sp, #0xa0] ++ ++ # restore stack from GP + FPU ++ add sp, sp, #0xb0 ++ ++ ret x4 ++.size jump_fcontext,.-jump_fcontext ++# Mark that we don't need executable stack. ++.section .note.GNU-stack,"",%progbits +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/third-party/boost/asm/arm64-v8a/make_arm64_aapcs_elf_gas.S b/node_modules/react-native/ReactAndroid/bin/src/main/jni/third-party/boost/asm/arm64-v8a/make_arm64_aapcs_elf_gas.S +new file mode 100644 +index 0000000..e71a91c +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/third-party/boost/asm/arm64-v8a/make_arm64_aapcs_elf_gas.S +@@ -0,0 +1,85 @@ ++/* ++ Copyright Edward Nevill + Oliver Kowalke 2015 ++ Distributed under the Boost Software License, Version 1.0. ++ (See accompanying file LICENSE_1_0.txt or copy at ++ http://www.boost.org/LICENSE_1_0.txt) ++*/ ++/******************************************************* ++ * * ++ * ------------------------------------------------- * ++ * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * ++ * ------------------------------------------------- * ++ * | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| * ++ * ------------------------------------------------- * ++ * | d8 | d9 | d10 | d11 | * ++ * ------------------------------------------------- * ++ * ------------------------------------------------- * ++ * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * ++ * ------------------------------------------------- * ++ * | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| * ++ * ------------------------------------------------- * ++ * | d12 | d13 | d14 | d15 | * ++ * ------------------------------------------------- * ++ * ------------------------------------------------- * ++ * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * ++ * ------------------------------------------------- * ++ * | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| * ++ * ------------------------------------------------- * ++ * | x19 | x20 | x21 | x22 | * ++ * ------------------------------------------------- * ++ * ------------------------------------------------- * ++ * | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | * ++ * ------------------------------------------------- * ++ * | 0x60| 0x64| 0x68| 0x6c| 0x70| 0x74| 0x78| 0x7c| * ++ * ------------------------------------------------- * ++ * | x23 | x24 | x25 | x26 | * ++ * ------------------------------------------------- * ++ * ------------------------------------------------- * ++ * | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | * ++ * ------------------------------------------------- * ++ * | 0x80| 0x84| 0x88| 0x8c| 0x90| 0x94| 0x98| 0x9c| * ++ * ------------------------------------------------- * ++ * | x27 | x28 | FP | LR | * ++ * ------------------------------------------------- * ++ * ------------------------------------------------- * ++ * | 40 | 41 | 42 | 43 | | | * ++ * ------------------------------------------------- * ++ * | 0xa0| 0xa4| 0xa8| 0xac| | | * ++ * ------------------------------------------------- * ++ * | PC | align | | | * ++ * ------------------------------------------------- * ++ * * ++ *******************************************************/ ++ ++.cpu generic+fp+simd ++.text ++.align 2 ++.global make_fcontext ++.type make_fcontext, %function ++make_fcontext: ++ # shift address in x0 (allocated stack) to lower 16 byte boundary ++ and x0, x0, ~0xF ++ ++ # reserve space for context-data on context-stack ++ sub x0, x0, #0xb0 ++ ++ # third arg of make_fcontext() == address of context-function ++ # store address as a PC to jump in ++ str x2, [x0, #0xa0] ++ ++ # save address of finish as return-address for context-function ++ # will be entered after context-function returns (LR register) ++ adr x1, finish ++ str x1, [x0, #0x98] ++ ++ ret x30 // return pointer to context-data (x0) ++ ++finish: ++ # exit code is zero ++ mov x0, #0 ++ # exit application ++ bl _exit ++ ++.size make_fcontext,.-make_fcontext ++# Mark that we don't need executable stack. ++.section .note.GNU-stack,"",%progbits +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/third-party/boost/asm/arm64-v8a/ontop_arm64_aapcs_elf_gas.S b/node_modules/react-native/ReactAndroid/bin/src/main/jni/third-party/boost/asm/arm64-v8a/ontop_arm64_aapcs_elf_gas.S +new file mode 100644 +index 0000000..7e3b047 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/third-party/boost/asm/arm64-v8a/ontop_arm64_aapcs_elf_gas.S +@@ -0,0 +1,113 @@ ++/* ++ Copyright Edward Nevill + Oliver Kowalke 2015 ++ Distributed under the Boost Software License, Version 1.0. ++ (See accompanying file LICENSE_1_0.txt or copy at ++ http://www.boost.org/LICENSE_1_0.txt) ++*/ ++/******************************************************* ++ * * ++ * ------------------------------------------------- * ++ * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * ++ * ------------------------------------------------- * ++ * | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| * ++ * ------------------------------------------------- * ++ * | d8 | d9 | d10 | d11 | * ++ * ------------------------------------------------- * ++ * ------------------------------------------------- * ++ * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * ++ * ------------------------------------------------- * ++ * | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| * ++ * ------------------------------------------------- * ++ * | d12 | d13 | d14 | d15 | * ++ * ------------------------------------------------- * ++ * ------------------------------------------------- * ++ * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * ++ * ------------------------------------------------- * ++ * | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| * ++ * ------------------------------------------------- * ++ * | x19 | x20 | x21 | x22 | * ++ * ------------------------------------------------- * ++ * ------------------------------------------------- * ++ * | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | * ++ * ------------------------------------------------- * ++ * | 0x60| 0x64| 0x68| 0x6c| 0x70| 0x74| 0x78| 0x7c| * ++ * ------------------------------------------------- * ++ * | x23 | x24 | x25 | x26 | * ++ * ------------------------------------------------- * ++ * ------------------------------------------------- * ++ * | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | * ++ * ------------------------------------------------- * ++ * | 0x80| 0x84| 0x88| 0x8c| 0x90| 0x94| 0x98| 0x9c| * ++ * ------------------------------------------------- * ++ * | x27 | x28 | FP | LR | * ++ * ------------------------------------------------- * ++ * ------------------------------------------------- * ++ * | 40 | 41 | 42 | 43 | | | * ++ * ------------------------------------------------- * ++ * | 0xa0| 0xa4| 0xa8| 0xac| | | * ++ * ------------------------------------------------- * ++ * | PC | align | | | * ++ * ------------------------------------------------- * ++ * * ++ *******************************************************/ ++ ++.cpu generic+fp+simd ++.text ++.align 2 ++.global ontop_fcontext ++.type ontop_fcontext, %function ++ontop_fcontext: ++ # prepare stack for GP + FPU ++ sub sp, sp, #0xb0 ++ ++ # save d8 - d15 ++ stp d8, d9, [sp, #0x00] ++ stp d10, d11, [sp, #0x10] ++ stp d12, d13, [sp, #0x20] ++ stp d14, d15, [sp, #0x30] ++ ++ # save x19-x30 ++ stp x19, x20, [sp, #0x40] ++ stp x21, x22, [sp, #0x50] ++ stp x23, x24, [sp, #0x60] ++ stp x25, x26, [sp, #0x70] ++ stp x27, x28, [sp, #0x80] ++ stp x29, x30, [sp, #0x90] ++ ++ # save LR as PC ++ str x30, [sp, #0xa0] ++ ++ # store RSP (pointing to context-data) in X5 ++ mov x4, sp ++ ++ # restore RSP (pointing to context-data) from X1 ++ mov sp, x0 ++ ++ # load d8 - d15 ++ ldp d8, d9, [sp, #0x00] ++ ldp d10, d11, [sp, #0x10] ++ ldp d12, d13, [sp, #0x20] ++ ldp d14, d15, [sp, #0x30] ++ ++ # load x19-x30 ++ ldp x19, x20, [sp, #0x40] ++ ldp x21, x22, [sp, #0x50] ++ ldp x23, x24, [sp, #0x60] ++ ldp x25, x26, [sp, #0x70] ++ ldp x27, x28, [sp, #0x80] ++ ldp x29, x30, [sp, #0x90] ++ ++ # return transfer_t from jump ++ # pass transfer_t as first arg in context function ++ # X0 == FCTX, X1 == DATA ++ mov x0, x4 ++ ++ # skip pc ++ # restore stack from GP + FPU ++ add sp, sp, #0xb0 ++ ++ # jump to ontop-function ++ ret x2 ++.size ontop_fcontext,.-ontop_fcontext ++# Mark that we don't need executable stack. ++.section .note.GNU-stack,"",%progbits +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/third-party/boost/asm/armeabi-v7a/jump_arm_aapcs_elf_gas.S b/node_modules/react-native/ReactAndroid/bin/src/main/jni/third-party/boost/asm/armeabi-v7a/jump_arm_aapcs_elf_gas.S +new file mode 100644 +index 0000000..d0f7fa2 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/third-party/boost/asm/armeabi-v7a/jump_arm_aapcs_elf_gas.S +@@ -0,0 +1,86 @@ ++/* ++ Copyright Oliver Kowalke 2009. ++ Distributed under the Boost Software License, Version 1.0. ++ (See accompanying file LICENSE_1_0.txt or copy at ++ http://www.boost.org/LICENSE_1_0.txt) ++*/ ++ ++/******************************************************* ++ * * ++ * ------------------------------------------------- * ++ * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * ++ * ------------------------------------------------- * ++ * | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| * ++ * ------------------------------------------------- * ++ * | s16 | s17 | s18 | s19 | s20 | s21 | s22 | s23 | * ++ * ------------------------------------------------- * ++ * ------------------------------------------------- * ++ * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * ++ * ------------------------------------------------- * ++ * | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| * ++ * ------------------------------------------------- * ++ * | s24 | s25 | s26 | s27 | s28 | s29 | s30 | s31 | * ++ * ------------------------------------------------- * ++ * ------------------------------------------------- * ++ * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * ++ * ------------------------------------------------- * ++ * | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| * ++ * ------------------------------------------------- * ++ * |hiddn| v1 | v2 | v3 | v4 | v5 | v6 | v7 | * ++ * ------------------------------------------------- * ++ * ------------------------------------------------- * ++ * | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | * ++ * ------------------------------------------------- * ++ * | 0x60| 0x64| 0x68| 0x6c| 0x70| 0x74| 0x78| 0x7c| * ++ * ------------------------------------------------- * ++ * | v8 | lr | pc | FCTX| DATA| | * ++ * ------------------------------------------------- * ++ * * ++ *******************************************************/ ++ ++.text ++.globl jump_fcontext ++.align 2 ++.type jump_fcontext,%function ++jump_fcontext: ++ @ save LR as PC ++ push {lr} ++ @ save hidden,V1-V8,LR ++ push {a1,v1-v8,lr} ++ ++ @ prepare stack for FPU ++ sub sp, sp, #64 ++#if (defined(__VFP_FP__) && !defined(__SOFTFP__)) ++ @ save S16-S31 ++ vstmia sp, {d8-d15} ++#endif ++ ++ @ store RSP (pointing to context-data) in A1 ++ mov a1, sp ++ ++ @ restore RSP (pointing to context-data) from A2 ++ mov sp, a2 ++ ++#if (defined(__VFP_FP__) && !defined(__SOFTFP__)) ++ @ restore S16-S31 ++ vldmia sp, {d8-d15} ++#endif ++ @ prepare stack for FPU ++ add sp, sp, #64 ++ ++ @ restore hidden,V1-V8,LR ++ pop {a4,v1-v8,lr} ++ ++ @ return transfer_t from jump ++ str a1, [a4, #0] ++ str a3, [a4, #4] ++ @ pass transfer_t as first arg in context function ++ @ A1 == FCTX, A2 == DATA ++ mov a2, a3 ++ ++ @ restore PC ++ pop {pc} ++.size jump_fcontext,.-jump_fcontext ++ ++@ Mark that we don't need executable stack. ++.section .note.GNU-stack,"",%progbits +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/third-party/boost/asm/armeabi-v7a/make_arm_aapcs_elf_gas.S b/node_modules/react-native/ReactAndroid/bin/src/main/jni/third-party/boost/asm/armeabi-v7a/make_arm_aapcs_elf_gas.S +new file mode 100644 +index 0000000..993dac1 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/third-party/boost/asm/armeabi-v7a/make_arm_aapcs_elf_gas.S +@@ -0,0 +1,79 @@ ++/* ++ Copyright Oliver Kowalke 2009. ++ Distributed under the Boost Software License, Version 1.0. ++ (See accompanying file LICENSE_1_0.txt or copy at ++ http://www.boost.org/LICENSE_1_0.txt) ++*/ ++ ++/******************************************************* ++ * * ++ * ------------------------------------------------- * ++ * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * ++ * ------------------------------------------------- * ++ * | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| * ++ * ------------------------------------------------- * ++ * | s16 | s17 | s18 | s19 | s20 | s21 | s22 | s23 | * ++ * ------------------------------------------------- * ++ * ------------------------------------------------- * ++ * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * ++ * ------------------------------------------------- * ++ * | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| * ++ * ------------------------------------------------- * ++ * | s24 | s25 | s26 | s27 | s28 | s29 | s30 | s31 | * ++ * ------------------------------------------------- * ++ * ------------------------------------------------- * ++ * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * ++ * ------------------------------------------------- * ++ * | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| * ++ * ------------------------------------------------- * ++ * |hiddn| v1 | v2 | v3 | v4 | v5 | v6 | v7 | * ++ * ------------------------------------------------- * ++ * ------------------------------------------------- * ++ * | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | * ++ * ------------------------------------------------- * ++ * | 0x60| 0x64| 0x68| 0x6c| 0x70| 0x74| 0x78| 0x7c| * ++ * ------------------------------------------------- * ++ * | v8 | lr | pc | FCTX| DATA| | * ++ * ------------------------------------------------- * ++ * * ++ *******************************************************/ ++ ++.text ++.globl make_fcontext ++.align 2 ++.type make_fcontext,%function ++make_fcontext: ++ @ shift address in A1 to lower 16 byte boundary ++ bic a1, a1, #15 ++ ++ @ reserve space for context-data on context-stack ++ sub a1, a1, #128 ++ ++ @ third arg of make_fcontext() == address of context-function ++ str a3, [a1, #104] ++ ++ @ compute address of returned transfer_t ++ add a2, a1, #108 ++ mov a3, a2 ++ str a3, [a1, #64] ++ ++ @ compute abs address of label finish ++ adr a2, finish ++ @ save address of finish as return-address for context-function ++ @ will be entered after context-function returns ++ str a2, [a1, #100] ++ ++#if (defined(__VFP_FP__) && !defined(__SOFTFP__)) ++#endif ++ ++ bx lr @ return pointer to context-data ++ ++finish: ++ @ exit code is zero ++ mov a1, #0 ++ @ exit application ++ bl _exit@PLT ++.size make_fcontext,.-make_fcontext ++ ++@ Mark that we don't need executable stack. ++.section .note.GNU-stack,"",%progbits +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/third-party/boost/asm/armeabi-v7a/ontop_arm_aapcs_elf_gas.S b/node_modules/react-native/ReactAndroid/bin/src/main/jni/third-party/boost/asm/armeabi-v7a/ontop_arm_aapcs_elf_gas.S +new file mode 100644 +index 0000000..9d9198f +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/third-party/boost/asm/armeabi-v7a/ontop_arm_aapcs_elf_gas.S +@@ -0,0 +1,91 @@ ++/* ++ Copyright Oliver Kowalke 2009. ++ Distributed under the Boost Software License, Version 1.0. ++ (See accompanying file LICENSE_1_0.txt or copy at ++ http://www.boost.org/LICENSE_1_0.txt) ++*/ ++ ++/******************************************************* ++ * * ++ * ------------------------------------------------- * ++ * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * ++ * ------------------------------------------------- * ++ * | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| * ++ * ------------------------------------------------- * ++ * | s16 | s17 | s18 | s19 | s20 | s21 | s22 | s23 | * ++ * ------------------------------------------------- * ++ * ------------------------------------------------- * ++ * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * ++ * ------------------------------------------------- * ++ * | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| * ++ * ------------------------------------------------- * ++ * | s24 | s25 | s26 | s27 | s28 | s29 | s30 | s31 | * ++ * ------------------------------------------------- * ++ * ------------------------------------------------- * ++ * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * ++ * ------------------------------------------------- * ++ * | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| * ++ * ------------------------------------------------- * ++ * |hiddn| v1 | v2 | v3 | v4 | v5 | v6 | v7 | * ++ * ------------------------------------------------- * ++ * ------------------------------------------------- * ++ * | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | * ++ * ------------------------------------------------- * ++ * | 0x60| 0x64| 0x68| 0x6c| 0x70| 0x74| 0x78| 0x7c| * ++ * ------------------------------------------------- * ++ * | v8 | lr | pc | FCTX| DATA| | * ++ * ------------------------------------------------- * ++ * * ++ *******************************************************/ ++ ++.text ++.globl ontop_fcontext ++.align 2 ++.type ontop_fcontext,%function ++ontop_fcontext: ++ @ save LR as PC ++ push {lr} ++ @ save hidden,V1-V8,LR ++ push {a1,v1-v8,lr} ++ ++ @ prepare stack for FPU ++ sub sp, sp, #64 ++#if (defined(__VFP_FP__) && !defined(__SOFTFP__)) ++ @ save S16-S31 ++ vstmia sp, {d8-d15} ++#endif ++ ++ @ store RSP (pointing to context-data) in A1 ++ mov a1, sp ++ ++ @ restore RSP (pointing to context-data) from A2 ++ mov sp, a2 ++ ++ @ store parent context in A2 ++ mov a2, a1 ++ ++#if (defined(__VFP_FP__) && !defined(__SOFTFP__)) ++ @ restore S16-S31 ++ vldmia sp, {d8-d15} ++#endif ++ @ prepare stack for FPU ++ add sp, sp, #64 ++ ++ @ restore hidden,V1-V8,LR ++ pop {a1,v1-v8,lr} ++ ++ @ return transfer_t from jump ++ str a2, [a1, #0] ++ str a3, [a1, #4] ++ @ pass transfer_t as first arg in context function ++ @ A1 == hidden, A2 == FCTX, A3 == DATA ++ ++ @ skip PC ++ add sp, sp, #4 ++ ++ @ jump to ontop-function ++ bx a4 ++.size ontop_fcontext,.-ontop_fcontext ++ ++@ Mark that we don't need executable stack. ++.section .note.GNU-stack,"",%progbits +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/third-party/boost/asm/x86/jump_i386_sysv_elf_gas.S b/node_modules/react-native/ReactAndroid/bin/src/main/jni/third-party/boost/asm/x86/jump_i386_sysv_elf_gas.S +new file mode 100644 +index 0000000..25f01db +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/third-party/boost/asm/x86/jump_i386_sysv_elf_gas.S +@@ -0,0 +1,78 @@ ++/* ++ Copyright Oliver Kowalke 2009. ++ Distributed under the Boost Software License, Version 1.0. ++ (See accompanying file LICENSE_1_0.txt or copy at ++ http://www.boost.org/LICENSE_1_0.txt) ++*/ ++ ++/**************************************************************************************** ++ * * ++ * ---------------------------------------------------------------------------------- * ++ * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * ++ * ---------------------------------------------------------------------------------- * ++ * | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | * ++ * ---------------------------------------------------------------------------------- * ++ * | fc_mxcsr|fc_x87_cw| EDI | ESI | EBX | EBP | EIP | hidden | * ++ * ---------------------------------------------------------------------------------- * ++ * ---------------------------------------------------------------------------------- * ++ * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * ++ * ---------------------------------------------------------------------------------- * ++ * | 0x20 | 0x24 | | * ++ * ---------------------------------------------------------------------------------- * ++ * | to | data | | * ++ * ---------------------------------------------------------------------------------- * ++ * * ++ ****************************************************************************************/ ++ ++.text ++.globl jump_fcontext ++.align 2 ++.type jump_fcontext,@function ++jump_fcontext: ++ leal -0x18(%esp), %esp /* prepare stack */ ++ ++ stmxcsr (%esp) /* save MMX control- and status-word */ ++ fnstcw 0x4(%esp) /* save x87 control-word */ ++ ++ movl %edi, 0x8(%esp) /* save EDI */ ++ movl %esi, 0xc(%esp) /* save ESI */ ++ movl %ebx, 0x10(%esp) /* save EBX */ ++ movl %ebp, 0x14(%esp) /* save EBP */ ++ ++ /* store ESP (pointing to context-data) in ECX */ ++ movl %esp, %ecx ++ ++ /* first arg of jump_fcontext() == fcontext to jump to */ ++ movl 0x20(%esp), %eax ++ ++ /* second arg of jump_fcontext() == data to be transferred */ ++ movl 0x24(%esp), %edx ++ ++ /* restore ESP (pointing to context-data) from EAX */ ++ movl %eax, %esp ++ ++ /* address of returned transport_t */ ++ movl 0x1c(%esp), %eax ++ /* return parent fcontext_t */ ++ movl %ecx, (%eax) ++ /* return data */ ++ movl %edx, 0x4(%eax) ++ ++ movl 0x18(%esp), %ecx /* restore EIP */ ++ ++ ldmxcsr (%esp) /* restore MMX control- and status-word */ ++ fldcw 0x4(%esp) /* restore x87 control-word */ ++ ++ movl 0x8(%esp), %edi /* restore EDI */ ++ movl 0xc(%esp), %esi /* restore ESI */ ++ movl 0x10(%esp), %ebx /* restore EBX */ ++ movl 0x14(%esp), %ebp /* restore EBP */ ++ ++ leal 0x20(%esp), %esp /* prepare stack */ ++ ++ /* jump to context */ ++ jmp *%ecx ++.size jump_fcontext,.-jump_fcontext ++ ++/* Mark that we don't need executable stack. */ ++.section .note.GNU-stack,"",%progbits +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/third-party/boost/asm/x86/make_i386_sysv_elf_gas.S b/node_modules/react-native/ReactAndroid/bin/src/main/jni/third-party/boost/asm/x86/make_i386_sysv_elf_gas.S +new file mode 100644 +index 0000000..de77e88 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/third-party/boost/asm/x86/make_i386_sysv_elf_gas.S +@@ -0,0 +1,106 @@ ++/* ++ Copyright Oliver Kowalke 2009. ++ Distributed under the Boost Software License, Version 1.0. ++ (See accompanying file LICENSE_1_0.txt or copy at ++ http://www.boost.org/LICENSE_1_0.txt) ++*/ ++ ++/**************************************************************************************** ++ * * ++ * ---------------------------------------------------------------------------------- * ++ * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * ++ * ---------------------------------------------------------------------------------- * ++ * | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | * ++ * ---------------------------------------------------------------------------------- * ++ * | fc_mxcsr|fc_x87_cw| EDI | ESI | EBX | EBP | EIP | hidden | * ++ * ---------------------------------------------------------------------------------- * ++ * ---------------------------------------------------------------------------------- * ++ * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * ++ * ---------------------------------------------------------------------------------- * ++ * | 0x20 | 0x24 | | * ++ * ---------------------------------------------------------------------------------- * ++ * | to | data | | * ++ * ---------------------------------------------------------------------------------- * ++ * * ++ ****************************************************************************************/ ++ ++.text ++.globl make_fcontext ++.align 2 ++.type make_fcontext,@function ++make_fcontext: ++ /* first arg of make_fcontext() == top of context-stack */ ++ movl 0x4(%esp), %eax ++ ++ /* reserve space for first argument of context-function ++ eax might already point to a 16byte border */ ++ leal -0x8(%eax), %eax ++ ++ /* shift address in EAX to lower 16 byte boundary */ ++ andl $-16, %eax ++ ++ /* reserve space for context-data on context-stack */ ++ leal -0x28(%eax), %eax ++ ++ /* third arg of make_fcontext() == address of context-function */ ++ /* stored in EBX */ ++ movl 0xc(%esp), %ecx ++ movl %ecx, 0x10(%eax) ++ ++ /* save MMX control- and status-word */ ++ stmxcsr (%eax) ++ /* save x87 control-word */ ++ fnstcw 0x4(%eax) ++ ++ /* return transport_t */ ++ /* FCTX == EDI, DATA == ESI */ ++ leal 0x8(%eax), %ecx ++ movl %ecx, 0x1c(%eax) ++ ++ /* compute abs address of label trampoline */ ++ call 1f ++ /* address of trampoline 1 */ ++1: popl %ecx ++ /* compute abs address of label trampoline */ ++ addl $trampoline-1b, %ecx ++ /* save address of trampoline as return address */ ++ /* will be entered after calling jump_fcontext() first time */ ++ movl %ecx, 0x18(%eax) ++ ++ /* compute abs address of label finish */ ++ call 2f ++ /* address of label 2 */ ++2: popl %ecx ++ /* compute abs address of label finish */ ++ addl $finish-2b, %ecx ++ /* save address of finish as return-address for context-function */ ++ /* will be entered after context-function returns */ ++ movl %ecx, 0x14(%eax) ++ ++ ret /* return pointer to context-data */ ++ ++trampoline: ++ /* move transport_t for entering context-function */ ++ movl %edi, (%esp) ++ movl %esi, 0x4(%esp) ++ pushl %ebp ++ /* jump to context-function */ ++ jmp *%ebx ++ ++finish: ++ call 3f ++ /* address of label 3 */ ++3: popl %ebx ++ /* compute address of GOT and store it in EBX */ ++ addl $_GLOBAL_OFFSET_TABLE_+[.-3b], %ebx ++ ++ /* exit code is zero */ ++ xorl %eax, %eax ++ movl %eax, (%esp) ++ /* exit application */ ++ call _exit@PLT ++ hlt ++.size make_fcontext,.-make_fcontext ++ ++/* Mark that we don't need executable stack. */ ++.section .note.GNU-stack,"",%progbits +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/third-party/boost/asm/x86/ontop_i386_sysv_elf_gas.S b/node_modules/react-native/ReactAndroid/bin/src/main/jni/third-party/boost/asm/x86/ontop_i386_sysv_elf_gas.S +new file mode 100644 +index 0000000..d3a6692 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/third-party/boost/asm/x86/ontop_i386_sysv_elf_gas.S +@@ -0,0 +1,85 @@ ++/* ++ Copyright Oliver Kowalke 2009. ++ Distributed under the Boost Software License, Version 1.0. ++ (See accompanying file LICENSE_1_0.txt or copy at ++ http://www.boost.org/LICENSE_1_0.txt) ++*/ ++ ++/**************************************************************************************** ++ * * ++ * ---------------------------------------------------------------------------------- * ++ * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * ++ * ---------------------------------------------------------------------------------- * ++ * | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | * ++ * ---------------------------------------------------------------------------------- * ++ * | fc_mxcsr|fc_x87_cw| EDI | ESI | EBX | EBP | EIP | hidden | * ++ * ---------------------------------------------------------------------------------- * ++ * ---------------------------------------------------------------------------------- * ++ * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * ++ * ---------------------------------------------------------------------------------- * ++ * | 0x20 | 0x24 | | * ++ * ---------------------------------------------------------------------------------- * ++ * | to | data | | * ++ * ---------------------------------------------------------------------------------- * ++ * * ++ ****************************************************************************************/ ++ ++.text ++.globl ontop_fcontext ++.align 2 ++.type ontop_fcontext,@function ++ontop_fcontext: ++ leal -0x18(%esp), %esp /* prepare stack */ ++ ++ stmxcsr (%esp) /* save MMX control- and status-word */ ++ fnstcw 0x4(%esp) /* save x87 control-word */ ++ ++ movl %edi, 0x8(%esp) /* save EDI */ ++ movl %esi, 0xc(%esp) /* save ESI */ ++ movl %ebx, 0x10(%esp) /* save EBX */ ++ movl %ebp, 0x14(%esp) /* save EBP */ ++ ++ /* store ESP (pointing to context-data) in ECX */ ++ movl %esp, %ecx ++ ++ /* first arg of ontop_fcontext() == fcontext to jump to */ ++ movl 0x20(%esp), %eax ++ ++ /* pass parent fcontext_t */ ++ movl %ecx, 0x20(%eax) ++ ++ /* second arg of ontop_fcontext() == data to be transferred */ ++ movl 0x24(%esp), %ecx ++ ++ /* pass data */ ++ movl %ecx, 0x24(%eax) ++ ++ /* third arg of ontop_fcontext() == ontop-function */ ++ movl 0x28(%esp), %ecx ++ ++ /* restore ESP (pointing to context-data) from EAX */ ++ movl %eax, %esp ++ ++ /* address of returned transport_t */ ++ movl 0x1c(%esp), %eax ++ /* return parent fcontext_t */ ++ movl %ecx, (%eax) ++ /* return data */ ++ movl %edx, 0x4(%eax) ++ ++ ldmxcsr (%esp) /* restore MMX control- and status-word */ ++ fldcw 0x4(%esp) /* restore x87 control-word */ ++ ++ movl 0x8(%esp), %edi /* restore EDI */ ++ movl 0xc(%esp), %esi /* restore ESI */ ++ movl 0x10(%esp), %ebx /* restore EBX */ ++ movl 0x14(%esp), %ebp /* restore EBP */ ++ ++ leal 0x18(%esp), %esp /* prepare stack */ ++ ++ /* jump to context */ ++ jmp *%ecx ++.size ontop_fcontext,.-ontop_fcontext ++ ++/* Mark that we don't need executable stack. */ ++.section .note.GNU-stack,"",%progbits +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/third-party/boost/asm/x86_64/jump_x86_64_sysv_elf_gas.S b/node_modules/react-native/ReactAndroid/bin/src/main/jni/third-party/boost/asm/x86_64/jump_x86_64_sysv_elf_gas.S +new file mode 100644 +index 0000000..0194238 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/third-party/boost/asm/x86_64/jump_x86_64_sysv_elf_gas.S +@@ -0,0 +1,76 @@ ++/* ++ Copyright Oliver Kowalke 2009. ++ Distributed under the Boost Software License, Version 1.0. ++ (See accompanying file LICENSE_1_0.txt or copy at ++ http://www.boost.org/LICENSE_1_0.txt) ++*/ ++ ++/**************************************************************************************** ++ * * ++ * ---------------------------------------------------------------------------------- * ++ * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * ++ * ---------------------------------------------------------------------------------- * ++ * | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | * ++ * ---------------------------------------------------------------------------------- * ++ * | fc_mxcsr|fc_x87_cw| R12 | R13 | R14 | * ++ * ---------------------------------------------------------------------------------- * ++ * ---------------------------------------------------------------------------------- * ++ * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * ++ * ---------------------------------------------------------------------------------- * ++ * | 0x20 | 0x24 | 0x28 | 0x2c | 0x30 | 0x34 | 0x38 | 0x3c | * ++ * ---------------------------------------------------------------------------------- * ++ * | R15 | RBX | RBP | RIP | * ++ * ---------------------------------------------------------------------------------- * ++ * * ++ ****************************************************************************************/ ++ ++.text ++.globl jump_fcontext ++.type jump_fcontext,@function ++.align 16 ++jump_fcontext: ++ leaq -0x38(%rsp), %rsp /* prepare stack */ ++ ++ stmxcsr (%rsp) /* save MMX control- and status-word */ ++ fnstcw 0x4(%rsp) /* save x87 control-word */ ++ ++ movq %r12, 0x8(%rsp) /* save R12 */ ++ movq %r13, 0x10(%rsp) /* save R13 */ ++ movq %r14, 0x18(%rsp) /* save R14 */ ++ movq %r15, 0x20(%rsp) /* save R15 */ ++ movq %rbx, 0x28(%rsp) /* save RBX */ ++ movq %rbp, 0x30(%rsp) /* save RBP */ ++ ++ /* store RSP (pointing to context-data) in RAX */ ++ movq %rsp, %rax ++ ++ /* restore RSP (pointing to context-data) from RDI */ ++ movq %rdi, %rsp ++ ++ movq 0x38(%rsp), %r8 /* restore return-address */ ++ ++ ldmxcsr (%rsp) /* restore MMX control- and status-word */ ++ fldcw 0x4(%rsp) /* restore x87 control-word */ ++ ++ movq 0x8(%rsp), %r12 /* restore R12 */ ++ movq 0x10(%rsp), %r13 /* restore R13 */ ++ movq 0x18(%rsp), %r14 /* restore R14 */ ++ movq 0x20(%rsp), %r15 /* restore R15 */ ++ movq 0x28(%rsp), %rbx /* restore RBX */ ++ movq 0x30(%rsp), %rbp /* restore RBP */ ++ ++ leaq 0x40(%rsp), %rsp /* prepare stack */ ++ ++ /* return transfer_t from jump */ ++ /* RAX == fctx, RDX == data */ ++ movq %rsi, %rdx ++ /* pass transfer_t as first arg in context function */ ++ /* RDI == fctx, RSI == data */ ++ movq %rax, %rdi ++ ++ /* indirect jump to context */ ++ jmp *%r8 ++.size jump_fcontext,.-jump_fcontext ++ ++/* Mark that we don't need executable stack. */ ++.section .note.GNU-stack,"",%progbits +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/third-party/boost/asm/x86_64/make_x86_64_sysv_elf_gas.S b/node_modules/react-native/ReactAndroid/bin/src/main/jni/third-party/boost/asm/x86_64/make_x86_64_sysv_elf_gas.S +new file mode 100644 +index 0000000..25a0c00 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/third-party/boost/asm/x86_64/make_x86_64_sysv_elf_gas.S +@@ -0,0 +1,81 @@ ++/* ++ Copyright Oliver Kowalke 2009. ++ Distributed under the Boost Software License, Version 1.0. ++ (See accompanying file LICENSE_1_0.txt or copy at ++ http://www.boost.org/LICENSE_1_0.txt) ++*/ ++ ++/**************************************************************************************** ++ * * ++ * ---------------------------------------------------------------------------------- * ++ * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * ++ * ---------------------------------------------------------------------------------- * ++ * | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | * ++ * ---------------------------------------------------------------------------------- * ++ * | fc_mxcsr|fc_x87_cw| R12 | R13 | R14 | * ++ * ---------------------------------------------------------------------------------- * ++ * ---------------------------------------------------------------------------------- * ++ * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * ++ * ---------------------------------------------------------------------------------- * ++ * | 0x20 | 0x24 | 0x28 | 0x2c | 0x30 | 0x34 | 0x38 | 0x3c | * ++ * ---------------------------------------------------------------------------------- * ++ * | R15 | RBX | RBP | RIP | * ++ * ---------------------------------------------------------------------------------- * ++ * * ++ ****************************************************************************************/ ++ ++.text ++.globl make_fcontext ++.type make_fcontext,@function ++.align 16 ++make_fcontext: ++ /* first arg of make_fcontext() == top of context-stack */ ++ movq %rdi, %rax ++ ++ /* shift address in RAX to lower 16 byte boundary */ ++ andq $-16, %rax ++ ++ /* reserve space for context-data on context-stack */ ++ /* on context-function entry: (RSP -0x8) % 16 == 0 */ ++ leaq -0x40(%rax), %rax ++ ++ /* third arg of make_fcontext() == address of context-function */ ++ /* stored in RBX */ ++ movq %rdx, 0x28(%rax) ++ ++ /* save MMX control- and status-word */ ++ stmxcsr (%rax) ++ /* save x87 control-word */ ++ fnstcw 0x4(%rax) ++ ++ /* compute abs address of label trampoline */ ++ leaq trampoline(%rip), %rcx ++ /* save address of trampoline as return-address for context-function */ ++ /* will be entered after calling jump_fcontext() first time */ ++ movq %rcx, 0x38(%rax) ++ ++ /* compute abs address of label finish */ ++ leaq finish(%rip), %rcx ++ /* save address of finish as return-address for context-function */ ++ /* will be entered after context-function returns */ ++ movq %rcx, 0x30(%rax) ++ ++ ret /* return pointer to context-data */ ++ ++trampoline: ++ /* store return address on stack */ ++ /* fix stack alignment */ ++ push %rbp ++ /* jump to context-function */ ++ jmp *%rbx ++ ++finish: ++ /* exit code is zero */ ++ xorq %rdi, %rdi ++ /* exit application */ ++ call _exit@PLT ++ hlt ++.size make_fcontext,.-make_fcontext ++ ++/* Mark that we don't need executable stack. */ ++.section .note.GNU-stack,"",%progbits +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/third-party/boost/asm/x86_64/ontop_x86_64_sysv_elf_gas.S b/node_modules/react-native/ReactAndroid/bin/src/main/jni/third-party/boost/asm/x86_64/ontop_x86_64_sysv_elf_gas.S +new file mode 100644 +index 0000000..d2a9373 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/third-party/boost/asm/x86_64/ontop_x86_64_sysv_elf_gas.S +@@ -0,0 +1,79 @@ ++/* ++ Copyright Oliver Kowalke 2009. ++ Distributed under the Boost Software License, Version 1.0. ++ (See accompanying file LICENSE_1_0.txt or copy at ++ http://www.boost.org/LICENSE_1_0.txt) ++*/ ++ ++/**************************************************************************************** ++ * * ++ * ---------------------------------------------------------------------------------- * ++ * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * ++ * ---------------------------------------------------------------------------------- * ++ * | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | * ++ * ---------------------------------------------------------------------------------- * ++ * | fc_mxcsr|fc_x87_cw| R12 | R13 | R14 | * ++ * ---------------------------------------------------------------------------------- * ++ * ---------------------------------------------------------------------------------- * ++ * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * ++ * ---------------------------------------------------------------------------------- * ++ * | 0x20 | 0x24 | 0x28 | 0x2c | 0x30 | 0x34 | 0x38 | 0x3c | * ++ * ---------------------------------------------------------------------------------- * ++ * | R15 | RBX | RBP | RIP | * ++ * ---------------------------------------------------------------------------------- * ++ * * ++ ****************************************************************************************/ ++ ++.text ++.globl ontop_fcontext ++.type ontop_fcontext,@function ++.align 16 ++ontop_fcontext: ++ /* preserve ontop-function in R8 */ ++ movq %rdx, %r8 ++ ++ leaq -0x38(%rsp), %rsp /* prepare stack */ ++ ++ stmxcsr (%rsp) /* save MMX control- and status-word */ ++ fnstcw 0x4(%rsp) /* save x87 control-word */ ++ ++ movq %r12, 0x8(%rsp) /* save R12 */ ++ movq %r13, 0x10(%rsp) /* save R13 */ ++ movq %r14, 0x18(%rsp) /* save R14 */ ++ movq %r15, 0x20(%rsp) /* save R15 */ ++ movq %rbx, 0x28(%rsp) /* save RBX */ ++ movq %rbp, 0x30(%rsp) /* save RBP */ ++ ++ /* store RSP (pointing to context-data) in RAX */ ++ movq %rsp, %rax ++ ++ /* restore RSP (pointing to context-data) from RDI */ ++ movq %rdi, %rsp ++ ++ ldmxcsr (%rsp) /* restore MMX control- and status-word */ ++ fldcw 0x4(%rsp) /* restore x87 control-word */ ++ ++ movq 0x8(%rsp), %r12 /* restore R12 */ ++ movq 0x10(%rsp), %r13 /* restore R13 */ ++ movq 0x18(%rsp), %r14 /* restore R14 */ ++ movq 0x20(%rsp), %r15 /* restore R15 */ ++ movq 0x28(%rsp), %rbx /* restore RBX */ ++ movq 0x30(%rsp), %rbp /* restore RBP */ ++ ++ leaq 0x38(%rsp), %rsp /* prepare stack */ ++ ++ /* return transfer_t from jump */ ++ /* RAX == fctx, RDX == data */ ++ movq %rsi, %rdx ++ /* pass transfer_t as first arg in context function */ ++ /* RDI == fctx, RSI == data */ ++ movq %rax, %rdi ++ ++ /* keep return-address on stack */ ++ ++ /* indirect jump to context */ ++ jmp *%r8 ++.size ontop_fcontext,.-ontop_fcontext ++ ++/* Mark that we don't need executable stack. */ ++.section .note.GNU-stack,"",%progbits +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/third-party/double-conversion/CMakeLists.txt b/node_modules/react-native/ReactAndroid/bin/src/main/jni/third-party/double-conversion/CMakeLists.txt +new file mode 100644 +index 0000000..d32b34c +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/third-party/double-conversion/CMakeLists.txt +@@ -0,0 +1,23 @@ ++# 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. ++ ++cmake_minimum_required(VERSION 3.13) ++set(CMAKE_VERBOSE_MAKEFILE on) ++ ++add_compile_options(-Wno-unused-variable -Wno-unused-local-typedefs) ++ ++add_library(double-conversion ++ STATIC ++ double-conversion/bignum.cc ++ double-conversion/bignum-dtoa.cc ++ double-conversion/cached-powers.cc ++ double-conversion/diy-fp.cc ++ double-conversion/double-conversion.cc ++ double-conversion/fast-dtoa.cc ++ double-conversion/fixed-dtoa.cc ++ double-conversion/strtod.cc) ++ ++target_include_directories(double-conversion PUBLIC .) ++ +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/third-party/fmt/CMakeLists.txt b/node_modules/react-native/ReactAndroid/bin/src/main/jni/third-party/fmt/CMakeLists.txt +new file mode 100644 +index 0000000..65d6a74 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/third-party/fmt/CMakeLists.txt +@@ -0,0 +1,13 @@ ++# 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. ++ ++cmake_minimum_required(VERSION 3.13) ++set(CMAKE_VERBOSE_MAKEFILE on) ++ ++add_compile_options(-std=c++20 -fexceptions) ++ ++add_library(fmt STATIC src/format.cc) ++ ++target_include_directories(fmt PUBLIC include) +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/third-party/folly/CMakeLists.txt b/node_modules/react-native/ReactAndroid/bin/src/main/jni/third-party/folly/CMakeLists.txt +new file mode 100644 +index 0000000..9cef8e8 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/third-party/folly/CMakeLists.txt +@@ -0,0 +1,70 @@ ++# 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. ++ ++cmake_minimum_required(VERSION 3.13) ++set(CMAKE_VERBOSE_MAKEFILE on) ++ ++SET(folly_FLAGS ++ -DFOLLY_NO_CONFIG=1 ++ -DFOLLY_HAVE_CLOCK_GETTIME=1 ++ -DFOLLY_USE_LIBCPP=1 ++ -DFOLLY_CFG_NO_COROUTINES=1 ++ -DFOLLY_MOBILE=1 ++ -DFOLLY_HAVE_RECVMMSG=1 ++ -DFOLLY_HAVE_PTHREAD=1 ++ # If APP_PLATFORM in Application.mk targets android-23 above, please comment ++ # the following line. NDK uses GNU style stderror_r() after API 23. ++ -DFOLLY_HAVE_XSI_STRERROR_R=1 ++ ) ++ ++################## ++### folly_runtime ### ++################## ++ ++SET(folly_runtime_SRC ++ folly/Conv.cpp ++ folly/Demangle.cpp ++ folly/dynamic.cpp ++ folly/FileUtil.cpp ++ folly/Format.cpp ++ folly/json_pointer.cpp ++ folly/json.cpp ++ folly/ScopeGuard.cpp ++ folly/SharedMutex.cpp ++ folly/String.cpp ++ folly/Unicode.cpp ++ folly/concurrency/CacheLocality.cpp ++ folly/container/detail/F14Table.cpp ++ folly/detail/FileUtilDetail.cpp ++ folly/detail/Futex.cpp ++ folly/detail/SplitStringSimd.cpp ++ folly/detail/UniqueInstance.cpp ++ folly/hash/SpookyHashV2.cpp ++ folly/lang/CString.cpp ++ folly/lang/SafeAssert.cpp ++ folly/lang/ToAscii.cpp ++ folly/memory/detail/MallocImpl.cpp ++ folly/net/NetOps.cpp ++ folly/portability/SysUio.cpp ++ folly/synchronization/SanitizeThread.cpp ++ folly/synchronization/ParkingLot.cpp ++ folly/system/AtFork.cpp ++ folly/system/ThreadId.cpp ++ folly/system/ThreadName.cpp) ++ ++add_library(folly_runtime SHARED ${folly_runtime_SRC}) ++ ++target_compile_options(folly_runtime ++ PRIVATE ++ -fexceptions ++ -fno-omit-frame-pointer ++ -frtti ++ -Wno-sign-compare ++ ${folly_FLAGS}) ++ ++target_compile_options(folly_runtime PUBLIC ${folly_FLAGS}) ++ ++target_include_directories(folly_runtime PUBLIC .) ++target_link_libraries(folly_runtime glog double-conversion boost fmt) +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/third-party/glog/CMakeLists.txt b/node_modules/react-native/ReactAndroid/bin/src/main/jni/third-party/glog/CMakeLists.txt +new file mode 100644 +index 0000000..4f07a4e +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/third-party/glog/CMakeLists.txt +@@ -0,0 +1,35 @@ ++# 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. ++ ++cmake_minimum_required(VERSION 3.13) ++set(CMAKE_VERBOSE_MAKEFILE on) ++ ++add_compile_options( ++ -Wwrite-strings ++ -Woverloaded-virtual ++ -Wno-sign-compare ++ -DNDEBUG ++ -g ++ -O2 ++ -DHAVE_PREAD=1 ++) ++ ++add_library(glog ++ SHARED ++ glog-0.3.5/src/demangle.cc ++ glog-0.3.5/src/logging.cc ++ glog-0.3.5/src/raw_logging.cc ++ glog-0.3.5/src/signalhandler.cc ++ glog-0.3.5/src/symbolize.cc ++ glog-0.3.5/src/utilities.cc ++ glog-0.3.5/src/vlog_is_on.cc ++ ) ++ ++# For private compilation, we include all the headers. ++# config.h is also there. ++target_include_directories(glog PRIVATE .) ++# For consumer, we set the `exported` dir as the ++# include folder. ++target_include_directories(glog PUBLIC exported) +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/third-party/glog/config.h b/node_modules/react-native/ReactAndroid/bin/src/main/jni/third-party/glog/config.h +new file mode 100644 +index 0000000..ab05c5a +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/third-party/glog/config.h +@@ -0,0 +1,182 @@ ++/* src/config.h. Generated from config.h.in by configure. */ ++/* src/config.h.in. Generated from configure.ac by autoheader. */ ++ ++/* define if glog doesn't use RTTI */ ++#define DISABLE_RTTI 1 ++ ++/* Namespace for Google classes */ ++#define GOOGLE_NAMESPACE google ++ ++/* Define if you have the `dladdr' function */ ++#define HAVE_DLADDR 1 ++ ++/* Define to 1 if you have the header file. */ ++#define HAVE_DLFCN_H 1 ++ ++/* Define to 1 if you have the header file. */ ++/* #undef HAVE_EXECINFO_H */ ++ ++/* Define if you have the `fcntl' function */ ++#define HAVE_FCNTL 1 ++ ++/* Define to 1 if you have the header file. */ ++/* #undef HAVE_GLOB_H */ ++ ++/* Define to 1 if you have the header file. */ ++#define HAVE_INTTYPES_H 1 ++ ++/* Define to 1 if you have the `pthread' library (-lpthread). */ ++/* #undef HAVE_LIBPTHREAD */ ++ ++/* Define to 1 if you have the header file. */ ++/* #undef HAVE_LIBUNWIND_H */ ++ ++/* define if you have google gflags library */ ++/* #undef HAVE_LIB_GFLAGS */ ++ ++/* define if you have google gmock library */ ++/* #undef HAVE_LIB_GMOCK */ ++ ++/* define if you have google gtest library */ ++/* #undef HAVE_LIB_GTEST */ ++ ++/* define if you have libunwind */ ++/* #undef HAVE_LIB_UNWIND */ ++ ++/* Define to 1 if you have the header file. */ ++#define HAVE_MEMORY_H 1 ++ ++/* define if the compiler implements namespaces */ ++#define HAVE_NAMESPACES 1 ++ ++/* NDK android-16 provides ssize_t pread(int, void*, size_t, off_t) */ ++#define HAVE_PREAD 1 ++ ++/* Define if you have POSIX threads libraries and header files. */ ++#define HAVE_PTHREAD 1 ++ ++/* Define to 1 if you have the header file. */ ++#define HAVE_PWD_H 1 ++ ++/* define if the compiler implements pthread_rwlock_* */ ++#define HAVE_RWLOCK 1 ++ ++/* Define if you have the `sigaltstack' function */ ++#define HAVE_SIGALTSTACK 1 ++ ++/* Define to 1 if you have the header file. */ ++#define HAVE_STDINT_H 1 ++ ++/* Define to 1 if you have the header file. */ ++#define HAVE_STDLIB_H 1 ++ ++/* Define to 1 if you have the header file. */ ++#define HAVE_STRINGS_H 1 ++ ++/* Define to 1 if you have the header file. */ ++#define HAVE_STRING_H 1 ++ ++/* Define to 1 if you have the header file. */ ++/* #undef HAVE_SYSCALL_H */ ++ ++/* Define to 1 if you have the header file. */ ++#define HAVE_SYSLOG_H 1 ++ ++/* Define to 1 if you have the header file. */ ++#define HAVE_SYS_STAT_H 1 ++ ++/* Define to 1 if you have the header file. */ ++#define HAVE_SYS_SYSCALL_H 1 ++ ++/* Define to 1 if you have the header file. */ ++#define HAVE_SYS_TIME_H 1 ++ ++/* Define to 1 if you have the header file. */ ++#define HAVE_SYS_TYPES_H 1 ++ ++/* Define to 1 if you have the header file. */ ++/* #undef HAVE_SYS_UCONTEXT_H */ ++ ++/* Define to 1 if you have the header file. */ ++#define HAVE_SYS_UTSNAME_H 1 ++ ++/* Define to 1 if you have the header file. */ ++/* #undef HAVE_UCONTEXT_H */ ++ ++/* Define to 1 if you have the header file. */ ++#define HAVE_UNISTD_H 1 ++ ++/* Define to 1 if you have the header file. */ ++#define HAVE_UNWIND_H 1 ++ ++/* define if the compiler supports using expression for operator */ ++#define HAVE_USING_OPERATOR 1 ++ ++/* define if your compiler has __attribute__ */ ++#define HAVE___ATTRIBUTE__ 1 ++ ++/* define if your compiler has __builtin_expect */ ++#define HAVE___BUILTIN_EXPECT 1 ++ ++/* define if your compiler has __sync_val_compare_and_swap */ ++#define HAVE___SYNC_VAL_COMPARE_AND_SWAP 1 ++ ++/* Define to the sub-directory in which libtool stores uninstalled libraries. ++ */ ++#define LT_OBJDIR ".libs/" ++ ++/* Name of package */ ++#define PACKAGE "glog" ++ ++/* Define to the address where bug reports for this package should be sent. */ ++#define PACKAGE_BUGREPORT "opensource@google.com" ++ ++/* Define to the full name of this package. */ ++#define PACKAGE_NAME "glog" ++ ++/* Define to the full name and version of this package. */ ++#define PACKAGE_STRING "glog 0.3.5" ++ ++/* Define to the one symbol short name of this package. */ ++#define PACKAGE_TARNAME "glog" ++ ++/* Define to the home page for this package. */ ++#define PACKAGE_URL "" ++ ++/* Define to the version of this package. */ ++#define PACKAGE_VERSION "0.3.5" ++ ++/* How to access the PC from a struct ucontext */ ++/* #undef PC_FROM_UCONTEXT */ ++ ++/* Define to necessary symbol if this constant uses a non-standard name on ++ your system. */ ++/* #undef PTHREAD_CREATE_JOINABLE */ ++ ++/* The size of `void *', as computed by sizeof. */ ++#define SIZEOF_VOID_P 4 ++ ++/* Define to 1 if you have the ANSI C header files. */ ++/* #undef STDC_HEADERS */ ++ ++/* the namespace where STL code like vector<> is defined */ ++#define STL_NAMESPACE std ++ ++/* location of source code */ ++#define TEST_SRC_DIR "." ++ ++/* Version number of package */ ++#define VERSION "0.3.5" ++ ++/* Stops putting the code inside the Google namespace */ ++#define _END_GOOGLE_NAMESPACE_ } ++ ++/* Puts following code inside the Google namespace */ ++#define _START_GOOGLE_NAMESPACE_ namespace google { ++ ++ ++/* TODO(vjn/dreiss): revisit these when use the android-21 (or newer) NDK platform. */ ++#undef HAVE_SYSCALL_H ++#undef HAVE_SYS_SYSCALL_H ++#undef OS_LINUX ++#undef OS_MACOSX +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/jni/third-party/jsc/CMakeLists.txt b/node_modules/react-native/ReactAndroid/bin/src/main/jni/third-party/jsc/CMakeLists.txt +new file mode 100644 +index 0000000..4f72ace +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/jni/third-party/jsc/CMakeLists.txt +@@ -0,0 +1,15 @@ ++# 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. ++ ++cmake_minimum_required(VERSION 3.13) ++set(CMAKE_VERBOSE_MAKEFILE on) ++ ++add_library(jsc SHARED IMPORTED GLOBAL) ++set_target_properties(jsc ++ PROPERTIES ++ IMPORTED_LOCATION ++ ${CMAKE_CURRENT_SOURCE_DIR}/jni/${ANDROID_ABI}/libjsc.so) ++ ++target_include_directories(jsc INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/res/devsupport/anim/catalyst_push_up_in.xml b/node_modules/react-native/ReactAndroid/bin/src/main/res/devsupport/anim/catalyst_push_up_in.xml +new file mode 100644 +index 0000000..aef91bc +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/res/devsupport/anim/catalyst_push_up_in.xml +@@ -0,0 +1,13 @@ ++ ++ ++ ++ ++ +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/res/devsupport/anim/catalyst_push_up_out.xml b/node_modules/react-native/ReactAndroid/bin/src/main/res/devsupport/anim/catalyst_push_up_out.xml +new file mode 100644 +index 0000000..790e275 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/res/devsupport/anim/catalyst_push_up_out.xml +@@ -0,0 +1,13 @@ ++ ++ ++ ++ ++ +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/res/devsupport/drawable/redbox_top_border_background.xml b/node_modules/react-native/ReactAndroid/bin/src/main/res/devsupport/drawable/redbox_top_border_background.xml +new file mode 100644 +index 0000000..84ca146 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/res/devsupport/drawable/redbox_top_border_background.xml +@@ -0,0 +1,18 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/res/devsupport/layout/dev_loading_view.xml b/node_modules/react-native/ReactAndroid/bin/src/main/res/devsupport/layout/dev_loading_view.xml +new file mode 100644 +index 0000000..b7e6b8c +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/res/devsupport/layout/dev_loading_view.xml +@@ -0,0 +1,17 @@ ++ ++ ++ +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/res/devsupport/layout/fps_view.xml b/node_modules/react-native/ReactAndroid/bin/src/main/res/devsupport/layout/fps_view.xml +new file mode 100644 +index 0000000..468caa9 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/res/devsupport/layout/fps_view.xml +@@ -0,0 +1,18 @@ ++ ++ ++ ++ ++ +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/res/devsupport/layout/redbox_item_frame.xml b/node_modules/react-native/ReactAndroid/bin/src/main/res/devsupport/layout/redbox_item_frame.xml +new file mode 100644 +index 0000000..98d8080 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/res/devsupport/layout/redbox_item_frame.xml +@@ -0,0 +1,26 @@ ++ ++ ++ ++ +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/res/devsupport/layout/redbox_item_title.xml b/node_modules/react-native/ReactAndroid/bin/src/main/res/devsupport/layout/redbox_item_title.xml +new file mode 100644 +index 0000000..9736037 +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/res/devsupport/layout/redbox_item_title.xml +@@ -0,0 +1,11 @@ ++ +diff --git a/node_modules/react-native/ReactAndroid/bin/src/main/res/devsupport/layout/redbox_view.xml b/node_modules/react-native/ReactAndroid/bin/src/main/res/devsupport/layout/redbox_view.xml +new file mode 100644 +index 0000000..514d39d +--- /dev/null ++++ b/node_modules/react-native/ReactAndroid/bin/src/main/res/devsupport/layout/redbox_view.xml +@@ -0,0 +1,75 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++