mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Compare commits
50
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
59a8c9647d | ||
|
|
54ebfafb21 | ||
|
|
a7dc5051d3 | ||
|
|
6e011c98c1 | ||
|
|
0ee665ce12 | ||
|
|
2dada2193a | ||
|
|
3d4f0f48fe | ||
|
|
da7bf9c545 | ||
|
|
29c1f72801 | ||
|
|
ae89022f9a | ||
|
|
7438fcd5d2 | ||
|
|
5ae5a120a7 | ||
|
|
9962add377 | ||
|
|
c015f626a8 | ||
|
|
cda0ad8c5f | ||
|
|
dab8a45623 | ||
|
|
40c60adacf | ||
|
|
a7cd3cc08f | ||
|
|
87f8e85b7f | ||
|
|
f6f5ea0b2e | ||
|
|
6c49572ee4 | ||
|
|
529f55c8c9 | ||
|
|
481fb612a2 | ||
|
|
3ce6a05aac | ||
|
|
813b9441ca | ||
|
|
cf5040b4f8 | ||
|
|
019a553ea4 | ||
|
|
2ae5a74f06 | ||
|
|
3d4a4caac8 | ||
|
|
cdc4a8ead4 | ||
|
|
226d2ba160 | ||
|
|
a16c6c9477 | ||
|
|
59b8974d3c | ||
|
|
2c30215bc7 | ||
|
|
f568c9b953 | ||
|
|
968909488a | ||
|
|
e7ce4ff0bf | ||
|
|
49be01add1 | ||
|
|
13120f630d | ||
|
|
d0140ce53b | ||
|
|
d0fb33822d | ||
|
|
2152180fa0 | ||
|
|
e7aeea26bd | ||
|
|
c04248dc5c | ||
|
|
02e3a999ed | ||
|
|
44b2da0df2 | ||
|
|
dae2f606c7 | ||
|
|
5774bd105d | ||
|
|
3a3f3a417d | ||
|
|
71edbe1548 |
@@ -19,6 +19,7 @@ on:
|
||||
|
||||
jobs:
|
||||
create_release:
|
||||
if: github.repository == 'facebook/react-native'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
|
||||
@@ -23,6 +23,7 @@ jobs:
|
||||
|
||||
prepare_hermes_workspace:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'facebook/react-native'
|
||||
env:
|
||||
HERMES_WS_DIR: /tmp/hermes
|
||||
HERMES_VERSION_FILE: packages/react-native/sdks/.hermesversion
|
||||
@@ -50,8 +51,8 @@ jobs:
|
||||
- name: Build HermesC Apple
|
||||
uses: ./.github/actions/build-hermesc-apple
|
||||
with:
|
||||
hermes-version: ${{ needs.prepare_hermes_workspace.output.hermes-version }}
|
||||
react-native-version: ${{ needs.prepare_hermes_workspace.output.react-native-version }}
|
||||
hermes-version: ${{ needs.prepare_hermes_workspace.outputs.hermes-version }}
|
||||
react-native-version: ${{ needs.prepare_hermes_workspace.outputs.react-native-version }}
|
||||
|
||||
build_apple_slices_hermes:
|
||||
runs-on: macos-14
|
||||
@@ -75,7 +76,7 @@ jobs:
|
||||
uses: ./.github/actions/build-apple-slices-hermes
|
||||
with:
|
||||
flavor: ${{ matrix.flavor }}
|
||||
slice: ${{ matrix.slice}}
|
||||
slice: ${{ matrix.slice }}
|
||||
hermes-version: ${{ needs.prepare_hermes_workspace.outputs.hermes-version }}
|
||||
react-native-version: ${{ needs.prepare_hermes_workspace.outputs.react-native-version }}
|
||||
|
||||
@@ -101,6 +102,7 @@ jobs:
|
||||
flavor: ${{ matrix.flavor }}
|
||||
|
||||
prebuild_apple_dependencies:
|
||||
if: github.repository == 'facebook/react-native'
|
||||
uses: ./.github/workflows/prebuild-ios-dependencies.yml
|
||||
secrets: inherit
|
||||
|
||||
@@ -145,6 +147,7 @@ jobs:
|
||||
|
||||
build_android:
|
||||
runs-on: 8-core-ubuntu
|
||||
if: github.repository == 'facebook/react-native'
|
||||
needs: [set_release_type]
|
||||
container:
|
||||
image: reactnativecommunity/react-native-android:latest
|
||||
|
||||
@@ -9,6 +9,7 @@ on:
|
||||
jobs:
|
||||
publish_bumped_packages:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'facebook/react-native'
|
||||
env:
|
||||
GHA_NPM_TOKEN: ${{ secrets.GHA_NPM_TOKEN }}
|
||||
steps:
|
||||
|
||||
@@ -21,6 +21,7 @@ jobs:
|
||||
|
||||
prepare_hermes_workspace:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'facebook/react-native'
|
||||
env:
|
||||
HERMES_WS_DIR: /tmp/hermes
|
||||
HERMES_VERSION_FILE: packages/react-native/sdks/.hermesversion
|
||||
@@ -98,6 +99,7 @@ jobs:
|
||||
flavor: ${{ matrix.flavor }}
|
||||
|
||||
prebuild_apple_dependencies:
|
||||
if: github.repository == 'facebook/react-native'
|
||||
uses: ./.github/workflows/prebuild-ios-dependencies.yml
|
||||
secrets: inherit
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ on:
|
||||
jobs:
|
||||
rerun:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'facebook/react-native'
|
||||
steps:
|
||||
- name: rerun ${{ inputs.run_id }}
|
||||
env:
|
||||
|
||||
@@ -11,6 +11,7 @@ on:
|
||||
jobs:
|
||||
set_release_type:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'facebook/react-native'
|
||||
outputs:
|
||||
RELEASE_TYPE: ${{ steps.set_release_type.outputs.RELEASE_TYPE }}
|
||||
env:
|
||||
@@ -34,6 +35,7 @@ jobs:
|
||||
|
||||
prepare_hermes_workspace:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'facebook/react-native'
|
||||
env:
|
||||
HERMES_WS_DIR: /tmp/hermes
|
||||
HERMES_VERSION_FILE: packages/react-native/sdks/.hermesversion
|
||||
@@ -112,6 +114,7 @@ jobs:
|
||||
flavor: ${{ matrix.flavor }}
|
||||
|
||||
prebuild_apple_dependencies:
|
||||
if: github.repository == 'facebook/react-native'
|
||||
uses: ./.github/workflows/prebuild-ios-dependencies.yml
|
||||
secrets: inherit
|
||||
|
||||
@@ -379,7 +382,8 @@ jobs:
|
||||
runs-on: 8-core-ubuntu
|
||||
needs: [set_release_type]
|
||||
container:
|
||||
image: reactnativecommunity/react-native-android:latest
|
||||
# Version is pinned to v18.0 to unblock `run_fantom_tests` - see https://github.com/react-native-community/docker-android/pull/242#issuecomment-3280029122
|
||||
image: reactnativecommunity/react-native-android:v18.0
|
||||
env:
|
||||
TERM: "dumb"
|
||||
GRADLE_OPTS: "-Dorg.gradle.daemon=false"
|
||||
@@ -594,6 +598,7 @@ jobs:
|
||||
|
||||
test_js:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'facebook/react-native'
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -608,6 +613,7 @@ jobs:
|
||||
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'facebook/react-native'
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
steps:
|
||||
|
||||
@@ -27,6 +27,7 @@ on:
|
||||
jobs:
|
||||
validate-dotslash-artifacts:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'facebook/react-native'
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
@@ -1,5 +1,53 @@
|
||||
# Changelog
|
||||
|
||||
## v0.81.2
|
||||
|
||||
### Added
|
||||
|
||||
#### Android specific
|
||||
|
||||
- Create a debugOptimized buildType for Android ([5e3edafec6](https://github.com/facebook/react-native/commit/5e3edafec6c69558521061dced7a6bcd046576b0) by [@cortinico](https://github.com/cortinico))
|
||||
- Add `useNativeEqualsInNativeReadableArrayAndroid` and `useNativeTransformHelperAndroid` feature flag to the experimental channel. This should alleviate some of the perf issue users are seeing on Android + Reanimated + NewArch on 0.81([a346096da8](https://github.com/facebook/react-native/commit/a346096da81fccf5fbc82d83bfc128695e6ec3a5) by [@cortinico](https://github.com/cortinico))
|
||||
|
||||
### Fixed
|
||||
|
||||
#### iOS specific
|
||||
|
||||
- Fix Node scripts related to prebuilt tarball extraction for paths containing whitespaces ([366f2ad505](https://github.com/facebook/react-native/commit/366f2ad5057ffecc1f5b211f6aae29567ae6b7e5) by [@kitten](https://github.com/kitten))
|
||||
- Use autolinking-generated react-native-config output in second step of cocoapods linking that generates artifacts and generated source ([a2eb29e5e7](https://github.com/facebook/react-native/commit/a2eb29e5e7aef8bbdf4c647c8467b5292b013b20) by [@kitten](https://github.com/kitten))
|
||||
|
||||
## v0.82.0-rc.1
|
||||
|
||||
### Added
|
||||
|
||||
#### Android specific
|
||||
|
||||
- **Hermes V1:** Added opt-in to use the new Hermes ([3e9990f860](https://github.com/facebook/react-native/commit/3e9990f860eb9380837ef431ca02def32c4261ad) by [@j-piasecki](https://github.com/j-piasecki))
|
||||
|
||||
#### iOS specific
|
||||
|
||||
- **Hermes V1:** Added opt-in to use the new Hermes ([e9cdc308b4](https://github.com/facebook/react-native/commit/e9cdc308b4c04753d85757e8877ac00c3c687b95) by [@j-piasecki](https://github.com/j-piasecki))
|
||||
|
||||
### Changed
|
||||
|
||||
- **Hermes V1:** Changed the source of hermesc binary to be an npm package ([2e0bd13a25](https://github.com/facebook/react-native/commit/2e0bd13a2533fe7ab64125a95b9215b806018c6e) by [@j-piasecki](https://github.com/j-piasecki))
|
||||
|
||||
### Deprecated
|
||||
|
||||
- **APIs:** Deprecate legacy javascript react native apis ([e7aeea26bd](https://github.com/facebook/react-native/commit/e7aeea26bde6e9cda0a3a0a55fc2a0421fb0c0e5) by [@RSNara](https://github.com/RSNara))
|
||||
|
||||
### Fixed
|
||||
|
||||
#### Android specific
|
||||
|
||||
- **Build From Source:** Fix build from source due to missing folder error on Gradle 9.0 ([9fbce3eff1](https://github.com/facebook/react-native/commit/9fbce3eff18060f16e796badc415ba733ede19af) by [@cortinico](https://github.com/cortinico))
|
||||
|
||||
#### iOS specific
|
||||
|
||||
- **RCTAlertController:** Simplify RCTAlertController, don't create additional UIWindow ([05c4321b19](https://github.com/facebook/react-native/commit/05c4321b194c3d0e146b6085bcaccc75acd3fd67) by [@okwasniewski](https://github.com/okwasniewski))
|
||||
- **Prebuild:** Fix Node scripts related to prebuilt tarball extraction for paths containing whitespaces ([9731e8ebc5](https://github.com/facebook/react-native/commit/9731e8ebc5ea87526a91b9903172639e062cd920) by [@kitten](https://github.com/kitten))
|
||||
- **Prebuild:** Use autolinking-generated react-native-config output in second step of cocoapods linking that generates artifacts and generated source ([f170db412b](https://github.com/facebook/react-native/commit/f170db412b3ab46fd0894d5d66431d9c230cd3a8) by [@kitten](https://github.com/kitten))
|
||||
|
||||
## v0.82.0-rc.0
|
||||
|
||||
### Breaking
|
||||
|
||||
@@ -17,10 +17,13 @@
|
||||
<img src="https://img.shields.io/npm/v/react-native?color=brightgreen&label=npm%20package" alt="Current npm package version." />
|
||||
</a>
|
||||
<a href="https://reactnative.dev/docs/contributing">
|
||||
<img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg" alt="PRs welcome!" />
|
||||
<img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg" alt="PRs are welcome!" />
|
||||
</a>
|
||||
<a href="https://twitter.com/intent/follow?screen_name=reactnative">
|
||||
<img src="https://img.shields.io/twitter/follow/reactnative.svg?label=Follow%20@reactnative" alt="Follow @reactnative" />
|
||||
<img src="https://img.shields.io/twitter/follow/reactnative.svg?label=Follow%20@reactnative" alt="Follow @reactnative on X" />
|
||||
</a>
|
||||
<a href="https://bsky.app/profile/reactnative.dev">
|
||||
<img src="https://img.shields.io/badge/Bluesky-0285FF?logo=bluesky&logoColor=fff" alt="Follow @reactnative.dev on Bluesky" />
|
||||
</a>
|
||||
</p>
|
||||
|
||||
|
||||
@@ -135,6 +135,7 @@ if (project.findProperty("react.internal.useHermesNightly")?.toString()?.toBoole
|
||||
configurations.all {
|
||||
resolutionStrategy.dependencySubstitution {
|
||||
substitute(project(":packages:react-native:ReactAndroid:hermes-engine"))
|
||||
// TODO: T237406039 update coordinates
|
||||
.using(module("com.facebook.react:hermes-android:0.+"))
|
||||
.because("Users opted to use hermes from nightly")
|
||||
}
|
||||
|
||||
+1
-1
@@ -100,7 +100,7 @@
|
||||
"jsonc-parser": "2.2.1",
|
||||
"markdownlint-cli2": "^0.17.2",
|
||||
"markdownlint-rule-relative-links": "^3.0.0",
|
||||
"memfs": "^4.7.7",
|
||||
"memfs": "^4.38.2",
|
||||
"metro-babel-register": "^0.83.1",
|
||||
"metro-transform-plugins": "^0.83.1",
|
||||
"micromatch": "^4.0.4",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
@generated SignedSource<<b6a779e724ecce5e727ee674dc20f809>>
|
||||
Git revision: e87564a24cf233c60aaebee8c418ec85724f7214
|
||||
@generated SignedSource<<0b54f75686e4893a5444839bf621a317>>
|
||||
Git revision: 5a792db1225adda206313e9bf751198a1ca7851a
|
||||
Built with --nohooks: false
|
||||
Is local checkout: false
|
||||
Remote URL: https://github.com/facebook/react-native-devtools-frontend
|
||||
|
||||
File diff suppressed because one or more lines are too long
+2
-2
File diff suppressed because one or more lines are too long
Vendored
+1
-1
@@ -238,7 +238,7 @@ import"../../ui/components/icon_button/icon_button.js";import"../../ui/component
|
||||
<td>${e.method}</td>
|
||||
<td>${e.params?d`<code>${JSON.stringify(e.params)}</code>`:""}</td>
|
||||
<td>
|
||||
${e.result?d`<code>${JSON.stringify(e.result)}</code>`:e.error?d`<code>${JSON.stringify(e.error)}</code>`:"(pending)"}
|
||||
${e.result?d`<code>${JSON.stringify(e.result)}</code>`:e.error?d`<code>${JSON.stringify(e.error)}</code>`:"id"in e?"(pending)":""}
|
||||
</td>
|
||||
<td data-value=${e.elapsedTime||0}>
|
||||
${"id"in e?e.elapsedTime?U(A.sMs,{PH1:String(e.elapsedTime)}):"(pending)":""}
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+7
-7
@@ -55,8 +55,8 @@ class ReactPlugin : Plugin<Project> {
|
||||
project,
|
||||
)
|
||||
|
||||
if (project.rootProject.isHermesV1Enabled != rootExtension.hermesV1Enabled.get()) {
|
||||
rootExtension.hermesV1Enabled.set(project.rootProject.isHermesV1Enabled)
|
||||
if (project.rootProject.isHermesV1Enabled) {
|
||||
rootExtension.hermesV1Enabled.set(true)
|
||||
}
|
||||
|
||||
// App Only Configuration
|
||||
@@ -71,11 +71,11 @@ class ReactPlugin : Plugin<Project> {
|
||||
project.afterEvaluate {
|
||||
val reactNativeDir = extension.reactNativeDir.get().asFile
|
||||
val propertiesFile = File(reactNativeDir, "ReactAndroid/gradle.properties")
|
||||
val versionAndGroupStrings = readVersionAndGroupStrings(propertiesFile)
|
||||
val hermesV1Enabled =
|
||||
if (project.rootProject.hasProperty("hermesV1Enabled"))
|
||||
project.rootProject.findProperty("hermesV1Enabled") == "true"
|
||||
else false
|
||||
val hermesVersionPropertiesFile =
|
||||
File(reactNativeDir, "sdks/hermes-engine/version.properties")
|
||||
val versionAndGroupStrings =
|
||||
readVersionAndGroupStrings(propertiesFile, hermesVersionPropertiesFile)
|
||||
val hermesV1Enabled = rootExtension.hermesV1Enabled.get()
|
||||
configureDependencies(project, versionAndGroupStrings, hermesV1Enabled)
|
||||
configureRepositories(project)
|
||||
}
|
||||
|
||||
+3
@@ -14,6 +14,7 @@ import com.facebook.react.utils.KotlinStdlibCompatUtils.capitalizeCompat
|
||||
import com.facebook.react.utils.NdkConfiguratorUtils.configureJsEnginePackagingOptions
|
||||
import com.facebook.react.utils.NdkConfiguratorUtils.configureNewArchPackagingOptions
|
||||
import com.facebook.react.utils.ProjectUtils.isHermesEnabled
|
||||
import com.facebook.react.utils.ProjectUtils.isHermesV1Enabled
|
||||
import com.facebook.react.utils.ProjectUtils.useThirdPartyJSC
|
||||
import com.facebook.react.utils.detectedCliFile
|
||||
import com.facebook.react.utils.detectedEntryFile
|
||||
@@ -48,6 +49,7 @@ internal fun Project.configureReactTasks(variant: Variant, config: ReactExtensio
|
||||
} else {
|
||||
isHermesEnabledInProject
|
||||
}
|
||||
val isHermesV1Enabled = project.isHermesV1Enabled || rootProject.isHermesV1Enabled
|
||||
val isDebuggableVariant =
|
||||
config.debuggableVariants.get().any { it.equals(variant.name, ignoreCase = true) }
|
||||
val useThirdPartyJSC = project.useThirdPartyJSC
|
||||
@@ -78,6 +80,7 @@ internal fun Project.configureReactTasks(variant: Variant, config: ReactExtensio
|
||||
task.jsBundleDir.set(jsBundleDir)
|
||||
task.resourcesDir.set(resourcesDir)
|
||||
task.hermesEnabled.set(isHermesEnabledInThisVariant)
|
||||
task.hermesV1Enabled.set(isHermesV1Enabled)
|
||||
task.minifyEnabled.set(!isHermesEnabledInThisVariant)
|
||||
task.devEnabled.set(false)
|
||||
task.jsIntermediateSourceMapsDir.set(jsIntermediateSourceMapsDir)
|
||||
|
||||
+3
-5
@@ -63,6 +63,8 @@ abstract class BundleHermesCTask : DefaultTask() {
|
||||
|
||||
@get:Input abstract val hermesEnabled: Property<Boolean>
|
||||
|
||||
@get:Input abstract val hermesV1Enabled: Property<Boolean>
|
||||
|
||||
@get:Input abstract val devEnabled: Property<Boolean>
|
||||
|
||||
@get:Input abstract val extraPackagerArgs: ListProperty<String>
|
||||
@@ -94,12 +96,8 @@ abstract class BundleHermesCTask : DefaultTask() {
|
||||
runCommand(bundleCommand)
|
||||
|
||||
if (hermesEnabled.get()) {
|
||||
val hermesV1Enabled =
|
||||
if (project.rootProject.hasProperty("hermesV1Enabled"))
|
||||
project.rootProject.findProperty("hermesV1Enabled") == "true"
|
||||
else false
|
||||
val detectedHermesCommand =
|
||||
detectOSAwareHermesCommand(root.get().asFile, hermesCommand.get(), hermesV1Enabled)
|
||||
detectOSAwareHermesCommand(root.get().asFile, hermesCommand.get(), hermesV1Enabled.get())
|
||||
val bytecodeFile = File("${bundleFile}.hbc")
|
||||
val outputSourceMap = resolveOutputSourceMap(bundleAssetFilename)
|
||||
val compilerSourceMap = resolveCompilerSourceMap(bundleAssetFilename)
|
||||
|
||||
+28
-11
@@ -13,7 +13,7 @@ import com.facebook.react.utils.PropertyUtils.EXCLUSIVE_ENTEPRISE_REPOSITORY
|
||||
import com.facebook.react.utils.PropertyUtils.INCLUDE_JITPACK_REPOSITORY
|
||||
import com.facebook.react.utils.PropertyUtils.INCLUDE_JITPACK_REPOSITORY_DEFAULT
|
||||
import com.facebook.react.utils.PropertyUtils.INTERNAL_HERMES_PUBLISHING_GROUP
|
||||
import com.facebook.react.utils.PropertyUtils.INTERNAL_HERMES_VERSION_NAME
|
||||
import com.facebook.react.utils.PropertyUtils.INTERNAL_HERMES_V1_VERSION_NAME
|
||||
import com.facebook.react.utils.PropertyUtils.INTERNAL_REACT_NATIVE_MAVEN_LOCAL_REPO
|
||||
import com.facebook.react.utils.PropertyUtils.INTERNAL_REACT_PUBLISHING_GROUP
|
||||
import com.facebook.react.utils.PropertyUtils.INTERNAL_USE_HERMES_NIGHTLY
|
||||
@@ -31,6 +31,7 @@ internal object DependencyUtils {
|
||||
internal data class Coordinates(
|
||||
val versionString: String,
|
||||
val hermesVersionString: String,
|
||||
val hermesV1VersionString: String,
|
||||
val reactGroupString: String = DEFAULT_INTERNAL_REACT_PUBLISHING_GROUP,
|
||||
val hermesGroupString: String = DEFAULT_INTERNAL_HERMES_PUBLISHING_GROUP,
|
||||
)
|
||||
@@ -113,7 +114,12 @@ internal object DependencyUtils {
|
||||
coordinates: Coordinates,
|
||||
hermesV1Enabled: Boolean = false,
|
||||
) {
|
||||
if (coordinates.versionString.isBlank() || coordinates.hermesVersionString.isBlank()) return
|
||||
if (
|
||||
coordinates.versionString.isBlank() ||
|
||||
(!hermesV1Enabled && coordinates.hermesVersionString.isBlank()) ||
|
||||
(hermesV1Enabled && coordinates.hermesV1VersionString.isBlank())
|
||||
)
|
||||
return
|
||||
project.rootProject.allprojects { eachProject ->
|
||||
eachProject.configurations.all { configuration ->
|
||||
// Here we set a dependencySubstitution for both react-native and hermes-engine as those
|
||||
@@ -133,7 +139,11 @@ internal object DependencyUtils {
|
||||
// Contributors only: The hermes-engine version is forced only if the user has
|
||||
// not opted into using nightlies for local development.
|
||||
configuration.resolutionStrategy.force(
|
||||
"${coordinates.reactGroupString}:hermes-android:${coordinates.versionString}"
|
||||
// TODO: T237406039 update coordinates
|
||||
if (hermesV1Enabled)
|
||||
"${coordinates.hermesGroupString}:hermes-android:${coordinates.hermesV1VersionString}"
|
||||
else
|
||||
"${coordinates.reactGroupString}:hermes-android:${coordinates.hermesVersionString}"
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -146,10 +156,11 @@ internal object DependencyUtils {
|
||||
): List<Triple<String, String, String>> {
|
||||
// TODO: T231755027 update coordinates and versioning
|
||||
val dependencySubstitution = mutableListOf<Triple<String, String, String>>()
|
||||
// TODO: T237406039 update coordinates
|
||||
val hermesVersionString =
|
||||
if (hermesV1Enabled)
|
||||
"${coordinates.hermesGroupString}:hermes-android:${coordinates.versionString}"
|
||||
else "${coordinates.reactGroupString}:hermes-android:${coordinates.versionString}"
|
||||
"${coordinates.hermesGroupString}:hermes-android:${coordinates.hermesV1VersionString}"
|
||||
else "${coordinates.reactGroupString}:hermes-android:${coordinates.hermesVersionString}"
|
||||
dependencySubstitution.add(
|
||||
Triple(
|
||||
"com.facebook.react:react-native",
|
||||
@@ -172,6 +183,7 @@ internal object DependencyUtils {
|
||||
"The react-android dependency was modified to use the correct Maven group.",
|
||||
)
|
||||
)
|
||||
// TODO: T237406039 update coordinates
|
||||
dependencySubstitution.add(
|
||||
Triple(
|
||||
"com.facebook.react:hermes-android",
|
||||
@@ -183,14 +195,10 @@ internal object DependencyUtils {
|
||||
return dependencySubstitution
|
||||
}
|
||||
|
||||
fun readVersionAndGroupStrings(propertiesFile: File): Coordinates {
|
||||
fun readVersionAndGroupStrings(propertiesFile: File, hermesVersionFile: File): Coordinates {
|
||||
val reactAndroidProperties = Properties()
|
||||
propertiesFile.inputStream().use { reactAndroidProperties.load(it) }
|
||||
val versionStringFromFile = (reactAndroidProperties[INTERNAL_VERSION_NAME] as? String).orEmpty()
|
||||
// TODO: T231755027 update HERMES_VERSION_NAME in gradle.properties to point to the correct
|
||||
// hermes version
|
||||
val hermesVersionStringFromFile =
|
||||
(reactAndroidProperties[INTERNAL_HERMES_VERSION_NAME] as? String).orEmpty()
|
||||
// If on a nightly, we need to fetch the -SNAPSHOT artifact from Sonatype.
|
||||
val versionString =
|
||||
if (versionStringFromFile.startsWith("0.0.0") || "-nightly-" in versionStringFromFile) {
|
||||
@@ -205,9 +213,18 @@ internal object DependencyUtils {
|
||||
val hermesGroupString =
|
||||
reactAndroidProperties[INTERNAL_HERMES_PUBLISHING_GROUP] as? String
|
||||
?: DEFAULT_INTERNAL_HERMES_PUBLISHING_GROUP
|
||||
// TODO: T237406039 read both versions from the same file
|
||||
val hermesVersionProperties = Properties()
|
||||
hermesVersionFile.inputStream().use { hermesVersionProperties.load(it) }
|
||||
|
||||
val hermesVersion = versionString
|
||||
val hermesV1Version =
|
||||
(hermesVersionProperties[INTERNAL_HERMES_V1_VERSION_NAME] as? String).orEmpty()
|
||||
|
||||
return Coordinates(
|
||||
versionString,
|
||||
hermesVersionStringFromFile,
|
||||
hermesVersion,
|
||||
hermesV1Version,
|
||||
reactGroupString,
|
||||
hermesGroupString,
|
||||
)
|
||||
|
||||
+1
@@ -153,6 +153,7 @@ internal fun detectOSAwareHermesCommand(
|
||||
|
||||
// 3. If Hermes V1 is enabled, use hermes-compiler from npm, otherwise, if the
|
||||
// react-native contains a pre-built hermesc, use it.
|
||||
// TODO: T237406039 use hermes-compiler from npm for both
|
||||
val hermesCPath = if (hermesV1Enabled) HERMES_COMPILER_NPM_DIR else HERMESC_IN_REACT_NATIVE_DIR
|
||||
val prebuiltHermesPath =
|
||||
hermesCPath
|
||||
|
||||
+6
-1
@@ -23,6 +23,7 @@ import com.facebook.react.utils.PropertyUtils.SCOPED_USE_THIRD_PARTY_JSC
|
||||
import com.facebook.react.utils.PropertyUtils.USE_THIRD_PARTY_JSC
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.file.DirectoryProperty
|
||||
import org.jetbrains.kotlin.gradle.plugin.extraProperties
|
||||
|
||||
internal object ProjectUtils {
|
||||
|
||||
@@ -75,7 +76,11 @@ internal object ProjectUtils {
|
||||
(project.hasProperty(HERMES_V1_ENABLED) &&
|
||||
project.property(HERMES_V1_ENABLED).toString().toBoolean()) ||
|
||||
(project.hasProperty(SCOPED_HERMES_V1_ENABLED) &&
|
||||
project.property(SCOPED_HERMES_V1_ENABLED).toString().toBoolean())
|
||||
project.property(SCOPED_HERMES_V1_ENABLED).toString().toBoolean()) ||
|
||||
(project.extraProperties.has(HERMES_V1_ENABLED) &&
|
||||
project.extraProperties.get(HERMES_V1_ENABLED).toString().toBoolean()) ||
|
||||
(project.extraProperties.has(SCOPED_HERMES_V1_ENABLED) &&
|
||||
project.extraProperties.get(SCOPED_HERMES_V1_ENABLED).toString().toBoolean())
|
||||
|
||||
internal fun Project.needsCodegenFromPackageJson(rootProperty: DirectoryProperty): Boolean {
|
||||
val parsedPackageJson = readPackageJsonFile(this, rootProperty)
|
||||
|
||||
+6
-2
@@ -79,6 +79,10 @@ object PropertyUtils {
|
||||
|
||||
/** Internal property used to control the version name of React Native */
|
||||
const val INTERNAL_VERSION_NAME = "VERSION_NAME"
|
||||
/** Internal property used to control the version name of Hermes Engine */
|
||||
const val INTERNAL_HERMES_VERSION_NAME = "HERMES_VERSION_NAME"
|
||||
|
||||
/**
|
||||
* Internal property, shared with iOS, used to control the version name of Hermes Engine. This is
|
||||
* stored in sdks/hermes-engine/version.properties
|
||||
*/
|
||||
const val INTERNAL_HERMES_V1_VERSION_NAME = "HERMES_V1_VERSION_NAME"
|
||||
}
|
||||
|
||||
+3
-3
@@ -33,9 +33,9 @@ class GeneratePackageListTaskTest {
|
||||
val inputFile = tempFolder.newFile("config.json")
|
||||
|
||||
val task =
|
||||
createTestTask<GeneratePackageListTask> {
|
||||
it.generatedOutputDirectory.set(outputFolder)
|
||||
it.autolinkInputFile.set(inputFile)
|
||||
createTestTask<GeneratePackageListTask> { testTask ->
|
||||
testTask.generatedOutputDirectory.set(outputFolder)
|
||||
testTask.autolinkInputFile.set(inputFile)
|
||||
}
|
||||
|
||||
assertThat(task.inputs.files.singleFile).isEqualTo(inputFile)
|
||||
|
||||
+5
-5
@@ -82,11 +82,11 @@ class PrepareGflagsTaskTest {
|
||||
val gflagsThirdPartyPath = tempFolder.newFolder("gflagspath/jni")
|
||||
val output = tempFolder.newFolder("output")
|
||||
val task =
|
||||
createTestTask<PrepareGflagsTask> {
|
||||
it.gflagsPath.setFrom(gflagspath)
|
||||
it.gflagsThirdPartyPath.set(gflagsThirdPartyPath)
|
||||
it.gflagsVersion.set("1.0.0")
|
||||
it.outputDir.set(output)
|
||||
createTestTask<PrepareGflagsTask> { taskConfig ->
|
||||
taskConfig.gflagsPath.setFrom(gflagspath)
|
||||
taskConfig.gflagsThirdPartyPath.set(gflagsThirdPartyPath)
|
||||
taskConfig.gflagsVersion.set("1.0.0")
|
||||
taskConfig.outputDir.set(output)
|
||||
}
|
||||
File(gflagspath, "gflags-1.0.0/src/gflags_declare.h.in").apply {
|
||||
parentFile.mkdirs()
|
||||
|
||||
+271
-26
@@ -271,54 +271,69 @@ class DependencyUtilsTest {
|
||||
.isEqualTo(2)
|
||||
}
|
||||
|
||||
// TODO: T236767053
|
||||
|
||||
@Test
|
||||
fun configureDependencies_withEmptyVersion_doesNothing() {
|
||||
val project = createProject()
|
||||
|
||||
configureDependencies(project, DependencyUtils.Coordinates("", ""))
|
||||
configureDependencies(project, DependencyUtils.Coordinates("", "", ""))
|
||||
|
||||
assertThat(project.configurations.first().resolutionStrategy.forcedModules.isEmpty()).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun configureDependencies_withVersionString_appliesResolutionStrategy() {
|
||||
fun configureDependencies_withVersionString_appliesResolutionStrategy_withClassicHermes() {
|
||||
val project = createProject()
|
||||
|
||||
configureDependencies(project, DependencyUtils.Coordinates("1.2.3", "1.2.3"))
|
||||
configureDependencies(project, DependencyUtils.Coordinates("1.2.3", "4.5.6", "7.8.9"))
|
||||
|
||||
val forcedModules = project.configurations.first().resolutionStrategy.forcedModules
|
||||
assertThat(forcedModules.any { it.toString() == "com.facebook.react:react-android:1.2.3" })
|
||||
.isTrue()
|
||||
assertThat(forcedModules.any { it.toString() == "com.facebook.react:hermes-android:1.2.3" })
|
||||
assertThat(forcedModules.any { it.toString() == "com.facebook.react:hermes-android:4.5.6" })
|
||||
.isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun configureDependencies_withVersionString_appliesOnAllProjects() {
|
||||
fun configureDependencies_withVersionString_appliesResolutionStrategy_withHermesV1() {
|
||||
val project = createProject()
|
||||
|
||||
configureDependencies(
|
||||
project,
|
||||
DependencyUtils.Coordinates("1.2.3", "4.5.6", "7.8.9"),
|
||||
hermesV1Enabled = true,
|
||||
)
|
||||
|
||||
val forcedModules = project.configurations.first().resolutionStrategy.forcedModules
|
||||
assertThat(forcedModules.any { it.toString() == "com.facebook.react:react-android:1.2.3" })
|
||||
.isTrue()
|
||||
assertThat(forcedModules.any { it.toString() == "com.facebook.hermes:hermes-android:7.8.9" })
|
||||
.isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun configureDependencies_withVersionString_appliesOnAllProjects_withClassicHermes() {
|
||||
val rootProject = ProjectBuilder.builder().build()
|
||||
val appProject = ProjectBuilder.builder().withName("app").withParent(rootProject).build()
|
||||
val libProject = ProjectBuilder.builder().withName("lib").withParent(rootProject).build()
|
||||
appProject.plugins.apply("com.android.application")
|
||||
libProject.plugins.apply("com.android.library")
|
||||
|
||||
configureDependencies(appProject, DependencyUtils.Coordinates("1.2.3", "1.2.3"))
|
||||
configureDependencies(appProject, DependencyUtils.Coordinates("1.2.3", "4.5.6", "7.8.9"))
|
||||
|
||||
val appForcedModules = appProject.configurations.first().resolutionStrategy.forcedModules
|
||||
val libForcedModules = libProject.configurations.first().resolutionStrategy.forcedModules
|
||||
assertThat(appForcedModules.any { it.toString() == "com.facebook.react:react-android:1.2.3" })
|
||||
.isTrue()
|
||||
assertThat(appForcedModules.any { it.toString() == "com.facebook.react:hermes-android:1.2.3" })
|
||||
assertThat(appForcedModules.any { it.toString() == "com.facebook.react:hermes-android:4.5.6" })
|
||||
.isTrue()
|
||||
assertThat(libForcedModules.any { it.toString() == "com.facebook.react:react-android:1.2.3" })
|
||||
.isTrue()
|
||||
assertThat(libForcedModules.any { it.toString() == "com.facebook.react:hermes-android:1.2.3" })
|
||||
assertThat(libForcedModules.any { it.toString() == "com.facebook.react:hermes-android:4.5.6" })
|
||||
.isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun configureDependencies_withVersionStringAndGroupString_appliesOnAllProjects() {
|
||||
fun configureDependencies_withVersionString_appliesOnAllProjects_withHermesV1() {
|
||||
val rootProject = ProjectBuilder.builder().build()
|
||||
val appProject = ProjectBuilder.builder().withName("app").withParent(rootProject).build()
|
||||
val libProject = ProjectBuilder.builder().withName("lib").withParent(rootProject).build()
|
||||
@@ -327,25 +342,93 @@ class DependencyUtilsTest {
|
||||
|
||||
configureDependencies(
|
||||
appProject,
|
||||
DependencyUtils.Coordinates("1.2.3", "1.2.3", "io.github.test"),
|
||||
DependencyUtils.Coordinates("1.2.3", "4.5.6", "7.8.9"),
|
||||
hermesV1Enabled = true,
|
||||
)
|
||||
|
||||
val appForcedModules = appProject.configurations.first().resolutionStrategy.forcedModules
|
||||
val libForcedModules = libProject.configurations.first().resolutionStrategy.forcedModules
|
||||
assertThat(appForcedModules.any { it.toString() == "com.facebook.react:react-android:1.2.3" })
|
||||
.isTrue()
|
||||
assertThat(appForcedModules.any { it.toString() == "com.facebook.hermes:hermes-android:7.8.9" })
|
||||
.isTrue()
|
||||
assertThat(libForcedModules.any { it.toString() == "com.facebook.react:react-android:1.2.3" })
|
||||
.isTrue()
|
||||
assertThat(libForcedModules.any { it.toString() == "com.facebook.hermes:hermes-android:7.8.9" })
|
||||
.isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun configureDependencies_withVersionStringAndGroupString_appliesOnAllProjects_withClassicHermes() {
|
||||
val rootProject = ProjectBuilder.builder().build()
|
||||
val appProject = ProjectBuilder.builder().withName("app").withParent(rootProject).build()
|
||||
val libProject = ProjectBuilder.builder().withName("lib").withParent(rootProject).build()
|
||||
appProject.plugins.apply("com.android.application")
|
||||
libProject.plugins.apply("com.android.library")
|
||||
|
||||
configureDependencies(
|
||||
appProject,
|
||||
DependencyUtils.Coordinates(
|
||||
"1.2.3",
|
||||
"4.5.6",
|
||||
"7.8.9",
|
||||
"io.github.test",
|
||||
"io.github.test.hermes",
|
||||
),
|
||||
)
|
||||
|
||||
val appForcedModules = appProject.configurations.first().resolutionStrategy.forcedModules
|
||||
val libForcedModules = libProject.configurations.first().resolutionStrategy.forcedModules
|
||||
assertThat(appForcedModules.any { it.toString() == "io.github.test:react-android:1.2.3" })
|
||||
.isTrue()
|
||||
assertThat(appForcedModules.any { it.toString() == "io.github.test:hermes-android:1.2.3" })
|
||||
assertThat(appForcedModules.any { it.toString() == "io.github.test:hermes-android:4.5.6" })
|
||||
.isTrue()
|
||||
assertThat(libForcedModules.any { it.toString() == "io.github.test:react-android:1.2.3" })
|
||||
.isTrue()
|
||||
assertThat(libForcedModules.any { it.toString() == "io.github.test:hermes-android:1.2.3" })
|
||||
assertThat(libForcedModules.any { it.toString() == "io.github.test:hermes-android:4.5.6" })
|
||||
.isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getDependencySubstitutions_withDefaultGroup_substitutesCorrectly() {
|
||||
fun configureDependencies_withVersionStringAndGroupString_appliesOnAllProjects_withHermesV1() {
|
||||
val rootProject = ProjectBuilder.builder().build()
|
||||
val appProject = ProjectBuilder.builder().withName("app").withParent(rootProject).build()
|
||||
val libProject = ProjectBuilder.builder().withName("lib").withParent(rootProject).build()
|
||||
appProject.plugins.apply("com.android.application")
|
||||
libProject.plugins.apply("com.android.library")
|
||||
|
||||
configureDependencies(
|
||||
appProject,
|
||||
DependencyUtils.Coordinates(
|
||||
"1.2.3",
|
||||
"4.5.6",
|
||||
"7.8.9",
|
||||
"io.github.test",
|
||||
"io.github.test.hermes",
|
||||
),
|
||||
hermesV1Enabled = true,
|
||||
)
|
||||
|
||||
val appForcedModules = appProject.configurations.first().resolutionStrategy.forcedModules
|
||||
val libForcedModules = libProject.configurations.first().resolutionStrategy.forcedModules
|
||||
assertThat(appForcedModules.any { it.toString() == "io.github.test:react-android:1.2.3" })
|
||||
.isTrue()
|
||||
assertThat(
|
||||
appForcedModules.any { it.toString() == "io.github.test.hermes:hermes-android:7.8.9" }
|
||||
)
|
||||
.isTrue()
|
||||
assertThat(libForcedModules.any { it.toString() == "io.github.test:react-android:1.2.3" })
|
||||
.isTrue()
|
||||
assertThat(
|
||||
libForcedModules.any { it.toString() == "io.github.test.hermes:hermes-android:7.8.9" }
|
||||
)
|
||||
.isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getDependencySubstitutions_withDefaultGroup_substitutesCorrectly_withClassicHermes() {
|
||||
val dependencySubstitutions =
|
||||
getDependencySubstitutions(DependencyUtils.Coordinates("0.42.0", "0.42.0"))
|
||||
getDependencySubstitutions(DependencyUtils.Coordinates("0.42.0", "0.42.0", "0.43.0"))
|
||||
|
||||
assertThat("com.facebook.react:react-native").isEqualTo(dependencySubstitutions[0].first)
|
||||
assertThat("com.facebook.react:react-android:0.42.0")
|
||||
@@ -364,10 +447,40 @@ class DependencyUtilsTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getDependencySubstitutions_withCustomGroup_substitutesCorrectly() {
|
||||
fun getDependencySubstitutions_withDefaultGroup_substitutesCorrectly_withHermesV1() {
|
||||
val dependencySubstitutions =
|
||||
getDependencySubstitutions(
|
||||
DependencyUtils.Coordinates("0.42.0", "0.42.0", "io.github.test")
|
||||
DependencyUtils.Coordinates("0.42.0", "0.42.0", "0.43.0"),
|
||||
hermesV1Enabled = true,
|
||||
)
|
||||
|
||||
assertThat("com.facebook.react:react-native").isEqualTo(dependencySubstitutions[0].first)
|
||||
assertThat("com.facebook.react:react-android:0.42.0")
|
||||
.isEqualTo(dependencySubstitutions[0].second)
|
||||
assertThat(
|
||||
"The react-native artifact was deprecated in favor of react-android due to https://github.com/facebook/react-native/issues/35210."
|
||||
)
|
||||
.isEqualTo(dependencySubstitutions[0].third)
|
||||
assertThat("com.facebook.react:hermes-engine").isEqualTo(dependencySubstitutions[1].first)
|
||||
assertThat("com.facebook.hermes:hermes-android:0.43.0")
|
||||
.isEqualTo(dependencySubstitutions[1].second)
|
||||
assertThat(
|
||||
"The hermes-engine artifact was deprecated in favor of hermes-android due to https://github.com/facebook/react-native/issues/35210."
|
||||
)
|
||||
.isEqualTo(dependencySubstitutions[1].third)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getDependencySubstitutions_withCustomGroup_substitutesCorrectly_withClassicHermes() {
|
||||
val dependencySubstitutions =
|
||||
getDependencySubstitutions(
|
||||
DependencyUtils.Coordinates(
|
||||
"0.42.0",
|
||||
"0.42.0",
|
||||
"0.43.0",
|
||||
"io.github.test",
|
||||
"io.github.test.hermes",
|
||||
)
|
||||
)
|
||||
|
||||
assertThat("com.facebook.react:react-native").isEqualTo(dependencySubstitutions[0].first)
|
||||
@@ -392,6 +505,44 @@ class DependencyUtilsTest {
|
||||
.isEqualTo(dependencySubstitutions[3].third)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getDependencySubstitutions_withCustomGroup_substitutesCorrectly_withHermesV1() {
|
||||
val dependencySubstitutions =
|
||||
getDependencySubstitutions(
|
||||
DependencyUtils.Coordinates(
|
||||
"0.42.0",
|
||||
"0.42.0",
|
||||
"0.43.0",
|
||||
"io.github.test",
|
||||
"io.github.test.hermes",
|
||||
),
|
||||
hermesV1Enabled = true,
|
||||
)
|
||||
|
||||
assertThat("com.facebook.react:react-native").isEqualTo(dependencySubstitutions[0].first)
|
||||
assertThat("io.github.test:react-android:0.42.0").isEqualTo(dependencySubstitutions[0].second)
|
||||
assertThat(
|
||||
"The react-native artifact was deprecated in favor of react-android due to https://github.com/facebook/react-native/issues/35210."
|
||||
)
|
||||
.isEqualTo(dependencySubstitutions[0].third)
|
||||
assertThat("com.facebook.react:hermes-engine").isEqualTo(dependencySubstitutions[1].first)
|
||||
assertThat("io.github.test.hermes:hermes-android:0.43.0")
|
||||
.isEqualTo(dependencySubstitutions[1].second)
|
||||
assertThat(
|
||||
"The hermes-engine artifact was deprecated in favor of hermes-android due to https://github.com/facebook/react-native/issues/35210."
|
||||
)
|
||||
.isEqualTo(dependencySubstitutions[1].third)
|
||||
assertThat("com.facebook.react:react-android").isEqualTo(dependencySubstitutions[2].first)
|
||||
assertThat("io.github.test:react-android:0.42.0").isEqualTo(dependencySubstitutions[2].second)
|
||||
assertThat("The react-android dependency was modified to use the correct Maven group.")
|
||||
.isEqualTo(dependencySubstitutions[2].third)
|
||||
assertThat("com.facebook.react:hermes-android").isEqualTo(dependencySubstitutions[3].first)
|
||||
assertThat("io.github.test.hermes:hermes-android:0.43.0")
|
||||
.isEqualTo(dependencySubstitutions[3].second)
|
||||
assertThat("The hermes-android dependency was modified to use the correct Maven group.")
|
||||
.isEqualTo(dependencySubstitutions[3].third)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun readVersionString_withCorrectVersionString_returnsIt() {
|
||||
val propertiesFile =
|
||||
@@ -405,9 +556,25 @@ class DependencyUtilsTest {
|
||||
)
|
||||
}
|
||||
|
||||
val versionString = readVersionAndGroupStrings(propertiesFile).versionString
|
||||
val hermesVersionFile =
|
||||
tempFolder.newFile("version.properties").apply {
|
||||
writeText(
|
||||
"""
|
||||
HERMES_V1_VERSION_NAME=1000.0.0
|
||||
ANOTHER_PROPERTY=true
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
val strings = readVersionAndGroupStrings(propertiesFile, hermesVersionFile)
|
||||
val versionString = strings.versionString
|
||||
val hermesVersionString = strings.hermesVersionString
|
||||
val hermesV1VersionString = strings.hermesV1VersionString
|
||||
|
||||
assertThat(versionString).isEqualTo("1000.0.0")
|
||||
assertThat(hermesVersionString).isEqualTo("1000.0.0")
|
||||
assertThat(hermesV1VersionString).isEqualTo("1000.0.0")
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -417,15 +584,33 @@ class DependencyUtilsTest {
|
||||
writeText(
|
||||
"""
|
||||
VERSION_NAME=0.0.0-20221101-2019-cfe811ab1
|
||||
HERMES_VERSION_NAME=0.12.0-commitly-20221101-2019-cfe811ab1
|
||||
HERMES_V1_VERSION_NAME=250829098.0.0-stable
|
||||
ANOTHER_PROPERTY=true
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
val versionString = readVersionAndGroupStrings(propertiesFile).versionString
|
||||
val hermesVersionFile =
|
||||
tempFolder.newFile("version.properties").apply {
|
||||
writeText(
|
||||
"""
|
||||
HERMES_V1_VERSION_NAME=250829098.0.0-stable
|
||||
ANOTHER_PROPERTY=true
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
val strings = readVersionAndGroupStrings(propertiesFile, hermesVersionFile)
|
||||
val versionString = strings.versionString
|
||||
val hermesVersionString = strings.hermesVersionString
|
||||
val hermesV1VersionString = strings.hermesV1VersionString
|
||||
|
||||
assertThat(versionString).isEqualTo("0.0.0-20221101-2019-cfe811ab1-SNAPSHOT")
|
||||
assertThat(hermesVersionString).isEqualTo("0.0.0-20221101-2019-cfe811ab1-SNAPSHOT")
|
||||
assertThat(hermesV1VersionString).isEqualTo("250829098.0.0-stable")
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -440,8 +625,23 @@ class DependencyUtilsTest {
|
||||
)
|
||||
}
|
||||
|
||||
val versionString = readVersionAndGroupStrings(propertiesFile).versionString
|
||||
val hermesVersionFile =
|
||||
tempFolder.newFile("version.properties").apply {
|
||||
writeText(
|
||||
"""
|
||||
ANOTHER_PROPERTY=true
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
val strings = readVersionAndGroupStrings(propertiesFile, hermesVersionFile)
|
||||
val versionString = strings.versionString
|
||||
val hermesVersionString = strings.hermesVersionString
|
||||
val hermesV1VersionString = strings.hermesV1VersionString
|
||||
assertThat(versionString).isEqualTo("")
|
||||
assertThat(hermesVersionString).isEqualTo("")
|
||||
assertThat(hermesV1VersionString).isEqualTo("")
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -457,8 +657,24 @@ class DependencyUtilsTest {
|
||||
)
|
||||
}
|
||||
|
||||
val versionString = readVersionAndGroupStrings(propertiesFile).versionString
|
||||
val hermesVersionFile =
|
||||
tempFolder.newFile("version.properties").apply {
|
||||
writeText(
|
||||
"""
|
||||
HERMES_V1_VERSION_NAME=
|
||||
ANOTHER_PROPERTY=true
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
val strings = readVersionAndGroupStrings(propertiesFile, hermesVersionFile)
|
||||
val versionString = strings.versionString
|
||||
val hermesVersionString = strings.hermesVersionString
|
||||
val hermesV1VersionString = strings.hermesV1VersionString
|
||||
assertThat(versionString).isEqualTo("")
|
||||
assertThat(hermesVersionString).isEqualTo("")
|
||||
assertThat(hermesV1VersionString).isEqualTo("")
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -468,15 +684,30 @@ class DependencyUtilsTest {
|
||||
writeText(
|
||||
"""
|
||||
react.internal.publishingGroup=io.github.test
|
||||
react.internal.hermesPublishingGroup=io.github.test
|
||||
ANOTHER_PROPERTY=true
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
val groupString = readVersionAndGroupStrings(propertiesFile).reactGroupString
|
||||
val hermesVersionFile =
|
||||
tempFolder.newFile("version.properties").apply {
|
||||
writeText(
|
||||
"""
|
||||
HERMES_V1_VERSION_NAME=
|
||||
ANOTHER_PROPERTY=true
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
assertThat(groupString).isEqualTo("io.github.test")
|
||||
val strings = readVersionAndGroupStrings(propertiesFile, hermesVersionFile)
|
||||
val reactGroupString = strings.reactGroupString
|
||||
val hermesGroupString = strings.hermesGroupString
|
||||
|
||||
assertThat(reactGroupString).isEqualTo("io.github.test")
|
||||
assertThat(hermesGroupString).isEqualTo("io.github.test")
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -491,9 +722,23 @@ class DependencyUtilsTest {
|
||||
)
|
||||
}
|
||||
|
||||
val groupString = readVersionAndGroupStrings(propertiesFile).reactGroupString
|
||||
val hermesVersionFile =
|
||||
tempFolder.newFile("version.properties").apply {
|
||||
writeText(
|
||||
"""
|
||||
HERMES_V1_VERSION_NAME=
|
||||
ANOTHER_PROPERTY=true
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
assertThat(groupString).isEqualTo("com.facebook.react")
|
||||
val strings = readVersionAndGroupStrings(propertiesFile, hermesVersionFile)
|
||||
val reactGroupString = strings.reactGroupString
|
||||
val hermesGroupString = strings.hermesGroupString
|
||||
|
||||
assertThat(reactGroupString).isEqualTo("com.facebook.react")
|
||||
assertThat(hermesGroupString).isEqualTo("com.facebook.hermes")
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+1
-1
@@ -166,7 +166,7 @@ class PathUtilsTest {
|
||||
@WithOs(OS.MAC)
|
||||
fun detectOSAwareHermesCommand_withHermesV1Enabled() {
|
||||
tempFolder.newFolder("node_modules/hermes-compiler/osx-bin/")
|
||||
val expected = tempFolder.newFile("node_modules/hermes-compiler/osx-bin//hermesc")
|
||||
val expected = tempFolder.newFile("node_modules/hermes-compiler/osx-bin/hermesc")
|
||||
|
||||
assertThat(detectOSAwareHermesCommand(tempFolder.root, "", hermesV1Enabled = true))
|
||||
.isEqualTo(expected.toString())
|
||||
|
||||
+5
-5
@@ -25,14 +25,14 @@ class OsRule : TestRule {
|
||||
override fun evaluate() {
|
||||
val annotation = description.annotations.filterIsInstance<WithOs>().firstOrNull()
|
||||
|
||||
annotation?.os?.propertyName?.let {
|
||||
annotation?.os?.propertyName?.let { osName ->
|
||||
retainOs = System.getProperty(OS_NAME_KEY)
|
||||
System.setProperty(OS_NAME_KEY, it)
|
||||
System.setProperty(OS_NAME_KEY, osName)
|
||||
}
|
||||
annotation?.arch?.let {
|
||||
if (it.isNotBlank()) {
|
||||
annotation?.arch?.let { arch ->
|
||||
if (arch.isNotBlank()) {
|
||||
retainArch = System.getProperty(OS_ARCH_KEY)
|
||||
System.setProperty(OS_ARCH_KEY, it)
|
||||
System.setProperty(OS_ARCH_KEY, arch)
|
||||
}
|
||||
}
|
||||
try {
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <React/RCTBridgeDelegate.h>
|
||||
#import <React/RCTConvert.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "RCTDefaultReactNativeFactoryDelegate.h"
|
||||
#import "RCTReactNativeFactory.h"
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#import "RCTAppDelegate.h"
|
||||
#import <React/RCTBridgeDelegate.h>
|
||||
#import <React/RCTLog.h>
|
||||
#import <React/RCTRootView.h>
|
||||
#import <React/RCTSurfacePresenterBridgeAdapter.h>
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
*
|
||||
* @flow strict
|
||||
* @format
|
||||
* @deprecated
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
*
|
||||
* @flow strict
|
||||
* @format
|
||||
* @deprecated
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
*
|
||||
* @flow
|
||||
* @format
|
||||
* @deprecated
|
||||
*/
|
||||
|
||||
import NativeTiming from './NativeTiming';
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
*
|
||||
* @flow strict
|
||||
* @format
|
||||
* @deprecated
|
||||
*/
|
||||
|
||||
export * from '../../../src/private/specs_DEPRECATED/modules/NativeTiming';
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
*
|
||||
* @flow
|
||||
* @format
|
||||
* @deprecated
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
@@ -30,7 +30,8 @@ UIImage *RCTBlurredImageWithRadius(UIImage *inputImage, CGFloat radius)
|
||||
}].CGImage;
|
||||
}
|
||||
|
||||
vImage_Buffer buffer1, buffer2;
|
||||
vImage_Buffer buffer1;
|
||||
vImage_Buffer buffer2;
|
||||
buffer1.width = buffer2.width = CGImageGetWidth(imageRef);
|
||||
buffer1.height = buffer2.height = CGImageGetHeight(imageRef);
|
||||
buffer1.rowBytes = buffer2.rowBytes = CGImageGetBytesPerRow(imageRef);
|
||||
|
||||
@@ -212,7 +212,8 @@ BOOL RCTUpscalingRequired(
|
||||
sourceSize.height *= scale;
|
||||
|
||||
// Calculate aspect ratios if needed (don't bother if resizeMode == stretch)
|
||||
CGFloat aspect = 0.0, targetAspect = 0.0;
|
||||
CGFloat aspect = 0.0;
|
||||
CGFloat targetAspect = 0.0;
|
||||
if (resizeMode != RCTResizeModeStretch) {
|
||||
aspect = sourceSize.width / sourceSize.height;
|
||||
targetAspect = destSize.width / destSize.height;
|
||||
|
||||
@@ -90,9 +90,15 @@ uint32_t RCTInterpolateColorInRange(CGFloat value, NSArray<NSNumber *> *inputRan
|
||||
CGFloat inputMin = inputRange[rangeIndex].doubleValue;
|
||||
CGFloat inputMax = inputRange[rangeIndex + 1].doubleValue;
|
||||
|
||||
CGFloat redMin, greenMin, blueMin, alphaMin;
|
||||
CGFloat redMin;
|
||||
CGFloat greenMin;
|
||||
CGFloat blueMin;
|
||||
CGFloat alphaMin;
|
||||
[outputRange[rangeIndex] getRed:&redMin green:&greenMin blue:&blueMin alpha:&alphaMin];
|
||||
CGFloat redMax, greenMax, blueMax, alphaMax;
|
||||
CGFloat redMax;
|
||||
CGFloat greenMax;
|
||||
CGFloat blueMax;
|
||||
CGFloat alphaMax;
|
||||
[outputRange[rangeIndex + 1] getRed:&redMax green:&greenMax blue:&blueMax alpha:&alphaMax];
|
||||
|
||||
return RCTColorFromComponents(
|
||||
|
||||
@@ -10,9 +10,9 @@
|
||||
#import "RCTNetworkConversions.h"
|
||||
|
||||
#import <React/RCTLog.h>
|
||||
#import <jsinspector-modern/network/NetworkReporter.h>
|
||||
#import <react/networking/NetworkReporter.h>
|
||||
|
||||
using namespace facebook::react::jsinspector_modern;
|
||||
using namespace facebook::react;
|
||||
|
||||
#ifdef REACT_NATIVE_DEBUGGER_ENABLED
|
||||
namespace {
|
||||
|
||||
@@ -50,6 +50,7 @@ Pod::Spec.new do |s|
|
||||
add_dependency(s, "React-jsinspectorcdp", :framework_name => 'jsinspector_moderncdp')
|
||||
add_dependency(s, "React-jsinspectornetwork", :framework_name => 'jsinspector_modernnetwork')
|
||||
add_dependency(s, "React-NativeModulesApple", :additional_framework_paths => ["build/generated/ios"])
|
||||
add_dependency(s, "React-networking", :framework_name => 'React_networking')
|
||||
|
||||
add_rn_third_party_dependencies(s)
|
||||
add_rncore_dependency(s)
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* @noformat
|
||||
* @nolint
|
||||
* @flow strict
|
||||
* @generated SignedSource<<deb7924d11c790f99448a1c2f0edddb9>>
|
||||
* @generated SignedSource<<c0e57723772ea5f1aa8c3c897ac3c216>>
|
||||
*/
|
||||
|
||||
import type {
|
||||
@@ -135,6 +135,7 @@ export type RenderRootOptions = {
|
||||
error: mixed,
|
||||
errorInfo: {+componentStack?: ?string},
|
||||
) => void,
|
||||
onDefaultTransitionIndicator?: () => void | (() => void),
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -67,7 +67,7 @@ template <typename T>
|
||||
facebook::react::LazyVector<T> RCTBridgingToVec(id value, T (^ctor)(id element))
|
||||
{
|
||||
NSArray *array = RCTBridgingToArray(value);
|
||||
typedef typename facebook::react::LazyVector<T>::size_type _size_t;
|
||||
using _size_t = typename facebook::react::LazyVector<T>::size_type;
|
||||
_size_t size = static_cast<_size_t>(array.count);
|
||||
return facebook::react::LazyVector<T>::fromUnsafeRawValue(array, size, ctor);
|
||||
}
|
||||
|
||||
@@ -211,6 +211,18 @@ let reactHermes = RNTarget(
|
||||
]
|
||||
)
|
||||
|
||||
/// React-networking.podspec
|
||||
let reactNetworking = RNTarget(
|
||||
name: .reactNetworking,
|
||||
path: "ReactCommon/react/networking",
|
||||
excludedPaths: ["tests"],
|
||||
dependencies: [.reactNativeDependencies, .reactJsInspectorNetwork, .reactPerformanceTimeline],
|
||||
defines: [
|
||||
CXXSetting.define("REACT_NATIVE_DEBUGGER_ENABLED", to: "1", .when(configuration: BuildConfiguration.debug)),
|
||||
CXXSetting.define("REACT_NATIVE_DEBUGGER_ENABLED_DEVONLY", to: "1", .when(configuration: BuildConfiguration.debug)),
|
||||
]
|
||||
)
|
||||
|
||||
/// React-performancecdpmetrics.podspec
|
||||
let reactPerformanceCdpMetrics = RNTarget(
|
||||
name: .reactPerformanceCdpMetrics,
|
||||
@@ -304,6 +316,13 @@ let reactIdleCallbacksNativeModule = RNTarget(
|
||||
dependencies: [.reactNativeDependencies, .reactDebug, .reactFeatureFlags, .reactUtils, .reactPerfLogger, .reactCxxReact, .reactTurboModuleCore]
|
||||
)
|
||||
|
||||
/// React-webperformance.podspec
|
||||
let reactWebPerformanceNativeModule = RNTarget(
|
||||
name: .reactWebPerformanceNativeModule,
|
||||
path: "ReactCommon/react/nativemodule/webperformance",
|
||||
dependencies: [.reactNativeDependencies, .reactCxxReact, .reactTurboModuleCore, .reactPerformanceTimeline]
|
||||
)
|
||||
|
||||
/// React-featureflagnativemodule.podspec
|
||||
let reactFeatureflagsNativemodule = RNTarget(
|
||||
name: .reactFeatureflagsNativemodule,
|
||||
@@ -566,6 +585,7 @@ let targets = [
|
||||
reactNativeDependencies,
|
||||
hermesPrebuilt,
|
||||
reactJsiTooling,
|
||||
reactNetworking,
|
||||
reactPerformanceCdpMetrics,
|
||||
reactPerformanceTimeline,
|
||||
reactRuntimeScheduler,
|
||||
@@ -590,6 +610,7 @@ let targets = [
|
||||
reactTurboModuleCoreDefaults,
|
||||
reactTurboModuleCoreMicrotasks,
|
||||
reactIdleCallbacksNativeModule,
|
||||
reactWebPerformanceNativeModule,
|
||||
reactFeatureflagsNativemodule,
|
||||
reactNativeModuleDom,
|
||||
reactAppDelegate,
|
||||
@@ -737,6 +758,7 @@ extension String {
|
||||
static let hermesPrebuilt = "hermes-prebuilt"
|
||||
|
||||
static let reactJsiTooling = "React-jsitooling"
|
||||
static let reactNetworking = "React-networking"
|
||||
static let reactPerformanceCdpMetrics = "React-performancecdpmetrics"
|
||||
static let reactPerformanceTimeline = "React-performancetimeline"
|
||||
static let reactRuntimeScheduler = "React-runtimescheduler"
|
||||
@@ -764,6 +786,7 @@ extension String {
|
||||
static let reactTurboModuleCoreDefaults = "ReactCommon/turbomodule/core/defaults"
|
||||
static let reactTurboModuleCoreMicrotasks = "ReactCommon/turbomodule/core/microtasks"
|
||||
static let reactIdleCallbacksNativeModule = "React-idlecallbacksnativemodule"
|
||||
static let reactWebPerformanceNativeModule = "React-webperformancenativemodule"
|
||||
static let reactFeatureflagsNativemodule = "React-featureflagsnativemodule"
|
||||
static let reactNativeModuleDom = "React-domnativemodule"
|
||||
static let reactAppDelegate = "React-RCTAppDelegate"
|
||||
|
||||
@@ -69,6 +69,7 @@ RCT_EXTERN_C_END
|
||||
* will be used as the JS module name. If omitted, the JS module name will
|
||||
* match the Objective-C class name.
|
||||
*/
|
||||
#ifndef RCT_FIT_RM_OLD_RUNTIME
|
||||
#define RCT_EXPORT_MODULE(js_name) \
|
||||
RCT_EXTERN void RCTRegisterModule(Class); \
|
||||
+(NSString *)moduleName \
|
||||
@@ -80,6 +81,17 @@ RCT_EXTERN_C_END
|
||||
RCTRegisterModule(self); \
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define RCT_EXPORT_MODULE(js_name) \
|
||||
RCT_EXTERN void RCTRegisterModule(Class); \
|
||||
+(NSString *)moduleName \
|
||||
{ \
|
||||
return @ #js_name; \
|
||||
}
|
||||
|
||||
#endif // RCT_FIT_RM_OLD_RUNTIME
|
||||
|
||||
/**
|
||||
* Same as RCT_EXPORT_MODULE, but uses __attribute__((constructor)) for module
|
||||
* registration. Useful for registering swift classes that forbids use of load
|
||||
|
||||
@@ -721,13 +721,13 @@ NSData *__nullable RCTGzipData(NSData *__nullable input, float level)
|
||||
|
||||
void *libz = dlopen("/usr/lib/libz.dylib", RTLD_LAZY);
|
||||
|
||||
typedef int (*DeflateInit2_)(z_streamp, int, int, int, int, int, const char *, int);
|
||||
using DeflateInit2_ = int (*)(z_streamp, int, int, int, int, int, const char *, int);
|
||||
DeflateInit2_ deflateInit2_ = (DeflateInit2_)dlsym(libz, "deflateInit2_");
|
||||
|
||||
typedef int (*Deflate)(z_streamp, int);
|
||||
using Deflate = int (*)(z_streamp, int);
|
||||
Deflate deflate = (Deflate)dlsym(libz, "deflate");
|
||||
|
||||
typedef int (*DeflateEnd)(z_streamp);
|
||||
using DeflateEnd = int (*)(z_streamp);
|
||||
DeflateEnd deflateEnd = (DeflateEnd)dlsym(libz, "deflateEnd");
|
||||
|
||||
z_stream stream;
|
||||
|
||||
@@ -238,11 +238,10 @@ static NSDictionary *RCTExportedDimensions(CGFloat fontScale)
|
||||
- (void)interfaceOrientationDidChange
|
||||
{
|
||||
#if TARGET_OS_IOS && !TARGET_OS_MACCATALYST
|
||||
UIApplication *application = RCTSharedApplication();
|
||||
UIInterfaceOrientation nextOrientation = RCTKeyWindow().windowScene.interfaceOrientation;
|
||||
UIWindow *window = RCTKeyWindow();
|
||||
UIInterfaceOrientation nextOrientation = window.windowScene.interfaceOrientation;
|
||||
|
||||
BOOL isRunningInFullScreen =
|
||||
CGRectEqualToRect(application.delegate.window.frame, application.delegate.window.screen.bounds);
|
||||
BOOL isRunningInFullScreen = window ? CGRectEqualToRect(window.frame, window.screen.bounds) : YES;
|
||||
// We are catching here two situations for multitasking view:
|
||||
// a) The app is in Split View and the container gets resized -> !isRunningInFullScreen
|
||||
// b) The app changes to/from fullscreen example: App runs in slide over mode and goes into fullscreen->
|
||||
|
||||
+2
-1
@@ -81,7 +81,8 @@
|
||||
return;
|
||||
}
|
||||
|
||||
CGFloat top = 0, left = 0;
|
||||
CGFloat top = 0;
|
||||
CGFloat left = 0;
|
||||
if (contentSize.width < boundsSize.width) {
|
||||
left = (boundsSize.width - contentSize.width) * 0.5f;
|
||||
}
|
||||
|
||||
@@ -91,9 +91,9 @@ Pod::Spec.new do |s|
|
||||
add_dependency(s, "React-RCTAnimation", :framework_name => 'RCTAnimation')
|
||||
add_dependency(s, "React-jsinspector", :framework_name => 'jsinspector_modern')
|
||||
add_dependency(s, "React-jsinspectorcdp", :framework_name => 'jsinspector_moderncdp')
|
||||
add_dependency(s, "React-jsinspectornetwork", :framework_name => 'jsinspector_modernnetwork')
|
||||
add_dependency(s, "React-jsinspectortracing", :framework_name => 'jsinspector_moderntracing')
|
||||
add_dependency(s, "React-performancecdpmetrics", :framework_name => 'React_performancecdpmetrics')
|
||||
add_dependency(s, "React-networking", :framework_name => 'React_networking')
|
||||
add_dependency(s, "React-renderercss")
|
||||
add_dependency(s, "React-RCTFBReactNativeSpec")
|
||||
|
||||
|
||||
@@ -80,7 +80,9 @@ static void RCTPathAddEllipticArc(
|
||||
CGFloat endAngle,
|
||||
BOOL clockwise)
|
||||
{
|
||||
CGFloat xScale = 1, yScale = 1, radius = 0;
|
||||
CGFloat xScale = 1;
|
||||
CGFloat yScale = 1;
|
||||
CGFloat radius = 0;
|
||||
if (size.width != 0) {
|
||||
xScale = 1;
|
||||
yScale = size.height / size.width;
|
||||
|
||||
@@ -679,7 +679,8 @@ RCT_SCROLL_EVENT_HANDLER(scrollViewDidScrollToTop, onScrollToTop)
|
||||
return;
|
||||
}
|
||||
|
||||
CGFloat top = 0, left = 0;
|
||||
CGFloat top = 0;
|
||||
CGFloat left = 0;
|
||||
if (contentSize.width < boundsSize.width) {
|
||||
left = (boundsSize.width - contentSize.width) * 0.5f;
|
||||
}
|
||||
|
||||
@@ -2354,12 +2354,14 @@ public class com/facebook/react/fabric/mounting/SurfaceMountingManager {
|
||||
public fun sendAccessibilityEvent (II)V
|
||||
public fun setJSResponder (IIZ)V
|
||||
public fun stopSurface ()V
|
||||
public fun storeSynchronousMountPropsOverride (ILcom/facebook/react/bridge/ReadableMap;)V
|
||||
public fun sweepActiveTouchForTag (I)V
|
||||
public fun updateEventEmitter (ILcom/facebook/react/fabric/events/EventEmitterWrapper;)V
|
||||
public fun updateLayout (IIIIIIII)V
|
||||
public fun updateOverflowInset (IIIII)V
|
||||
public fun updatePadding (IIIII)V
|
||||
public fun updateProps (ILcom/facebook/react/bridge/ReadableMap;)V
|
||||
public fun updatePropsSynchronously (ILcom/facebook/react/bridge/ReadableMap;)V
|
||||
public fun updateState (ILcom/facebook/react/uimanager/StateWrapper;)V
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
VERSION_NAME=1000.0.0
|
||||
HERMES_VERSION_NAME=1000.0.0
|
||||
react.internal.publishingGroup=com.facebook.react
|
||||
react.internal.hermesPublishingGroup=com.facebook.hermes
|
||||
|
||||
|
||||
@@ -88,7 +88,7 @@ val hermesVersionProvider: Provider<String> =
|
||||
val hermesVersionFile =
|
||||
File(
|
||||
reactNativeRootDir,
|
||||
if (hermesV1Enabled) "sdks/.hermesv1version" else "\"sdks/.hermesversion\"",
|
||||
if (hermesV1Enabled) "sdks/.hermesv1version" else "sdks/.hermesversion",
|
||||
)
|
||||
|
||||
if (hermesVersionFile.exists()) {
|
||||
|
||||
+1
-1
@@ -96,7 +96,7 @@ public class CatalystInstanceImpl implements CatalystInstance {
|
||||
private final TraceListener mTraceListener;
|
||||
private final JavaScriptModuleRegistry mJSModuleRegistry;
|
||||
private final JSBundleLoader mJSBundleLoader;
|
||||
private final ArrayList<PendingJSCall> mJSCallsPendingInit = new ArrayList<PendingJSCall>();
|
||||
private final ArrayList<PendingJSCall> mJSCallsPendingInit = new ArrayList<>();
|
||||
private final Object mJSCallsPendingInitLock = new Object();
|
||||
|
||||
private final NativeModuleRegistry mNativeModuleRegistry;
|
||||
|
||||
+1
-1
@@ -83,6 +83,6 @@ internal class BridgelessDevSupportManager(
|
||||
}
|
||||
|
||||
fun tracingState(): TracingState {
|
||||
return TracingState.DISABLED
|
||||
return TracingState.ENABLEDINCDPMODE
|
||||
}
|
||||
}
|
||||
|
||||
+11
-8
@@ -68,6 +68,7 @@ import com.facebook.react.devsupport.interfaces.StackFrame
|
||||
import com.facebook.react.devsupport.interfaces.TracingState
|
||||
import com.facebook.react.devsupport.interfaces.TracingStateProvider
|
||||
import com.facebook.react.devsupport.perfmonitor.PerfMonitorDevHelper
|
||||
import com.facebook.react.devsupport.perfmonitor.PerfMonitorOverlayManager
|
||||
import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags
|
||||
import com.facebook.react.internal.featureflags.ReactNativeNewArchitectureFeatureFlags
|
||||
import com.facebook.react.modules.core.RCTNativeAppEventEmitter
|
||||
@@ -77,6 +78,7 @@ import java.io.File
|
||||
import java.net.MalformedURLException
|
||||
import java.net.URL
|
||||
import java.util.Locale
|
||||
import javax.inject.Provider
|
||||
|
||||
public abstract class DevSupportManagerBase(
|
||||
protected val applicationContext: Context,
|
||||
@@ -182,7 +184,7 @@ public abstract class DevSupportManagerBase(
|
||||
null
|
||||
}
|
||||
|
||||
private var perfMonitorOverlayManager: PerfMonitorOverlayViewManager? = null
|
||||
private var perfMonitorOverlayManager: PerfMonitorOverlayManager? = null
|
||||
private var tracingStateProvider: TracingStateProvider? = null
|
||||
|
||||
init {
|
||||
@@ -215,19 +217,18 @@ public abstract class DevSupportManagerBase(
|
||||
if (
|
||||
ReactNativeNewArchitectureFeatureFlags.enableBridgelessArchitecture() &&
|
||||
ReactNativeFeatureFlags.perfMonitorV2Enabled() &&
|
||||
reactInstanceDevHelper is PerfMonitorDevHelper &&
|
||||
perfMonitorOverlayManager == null
|
||||
reactInstanceDevHelper is PerfMonitorDevHelper
|
||||
) {
|
||||
perfMonitorOverlayManager =
|
||||
PerfMonitorOverlayViewManager(
|
||||
Supplier {
|
||||
PerfMonitorOverlayManager(
|
||||
reactInstanceDevHelper,
|
||||
Provider {
|
||||
val context = reactInstanceDevHelper.currentActivity
|
||||
if (context == null || context.isFinishing) {
|
||||
return@Supplier null
|
||||
return@Provider null
|
||||
}
|
||||
context
|
||||
},
|
||||
reactInstanceDevHelper.inspectorTarget,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -548,10 +549,11 @@ public abstract class DevSupportManagerBase(
|
||||
override fun onNewReactContextCreated(reactContext: ReactContext) {
|
||||
resetCurrentContext(reactContext)
|
||||
|
||||
if (perfMonitorOverlayManager != null && reactInstanceDevHelper is PerfMonitorDevHelper) {
|
||||
if (reactInstanceDevHelper is PerfMonitorDevHelper) {
|
||||
perfMonitorOverlayManager?.let { manager ->
|
||||
reactInstanceDevHelper.inspectorTarget?.addPerfMonitorListener(manager)
|
||||
}
|
||||
perfMonitorOverlayManager?.enable()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -882,6 +884,7 @@ public abstract class DevSupportManagerBase(
|
||||
|
||||
override fun onPackagerDisconnected() {
|
||||
isPackagerConnected = false
|
||||
perfMonitorOverlayManager?.disable()
|
||||
}
|
||||
|
||||
override fun onPackagerReloadCommand() {
|
||||
|
||||
-278
@@ -1,278 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.devsupport
|
||||
|
||||
import android.app.Dialog
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.graphics.Typeface
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
import android.graphics.drawable.GradientDrawable
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.view.Gravity
|
||||
import android.view.Window
|
||||
import android.view.WindowManager
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import androidx.core.util.Supplier
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import com.facebook.react.R
|
||||
import com.facebook.react.bridge.UiThreadUtil
|
||||
import com.facebook.react.devsupport.interfaces.PerfMonitorOverlayManager
|
||||
import com.facebook.react.devsupport.interfaces.TracingState
|
||||
import com.facebook.react.devsupport.perfmonitor.PerfMonitorInspectorTargetBinding
|
||||
import com.facebook.react.devsupport.perfmonitor.PerfMonitorUpdateListener
|
||||
import com.facebook.react.uimanager.DisplayMetricsHolder
|
||||
import com.facebook.react.uimanager.PixelUtil
|
||||
import java.util.Locale
|
||||
|
||||
internal class PerfMonitorOverlayViewManager(
|
||||
private val contextSupplier: Supplier<Context?>,
|
||||
private val inspectorTarget: PerfMonitorInspectorTargetBinding?,
|
||||
) : PerfMonitorOverlayManager, PerfMonitorUpdateListener {
|
||||
private var initialized: Boolean = false
|
||||
private var enabled: Boolean = false
|
||||
private var hasInteractionData: Boolean = false
|
||||
private var interactionDialog: Dialog? = null
|
||||
private var buttonDialog: Dialog? = null
|
||||
private var durationLabel: TextView? = null
|
||||
private var ttl: Int = 0
|
||||
private var hideAfterTimeoutHandler: Handler? = null
|
||||
|
||||
override fun enable() {
|
||||
UiThreadUtil.runOnUiThread {
|
||||
enabled = true
|
||||
if (hasInteractionData) {
|
||||
showOverlay()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun disable() {
|
||||
UiThreadUtil.runOnUiThread {
|
||||
enabled = false
|
||||
hideOverlay()
|
||||
}
|
||||
}
|
||||
|
||||
override fun reset() {
|
||||
UiThreadUtil.runOnUiThread {
|
||||
hasInteractionData = false
|
||||
hideOverlay()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onRecordingStateChanged(state: TracingState) {
|
||||
// recordingState = state
|
||||
// view?.updateRecordingState(state)
|
||||
}
|
||||
|
||||
override fun onNewFocusedEvent(data: PerfMonitorUpdateListener.LongTaskEventData) {
|
||||
UiThreadUtil.runOnUiThread {
|
||||
ensureInitialized()
|
||||
durationLabel?.text = String.format(Locale.US, "%d ms", data.durationMs)
|
||||
durationLabel?.setTextColor(getDurationHighlightColor(data.responsivenessScore))
|
||||
hasInteractionData = true
|
||||
ttl = data.ttl
|
||||
|
||||
hideAfterTimeoutHandler?.removeCallbacksAndMessages(null)
|
||||
|
||||
if (enabled) {
|
||||
showOverlay()
|
||||
|
||||
// Schedule hiding overlay after ttl milliseconds
|
||||
if (ttl > 0) {
|
||||
if (hideAfterTimeoutHandler == null) {
|
||||
hideAfterTimeoutHandler = Handler(Looper.getMainLooper())
|
||||
}
|
||||
hideAfterTimeoutHandler?.postDelayed({ hideOverlay() }, ttl.toLong())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun ensureInitialized() {
|
||||
if (initialized) {
|
||||
return
|
||||
}
|
||||
val context = contextSupplier.get() ?: return
|
||||
DisplayMetricsHolder.initDisplayMetricsIfNotInitialized(context)
|
||||
createDialog(context)
|
||||
createButton(context)
|
||||
initialized = true
|
||||
}
|
||||
|
||||
private fun showOverlay() {
|
||||
interactionDialog?.show()
|
||||
buttonDialog?.show()
|
||||
}
|
||||
|
||||
private fun hideOverlay() {
|
||||
interactionDialog?.hide()
|
||||
buttonDialog?.hide()
|
||||
}
|
||||
|
||||
private fun createDialog(context: Context) {
|
||||
val containerLayout = createInnerLayout(context)
|
||||
val longTaskLabel =
|
||||
TextView(context).apply {
|
||||
textSize = TEXT_SIZE_PRIMARY
|
||||
text = "Long Task"
|
||||
setTextColor(Color.WHITE)
|
||||
typeface = TYPEFACE_BOLD
|
||||
}
|
||||
durationLabel =
|
||||
TextView(context).apply {
|
||||
textSize = TEXT_SIZE_PRIMARY
|
||||
setTextColor(COLOR_TEXT_GREEN)
|
||||
typeface = TYPEFACE_BOLD
|
||||
}
|
||||
containerLayout.addView(longTaskLabel)
|
||||
containerLayout.addView(durationLabel)
|
||||
|
||||
val dialog =
|
||||
createAnchoredDialog(context, dpToPx(140f), dpToPx(16f)).apply {
|
||||
setContentView(containerLayout)
|
||||
}
|
||||
dialog.window?.apply {
|
||||
attributes =
|
||||
attributes?.apply {
|
||||
flags =
|
||||
flags or
|
||||
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE or
|
||||
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
|
||||
}
|
||||
}
|
||||
|
||||
this.interactionDialog = dialog
|
||||
}
|
||||
|
||||
fun updateRecordingState(state: TracingState) {}
|
||||
|
||||
private fun createButton(context: Context) {
|
||||
val buttonInner = createInnerLayout(context)
|
||||
buttonInner.addView(
|
||||
TextView(context).apply {
|
||||
text = "Analyze"
|
||||
textSize = TEXT_SIZE_PRIMARY
|
||||
setTextColor(Color.WHITE)
|
||||
typeface = TYPEFACE_BOLD
|
||||
}
|
||||
)
|
||||
buttonInner.addView(
|
||||
TextView(context).apply {
|
||||
text = "cmd + A"
|
||||
textSize = TEXT_SIZE_ACCESSORY
|
||||
setTextColor(Color.WHITE)
|
||||
alpha = 0.7f
|
||||
typeface = TYPEFACE_BOLD
|
||||
}
|
||||
)
|
||||
val buttonView =
|
||||
LinearLayout(context).apply {
|
||||
orientation = LinearLayout.VERTICAL
|
||||
setPadding(
|
||||
dpToPx(8f).toInt(),
|
||||
dpToPx(16f).toInt(),
|
||||
dpToPx(16f).toInt(),
|
||||
dpToPx(8f).toInt(),
|
||||
)
|
||||
addView(buttonInner)
|
||||
setOnClickListener { inspectorTarget?.pauseAndAnalyzeBackgroundTrace() }
|
||||
}
|
||||
val dialog =
|
||||
createAnchoredDialog(context, dpToPx(0f), dpToPx(0f)).apply { setContentView(buttonView) }
|
||||
dialog.window?.apply {
|
||||
attributes =
|
||||
attributes?.apply { flags = flags or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE }
|
||||
}
|
||||
|
||||
this.buttonDialog = dialog
|
||||
}
|
||||
|
||||
private fun createAnchoredDialog(context: Context, offsetX: Float, offsetY: Float): Dialog {
|
||||
val dialog =
|
||||
Dialog(context, R.style.NoAnimationDialog).apply {
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE)
|
||||
window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
|
||||
window?.setDimAmount(0f)
|
||||
setCancelable(false)
|
||||
}
|
||||
dialog.window?.apply {
|
||||
attributes =
|
||||
attributes?.apply {
|
||||
width = WindowManager.LayoutParams.WRAP_CONTENT
|
||||
height = WindowManager.LayoutParams.WRAP_CONTENT
|
||||
gravity = Gravity.TOP or Gravity.END
|
||||
x = offsetX.toInt()
|
||||
y = offsetY.toInt()
|
||||
}
|
||||
}
|
||||
dialog.window?.decorView?.let { decorView ->
|
||||
ViewCompat.setOnApplyWindowInsetsListener(decorView) { view, windowInsets ->
|
||||
val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
|
||||
val layoutParams = (view.layoutParams as WindowManager.LayoutParams)
|
||||
layoutParams.y = insets.top + offsetY.toInt()
|
||||
dialog.window?.attributes = layoutParams
|
||||
WindowInsetsCompat.CONSUMED
|
||||
}
|
||||
}
|
||||
|
||||
return dialog
|
||||
}
|
||||
|
||||
private fun createInnerLayout(context: Context): LinearLayout {
|
||||
return LinearLayout(context).apply {
|
||||
orientation = LinearLayout.HORIZONTAL
|
||||
gravity = Gravity.CENTER_VERTICAL
|
||||
val paddingHorizontal = dpToPx(14f).toInt()
|
||||
val paddingVertical = dpToPx(8f).toInt()
|
||||
setPadding(paddingHorizontal, paddingVertical, paddingHorizontal, paddingVertical)
|
||||
layoutParams =
|
||||
LinearLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT,
|
||||
)
|
||||
background =
|
||||
GradientDrawable().apply {
|
||||
shape = GradientDrawable.RECTANGLE
|
||||
setColor(Color.BLACK)
|
||||
cornerRadius = dpToPx(14.5f)
|
||||
alpha = (0.8 * 255).toInt()
|
||||
setStroke(dpToPx(1f).toInt(), COLOR_OVERLAY_BORDER)
|
||||
}
|
||||
showDividers = LinearLayout.SHOW_DIVIDER_MIDDLE
|
||||
dividerDrawable =
|
||||
object : ColorDrawable(Color.TRANSPARENT) {
|
||||
override fun getIntrinsicWidth(): Int = dpToPx(8f).toInt()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getDurationHighlightColor(responsivenessScore: Int): Int {
|
||||
return when (responsivenessScore) {
|
||||
3 -> COLOR_TEXT_RED
|
||||
2 -> COLOR_TEXT_YELLOW
|
||||
else -> COLOR_TEXT_GREEN
|
||||
}
|
||||
}
|
||||
|
||||
private fun dpToPx(dp: Float): Float = PixelUtil.toPixelFromDIP(dp)
|
||||
|
||||
companion object {
|
||||
private val COLOR_TEXT_GREEN = Color.parseColor("#4AEB2F")
|
||||
private val COLOR_TEXT_YELLOW = Color.parseColor("#FFAA00")
|
||||
private val COLOR_TEXT_RED = Color.parseColor("#FF0000")
|
||||
private val COLOR_OVERLAY_BORDER = Color.parseColor("#6C6C6C")
|
||||
private val TEXT_SIZE_PRIMARY = 13f
|
||||
private val TEXT_SIZE_ACCESSORY = 9f
|
||||
private val TYPEFACE_BOLD = Typeface.create("sans-serif", Typeface.BOLD)
|
||||
}
|
||||
}
|
||||
-20
@@ -1,20 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.devsupport.interfaces
|
||||
|
||||
/** [Experimental] Interface to manage the V2 Perf Monitor overlay. */
|
||||
internal interface PerfMonitorOverlayManager {
|
||||
/** Enable the Perf Monitor overlay. Will be shown when updates are received. */
|
||||
public fun enable()
|
||||
|
||||
/** Disable the Perf Monitor overlay. Will remain hidden when updates are received. */
|
||||
public fun disable()
|
||||
|
||||
/** Reset the Perf Monitor overlay, e.g. after a reload. */
|
||||
public fun reset()
|
||||
}
|
||||
+5
@@ -7,11 +7,16 @@
|
||||
|
||||
package com.facebook.react.devsupport.perfmonitor
|
||||
|
||||
import com.facebook.react.devsupport.interfaces.TracingState
|
||||
|
||||
/**
|
||||
* [Experimental] Interface implemented by [com.facebook.react.runtime.ReactHostInspectorTarget]
|
||||
* exposing actions for the V2 Perf Monitor.
|
||||
*/
|
||||
internal interface PerfMonitorInspectorTargetBinding {
|
||||
/** Get the current CDP or background performance tracing state. */
|
||||
public fun getTracingState(): TracingState
|
||||
|
||||
/** Attempt to pause the current background performance trace, and open in DevTools. */
|
||||
public fun pauseAndAnalyzeBackgroundTrace()
|
||||
|
||||
|
||||
+64
@@ -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.
|
||||
*/
|
||||
|
||||
package com.facebook.react.devsupport.perfmonitor
|
||||
|
||||
import android.content.Context
|
||||
import com.facebook.react.bridge.UiThreadUtil
|
||||
import com.facebook.react.devsupport.interfaces.TracingState
|
||||
import javax.inject.Provider
|
||||
|
||||
internal class PerfMonitorOverlayManager(
|
||||
private val devHelper: PerfMonitorDevHelper,
|
||||
private val contextProvider: Provider<Context?>,
|
||||
) : PerfMonitorUpdateListener {
|
||||
private var enabled: Boolean = false
|
||||
private var initialized: Boolean = false
|
||||
private var view: PerfMonitorOverlayView? = null
|
||||
|
||||
private fun init() {
|
||||
if (initialized || !enabled) {
|
||||
return
|
||||
}
|
||||
|
||||
UiThreadUtil.runOnUiThread {
|
||||
val context = contextProvider.get() ?: return@runOnUiThread
|
||||
view = PerfMonitorOverlayView(context)
|
||||
|
||||
// Start background tracing
|
||||
devHelper.inspectorTarget?.resumeBackgroundTrace()
|
||||
|
||||
view?.show()
|
||||
initialized = true
|
||||
}
|
||||
}
|
||||
|
||||
/** Enable the Perf Monitor overlay. Will be shown when updates are received. */
|
||||
fun enable() {
|
||||
enabled = true
|
||||
init()
|
||||
}
|
||||
|
||||
/** Disable the Perf Monitor overlay. Will remain hidden when updates are received. */
|
||||
fun disable() {
|
||||
UiThreadUtil.runOnUiThread { view?.hide() }
|
||||
view = null
|
||||
enabled = false
|
||||
}
|
||||
|
||||
/** Reset the Perf Monitor overlay, e.g. after a reload. */
|
||||
fun reset() {
|
||||
// Update with current recording state
|
||||
onRecordingStateChanged(
|
||||
devHelper.inspectorTarget?.getTracingState() ?: TracingState.ENABLEDINCDPMODE
|
||||
)
|
||||
}
|
||||
|
||||
override fun onRecordingStateChanged(state: TracingState) {
|
||||
view?.updateRecordingState(state)
|
||||
}
|
||||
}
|
||||
+189
@@ -0,0 +1,189 @@
|
||||
/*
|
||||
* 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.devsupport.perfmonitor
|
||||
|
||||
import android.app.Dialog
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.graphics.Typeface
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
import android.graphics.drawable.GradientDrawable
|
||||
import android.view.Gravity
|
||||
import android.view.Window
|
||||
import android.view.WindowManager
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import com.facebook.react.R
|
||||
import com.facebook.react.devsupport.interfaces.TracingState
|
||||
import com.facebook.react.uimanager.DisplayMetricsHolder
|
||||
import com.facebook.react.uimanager.PixelUtil
|
||||
|
||||
internal class PerfMonitorOverlayView(
|
||||
private val context: Context,
|
||||
) {
|
||||
private val dialog: Dialog
|
||||
private lateinit var statusLabel: TextView
|
||||
private lateinit var tooltipLabel: TextView
|
||||
private lateinit var statusIndicator: TextView
|
||||
|
||||
init {
|
||||
DisplayMetricsHolder.initDisplayMetricsIfNotInitialized(context)
|
||||
dialog = createToolbarDialog()
|
||||
}
|
||||
|
||||
fun show() {
|
||||
dialog.show()
|
||||
}
|
||||
|
||||
fun hide() {
|
||||
dialog.hide()
|
||||
}
|
||||
|
||||
fun updateRecordingState(state: TracingState) {
|
||||
if (state == TracingState.ENABLEDINCDPMODE) {
|
||||
dialog.hide()
|
||||
return
|
||||
}
|
||||
|
||||
if (state == TracingState.ENABLEDINBACKGROUNDMODE) {
|
||||
(statusIndicator.background as GradientDrawable).setColor(Color.RED)
|
||||
statusLabel.text = "Background Profiling Active"
|
||||
tooltipLabel.text = "Press ☰ to open"
|
||||
} else {
|
||||
(statusIndicator.background as GradientDrawable).setColor(Color.GRAY)
|
||||
statusLabel.text = "Background Profiling Stopped"
|
||||
tooltipLabel.text = "Press ☰ to restart"
|
||||
}
|
||||
dialog.show()
|
||||
}
|
||||
|
||||
private fun createToolbarDialog(): Dialog {
|
||||
statusIndicator =
|
||||
TextView(context).apply {
|
||||
width = dpToPx(12f).toInt()
|
||||
height = dpToPx(12f).toInt()
|
||||
background =
|
||||
GradientDrawable().apply {
|
||||
shape = GradientDrawable.OVAL
|
||||
setColor(Color.RED)
|
||||
}
|
||||
}
|
||||
|
||||
val textContainer =
|
||||
LinearLayout(context).apply {
|
||||
orientation = LinearLayout.VERTICAL
|
||||
layoutParams =
|
||||
LinearLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT,
|
||||
)
|
||||
}
|
||||
statusLabel =
|
||||
TextView(context).apply {
|
||||
textSize = TEXT_SIZE_PRIMARY
|
||||
setTextColor(Color.WHITE)
|
||||
typeface = TYPEFACE_BOLD
|
||||
}
|
||||
tooltipLabel =
|
||||
TextView(context).apply {
|
||||
textSize = TEXT_SIZE_ACCESSORY
|
||||
setTextColor(Color.WHITE)
|
||||
typeface = TYPEFACE_BOLD
|
||||
}
|
||||
textContainer.addView(statusLabel)
|
||||
textContainer.addView(tooltipLabel)
|
||||
|
||||
val containerLayout = createInnerLayout()
|
||||
containerLayout.addView(statusIndicator)
|
||||
containerLayout.addView(textContainer)
|
||||
|
||||
val dialog =
|
||||
createAnchoredDialog(dpToPx(12f), dpToPx(12f)).apply { setContentView(containerLayout) }
|
||||
dialog.window?.apply {
|
||||
attributes =
|
||||
attributes?.apply {
|
||||
flags =
|
||||
flags or
|
||||
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE or
|
||||
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
|
||||
}
|
||||
}
|
||||
|
||||
return dialog
|
||||
}
|
||||
|
||||
private fun createAnchoredDialog(offsetX: Float, offsetY: Float): Dialog {
|
||||
val dialog =
|
||||
Dialog(context, R.style.NoAnimationDialog).apply {
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE)
|
||||
window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
|
||||
window?.setDimAmount(0f)
|
||||
setCancelable(false)
|
||||
}
|
||||
dialog.window?.apply {
|
||||
attributes =
|
||||
attributes?.apply {
|
||||
width = WindowManager.LayoutParams.WRAP_CONTENT
|
||||
height = WindowManager.LayoutParams.WRAP_CONTENT
|
||||
gravity = Gravity.TOP or Gravity.END
|
||||
x = offsetX.toInt()
|
||||
y = offsetY.toInt()
|
||||
}
|
||||
}
|
||||
dialog.window?.decorView?.let { decorView ->
|
||||
ViewCompat.setOnApplyWindowInsetsListener(decorView) { view, windowInsets ->
|
||||
val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
|
||||
val layoutParams = (view.layoutParams as WindowManager.LayoutParams)
|
||||
layoutParams.y = insets.top + offsetY.toInt()
|
||||
dialog.window?.attributes = layoutParams
|
||||
WindowInsetsCompat.CONSUMED
|
||||
}
|
||||
}
|
||||
|
||||
return dialog
|
||||
}
|
||||
|
||||
private fun createInnerLayout(): LinearLayout {
|
||||
return LinearLayout(context).apply {
|
||||
orientation = LinearLayout.HORIZONTAL
|
||||
gravity = Gravity.CENTER_VERTICAL
|
||||
val paddingHorizontal = dpToPx(14f).toInt()
|
||||
val paddingVertical = dpToPx(7f).toInt()
|
||||
setPadding(paddingHorizontal, paddingVertical, paddingHorizontal, paddingVertical)
|
||||
layoutParams =
|
||||
LinearLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT,
|
||||
)
|
||||
background =
|
||||
GradientDrawable().apply {
|
||||
shape = GradientDrawable.RECTANGLE
|
||||
setColor(Color.BLACK)
|
||||
cornerRadius = dpToPx(14.5f)
|
||||
alpha = (0.8 * 255).toInt()
|
||||
setStroke(dpToPx(1f).toInt(), COLOR_OVERLAY_BORDER)
|
||||
}
|
||||
showDividers = LinearLayout.SHOW_DIVIDER_MIDDLE
|
||||
dividerDrawable =
|
||||
object : ColorDrawable(Color.TRANSPARENT) {
|
||||
override fun getIntrinsicWidth(): Int = dpToPx(8f).toInt()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun dpToPx(dp: Float): Float = PixelUtil.toPixelFromDIP(dp)
|
||||
|
||||
companion object {
|
||||
private val COLOR_OVERLAY_BORDER = Color.parseColor("#6C6C6C")
|
||||
private val TEXT_SIZE_PRIMARY = 12f
|
||||
private val TEXT_SIZE_ACCESSORY = 10f
|
||||
private val TYPEFACE_BOLD = Typeface.create("sans-serif", Typeface.BOLD)
|
||||
}
|
||||
}
|
||||
-9
@@ -10,15 +10,6 @@ import com.facebook.react.devsupport.interfaces.TracingState
|
||||
|
||||
/** [Experimental] An interface for subscribing to updates for the V2 Perf Monitor. */
|
||||
internal interface PerfMonitorUpdateListener {
|
||||
data class LongTaskEventData(
|
||||
val durationMs: Int,
|
||||
val responsivenessScore: Int,
|
||||
val ttl: Int,
|
||||
)
|
||||
|
||||
/** Called when a new active performance event should be displayed. */
|
||||
fun onNewFocusedEvent(data: LongTaskEventData)
|
||||
|
||||
/** Called when the recording state of the background performance trace has changed. */
|
||||
fun onRecordingStateChanged(state: TracingState)
|
||||
}
|
||||
|
||||
+2
-1
@@ -791,7 +791,8 @@ public class FabricUIManager
|
||||
@Override
|
||||
public void execute(MountingManager mountingManager) {
|
||||
try {
|
||||
mountingManager.updateProps(reactTag, props);
|
||||
mountingManager.storeSynchronousMountPropsOverride(reactTag, props);
|
||||
mountingManager.updatePropsSynchronously(reactTag, props);
|
||||
} catch (Exception ex) {
|
||||
// TODO T42943890: Fix animations in Fabric and remove this try/catch?
|
||||
// There might always be race conditions between surface teardown and
|
||||
|
||||
+12
-2
@@ -265,13 +265,23 @@ internal class MountingManager(
|
||||
}
|
||||
|
||||
@UiThread
|
||||
fun updateProps(reactTag: Int, props: ReadableMap?) {
|
||||
fun storeSynchronousMountPropsOverride(reactTag: Int, props: ReadableMap?) {
|
||||
assertOnUiThread()
|
||||
if (props == null) {
|
||||
return
|
||||
}
|
||||
|
||||
getSurfaceManagerForViewEnforced(reactTag).updateProps(reactTag, props)
|
||||
getSurfaceManagerForViewEnforced(reactTag).storeSynchronousMountPropsOverride(reactTag, props)
|
||||
}
|
||||
|
||||
@UiThread
|
||||
fun updatePropsSynchronously(reactTag: Int, props: ReadableMap?) {
|
||||
assertOnUiThread()
|
||||
if (props == null) {
|
||||
return
|
||||
}
|
||||
|
||||
getSurfaceManagerForViewEnforced(reactTag).updatePropsSynchronously(reactTag, props)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+115
-1
@@ -27,10 +27,14 @@ import com.facebook.react.bridge.ReactNoCrashSoftException;
|
||||
import com.facebook.react.bridge.ReactSoftExceptionLogger;
|
||||
import com.facebook.react.bridge.ReadableArray;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.facebook.react.bridge.ReadableType;
|
||||
import com.facebook.react.bridge.RetryableMountingLayerException;
|
||||
import com.facebook.react.bridge.SoftAssertions;
|
||||
import com.facebook.react.bridge.UiThreadUtil;
|
||||
import com.facebook.react.bridge.WritableArray;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
import com.facebook.react.bridge.WritableNativeArray;
|
||||
import com.facebook.react.bridge.WritableNativeMap;
|
||||
import com.facebook.react.common.annotations.UnstableReactNativeAPI;
|
||||
import com.facebook.react.common.build.ReactBuildConfig;
|
||||
import com.facebook.react.common.mapbuffer.MapBuffer;
|
||||
@@ -53,7 +57,10 @@ import com.facebook.react.uimanager.ViewManagerRegistry;
|
||||
import com.facebook.react.uimanager.events.EventCategoryDef;
|
||||
import com.facebook.systrace.Systrace;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
import java.util.Queue;
|
||||
@@ -96,6 +103,11 @@ public class SurfaceMountingManager {
|
||||
// This is null *until* StopSurface is called.
|
||||
private SparseArrayCompat<Object> mTagSetForStoppedSurface;
|
||||
|
||||
// This is to make sure direct manipulation result will not be overridden by React update.
|
||||
@ThreadConfined(UI)
|
||||
private final SparseArrayCompat<Map<String, Object>> mTagToSynchronousMountProps =
|
||||
new SparseArrayCompat<>();
|
||||
|
||||
private final int mSurfaceId;
|
||||
|
||||
public SurfaceMountingManager(
|
||||
@@ -682,13 +694,110 @@ public class SurfaceMountingManager {
|
||||
}
|
||||
}
|
||||
|
||||
private static void overridePropsReadableMap(
|
||||
Map<String, Object> patchMap, WritableMap outputReadableMap) {
|
||||
for (Map.Entry<String, Object> entry : patchMap.entrySet()) {
|
||||
String propKey = entry.getKey();
|
||||
if (outputReadableMap.hasKey(propKey)) {
|
||||
Object propValue = entry.getValue();
|
||||
if (propKey.equals("transform")) {
|
||||
assert (outputReadableMap.getType(propKey) == ReadableType.Array
|
||||
&& propValue instanceof ArrayList);
|
||||
WritableArray array = new WritableNativeArray();
|
||||
for (Object item : (ArrayList<?>) propValue) {
|
||||
if (item instanceof HashMap) {
|
||||
WritableNativeMap itemMap = new WritableNativeMap();
|
||||
for (Map.Entry<String, Object> itemEntry :
|
||||
((HashMap<String, Object>) item).entrySet()) {
|
||||
if (itemEntry.getValue() instanceof String) {
|
||||
itemMap.putString(itemEntry.getKey(), (String) itemEntry.getValue());
|
||||
} else if (itemEntry.getValue() instanceof Number) {
|
||||
itemMap.putDouble(
|
||||
itemEntry.getKey(), ((Number) itemEntry.getValue()).doubleValue());
|
||||
}
|
||||
}
|
||||
array.pushMap(itemMap);
|
||||
}
|
||||
}
|
||||
outputReadableMap.putArray(propKey, array);
|
||||
} else if (propKey.equals("opacity")) {
|
||||
assert (outputReadableMap.getType(propKey) == ReadableType.Number
|
||||
&& propValue instanceof Number);
|
||||
outputReadableMap.putDouble(propKey, ((Number) propValue).doubleValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Map<String, Object> getHashMapFromPropsReadableMap(ReadableMap readableMap) {
|
||||
HashMap<String, Object> outputMap = new HashMap<>();
|
||||
|
||||
Iterator<Map.Entry<String, Object>> iter = readableMap.getEntryIterator();
|
||||
while (iter.hasNext()) {
|
||||
Map.Entry<String, Object> entry = iter.next();
|
||||
String propKey = entry.getKey();
|
||||
Object propValue = entry.getValue();
|
||||
if (propKey.equals("transform") && propValue instanceof ReadableArray) {
|
||||
ArrayList<HashMap<String, Object>> arrayList = new ArrayList<>();
|
||||
for (int i = 0; i < ((ReadableArray) propValue).size(); i++) {
|
||||
ReadableMap map = ((ReadableArray) propValue).getMap(i);
|
||||
if (map != null) {
|
||||
arrayList.add(map.toHashMap());
|
||||
}
|
||||
}
|
||||
outputMap.put(propKey, arrayList);
|
||||
} else if (propKey.equals("opacity") && propValue instanceof Number) {
|
||||
outputMap.put(propKey, ((Number) propValue).doubleValue());
|
||||
}
|
||||
}
|
||||
|
||||
return outputMap;
|
||||
}
|
||||
|
||||
public void storeSynchronousMountPropsOverride(int reactTag, ReadableMap props) {
|
||||
if (ReactNativeFeatureFlags.overrideBySynchronousMountPropsAtMountingAndroid()) {
|
||||
Map<String, Object> propsMap = getHashMapFromPropsReadableMap(props);
|
||||
if (mTagToSynchronousMountProps.containsKey(reactTag)) {
|
||||
Map<String, Object> mergedPropsMap =
|
||||
Assertions.assertNotNull(mTagToSynchronousMountProps.get(reactTag));
|
||||
mergedPropsMap.putAll(propsMap);
|
||||
mTagToSynchronousMountProps.put(reactTag, mergedPropsMap);
|
||||
} else {
|
||||
mTagToSynchronousMountProps.put(reactTag, propsMap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void updatePropsSynchronously(int reactTag, ReadableMap props) {
|
||||
updateProps(reactTag, props, true);
|
||||
}
|
||||
|
||||
public void updateProps(int reactTag, ReadableMap props) {
|
||||
updateProps(reactTag, props, false);
|
||||
}
|
||||
|
||||
@UiThread
|
||||
private void updateProps(
|
||||
int reactTag, ReadableMap props, Boolean shouldSkipSynchronousMountPropsOverride) {
|
||||
if (isStopped()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ViewState viewState = getViewState(reactTag);
|
||||
viewState.mCurrentProps = new ReactStylesDiffMap(props);
|
||||
|
||||
if (ReactNativeFeatureFlags.overrideBySynchronousMountPropsAtMountingAndroid()
|
||||
&& !shouldSkipSynchronousMountPropsOverride
|
||||
&& mTagToSynchronousMountProps.containsKey(reactTag)) {
|
||||
WritableMap modifiedProps = new WritableNativeMap();
|
||||
modifiedProps.merge(props);
|
||||
Map<String, Object> directPropsMap =
|
||||
Assertions.assertNotNull(mTagToSynchronousMountProps.get(reactTag));
|
||||
overridePropsReadableMap(directPropsMap, modifiedProps);
|
||||
viewState.mCurrentProps = new ReactStylesDiffMap(modifiedProps);
|
||||
} else {
|
||||
viewState.mCurrentProps = new ReactStylesDiffMap(props);
|
||||
}
|
||||
|
||||
View view = viewState.mView;
|
||||
|
||||
if (view == null) {
|
||||
@@ -1057,6 +1166,11 @@ public class SurfaceMountingManager {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ReactNativeFeatureFlags.overrideBySynchronousMountPropsAtMountingAndroid()
|
||||
&& mTagToSynchronousMountProps.containsKey(reactTag)) {
|
||||
mTagToSynchronousMountProps.remove(reactTag);
|
||||
}
|
||||
|
||||
ViewState viewState = getNullableViewState(reactTag);
|
||||
|
||||
if (viewState == null) {
|
||||
|
||||
+19
-1
@@ -4,7 +4,7 @@
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @generated SignedSource<<92a6edded037a504fc1c2c8ae88deae1>>
|
||||
* @generated SignedSource<<af10f4eea240ae4a228de9bbc4b78b7e>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -90,6 +90,12 @@ public object ReactNativeFeatureFlags {
|
||||
@JvmStatic
|
||||
public fun enableAccumulatedUpdatesInRawPropsAndroid(): Boolean = accessor.enableAccumulatedUpdatesInRawPropsAndroid()
|
||||
|
||||
/**
|
||||
* Enables linear text rendering on Android wherever subpixel text rendering is enabled
|
||||
*/
|
||||
@JvmStatic
|
||||
public fun enableAndroidLinearText(): Boolean = accessor.enableAndroidLinearText()
|
||||
|
||||
/**
|
||||
* Enables various optimizations throughout the path of measuring text on Android.
|
||||
*/
|
||||
@@ -300,6 +306,12 @@ public object ReactNativeFeatureFlags {
|
||||
@JvmStatic
|
||||
public fun enableVirtualViewWindowFocusDetection(): Boolean = accessor.enableVirtualViewWindowFocusDetection()
|
||||
|
||||
/**
|
||||
* Enable Web Performance APIs (Performance Timeline, User Timings, etc.) by default.
|
||||
*/
|
||||
@JvmStatic
|
||||
public fun enableWebPerformanceAPIsByDefault(): Boolean = accessor.enableWebPerformanceAPIsByDefault()
|
||||
|
||||
/**
|
||||
* Uses the default event priority instead of the discreet event priority by default when dispatching events from Fabric to React.
|
||||
*/
|
||||
@@ -324,6 +336,12 @@ public object ReactNativeFeatureFlags {
|
||||
@JvmStatic
|
||||
public fun hideOffscreenVirtualViewsOnIOS(): Boolean = accessor.hideOffscreenVirtualViewsOnIOS()
|
||||
|
||||
/**
|
||||
* Override props at mounting with synchronously mounted (i.e. direct manipulation) props from Native Animated.
|
||||
*/
|
||||
@JvmStatic
|
||||
public fun overrideBySynchronousMountPropsAtMountingAndroid(): Boolean = accessor.overrideBySynchronousMountPropsAtMountingAndroid()
|
||||
|
||||
/**
|
||||
* Enable the V2 in-app Performance Monitor. This flag is global and should not be changed across React Host lifetimes.
|
||||
*/
|
||||
|
||||
+31
-1
@@ -4,7 +4,7 @@
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @generated SignedSource<<ebbc6602fc8e3fb4c510bbd47361a7f0>>
|
||||
* @generated SignedSource<<0b5ee4e7d8800ea89c97b2501d121b6e>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -30,6 +30,7 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces
|
||||
private var disableTextLayoutManagerCacheAndroidCache: Boolean? = null
|
||||
private var enableAccessibilityOrderCache: Boolean? = null
|
||||
private var enableAccumulatedUpdatesInRawPropsAndroidCache: Boolean? = null
|
||||
private var enableAndroidLinearTextCache: Boolean? = null
|
||||
private var enableAndroidTextMeasurementOptimizationsCache: Boolean? = null
|
||||
private var enableBridgelessArchitectureCache: Boolean? = null
|
||||
private var enableCppPropsIteratorSetterCache: Boolean? = null
|
||||
@@ -65,10 +66,12 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces
|
||||
private var enableVirtualViewDebugFeaturesCache: Boolean? = null
|
||||
private var enableVirtualViewRenderStateCache: Boolean? = null
|
||||
private var enableVirtualViewWindowFocusDetectionCache: Boolean? = null
|
||||
private var enableWebPerformanceAPIsByDefaultCache: Boolean? = null
|
||||
private var fixMappingOfEventPrioritiesBetweenFabricAndReactCache: Boolean? = null
|
||||
private var fuseboxEnabledReleaseCache: Boolean? = null
|
||||
private var fuseboxNetworkInspectionEnabledCache: Boolean? = null
|
||||
private var hideOffscreenVirtualViewsOnIOSCache: Boolean? = null
|
||||
private var overrideBySynchronousMountPropsAtMountingAndroidCache: Boolean? = null
|
||||
private var perfMonitorV2EnabledCache: Boolean? = null
|
||||
private var preparedTextCacheSizeCache: Double? = null
|
||||
private var preventShadowTreeCommitExhaustionCache: Boolean? = null
|
||||
@@ -180,6 +183,15 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces
|
||||
return cached
|
||||
}
|
||||
|
||||
override fun enableAndroidLinearText(): Boolean {
|
||||
var cached = enableAndroidLinearTextCache
|
||||
if (cached == null) {
|
||||
cached = ReactNativeFeatureFlagsCxxInterop.enableAndroidLinearText()
|
||||
enableAndroidLinearTextCache = cached
|
||||
}
|
||||
return cached
|
||||
}
|
||||
|
||||
override fun enableAndroidTextMeasurementOptimizations(): Boolean {
|
||||
var cached = enableAndroidTextMeasurementOptimizationsCache
|
||||
if (cached == null) {
|
||||
@@ -495,6 +507,15 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces
|
||||
return cached
|
||||
}
|
||||
|
||||
override fun enableWebPerformanceAPIsByDefault(): Boolean {
|
||||
var cached = enableWebPerformanceAPIsByDefaultCache
|
||||
if (cached == null) {
|
||||
cached = ReactNativeFeatureFlagsCxxInterop.enableWebPerformanceAPIsByDefault()
|
||||
enableWebPerformanceAPIsByDefaultCache = cached
|
||||
}
|
||||
return cached
|
||||
}
|
||||
|
||||
override fun fixMappingOfEventPrioritiesBetweenFabricAndReact(): Boolean {
|
||||
var cached = fixMappingOfEventPrioritiesBetweenFabricAndReactCache
|
||||
if (cached == null) {
|
||||
@@ -531,6 +552,15 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces
|
||||
return cached
|
||||
}
|
||||
|
||||
override fun overrideBySynchronousMountPropsAtMountingAndroid(): Boolean {
|
||||
var cached = overrideBySynchronousMountPropsAtMountingAndroidCache
|
||||
if (cached == null) {
|
||||
cached = ReactNativeFeatureFlagsCxxInterop.overrideBySynchronousMountPropsAtMountingAndroid()
|
||||
overrideBySynchronousMountPropsAtMountingAndroidCache = cached
|
||||
}
|
||||
return cached
|
||||
}
|
||||
|
||||
override fun perfMonitorV2Enabled(): Boolean {
|
||||
var cached = perfMonitorV2EnabledCache
|
||||
if (cached == null) {
|
||||
|
||||
+7
-1
@@ -4,7 +4,7 @@
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @generated SignedSource<<4410628511f112f3eef22434a05fa757>>
|
||||
* @generated SignedSource<<5fbbabfffca4f13066ad1ab7f9462c13>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -48,6 +48,8 @@ public object ReactNativeFeatureFlagsCxxInterop {
|
||||
|
||||
@DoNotStrip @JvmStatic public external fun enableAccumulatedUpdatesInRawPropsAndroid(): Boolean
|
||||
|
||||
@DoNotStrip @JvmStatic public external fun enableAndroidLinearText(): Boolean
|
||||
|
||||
@DoNotStrip @JvmStatic public external fun enableAndroidTextMeasurementOptimizations(): Boolean
|
||||
|
||||
@DoNotStrip @JvmStatic public external fun enableBridgelessArchitecture(): Boolean
|
||||
@@ -118,6 +120,8 @@ public object ReactNativeFeatureFlagsCxxInterop {
|
||||
|
||||
@DoNotStrip @JvmStatic public external fun enableVirtualViewWindowFocusDetection(): Boolean
|
||||
|
||||
@DoNotStrip @JvmStatic public external fun enableWebPerformanceAPIsByDefault(): Boolean
|
||||
|
||||
@DoNotStrip @JvmStatic public external fun fixMappingOfEventPrioritiesBetweenFabricAndReact(): Boolean
|
||||
|
||||
@DoNotStrip @JvmStatic public external fun fuseboxEnabledRelease(): Boolean
|
||||
@@ -126,6 +130,8 @@ public object ReactNativeFeatureFlagsCxxInterop {
|
||||
|
||||
@DoNotStrip @JvmStatic public external fun hideOffscreenVirtualViewsOnIOS(): Boolean
|
||||
|
||||
@DoNotStrip @JvmStatic public external fun overrideBySynchronousMountPropsAtMountingAndroid(): Boolean
|
||||
|
||||
@DoNotStrip @JvmStatic public external fun perfMonitorV2Enabled(): Boolean
|
||||
|
||||
@DoNotStrip @JvmStatic public external fun preparedTextCacheSize(): Double
|
||||
|
||||
+7
-1
@@ -4,7 +4,7 @@
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @generated SignedSource<<411732d441bacbef37c3474b9041202c>>
|
||||
* @generated SignedSource<<bcad5baef5d072b71afba69bffabdb41>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -43,6 +43,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi
|
||||
|
||||
override fun enableAccumulatedUpdatesInRawPropsAndroid(): Boolean = false
|
||||
|
||||
override fun enableAndroidLinearText(): Boolean = false
|
||||
|
||||
override fun enableAndroidTextMeasurementOptimizations(): Boolean = false
|
||||
|
||||
override fun enableBridgelessArchitecture(): Boolean = false
|
||||
@@ -113,6 +115,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi
|
||||
|
||||
override fun enableVirtualViewWindowFocusDetection(): Boolean = false
|
||||
|
||||
override fun enableWebPerformanceAPIsByDefault(): Boolean = false
|
||||
|
||||
override fun fixMappingOfEventPrioritiesBetweenFabricAndReact(): Boolean = false
|
||||
|
||||
override fun fuseboxEnabledRelease(): Boolean = false
|
||||
@@ -121,6 +125,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi
|
||||
|
||||
override fun hideOffscreenVirtualViewsOnIOS(): Boolean = false
|
||||
|
||||
override fun overrideBySynchronousMountPropsAtMountingAndroid(): Boolean = false
|
||||
|
||||
override fun perfMonitorV2Enabled(): Boolean = false
|
||||
|
||||
override fun preparedTextCacheSize(): Double = 200.0
|
||||
|
||||
+34
-1
@@ -4,7 +4,7 @@
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @generated SignedSource<<2f65e0e9066a8c2c35c44ea7c73dbedc>>
|
||||
* @generated SignedSource<<0733f7a2ea498a0230bcfaa5b15a0b89>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -34,6 +34,7 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
|
||||
private var disableTextLayoutManagerCacheAndroidCache: Boolean? = null
|
||||
private var enableAccessibilityOrderCache: Boolean? = null
|
||||
private var enableAccumulatedUpdatesInRawPropsAndroidCache: Boolean? = null
|
||||
private var enableAndroidLinearTextCache: Boolean? = null
|
||||
private var enableAndroidTextMeasurementOptimizationsCache: Boolean? = null
|
||||
private var enableBridgelessArchitectureCache: Boolean? = null
|
||||
private var enableCppPropsIteratorSetterCache: Boolean? = null
|
||||
@@ -69,10 +70,12 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
|
||||
private var enableVirtualViewDebugFeaturesCache: Boolean? = null
|
||||
private var enableVirtualViewRenderStateCache: Boolean? = null
|
||||
private var enableVirtualViewWindowFocusDetectionCache: Boolean? = null
|
||||
private var enableWebPerformanceAPIsByDefaultCache: Boolean? = null
|
||||
private var fixMappingOfEventPrioritiesBetweenFabricAndReactCache: Boolean? = null
|
||||
private var fuseboxEnabledReleaseCache: Boolean? = null
|
||||
private var fuseboxNetworkInspectionEnabledCache: Boolean? = null
|
||||
private var hideOffscreenVirtualViewsOnIOSCache: Boolean? = null
|
||||
private var overrideBySynchronousMountPropsAtMountingAndroidCache: Boolean? = null
|
||||
private var perfMonitorV2EnabledCache: Boolean? = null
|
||||
private var preparedTextCacheSizeCache: Double? = null
|
||||
private var preventShadowTreeCommitExhaustionCache: Boolean? = null
|
||||
@@ -194,6 +197,16 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
|
||||
return cached
|
||||
}
|
||||
|
||||
override fun enableAndroidLinearText(): Boolean {
|
||||
var cached = enableAndroidLinearTextCache
|
||||
if (cached == null) {
|
||||
cached = currentProvider.enableAndroidLinearText()
|
||||
accessedFeatureFlags.add("enableAndroidLinearText")
|
||||
enableAndroidLinearTextCache = cached
|
||||
}
|
||||
return cached
|
||||
}
|
||||
|
||||
override fun enableAndroidTextMeasurementOptimizations(): Boolean {
|
||||
var cached = enableAndroidTextMeasurementOptimizationsCache
|
||||
if (cached == null) {
|
||||
@@ -544,6 +557,16 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
|
||||
return cached
|
||||
}
|
||||
|
||||
override fun enableWebPerformanceAPIsByDefault(): Boolean {
|
||||
var cached = enableWebPerformanceAPIsByDefaultCache
|
||||
if (cached == null) {
|
||||
cached = currentProvider.enableWebPerformanceAPIsByDefault()
|
||||
accessedFeatureFlags.add("enableWebPerformanceAPIsByDefault")
|
||||
enableWebPerformanceAPIsByDefaultCache = cached
|
||||
}
|
||||
return cached
|
||||
}
|
||||
|
||||
override fun fixMappingOfEventPrioritiesBetweenFabricAndReact(): Boolean {
|
||||
var cached = fixMappingOfEventPrioritiesBetweenFabricAndReactCache
|
||||
if (cached == null) {
|
||||
@@ -584,6 +607,16 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
|
||||
return cached
|
||||
}
|
||||
|
||||
override fun overrideBySynchronousMountPropsAtMountingAndroid(): Boolean {
|
||||
var cached = overrideBySynchronousMountPropsAtMountingAndroidCache
|
||||
if (cached == null) {
|
||||
cached = currentProvider.overrideBySynchronousMountPropsAtMountingAndroid()
|
||||
accessedFeatureFlags.add("overrideBySynchronousMountPropsAtMountingAndroid")
|
||||
overrideBySynchronousMountPropsAtMountingAndroidCache = cached
|
||||
}
|
||||
return cached
|
||||
}
|
||||
|
||||
override fun perfMonitorV2Enabled(): Boolean {
|
||||
var cached = perfMonitorV2EnabledCache
|
||||
if (cached == null) {
|
||||
|
||||
+3
-1
@@ -4,7 +4,7 @@
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @generated SignedSource<<f82b5905d822f8009c054a9443f86e39>>
|
||||
* @generated SignedSource<<4464982256b8ce543d9235fccbf67054>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -27,6 +27,8 @@ public open class ReactNativeFeatureFlagsOverrides_RNOSS_Canary_Android : ReactN
|
||||
|
||||
override fun enableFabricRenderer(): Boolean = true
|
||||
|
||||
override fun enableWebPerformanceAPIsByDefault(): Boolean = true
|
||||
|
||||
override fun useNativeViewConfigsInBridgelessMode(): Boolean = true
|
||||
|
||||
override fun useTurboModuleInterop(): Boolean = true
|
||||
|
||||
+7
-1
@@ -4,7 +4,7 @@
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @generated SignedSource<<e97601660cfd4f614ac934ba20ca4635>>
|
||||
* @generated SignedSource<<a51d970a5ea4e74b7871cc9521f9edce>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -43,6 +43,8 @@ public interface ReactNativeFeatureFlagsProvider {
|
||||
|
||||
@DoNotStrip public fun enableAccumulatedUpdatesInRawPropsAndroid(): Boolean
|
||||
|
||||
@DoNotStrip public fun enableAndroidLinearText(): Boolean
|
||||
|
||||
@DoNotStrip public fun enableAndroidTextMeasurementOptimizations(): Boolean
|
||||
|
||||
@DoNotStrip public fun enableBridgelessArchitecture(): Boolean
|
||||
@@ -113,6 +115,8 @@ public interface ReactNativeFeatureFlagsProvider {
|
||||
|
||||
@DoNotStrip public fun enableVirtualViewWindowFocusDetection(): Boolean
|
||||
|
||||
@DoNotStrip public fun enableWebPerformanceAPIsByDefault(): Boolean
|
||||
|
||||
@DoNotStrip public fun fixMappingOfEventPrioritiesBetweenFabricAndReact(): Boolean
|
||||
|
||||
@DoNotStrip public fun fuseboxEnabledRelease(): Boolean
|
||||
@@ -121,6 +125,8 @@ public interface ReactNativeFeatureFlagsProvider {
|
||||
|
||||
@DoNotStrip public fun hideOffscreenVirtualViewsOnIOS(): Boolean
|
||||
|
||||
@DoNotStrip public fun overrideBySynchronousMountPropsAtMountingAndroid(): Boolean
|
||||
|
||||
@DoNotStrip public fun perfMonitorV2Enabled(): Boolean
|
||||
|
||||
@DoNotStrip public fun preparedTextCacheSize(): Double
|
||||
|
||||
+2
-2
@@ -310,8 +310,8 @@ public open class JavaTimerManager(
|
||||
}
|
||||
}
|
||||
}
|
||||
timersToCall?.let {
|
||||
javaScriptTimerExecutor.callTimers(it)
|
||||
timersToCall?.let { timers ->
|
||||
javaScriptTimerExecutor.callTimers(timers)
|
||||
timersToCall = null
|
||||
}
|
||||
reactChoreographer.postFrameCallback(ReactChoreographer.CallbackType.TIMERS_EVENTS, this)
|
||||
|
||||
+1
-1
@@ -81,6 +81,6 @@ internal class ReactHostImplDevHelper(private val delegate: ReactHostImpl) :
|
||||
delegate.loadBundle(bundleLoader)
|
||||
|
||||
override fun getTracingState(): TracingState {
|
||||
return delegate.reactHostInspectorTarget?.tracingState() ?: TracingState.DISABLED
|
||||
return delegate.reactHostInspectorTarget?.getTracingState() ?: TracingState.ENABLEDINCDPMODE
|
||||
}
|
||||
}
|
||||
|
||||
+1
-13
@@ -43,7 +43,7 @@ internal class ReactHostInspectorTarget(reactHostImpl: ReactHostImpl) :
|
||||
|
||||
external fun tracingStateAsInt(): Int
|
||||
|
||||
fun tracingState(): TracingState {
|
||||
override fun getTracingState(): TracingState {
|
||||
return TracingState.entries[tracingStateAsInt()]
|
||||
}
|
||||
|
||||
@@ -65,18 +65,6 @@ internal class ReactHostInspectorTarget(reactHostImpl: ReactHostImpl) :
|
||||
}
|
||||
}
|
||||
|
||||
fun handleNativePerfMonitorMetricUpdate(
|
||||
longTaskDurationMs: Int,
|
||||
responsivenessScore: Int,
|
||||
ttl: Int,
|
||||
) {
|
||||
perfMonitorListeners.forEach { listener ->
|
||||
listener.onNewFocusedEvent(
|
||||
PerfMonitorUpdateListener.LongTaskEventData(longTaskDurationMs, responsivenessScore, ttl)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun close() {
|
||||
mHybridData.resetNative()
|
||||
}
|
||||
|
||||
+18
-2
@@ -245,7 +245,15 @@ public object ReactScrollViewHelper {
|
||||
@RequiresApi(Build.VERSION_CODES.N)
|
||||
@JvmStatic
|
||||
public fun removeScrollListener(listener: ScrollListener) {
|
||||
scrollListeners.removeIf { it.get() == null || it.get() == listener }
|
||||
// Avoid using removeIf, only available in API 26+
|
||||
val toRemove = ArrayList<WeakReference<ScrollListener>>()
|
||||
for (ref in scrollListeners) {
|
||||
val target = ref.get()
|
||||
if (target == null || target == listener) {
|
||||
toRemove.add(ref)
|
||||
}
|
||||
}
|
||||
scrollListeners.removeAll(toRemove)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@@ -256,7 +264,15 @@ public object ReactScrollViewHelper {
|
||||
@RequiresApi(Build.VERSION_CODES.N)
|
||||
@JvmStatic
|
||||
public fun removeLayoutChangeListener(listener: LayoutChangeListener) {
|
||||
layoutChangeListeners.removeIf { it.get() == null || it.get() == listener }
|
||||
// Avoid using removeIf, only available in API 26+
|
||||
val toRemove = ArrayList<WeakReference<LayoutChangeListener>>()
|
||||
for (ref in layoutChangeListeners) {
|
||||
val target = ref.get()
|
||||
if (target == null || target == listener) {
|
||||
toRemove.add(ref)
|
||||
}
|
||||
}
|
||||
layoutChangeListeners.removeAll(toRemove)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+4
@@ -14,6 +14,7 @@ import android.text.TextPaint
|
||||
import android.text.style.MetricAffectingSpan
|
||||
import com.facebook.react.common.ReactConstants
|
||||
import com.facebook.react.common.assets.ReactFontManager
|
||||
import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags
|
||||
import com.facebook.react.views.text.ReactTypefaceUtils
|
||||
|
||||
/**
|
||||
@@ -73,6 +74,9 @@ internal class CustomStyleSpan(
|
||||
fontFeatureSettings = fontFeatureSettingsParam
|
||||
setTypeface(typeface)
|
||||
isSubpixelText = true
|
||||
if (ReactNativeFeatureFlags.enableAndroidLinearText()) {
|
||||
isLinearText = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+16
-7
@@ -611,17 +611,26 @@ public open class ReactEditText public constructor(context: Context) : AppCompat
|
||||
|
||||
// Match behavior of CustomStyleSpan and enable SUBPIXEL_TEXT_FLAG when setting anything
|
||||
// nonstandard
|
||||
val enableSubpixelText =
|
||||
fontStyle != ReactConstants.UNSET ||
|
||||
fontWeight != ReactConstants.UNSET ||
|
||||
fontFamily != null ||
|
||||
fontFeatureSettings != null
|
||||
paintFlags =
|
||||
if (
|
||||
fontStyle != ReactConstants.UNSET ||
|
||||
fontWeight != ReactConstants.UNSET ||
|
||||
fontFamily != null ||
|
||||
fontFeatureSettings != null
|
||||
) {
|
||||
if (enableSubpixelText) {
|
||||
paintFlags or Paint.SUBPIXEL_TEXT_FLAG
|
||||
} else {
|
||||
paintFlags and (Paint.SUBPIXEL_TEXT_FLAG.inv())
|
||||
paintFlags and Paint.SUBPIXEL_TEXT_FLAG.inv()
|
||||
}
|
||||
|
||||
if (ReactNativeFeatureFlags.enableAndroidLinearText()) {
|
||||
paintFlags =
|
||||
if (enableSubpixelText) {
|
||||
paintFlags or Paint.LINEAR_TEXT_FLAG
|
||||
} else {
|
||||
paintFlags and Paint.LINEAR_TEXT_FLAG.inv()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public fun requestFocusFromJS() {
|
||||
|
||||
@@ -124,6 +124,8 @@ 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(react/nativemodule/webperformance)
|
||||
add_react_common_subdir(react/networking)
|
||||
add_react_common_subdir(jserrorhandler)
|
||||
add_react_common_subdir(react/runtime)
|
||||
add_react_common_subdir(react/runtime/hermes)
|
||||
@@ -190,6 +192,8 @@ add_library(reactnative
|
||||
$<TARGET_OBJECTS:react_nativemodule_featureflags>
|
||||
$<TARGET_OBJECTS:react_nativemodule_idlecallbacks>
|
||||
$<TARGET_OBJECTS:react_nativemodule_microtasks>
|
||||
$<TARGET_OBJECTS:react_nativemodule_webperformance>
|
||||
$<TARGET_OBJECTS:react_networking>
|
||||
$<TARGET_OBJECTS:react_newarchdefaults>
|
||||
$<TARGET_OBJECTS:react_performance_cdpmetrics>
|
||||
$<TARGET_OBJECTS:react_performance_timeline>
|
||||
@@ -279,6 +283,8 @@ target_include_directories(reactnative
|
||||
$<TARGET_PROPERTY:react_nativemodule_featureflags,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
$<TARGET_PROPERTY:react_nativemodule_idlecallbacks,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
$<TARGET_PROPERTY:react_nativemodule_microtasks,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
$<TARGET_PROPERTY:react_nativemodule_webperformance,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
$<TARGET_PROPERTY:react_networking,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
$<TARGET_PROPERTY:react_newarchdefaults,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
$<TARGET_PROPERTY:react_performance_cdpmetrics,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
$<TARGET_PROPERTY:react_performance_timeline,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
|
||||
@@ -20,6 +20,6 @@ target_include_directories(react_devsupportjni PUBLIC .)
|
||||
target_link_libraries(react_devsupportjni
|
||||
fbjni
|
||||
jsinspector
|
||||
jsinspector_network)
|
||||
react_networking)
|
||||
|
||||
target_compile_reactnative_options(react_devsupportjni PRIVATE)
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@
|
||||
|
||||
#include "JInspectorNetworkReporter.h"
|
||||
|
||||
#include <jsinspector-modern/network/NetworkReporter.h>
|
||||
#include <react/networking/NetworkReporter.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
|
||||
+43
-1
@@ -4,7 +4,7 @@
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @generated SignedSource<<f9c4f8d97edff1b016873b0a6121b76b>>
|
||||
* @generated SignedSource<<b3357ac501bc00f026a3a7ed90c83ba3>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -99,6 +99,12 @@ class ReactNativeFeatureFlagsJavaProvider
|
||||
return method(javaProvider_);
|
||||
}
|
||||
|
||||
bool enableAndroidLinearText() override {
|
||||
static const auto method =
|
||||
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("enableAndroidLinearText");
|
||||
return method(javaProvider_);
|
||||
}
|
||||
|
||||
bool enableAndroidTextMeasurementOptimizations() override {
|
||||
static const auto method =
|
||||
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("enableAndroidTextMeasurementOptimizations");
|
||||
@@ -309,6 +315,12 @@ class ReactNativeFeatureFlagsJavaProvider
|
||||
return method(javaProvider_);
|
||||
}
|
||||
|
||||
bool enableWebPerformanceAPIsByDefault() override {
|
||||
static const auto method =
|
||||
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("enableWebPerformanceAPIsByDefault");
|
||||
return method(javaProvider_);
|
||||
}
|
||||
|
||||
bool fixMappingOfEventPrioritiesBetweenFabricAndReact() override {
|
||||
static const auto method =
|
||||
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("fixMappingOfEventPrioritiesBetweenFabricAndReact");
|
||||
@@ -333,6 +345,12 @@ class ReactNativeFeatureFlagsJavaProvider
|
||||
return method(javaProvider_);
|
||||
}
|
||||
|
||||
bool overrideBySynchronousMountPropsAtMountingAndroid() override {
|
||||
static const auto method =
|
||||
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("overrideBySynchronousMountPropsAtMountingAndroid");
|
||||
return method(javaProvider_);
|
||||
}
|
||||
|
||||
bool perfMonitorV2Enabled() override {
|
||||
static const auto method =
|
||||
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("perfMonitorV2Enabled");
|
||||
@@ -507,6 +525,11 @@ bool JReactNativeFeatureFlagsCxxInterop::enableAccumulatedUpdatesInRawPropsAndro
|
||||
return ReactNativeFeatureFlags::enableAccumulatedUpdatesInRawPropsAndroid();
|
||||
}
|
||||
|
||||
bool JReactNativeFeatureFlagsCxxInterop::enableAndroidLinearText(
|
||||
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
|
||||
return ReactNativeFeatureFlags::enableAndroidLinearText();
|
||||
}
|
||||
|
||||
bool JReactNativeFeatureFlagsCxxInterop::enableAndroidTextMeasurementOptimizations(
|
||||
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
|
||||
return ReactNativeFeatureFlags::enableAndroidTextMeasurementOptimizations();
|
||||
@@ -682,6 +705,11 @@ bool JReactNativeFeatureFlagsCxxInterop::enableVirtualViewWindowFocusDetection(
|
||||
return ReactNativeFeatureFlags::enableVirtualViewWindowFocusDetection();
|
||||
}
|
||||
|
||||
bool JReactNativeFeatureFlagsCxxInterop::enableWebPerformanceAPIsByDefault(
|
||||
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
|
||||
return ReactNativeFeatureFlags::enableWebPerformanceAPIsByDefault();
|
||||
}
|
||||
|
||||
bool JReactNativeFeatureFlagsCxxInterop::fixMappingOfEventPrioritiesBetweenFabricAndReact(
|
||||
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
|
||||
return ReactNativeFeatureFlags::fixMappingOfEventPrioritiesBetweenFabricAndReact();
|
||||
@@ -702,6 +730,11 @@ bool JReactNativeFeatureFlagsCxxInterop::hideOffscreenVirtualViewsOnIOS(
|
||||
return ReactNativeFeatureFlags::hideOffscreenVirtualViewsOnIOS();
|
||||
}
|
||||
|
||||
bool JReactNativeFeatureFlagsCxxInterop::overrideBySynchronousMountPropsAtMountingAndroid(
|
||||
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
|
||||
return ReactNativeFeatureFlags::overrideBySynchronousMountPropsAtMountingAndroid();
|
||||
}
|
||||
|
||||
bool JReactNativeFeatureFlagsCxxInterop::perfMonitorV2Enabled(
|
||||
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
|
||||
return ReactNativeFeatureFlags::perfMonitorV2Enabled();
|
||||
@@ -863,6 +896,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() {
|
||||
makeNativeMethod(
|
||||
"enableAccumulatedUpdatesInRawPropsAndroid",
|
||||
JReactNativeFeatureFlagsCxxInterop::enableAccumulatedUpdatesInRawPropsAndroid),
|
||||
makeNativeMethod(
|
||||
"enableAndroidLinearText",
|
||||
JReactNativeFeatureFlagsCxxInterop::enableAndroidLinearText),
|
||||
makeNativeMethod(
|
||||
"enableAndroidTextMeasurementOptimizations",
|
||||
JReactNativeFeatureFlagsCxxInterop::enableAndroidTextMeasurementOptimizations),
|
||||
@@ -968,6 +1004,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() {
|
||||
makeNativeMethod(
|
||||
"enableVirtualViewWindowFocusDetection",
|
||||
JReactNativeFeatureFlagsCxxInterop::enableVirtualViewWindowFocusDetection),
|
||||
makeNativeMethod(
|
||||
"enableWebPerformanceAPIsByDefault",
|
||||
JReactNativeFeatureFlagsCxxInterop::enableWebPerformanceAPIsByDefault),
|
||||
makeNativeMethod(
|
||||
"fixMappingOfEventPrioritiesBetweenFabricAndReact",
|
||||
JReactNativeFeatureFlagsCxxInterop::fixMappingOfEventPrioritiesBetweenFabricAndReact),
|
||||
@@ -980,6 +1019,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() {
|
||||
makeNativeMethod(
|
||||
"hideOffscreenVirtualViewsOnIOS",
|
||||
JReactNativeFeatureFlagsCxxInterop::hideOffscreenVirtualViewsOnIOS),
|
||||
makeNativeMethod(
|
||||
"overrideBySynchronousMountPropsAtMountingAndroid",
|
||||
JReactNativeFeatureFlagsCxxInterop::overrideBySynchronousMountPropsAtMountingAndroid),
|
||||
makeNativeMethod(
|
||||
"perfMonitorV2Enabled",
|
||||
JReactNativeFeatureFlagsCxxInterop::perfMonitorV2Enabled),
|
||||
|
||||
+10
-1
@@ -4,7 +4,7 @@
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @generated SignedSource<<6a98f8398948f8d56e51d3eff19c5d05>>
|
||||
* @generated SignedSource<<2c969005f4c7bb24f98bf4e3ed3dc0e9>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -60,6 +60,9 @@ class JReactNativeFeatureFlagsCxxInterop
|
||||
static bool enableAccumulatedUpdatesInRawPropsAndroid(
|
||||
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
||||
|
||||
static bool enableAndroidLinearText(
|
||||
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
||||
|
||||
static bool enableAndroidTextMeasurementOptimizations(
|
||||
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
||||
|
||||
@@ -165,6 +168,9 @@ class JReactNativeFeatureFlagsCxxInterop
|
||||
static bool enableVirtualViewWindowFocusDetection(
|
||||
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
||||
|
||||
static bool enableWebPerformanceAPIsByDefault(
|
||||
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
||||
|
||||
static bool fixMappingOfEventPrioritiesBetweenFabricAndReact(
|
||||
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
||||
|
||||
@@ -177,6 +183,9 @@ class JReactNativeFeatureFlagsCxxInterop
|
||||
static bool hideOffscreenVirtualViewsOnIOS(
|
||||
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
||||
|
||||
static bool overrideBySynchronousMountPropsAtMountingAndroid(
|
||||
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
||||
|
||||
static bool perfMonitorV2Enabled(
|
||||
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
||||
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ target_compile_reactnative_options(hermes_executor PRIVATE)
|
||||
if(${CMAKE_BUILD_TYPE} MATCHES Debug OR REACT_NATIVE_DEBUG_OPTIMIZED)
|
||||
target_compile_options(hermes_executor PRIVATE -DHERMES_ENABLE_DEBUGGER=1)
|
||||
|
||||
if (DEFINED HERMES_V1_ENABLED)
|
||||
if (HERMES_V1_ENABLED)
|
||||
target_compile_options(hermes_executor PRIVATE -DHERMES_V1_ENABLED=1)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@ target_compile_reactnative_options(hermesinstancejni PRIVATE)
|
||||
if(${CMAKE_BUILD_TYPE} MATCHES Debug OR REACT_NATIVE_DEBUG_OPTIMIZED)
|
||||
target_compile_options(hermesinstancejni PRIVATE -DHERMES_ENABLE_DEBUGGER=1)
|
||||
|
||||
if (DEFINED HERMES_V1_ENABLED)
|
||||
if (HERMES_V1_ENABLED)
|
||||
target_compile_options(hermesinstancejni PRIVATE -DHERMES_V1_ENABLED=1)
|
||||
endif()
|
||||
endif ()
|
||||
|
||||
@@ -20,7 +20,7 @@ target_compile_reactnative_options(rninstance PRIVATE)
|
||||
if(${CMAKE_BUILD_TYPE} MATCHES Debug OR REACT_NATIVE_DEBUG_OPTIMIZED)
|
||||
target_compile_options(rninstance PRIVATE -DHERMES_ENABLE_DEBUGGER=1)
|
||||
|
||||
if (DEFINED HERMES_V1_ENABLED)
|
||||
if (HERMES_V1_ENABLED)
|
||||
target_compile_options(rninstance PRIVATE -DHERMES_V1_ENABLED=1)
|
||||
endif()
|
||||
endif ()
|
||||
|
||||
-11
@@ -120,17 +120,6 @@ void JReactHostInspectorTarget::onSetPausedInDebuggerMessage(
|
||||
}
|
||||
}
|
||||
|
||||
void JReactHostInspectorTarget::unstable_onPerfMonitorUpdate(
|
||||
const PerfMonitorUpdateRequest& request) {
|
||||
static auto method = javaClassStatic()->getMethod<void(jint, jint, jint)>(
|
||||
"handleNativePerfMonitorMetricUpdate");
|
||||
method(
|
||||
jobj_,
|
||||
request.activeInteraction.duration,
|
||||
static_cast<jint>(request.activeInteraction.responsivenessScore),
|
||||
request.activeInteraction.ttl);
|
||||
}
|
||||
|
||||
void JReactHostInspectorTarget::loadNetworkResource(
|
||||
const jsinspector_modern::LoadNetworkResourceRequest& params,
|
||||
jsinspector_modern::ScopedExecutor<
|
||||
|
||||
-2
@@ -113,8 +113,6 @@ class JReactHostInspectorTarget
|
||||
void onReload(const PageReloadRequest& request) override;
|
||||
void onSetPausedInDebuggerMessage(
|
||||
const OverlaySetPausedInDebuggerMessageRequest& request) override;
|
||||
void unstable_onPerfMonitorUpdate(
|
||||
const jsinspector_modern::PerfMonitorUpdateRequest& request) override;
|
||||
void loadNetworkResource(
|
||||
const jsinspector_modern::LoadNetworkResourceRequest& params,
|
||||
jsinspector_modern::ScopedExecutor<
|
||||
|
||||
@@ -33,7 +33,7 @@ if(${CMAKE_BUILD_TYPE} MATCHES Debug OR REACT_NATIVE_DEBUG_OPTIMIZED)
|
||||
-DHERMES_ENABLE_DEBUGGER=1
|
||||
)
|
||||
|
||||
if (DEFINED HERMES_V1_ENABLED)
|
||||
if (HERMES_V1_ENABLED)
|
||||
target_compile_options(hermes_executor_common PRIVATE -DHERMES_V1_ENABLED=1)
|
||||
endif()
|
||||
else()
|
||||
|
||||
@@ -24,7 +24,7 @@ if(${CMAKE_BUILD_TYPE} MATCHES Debug OR REACT_NATIVE_DEBUG_OPTIMIZED)
|
||||
-DHERMES_ENABLE_DEBUGGER=1
|
||||
)
|
||||
|
||||
if (DEFINED HERMES_V1_ENABLED)
|
||||
if (HERMES_V1_ENABLED)
|
||||
target_compile_options(hermes_inspector_modern PRIVATE -DHERMES_V1_ENABLED=1)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -192,9 +192,6 @@ std::shared_ptr<HostTarget> HostTarget::create(
|
||||
VoidExecutor executor) {
|
||||
std::shared_ptr<HostTarget> hostTarget{new HostTarget(delegate)};
|
||||
hostTarget->setExecutor(std::move(executor));
|
||||
if (InspectorFlags::getInstance().getPerfMonitorV2Enabled()) {
|
||||
hostTarget->installPerfMetricsBinding();
|
||||
}
|
||||
return hostTarget;
|
||||
}
|
||||
|
||||
@@ -279,17 +276,6 @@ void HostTarget::sendCommand(HostCommand command) {
|
||||
});
|
||||
}
|
||||
|
||||
void HostTarget::installPerfMetricsBinding() {
|
||||
perfMonitorUpdateHandler_ =
|
||||
std::make_unique<PerfMonitorUpdateHandler>(delegate_);
|
||||
perfMetricsBinding_ = std::make_unique<HostRuntimeBinding>(
|
||||
*this, // Used immediately
|
||||
"__chromium_devtools_metrics_reporter",
|
||||
[this](const std::string& message) {
|
||||
perfMonitorUpdateHandler_->handlePerfMetricsUpdate(message);
|
||||
});
|
||||
}
|
||||
|
||||
HostTargetController::HostTargetController(HostTarget& target)
|
||||
: target_(target) {}
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
#include "InspectorInterfaces.h"
|
||||
#include "InstanceTarget.h"
|
||||
#include "NetworkIOAgent.h"
|
||||
#include "PerfMonitorV2.h"
|
||||
#include "ScopedExecutor.h"
|
||||
#include "WeakList.h"
|
||||
|
||||
@@ -128,13 +127,6 @@ class HostTargetDelegate : public LoadNetworkResourceDelegate {
|
||||
virtual void onSetPausedInDebuggerMessage(
|
||||
const OverlaySetPausedInDebuggerMessageRequest& request) = 0;
|
||||
|
||||
/**
|
||||
* [Experimental] Called when the runtime has new data for the V2 Perf
|
||||
* Monitor overlay. This is called on the inspector thread.
|
||||
*/
|
||||
virtual void unstable_onPerfMonitorUpdate(
|
||||
const PerfMonitorUpdateRequest& /*request*/) {}
|
||||
|
||||
/**
|
||||
* Called by NetworkIOAgent on handling a `Network.loadNetworkResource` CDP
|
||||
* request. Platform implementations should override this to perform a
|
||||
@@ -324,7 +316,6 @@ class JSINSPECTOR_EXPORT HostTarget
|
||||
std::shared_ptr<ExecutionContextManager> executionContextManager_;
|
||||
std::shared_ptr<InstanceTarget> currentInstance_{nullptr};
|
||||
std::unique_ptr<HostCommandSender> commandSender_;
|
||||
std::unique_ptr<PerfMonitorUpdateHandler> perfMonitorUpdateHandler_;
|
||||
std::unique_ptr<HostRuntimeBinding> perfMetricsBinding_;
|
||||
|
||||
/**
|
||||
@@ -343,13 +334,6 @@ class JSINSPECTOR_EXPORT HostTarget
|
||||
return currentInstance_ != nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Install a runtime binding subscribing to the Interaction to Next Paint
|
||||
* (INP) live metric, which we broadcast to the V2 Perf Monitor overlay
|
||||
* via \ref HostTargetDelegate::unstable_onPerfMonitorUpdate.
|
||||
*/
|
||||
void installPerfMetricsBinding();
|
||||
|
||||
// Necessary to allow HostAgent to access HostTarget's internals in a
|
||||
// controlled way (i.e. only HostTargetController gets friend access, while
|
||||
// HostAgent itself doesn't).
|
||||
|
||||
@@ -33,10 +33,6 @@ bool InspectorFlags::getNetworkInspectionEnabled() const {
|
||||
return loadFlagsAndAssertUnchanged().networkInspectionEnabled;
|
||||
}
|
||||
|
||||
bool InspectorFlags::getPerfMonitorV2Enabled() const {
|
||||
return loadFlagsAndAssertUnchanged().perfMonitorV2Enabled;
|
||||
}
|
||||
|
||||
void InspectorFlags::dangerouslyResetFlags() {
|
||||
*this = InspectorFlags{};
|
||||
}
|
||||
@@ -63,9 +59,6 @@ const InspectorFlags::Values& InspectorFlags::loadFlagsAndAssertUnchanged()
|
||||
.networkInspectionEnabled =
|
||||
ReactNativeFeatureFlags::enableBridgelessArchitecture() &&
|
||||
ReactNativeFeatureFlags::fuseboxNetworkInspectionEnabled(),
|
||||
.perfMonitorV2Enabled =
|
||||
ReactNativeFeatureFlags::enableBridgelessArchitecture() &&
|
||||
ReactNativeFeatureFlags::perfMonitorV2Enabled(),
|
||||
};
|
||||
|
||||
if (cachedValues_.has_value() && !inconsistentFlagsStateLogged_) {
|
||||
|
||||
@@ -35,11 +35,6 @@ class InspectorFlags {
|
||||
*/
|
||||
bool getNetworkInspectionEnabled() const;
|
||||
|
||||
/**
|
||||
* Flag determining if the V2 in-app Performance Monitor is enabled.
|
||||
*/
|
||||
bool getPerfMonitorV2Enabled() const;
|
||||
|
||||
/**
|
||||
* Forcibly disable the main `getFuseboxEnabled()` flag. This should ONLY be
|
||||
* used by `ReactInstanceIntegrationTest`.
|
||||
@@ -57,7 +52,6 @@ class InspectorFlags {
|
||||
bool fuseboxEnabled;
|
||||
bool isProfilingBuild;
|
||||
bool networkInspectionEnabled;
|
||||
bool perfMonitorV2Enabled;
|
||||
bool operator==(const Values&) const = default;
|
||||
};
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include "Base64.h"
|
||||
#include "Utf8.h"
|
||||
|
||||
#include <jsinspector-modern/network/NetworkReporter.h>
|
||||
#include <jsinspector-modern/network/NetworkHandler.h>
|
||||
|
||||
#include <sstream>
|
||||
#include <tuple>
|
||||
@@ -272,19 +272,19 @@ bool NetworkIOAgent::handleRequest(
|
||||
}
|
||||
|
||||
if (InspectorFlags::getInstance().getNetworkInspectionEnabled()) {
|
||||
auto& networkReporter = NetworkReporter::getInstance();
|
||||
auto& networkHandler = NetworkHandler::getInstance();
|
||||
|
||||
// @cdp Network.enable support is experimental.
|
||||
if (req.method == "Network.enable") {
|
||||
networkReporter.setFrontendChannel(frontendChannel_);
|
||||
networkReporter.enableDebugging();
|
||||
networkHandler.setFrontendChannel(frontendChannel_);
|
||||
networkHandler.enable();
|
||||
frontendChannel_(cdp::jsonResult(req.id));
|
||||
return true;
|
||||
}
|
||||
|
||||
// @cdp Network.disable support is experimental.
|
||||
if (req.method == "Network.disable") {
|
||||
networkReporter.disableDebugging();
|
||||
networkHandler.disable();
|
||||
frontendChannel_(cdp::jsonResult(req.id));
|
||||
return true;
|
||||
}
|
||||
@@ -497,9 +497,9 @@ void NetworkIOAgent::handleGetResponseBody(const cdp::PreparsedRequest& req) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto& networkReporter = NetworkReporter::getInstance();
|
||||
auto& networkHandler = NetworkHandler::getInstance();
|
||||
|
||||
if (!networkReporter.isDebuggingEnabled()) {
|
||||
if (!networkHandler.isEnabled()) {
|
||||
frontendChannel_(cdp::jsonError(
|
||||
requestId,
|
||||
cdp::ErrorCode::InvalidRequest,
|
||||
@@ -508,7 +508,7 @@ void NetworkIOAgent::handleGetResponseBody(const cdp::PreparsedRequest& req) {
|
||||
}
|
||||
|
||||
auto storedResponse =
|
||||
networkReporter.getResponseBody(req.params.at("requestId").asString());
|
||||
networkHandler.getResponseBody(req.params.at("requestId").asString());
|
||||
|
||||
if (!storedResponse) {
|
||||
frontendChannel_(cdp::jsonError(
|
||||
|
||||
@@ -1,91 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#include "PerfMonitorV2.h"
|
||||
#include "HostTarget.h"
|
||||
|
||||
#include <folly/json.h>
|
||||
#include <react/timing/primitives.h>
|
||||
|
||||
namespace facebook::react::jsinspector_modern {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr uint16_t MIN_DURATION = 200;
|
||||
constexpr uint16_t DEFAULT_TTL = 4000;
|
||||
constexpr uint16_t BAD_EVENT_TTL = 20000;
|
||||
|
||||
InteractionResponsivenessScore getInteractionScore(uint16_t duration) {
|
||||
constexpr uint16_t GOOD_THRESHOLD = 200;
|
||||
constexpr uint16_t NEEDS_IMPROVEMENT_THRESHOLD = 500;
|
||||
|
||||
if (duration < GOOD_THRESHOLD) {
|
||||
return InteractionResponsivenessScore::Good;
|
||||
} else if (duration < NEEDS_IMPROVEMENT_THRESHOLD) {
|
||||
return InteractionResponsivenessScore::NeedsImprovement;
|
||||
} else {
|
||||
return InteractionResponsivenessScore::Poor;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void PerfMonitorUpdateHandler::handlePerfMetricsUpdate(
|
||||
const std::string& message) {
|
||||
auto payload = folly::parseJson(message);
|
||||
|
||||
if (payload.isObject()) {
|
||||
if (payload["name"] != "__ReactNative__LongTask") {
|
||||
return;
|
||||
}
|
||||
|
||||
auto duration = static_cast<uint16_t>(payload["duration"].asInt());
|
||||
|
||||
if (duration < MIN_DURATION) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto responsivenessScore = getInteractionScore(duration);
|
||||
auto ttl = responsivenessScore == InteractionResponsivenessScore::Poor
|
||||
? BAD_EVENT_TTL
|
||||
: DEFAULT_TTL;
|
||||
|
||||
LongTaskPayload newEvent{
|
||||
static_cast<uint16_t>(payload["startTime"].asInt()),
|
||||
duration,
|
||||
responsivenessScore,
|
||||
ttl};
|
||||
|
||||
if (shouldOverrideLastEvent(newEvent)) {
|
||||
lastEvent_ = newEvent;
|
||||
delegate_.unstable_onPerfMonitorUpdate(
|
||||
PerfMonitorUpdateRequest{newEvent});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool PerfMonitorUpdateHandler::shouldOverrideLastEvent(
|
||||
const LongTaskPayload& newEvent) {
|
||||
if (!lastEvent_) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Override if last event has expired
|
||||
if (HighResTimeStamp::now().toDOMHighResTimeStamp() >
|
||||
lastEvent_->startTime + lastEvent_->ttl) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Override if same or greater responsiveness score
|
||||
if (newEvent.responsivenessScore >= lastEvent_->responsivenessScore) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace facebook::react::jsinspector_modern
|
||||
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
namespace facebook::react::jsinspector_modern {
|
||||
|
||||
class HostTargetDelegate;
|
||||
|
||||
/**
|
||||
* See https://web.dev/articles/inp#good-score.
|
||||
*/
|
||||
enum class InteractionResponsivenessScore : int32_t {
|
||||
Good = 0,
|
||||
NeedsImprovement = 1,
|
||||
Poor = 2
|
||||
};
|
||||
|
||||
struct LongTaskPayload {
|
||||
uint16_t startTime;
|
||||
uint16_t duration;
|
||||
InteractionResponsivenessScore responsivenessScore;
|
||||
uint16_t ttl;
|
||||
};
|
||||
|
||||
struct PerfMonitorUpdateRequest {
|
||||
LongTaskPayload activeInteraction;
|
||||
};
|
||||
|
||||
/**
|
||||
* [Experimental] Utility to handle performance metrics updates received from
|
||||
* the runtime and forward update events to the V2 Perf Monitor UI.
|
||||
*/
|
||||
class PerfMonitorUpdateHandler {
|
||||
public:
|
||||
explicit PerfMonitorUpdateHandler(HostTargetDelegate& delegate)
|
||||
: delegate_(delegate) {}
|
||||
|
||||
/**
|
||||
* Handle a new "__chromium_devtools_metrics_reporter" message.
|
||||
*/
|
||||
void handlePerfMetricsUpdate(const std::string& message);
|
||||
|
||||
private:
|
||||
HostTargetDelegate& delegate_;
|
||||
std::optional<LongTaskPayload> lastEvent_;
|
||||
|
||||
bool shouldOverrideLastEvent(const LongTaskPayload& newInteraction);
|
||||
};
|
||||
|
||||
} // namespace facebook::react::jsinspector_modern
|
||||
@@ -24,6 +24,4 @@ target_include_directories(jsinspector_network PUBLIC ${REACT_COMMON_DIR})
|
||||
target_link_libraries(jsinspector_network
|
||||
folly_runtime
|
||||
glog
|
||||
jsinspector_cdp
|
||||
react_performance_timeline
|
||||
react_timing)
|
||||
jsinspector_cdp)
|
||||
|
||||
@@ -27,15 +27,6 @@ folly::dynamic headersToDynamic(const std::optional<Headers>& headers) {
|
||||
|
||||
} // namespace
|
||||
|
||||
/* static */ Request Request::fromInputParams(const RequestInfo& requestInfo) {
|
||||
return {
|
||||
.url = requestInfo.url,
|
||||
.method = requestInfo.httpMethod,
|
||||
.headers = requestInfo.headers,
|
||||
.postData = requestInfo.httpBody,
|
||||
};
|
||||
}
|
||||
|
||||
folly::dynamic Request::toDynamic() const {
|
||||
folly::dynamic result = folly::dynamic::object;
|
||||
|
||||
@@ -48,16 +39,16 @@ folly::dynamic Request::toDynamic() const {
|
||||
}
|
||||
|
||||
/* static */ Response Response::fromInputParams(
|
||||
const ResponseInfo& responseInfo,
|
||||
const std::string& url,
|
||||
uint16_t status,
|
||||
const std::optional<Headers>& headers,
|
||||
int encodedDataLength) {
|
||||
auto headers = responseInfo.headers.value_or(Headers());
|
||||
|
||||
return {
|
||||
.url = responseInfo.url,
|
||||
.status = responseInfo.statusCode,
|
||||
.statusText = httpReasonPhrase(responseInfo.statusCode),
|
||||
.url = url,
|
||||
.status = status,
|
||||
.statusText = httpReasonPhrase(status),
|
||||
.headers = headers,
|
||||
.mimeType = mimeTypeFromHeaders(headers),
|
||||
.mimeType = mimeTypeFromHeaders(headers.value_or(Headers())),
|
||||
.encodedDataLength = encodedDataLength,
|
||||
};
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user