react-native-tvos 0.83.4-2 → 0.83.9-0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (153) hide show
  1. package/Libraries/Core/ReactNativeVersion.js +2 -2
  2. package/Libraries/Utilities/Appearance.js +6 -1
  3. package/Libraries/Utilities/HMRClient.js +28 -1
  4. package/React/Base/RCTVersion.m +2 -2
  5. package/React/CoreModules/RCTDevLoadingView.mm +17 -0
  6. package/React/CoreModules/RCTJscSafeUrl+Internal.h +23 -0
  7. package/React/CoreModules/RCTJscSafeUrl.mm +38 -0
  8. package/React/CoreModules/RCTRedBox+Internal.h +42 -0
  9. package/React/CoreModules/RCTRedBox.mm +30 -471
  10. package/React/CoreModules/RCTRedBox2AnsiParser+Internal.h +22 -0
  11. package/React/CoreModules/RCTRedBox2AnsiParser.mm +55 -0
  12. package/React/CoreModules/RCTRedBox2Controller+Internal.h +34 -0
  13. package/React/CoreModules/RCTRedBox2Controller.mm +764 -0
  14. package/React/CoreModules/RCTRedBox2ErrorParser+Internal.h +46 -0
  15. package/React/CoreModules/RCTRedBox2ErrorParser.mm +57 -0
  16. package/React/CoreModules/RCTRedBoxController+Internal.h +31 -0
  17. package/React/CoreModules/RCTRedBoxController.mm +447 -0
  18. package/React/CoreModules/RCTRedBoxHMRClient+Internal.h +26 -0
  19. package/React/CoreModules/RCTRedBoxHMRClient.mm +125 -0
  20. package/React/CoreModules/React-CoreModules.podspec +1 -0
  21. package/React/DevSupport/RCTFrameTimingsObserver.h +24 -0
  22. package/React/DevSupport/RCTFrameTimingsObserver.mm +298 -0
  23. package/React/FBReactNativeSpec/FBReactNativeSpecJSI.h +40 -0
  24. package/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm +1 -2
  25. package/ReactAndroid/api/ReactAndroid.api +0 -9
  26. package/ReactAndroid/gradle.properties +1 -1
  27. package/ReactAndroid/publish.gradle +20 -46
  28. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/BridgelessDevSupportManager.kt +2 -2
  29. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerBase.kt +7 -7
  30. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/InspectorFlags.kt +4 -0
  31. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/inspector/FrameTimingSequence.kt +16 -0
  32. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/inspector/FrameTimingsObserver.kt +275 -0
  33. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/inspector/TracingState.kt +17 -0
  34. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/inspector/TracingStateListener.kt +15 -0
  35. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/{interfaces → inspector}/TracingStateProvider.kt +1 -1
  36. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/perfmonitor/PerfMonitorInspectorTargetBinding.kt +1 -1
  37. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/perfmonitor/PerfMonitorOverlayManager.kt +4 -4
  38. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/perfmonitor/PerfMonitorOverlayView.kt +3 -3
  39. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/perfmonitor/PerfMonitorUpdateListener.kt +1 -1
  40. package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt +31 -1
  41. package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt +51 -1
  42. package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt +11 -1
  43. package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt +11 -1
  44. package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt +56 -1
  45. package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt +11 -1
  46. package/ReactAndroid/src/main/java/com/facebook/react/internal/tracing/PerformanceTracer.kt +39 -0
  47. package/ReactAndroid/src/main/java/com/facebook/react/modules/blob/BlobModule.kt +1 -1
  48. package/ReactAndroid/src/main/java/com/facebook/react/modules/network/NetworkEventUtil.kt +20 -19
  49. package/ReactAndroid/src/main/java/com/facebook/react/modules/network/NetworkingModule.kt +6 -12
  50. package/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/ReactNativeVersion.kt +2 -2
  51. package/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.kt +86 -4
  52. package/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImplDevHelper.kt +3 -3
  53. package/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostInspectorTarget.kt +10 -6
  54. package/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java +7 -6
  55. package/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java +21 -3
  56. package/ReactAndroid/src/main/jni/CMakeLists.txt +7 -0
  57. package/ReactAndroid/src/main/jni/react/devsupport/JInspectorFlags.cpp +22 -0
  58. package/ReactAndroid/src/main/jni/react/devsupport/JInspectorFlags.h +2 -0
  59. package/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp +71 -1
  60. package/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h +16 -1
  61. package/ReactAndroid/src/main/jni/react/runtime/jni/JReactHostInspectorTarget.cpp +196 -17
  62. package/ReactAndroid/src/main/jni/react/runtime/jni/JReactHostInspectorTarget.h +168 -18
  63. package/ReactAndroid/src/main/jni/third-party/folly/CMakeLists.txt +1 -0
  64. package/ReactCommon/React-Fabric.podspec +6 -0
  65. package/ReactCommon/cxxreact/ReactNativeVersion.h +3 -3
  66. package/ReactCommon/hermes/inspector-modern/chrome/Registration.cpp +44 -2
  67. package/ReactCommon/jsinspector-modern/HostAgent.cpp +45 -10
  68. package/ReactCommon/jsinspector-modern/HostAgent.h +2 -2
  69. package/ReactCommon/jsinspector-modern/HostTarget.cpp +14 -7
  70. package/ReactCommon/jsinspector-modern/HostTarget.h +101 -14
  71. package/ReactCommon/jsinspector-modern/HostTargetTraceRecording.cpp +39 -8
  72. package/ReactCommon/jsinspector-modern/HostTargetTraceRecording.h +42 -5
  73. package/ReactCommon/jsinspector-modern/HostTargetTracing.cpp +54 -21
  74. package/ReactCommon/jsinspector-modern/HostTargetTracing.h +89 -0
  75. package/ReactCommon/jsinspector-modern/InspectorFlags.cpp +12 -0
  76. package/ReactCommon/jsinspector-modern/InspectorFlags.h +12 -0
  77. package/ReactCommon/jsinspector-modern/InspectorInterfaces.cpp +3 -7
  78. package/ReactCommon/jsinspector-modern/InstanceAgent.cpp +2 -11
  79. package/ReactCommon/jsinspector-modern/NetworkIOAgent.cpp +1 -1
  80. package/ReactCommon/jsinspector-modern/RuntimeAgent.cpp +19 -0
  81. package/ReactCommon/jsinspector-modern/RuntimeAgent.h +7 -0
  82. package/ReactCommon/jsinspector-modern/RuntimeTarget.cpp +33 -0
  83. package/ReactCommon/jsinspector-modern/RuntimeTarget.h +6 -0
  84. package/ReactCommon/jsinspector-modern/TracingAgent.cpp +29 -13
  85. package/ReactCommon/jsinspector-modern/TracingAgent.h +5 -4
  86. package/ReactCommon/jsinspector-modern/tests/HostTargetTest.cpp +65 -0
  87. package/ReactCommon/jsinspector-modern/tests/InspectorMocks.h +23 -2
  88. package/ReactCommon/jsinspector-modern/tests/JsiIntegrationTest.cpp +1 -0
  89. package/ReactCommon/jsinspector-modern/tests/NetworkReporterTest.cpp +1 -0
  90. package/ReactCommon/jsinspector-modern/tests/TracingTest.cpp +335 -0
  91. package/ReactCommon/jsinspector-modern/tests/TracingTest.h +95 -0
  92. package/ReactCommon/jsinspector-modern/tests/utils/InspectorFlagOverridesGuard.cpp +10 -0
  93. package/ReactCommon/jsinspector-modern/tests/utils/InspectorFlagOverridesGuard.h +3 -1
  94. package/ReactCommon/jsinspector-modern/tracing/CMakeLists.txt +1 -0
  95. package/ReactCommon/jsinspector-modern/tracing/FrameTimingSequence.h +61 -0
  96. package/ReactCommon/jsinspector-modern/tracing/HostTracingProfile.h +43 -0
  97. package/ReactCommon/jsinspector-modern/tracing/HostTracingProfileSerializer.cpp +165 -0
  98. package/ReactCommon/jsinspector-modern/tracing/HostTracingProfileSerializer.h +50 -0
  99. package/ReactCommon/jsinspector-modern/tracing/PerformanceTracer.cpp +16 -14
  100. package/ReactCommon/jsinspector-modern/tracing/PerformanceTracerSection.h +113 -0
  101. package/ReactCommon/jsinspector-modern/tracing/React-jsinspectortracing.podspec +1 -0
  102. package/ReactCommon/jsinspector-modern/tracing/TimeWindowedBuffer.h +158 -0
  103. package/ReactCommon/jsinspector-modern/tracing/TraceEvent.h +2 -1
  104. package/ReactCommon/jsinspector-modern/tracing/TraceEventGenerator.cpp +100 -0
  105. package/ReactCommon/jsinspector-modern/tracing/TraceEventGenerator.h +60 -0
  106. package/ReactCommon/jsinspector-modern/tracing/TraceEventSerializer.cpp +44 -1
  107. package/ReactCommon/jsinspector-modern/tracing/TraceEventSerializer.h +7 -0
  108. package/ReactCommon/jsinspector-modern/tracing/TraceRecordingState.h +18 -7
  109. package/ReactCommon/jsinspector-modern/tracing/TracingCategory.h +136 -0
  110. package/ReactCommon/jsinspector-modern/tracing/tests/TimeWindowedBufferTest.cpp +352 -0
  111. package/ReactCommon/react/debug/CMakeLists.txt +2 -1
  112. package/ReactCommon/react/debug/React-debug.podspec +7 -1
  113. package/ReactCommon/react/debug/redbox/AnsiParser.cpp +139 -0
  114. package/ReactCommon/react/debug/redbox/AnsiParser.h +35 -0
  115. package/ReactCommon/react/debug/redbox/JscSafeUrl.cpp +179 -0
  116. package/ReactCommon/react/debug/redbox/JscSafeUrl.h +27 -0
  117. package/ReactCommon/react/debug/redbox/RedBoxErrorParser.cpp +171 -0
  118. package/ReactCommon/react/debug/redbox/RedBoxErrorParser.h +40 -0
  119. package/ReactCommon/react/debug/redbox/tests/AnsiParserTest.cpp +97 -0
  120. package/ReactCommon/react/debug/redbox/tests/JscSafeUrlTest.cpp +173 -0
  121. package/ReactCommon/react/debug/redbox/tests/RedBoxErrorParserTest.cpp +107 -0
  122. package/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp +21 -1
  123. package/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h +26 -1
  124. package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp +140 -50
  125. package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h +12 -2
  126. package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h +21 -1
  127. package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h +46 -1
  128. package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h +6 -1
  129. package/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModule.mm +3 -1
  130. package/ReactCommon/react/nativemodule/defaults/CMakeLists.txt +1 -0
  131. package/ReactCommon/react/nativemodule/defaults/DefaultTurboModules.cpp +7 -0
  132. package/ReactCommon/react/nativemodule/defaults/React-defaultsnativemodule.podspec +1 -0
  133. package/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp +26 -1
  134. package/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h +11 -1
  135. package/ReactCommon/react/nativemodule/mutationobserver/NativeMutationObserver.h +4 -0
  136. package/ReactCommon/react/nativemodule/mutationobserver/React-mutationobservernativemodule.podspec +66 -0
  137. package/ReactCommon/react/performance/timeline/PerformanceObserver.cpp +18 -6
  138. package/ReactCommon/react/performance/timeline/PerformanceObserver.h +2 -0
  139. package/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHost.mm +115 -0
  140. package/ReactCommon/{jsinspector-modern → react/utils}/Base64.h +2 -2
  141. package/gradle/libs.versions.toml +1 -1
  142. package/package.json +10 -10
  143. package/scripts/cocoapods/utils.rb +1 -0
  144. package/scripts/react_native_pods.rb +1 -0
  145. package/src/private/featureflags/ReactNativeFeatureFlags.js +26 -1
  146. package/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js +6 -1
  147. package/src/private/setup/setUpDefaultReactNativeEnvironment.js +6 -0
  148. package/third-party-podspecs/RCT-Folly.podspec +1 -1
  149. package/third-party-podspecs/fmt.podspec +2 -2
  150. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/interfaces/TracingState.kt +0 -19
  151. package/ReactCommon/jsinspector-modern/tracing/TraceRecordingStateSerializer.cpp +0 -68
  152. package/ReactCommon/jsinspector-modern/tracing/TraceRecordingStateSerializer.h +0 -42
  153. package/ReactCommon/jsinspector-modern/tracing/TracingState.h +0 -24
@@ -3,25 +3,17 @@
3
3
  *
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
- *
7
- * This file is modified from the original Meta source to work in the
8
- * `react-native-ci` project.
9
6
  */
10
- /* groovylint-disable CompileStatic, DuplicateStringLiteral, LineLength, NestedBlockDepth, NoDef, UnusedVariable, VariableTypeRequired */
11
7
 
12
8
  apply plugin: 'maven-publish'
13
9
  apply plugin: 'signing'
14
10
 
15
- def isSnapshot = false
16
- // Rewritten when copying this to ReactAndroid/publish.gradle
17
- def signingKey = findProperty('SIGNING_KEY')
18
- def signingPwd = findProperty('SIGNING_PWD')
19
- def sonatypeUsername = findProperty('SONATYPE_USERNAME')
20
- def sonatypePassword = findProperty('SONATYPE_PASSWORD')
11
+ def isSnapshot = findProperty("isSnapshot")?.toBoolean()
12
+ def signingKey = findProperty("SIGNING_KEY")
13
+ def signingPwd = findProperty("SIGNING_PWD")
21
14
 
22
15
  def reactAndroidProjectDir = project(':packages:react-native:ReactAndroid').projectDir
23
- def mavenTempLocalUrl = 'file:///home/expo/workingdir/build/maven-local'
24
- // Rewritten when copying this to ReactAndroid/publish.gradle
16
+ def mavenTempLocalUrl = "file:///tmp/maven-local"
25
17
 
26
18
  publishing {
27
19
  publications {
@@ -29,7 +21,7 @@ publishing {
29
21
  afterEvaluate {
30
22
  // We do a multi variant release, so for Android libraries
31
23
  // we publish `components.release`
32
- if (plugins.hasPlugin('com.android.library')) {
24
+ if (plugins.hasPlugin("com.android.library")) {
33
25
  from components.default
34
26
  }
35
27
  }
@@ -37,35 +29,35 @@ publishing {
37
29
  // We populate the publishing version using the project version,
38
30
  // appending -SNAPSHOT if on nightly or prerelase.
39
31
  if (isSnapshot) {
40
- version = this.version + '-SNAPSHOT'
32
+ version = this.version + "-SNAPSHOT"
41
33
  } else {
42
34
  version = this.version
43
35
  }
44
36
 
45
37
  pom {
46
- name = 'react-native'
47
- description = 'A framework for building native apps with React'
48
- url = 'https://github.com/facebook/react-native'
38
+ name = "react-native"
39
+ description = "A framework for building native apps with React"
40
+ url = "https://github.com/facebook/react-native"
49
41
 
50
42
  developers {
51
43
  developer {
52
- id = 'facebook'
53
- name = 'Facebook'
44
+ id = "facebook"
45
+ name = "Facebook"
54
46
  }
55
47
  }
56
48
 
57
49
  licenses {
58
50
  license {
59
- name = 'MIT License'
60
- url = 'https://github.com/facebook/react-native/blob/HEAD/LICENSE'
61
- distribution = 'repo'
51
+ name = "MIT License"
52
+ url = "https://github.com/facebook/react-native/blob/HEAD/LICENSE"
53
+ distribution = "repo"
62
54
  }
63
55
  }
64
56
 
65
57
  scm {
66
- url = 'https://github.com/facebook/react-native.git'
67
- connection = 'scm:git:https://github.com/facebook/react-native.git'
68
- developerConnection = 'scm:git:git@github.com:facebook/react-native.git'
58
+ url = "https://github.com/facebook/react-native.git"
59
+ connection = "scm:git:https://github.com/facebook/react-native.git"
60
+ developerConnection = "scm:git:git@github.com:facebook/react-native.git"
69
61
  }
70
62
  }
71
63
  }
@@ -73,36 +65,18 @@ publishing {
73
65
 
74
66
  repositories {
75
67
  maven {
76
- name = 'mavenTempLocal'
68
+ name = "mavenTempLocal"
77
69
  url = mavenTempLocalUrl
78
70
  }
79
- maven {
80
- name = 'sonatypeRelease'
81
- url = 'https://ossrh-staging-api.central.sonatype.com/service/local/staging/deploy/maven2/'
82
- // url = 'https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/'
83
- credentials(PasswordCredentials) {
84
- username = sonatypeUsername
85
- password = sonatypePassword
86
- }
87
- }
88
- maven {
89
- name = 'sonatypeSnapshot'
90
- url = 'https://central.sonatype.com/repository/maven-snapshots/'
91
- // url = 'https://s01.oss.sonatype.org/content/repositories/snapshots/'
92
- credentials(PasswordCredentials) {
93
- username = sonatypeUsername
94
- password = sonatypePassword
95
- }
96
- }
97
71
  }
98
72
 
99
73
  if (signingKey && signingPwd) {
100
- logger.info('PGP Key found - Signing enabled')
74
+ logger.info("PGP Key found - Signing enabled")
101
75
  signing {
102
76
  useInMemoryPgpKeys(signingKey, signingPwd)
103
77
  sign(publishing.publications.release)
104
78
  }
105
79
  } else {
106
- logger.info('Signing disabled as the PGP key was not found')
80
+ logger.info("Signing disabled as the PGP key was not found")
107
81
  }
108
82
  }
@@ -10,12 +10,12 @@ package com.facebook.react.devsupport
10
10
  import android.content.Context
11
11
  import com.facebook.react.bridge.UiThreadUtil
12
12
  import com.facebook.react.common.SurfaceDelegateFactory
13
+ import com.facebook.react.devsupport.inspector.TracingState
13
14
  import com.facebook.react.devsupport.interfaces.DevBundleDownloadListener
14
15
  import com.facebook.react.devsupport.interfaces.DevLoadingViewManager
15
16
  import com.facebook.react.devsupport.interfaces.DevSupportManager
16
17
  import com.facebook.react.devsupport.interfaces.PausedInDebuggerOverlayManager
17
18
  import com.facebook.react.devsupport.interfaces.RedBoxHandler
18
- import com.facebook.react.devsupport.interfaces.TracingState
19
19
  import com.facebook.react.packagerconnection.RequestHandler
20
20
 
21
21
  /**
@@ -83,6 +83,6 @@ internal class BridgelessDevSupportManager(
83
83
  }
84
84
 
85
85
  fun tracingState(): TracingState {
86
- return TracingState.ENABLEDINCDPMODE
86
+ return TracingState.ENABLED_IN_CDP_MODE
87
87
  }
88
88
  }
@@ -52,6 +52,8 @@ import com.facebook.react.devsupport.DevServerHelper.PackagerCommandListener
52
52
  import com.facebook.react.devsupport.InspectorFlags.getFuseboxEnabled
53
53
  import com.facebook.react.devsupport.StackTraceHelper.convertJavaStackTrace
54
54
  import com.facebook.react.devsupport.StackTraceHelper.convertJsStackTrace
55
+ import com.facebook.react.devsupport.inspector.TracingState
56
+ import com.facebook.react.devsupport.inspector.TracingStateProvider
55
57
  import com.facebook.react.devsupport.interfaces.BundleLoadCallback
56
58
  import com.facebook.react.devsupport.interfaces.DebuggerFrontendPanelName
57
59
  import com.facebook.react.devsupport.interfaces.DevBundleDownloadListener
@@ -66,8 +68,6 @@ import com.facebook.react.devsupport.interfaces.PackagerStatusCallback
66
68
  import com.facebook.react.devsupport.interfaces.PausedInDebuggerOverlayManager
67
69
  import com.facebook.react.devsupport.interfaces.RedBoxHandler
68
70
  import com.facebook.react.devsupport.interfaces.StackFrame
69
- import com.facebook.react.devsupport.interfaces.TracingState
70
- import com.facebook.react.devsupport.interfaces.TracingStateProvider
71
71
  import com.facebook.react.devsupport.perfmonitor.PerfMonitorDevHelper
72
72
  import com.facebook.react.devsupport.perfmonitor.PerfMonitorOverlayManager
73
73
  import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags
@@ -396,21 +396,21 @@ public abstract class DevSupportManagerBase(
396
396
 
397
397
  val analyzePerformanceItemString =
398
398
  when (tracingState) {
399
- TracingState.ENABLEDINBACKGROUNDMODE ->
399
+ TracingState.ENABLED_IN_BACKGROUND_MODE ->
400
400
  applicationContext.getString(R.string.catalyst_performance_background)
401
- TracingState.ENABLEDINCDPMODE ->
401
+ TracingState.ENABLED_IN_CDP_MODE ->
402
402
  applicationContext.getString(R.string.catalyst_performance_cdp)
403
403
  TracingState.DISABLED ->
404
404
  applicationContext.getString(R.string.catalyst_performance_disabled)
405
405
  }
406
406
 
407
- if (!isConnected || tracingState == TracingState.ENABLEDINCDPMODE) {
407
+ if (!isConnected || tracingState == TracingState.ENABLED_IN_CDP_MODE) {
408
408
  disabledItemKeys.add(analyzePerformanceItemString)
409
409
  }
410
410
 
411
411
  options[analyzePerformanceItemString] =
412
412
  when (tracingState) {
413
- TracingState.ENABLEDINBACKGROUNDMODE ->
413
+ TracingState.ENABLED_IN_BACKGROUND_MODE ->
414
414
  DevOptionHandler {
415
415
  UiThreadUtil.runOnUiThread {
416
416
  if (reactInstanceDevHelper is PerfMonitorDevHelper) {
@@ -427,7 +427,7 @@ public abstract class DevSupportManagerBase(
427
427
  if (reactInstanceDevHelper is PerfMonitorDevHelper)
428
428
  reactInstanceDevHelper.inspectorTarget?.resumeBackgroundTrace()
429
429
  }
430
- TracingState.ENABLEDINCDPMODE -> DevOptionHandler {}
430
+ TracingState.ENABLED_IN_CDP_MODE -> DevOptionHandler {}
431
431
  }
432
432
  }
433
433
 
@@ -17,7 +17,11 @@ internal object InspectorFlags {
17
17
  SoLoader.loadLibrary("react_devsupportjni")
18
18
  }
19
19
 
20
+ @DoNotStrip @JvmStatic external fun getScreenshotCaptureEnabled(): Boolean
21
+
20
22
  @DoNotStrip @JvmStatic external fun getFuseboxEnabled(): Boolean
21
23
 
22
24
  @DoNotStrip @JvmStatic external fun getIsProfilingBuild(): Boolean
25
+
26
+ @DoNotStrip @JvmStatic external fun getFrameRecordingEnabled(): Boolean
23
27
  }
@@ -0,0 +1,16 @@
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ package com.facebook.react.devsupport.inspector
9
+
10
+ internal data class FrameTimingSequence(
11
+ val id: Int,
12
+ val threadId: Int,
13
+ val beginTimestamp: Long,
14
+ val endTimestamp: Long,
15
+ val screenshot: ByteArray? = null,
16
+ )
@@ -0,0 +1,275 @@
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ package com.facebook.react.devsupport.inspector
9
+
10
+ import android.graphics.Bitmap
11
+ import android.os.Build
12
+ import android.os.Handler
13
+ import android.os.Looper
14
+ import android.os.Process
15
+ import android.view.FrameMetrics
16
+ import android.view.PixelCopy
17
+ import android.view.Window
18
+ import com.facebook.proguard.annotations.DoNotStripAny
19
+ import java.io.ByteArrayOutputStream
20
+ import java.util.concurrent.Executors
21
+ import java.util.concurrent.atomic.AtomicBoolean
22
+ import java.util.concurrent.atomic.AtomicReference
23
+ import kotlinx.coroutines.CoroutineDispatcher
24
+ import kotlinx.coroutines.CoroutineScope
25
+ import kotlinx.coroutines.Dispatchers
26
+ import kotlinx.coroutines.asCoroutineDispatcher
27
+ import kotlinx.coroutines.launch
28
+
29
+ @DoNotStripAny
30
+ internal class FrameTimingsObserver(
31
+ private val screenshotsEnabled: Boolean,
32
+ private val onFrameTimingSequence: (sequence: FrameTimingSequence) -> Unit,
33
+ ) {
34
+ private val isSupported = Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
35
+ private val mainHandler = Handler(Looper.getMainLooper())
36
+
37
+ // Serial dispatcher for encoding work (single background thread). We limit to 1 thread to
38
+ // minimize the performance impact of screenshot recording.
39
+ private val encodingDispatcher: CoroutineDispatcher =
40
+ Executors.newSingleThreadExecutor().asCoroutineDispatcher()
41
+
42
+ // Stores the most recently captured frame to opportunistically encode after the current frame.
43
+ // Replaced frames are emitted as timings without screenshots.
44
+ private val lastFrameBuffer = AtomicReference<FrameData?>(null)
45
+
46
+ private var frameCounter: Int = 0
47
+ private val encodingInProgress = AtomicBoolean(false)
48
+ @Volatile private var isTracing: Boolean = false
49
+ @Volatile private var currentWindow: Window? = null
50
+
51
+ private data class FrameData(
52
+ val bitmap: Bitmap,
53
+ val frameId: Int,
54
+ val threadId: Int,
55
+ val beginTimestamp: Long,
56
+ val endTimestamp: Long,
57
+ )
58
+
59
+ fun start() {
60
+ if (!isSupported) {
61
+ return
62
+ }
63
+
64
+ frameCounter = 0
65
+ encodingInProgress.set(false)
66
+ lastFrameBuffer.set(null)
67
+ isTracing = true
68
+
69
+ // Emit initial frame event
70
+ val timestamp = System.nanoTime()
71
+ emitFrameTiming(timestamp, timestamp)
72
+
73
+ currentWindow?.addOnFrameMetricsAvailableListener(frameMetricsListener, mainHandler)
74
+ }
75
+
76
+ fun stop() {
77
+ if (!isSupported) {
78
+ return
79
+ }
80
+
81
+ isTracing = false
82
+
83
+ currentWindow?.removeOnFrameMetricsAvailableListener(frameMetricsListener)
84
+ mainHandler.removeCallbacksAndMessages(null)
85
+ lastFrameBuffer.getAndSet(null)?.bitmap?.recycle()
86
+ }
87
+
88
+ fun setCurrentWindow(window: Window?) {
89
+ if (!isSupported || currentWindow === window) {
90
+ return
91
+ }
92
+
93
+ currentWindow?.removeOnFrameMetricsAvailableListener(frameMetricsListener)
94
+ currentWindow = window
95
+ if (isTracing) {
96
+ currentWindow?.addOnFrameMetricsAvailableListener(frameMetricsListener, mainHandler)
97
+ }
98
+ }
99
+
100
+ private val frameMetricsListener =
101
+ Window.OnFrameMetricsAvailableListener { _, frameMetrics, _ ->
102
+ // Guard against calls after stop()
103
+ if (!isTracing) {
104
+ return@OnFrameMetricsAvailableListener
105
+ }
106
+ val beginTimestamp = frameMetrics.getMetric(FrameMetrics.VSYNC_TIMESTAMP)
107
+ val endTimestamp = beginTimestamp + frameMetrics.getMetric(FrameMetrics.TOTAL_DURATION)
108
+ emitFrameTiming(beginTimestamp, endTimestamp)
109
+ }
110
+
111
+ private fun emitFrameTiming(beginTimestamp: Long, endTimestamp: Long) {
112
+ val frameId = frameCounter++
113
+ val threadId = Process.myTid()
114
+
115
+ if (!screenshotsEnabled) {
116
+ // Screenshots disabled - emit without screenshot
117
+ emitFrameEvent(frameId, threadId, beginTimestamp, endTimestamp, null)
118
+ return
119
+ }
120
+
121
+ captureScreenshot(frameId, threadId, beginTimestamp, endTimestamp) { frameData ->
122
+ if (frameData != null) {
123
+ if (encodingInProgress.compareAndSet(false, true)) {
124
+ // Not encoding - encode this frame immediately
125
+ encodeFrame(frameData)
126
+ } else {
127
+ // Encoding thread busy - store current screenshot in buffer for tail-capture
128
+ val oldFrameData = lastFrameBuffer.getAndSet(frameData)
129
+ if (oldFrameData != null) {
130
+ // Skipped frame - emit event without screenshot
131
+ emitFrameEvent(
132
+ oldFrameData.frameId,
133
+ oldFrameData.threadId,
134
+ oldFrameData.beginTimestamp,
135
+ oldFrameData.endTimestamp,
136
+ null,
137
+ )
138
+ oldFrameData.bitmap.recycle()
139
+ }
140
+ }
141
+ } else {
142
+ // Failed to capture (e.g. timeout) - emit without screenshot
143
+ emitFrameEvent(frameId, threadId, beginTimestamp, endTimestamp, null)
144
+ }
145
+ }
146
+ }
147
+
148
+ private fun emitFrameEvent(
149
+ frameId: Int,
150
+ threadId: Int,
151
+ beginTimestamp: Long,
152
+ endTimestamp: Long,
153
+ screenshot: ByteArray?,
154
+ ) {
155
+ CoroutineScope(Dispatchers.Default).launch {
156
+ onFrameTimingSequence(
157
+ FrameTimingSequence(frameId, threadId, beginTimestamp, endTimestamp, screenshot)
158
+ )
159
+ }
160
+ }
161
+
162
+ private fun encodeFrame(frameData: FrameData) {
163
+ CoroutineScope(encodingDispatcher).launch {
164
+ try {
165
+ val screenshot = encodeScreenshot(frameData.bitmap)
166
+ emitFrameEvent(
167
+ frameData.frameId,
168
+ frameData.threadId,
169
+ frameData.beginTimestamp,
170
+ frameData.endTimestamp,
171
+ screenshot,
172
+ )
173
+ } finally {
174
+ frameData.bitmap.recycle()
175
+ }
176
+
177
+ // Clear encoding flag early, allowing new frames to start fresh encoding sessions
178
+ encodingInProgress.set(false)
179
+
180
+ // Opportunistically encode tail frame (if present) without blocking new frames
181
+ val tailFrame = lastFrameBuffer.getAndSet(null)
182
+ if (tailFrame != null) {
183
+ try {
184
+ val screenshot = encodeScreenshot(tailFrame.bitmap)
185
+ emitFrameEvent(
186
+ tailFrame.frameId,
187
+ tailFrame.threadId,
188
+ tailFrame.beginTimestamp,
189
+ tailFrame.endTimestamp,
190
+ screenshot,
191
+ )
192
+ } finally {
193
+ tailFrame.bitmap.recycle()
194
+ }
195
+ }
196
+ }
197
+ }
198
+
199
+ // Must be called from the main thread so that PixelCopy captures the current frame.
200
+ private fun captureScreenshot(
201
+ frameId: Int,
202
+ threadId: Int,
203
+ beginTimestamp: Long,
204
+ endTimestamp: Long,
205
+ callback: (FrameData?) -> Unit,
206
+ ) {
207
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
208
+ // PixelCopy not available
209
+ callback(null)
210
+ return
211
+ }
212
+
213
+ val window = currentWindow
214
+ if (window == null) {
215
+ // No window
216
+ callback(null)
217
+ return
218
+ }
219
+
220
+ val decorView = window.decorView
221
+ val width = decorView.width
222
+ val height = decorView.height
223
+ val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
224
+
225
+ PixelCopy.request(
226
+ window,
227
+ bitmap,
228
+ { copyResult ->
229
+ if (copyResult == PixelCopy.SUCCESS) {
230
+ callback(FrameData(bitmap, frameId, threadId, beginTimestamp, endTimestamp))
231
+ } else {
232
+ bitmap.recycle()
233
+ callback(null)
234
+ }
235
+ },
236
+ mainHandler,
237
+ )
238
+ }
239
+
240
+ private fun encodeScreenshot(bitmap: Bitmap): ByteArray? {
241
+ var scaledBitmap: Bitmap? = null
242
+ return try {
243
+ val window = currentWindow ?: return null
244
+ val width = bitmap.width
245
+ val height = bitmap.height
246
+ val density = window.context.resources.displayMetrics.density
247
+ val scaledWidth = (width / density * SCREENSHOT_SCALE_FACTOR).toInt()
248
+ val scaledHeight = (height / density * SCREENSHOT_SCALE_FACTOR).toInt()
249
+ scaledBitmap = Bitmap.createScaledBitmap(bitmap, scaledWidth, scaledHeight, true)
250
+
251
+ val compressFormat =
252
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) Bitmap.CompressFormat.WEBP_LOSSY
253
+ else Bitmap.CompressFormat.JPEG
254
+
255
+ ByteArrayOutputStream(SCREENSHOT_OUTPUT_SIZE_HINT).use { outputStream ->
256
+ scaledBitmap.compress(compressFormat, SCREENSHOT_QUALITY, outputStream)
257
+ outputStream.toByteArray()
258
+ }
259
+ } catch (e: Exception) {
260
+ null
261
+ } finally {
262
+ scaledBitmap?.recycle()
263
+ }
264
+ }
265
+
266
+ companion object {
267
+ private const val SCREENSHOT_SCALE_FACTOR = 1.0f
268
+ private const val SCREENSHOT_QUALITY = 80
269
+
270
+ // Capacity hint for the ByteArrayOutputStream used during bitmap
271
+ // compression. Sized slightly above typical compressed output to minimise
272
+ // internal buffer resizing.
273
+ private const val SCREENSHOT_OUTPUT_SIZE_HINT = 65536 // 64 KB
274
+ }
275
+ }
@@ -0,0 +1,17 @@
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ package com.facebook.react.devsupport.inspector
9
+
10
+ import com.facebook.proguard.annotations.DoNotStripAny
11
+
12
+ @DoNotStripAny
13
+ internal enum class TracingState {
14
+ DISABLED, // There is no active trace
15
+ ENABLED_IN_BACKGROUND_MODE, // Trace is currently running in background mode
16
+ ENABLED_IN_CDP_MODE, // Trace is currently running in CDP mode
17
+ }
@@ -0,0 +1,15 @@
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ package com.facebook.react.devsupport.inspector
9
+
10
+ import com.facebook.proguard.annotations.DoNotStripAny
11
+
12
+ @DoNotStripAny
13
+ internal fun interface TracingStateListener {
14
+ public fun onStateChanged(state: TracingState, screenshotsEnabled: Boolean)
15
+ }
@@ -5,7 +5,7 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
- package com.facebook.react.devsupport.interfaces
8
+ package com.facebook.react.devsupport.inspector
9
9
 
10
10
  internal interface TracingStateProvider {
11
11
  fun getTracingState(): TracingState
@@ -7,7 +7,7 @@
7
7
 
8
8
  package com.facebook.react.devsupport.perfmonitor
9
9
 
10
- import com.facebook.react.devsupport.interfaces.TracingState
10
+ import com.facebook.react.devsupport.inspector.TracingState
11
11
 
12
12
  /**
13
13
  * [Experimental] Interface implemented by [com.facebook.react.runtime.ReactHostInspectorTarget]
@@ -8,7 +8,7 @@
8
8
  package com.facebook.react.devsupport.perfmonitor
9
9
 
10
10
  import com.facebook.react.bridge.UiThreadUtil
11
- import com.facebook.react.devsupport.interfaces.TracingState
11
+ import com.facebook.react.devsupport.inspector.TracingState
12
12
 
13
13
  internal class PerfMonitorOverlayManager(
14
14
  private val devHelper: PerfMonitorDevHelper,
@@ -21,7 +21,7 @@ internal class PerfMonitorOverlayManager(
21
21
  get() = enabled
22
22
 
23
23
  private var view: PerfMonitorOverlayView? = null
24
- private var tracingState: TracingState = TracingState.ENABLEDINCDPMODE
24
+ private var tracingState: TracingState = TracingState.ENABLED_IN_CDP_MODE
25
25
  private var perfIssueCount: Int = 0
26
26
 
27
27
  /** Enable the Perf Monitor overlay. */
@@ -92,7 +92,7 @@ internal class PerfMonitorOverlayManager(
92
92
 
93
93
  private fun handleRecordingButtonPress() {
94
94
  when (tracingState) {
95
- TracingState.ENABLEDINBACKGROUNDMODE -> {
95
+ TracingState.ENABLED_IN_BACKGROUND_MODE -> {
96
96
  devHelper.inspectorTarget?.let { target ->
97
97
  if (!target.pauseAndAnalyzeBackgroundTrace()) {
98
98
  onRequestOpenDevTools()
@@ -102,7 +102,7 @@ internal class PerfMonitorOverlayManager(
102
102
  TracingState.DISABLED -> {
103
103
  devHelper.inspectorTarget?.resumeBackgroundTrace()
104
104
  }
105
- TracingState.ENABLEDINCDPMODE -> Unit
105
+ TracingState.ENABLED_IN_CDP_MODE -> Unit
106
106
  }
107
107
  }
108
108
  }
@@ -21,7 +21,7 @@ import android.widget.TextView
21
21
  import androidx.core.view.ViewCompat
22
22
  import androidx.core.view.WindowInsetsCompat
23
23
  import com.facebook.react.R
24
- import com.facebook.react.devsupport.interfaces.TracingState
24
+ import com.facebook.react.devsupport.inspector.TracingState
25
25
  import com.facebook.react.uimanager.DisplayMetricsHolder
26
26
  import com.facebook.react.uimanager.PixelUtil
27
27
 
@@ -50,12 +50,12 @@ internal class PerfMonitorOverlayView(
50
50
  }
51
51
 
52
52
  fun updateRecordingState(state: TracingState) {
53
- if (state == TracingState.ENABLEDINCDPMODE) {
53
+ if (state == TracingState.ENABLED_IN_CDP_MODE) {
54
54
  dialog.hide()
55
55
  return
56
56
  }
57
57
 
58
- if (state == TracingState.ENABLEDINBACKGROUNDMODE) {
58
+ if (state == TracingState.ENABLED_IN_BACKGROUND_MODE) {
59
59
  (statusIndicator.background as GradientDrawable).setColor(Color.RED)
60
60
  statusLabel.text = "Profiling Active"
61
61
  tooltipLabel.text =
@@ -7,7 +7,7 @@
7
7
 
8
8
  package com.facebook.react.devsupport.perfmonitor
9
9
 
10
- import com.facebook.react.devsupport.interfaces.TracingState
10
+ import com.facebook.react.devsupport.inspector.TracingState
11
11
 
12
12
  /** [Experimental] An interface for subscribing to updates for the V2 Perf Monitor. */
13
13
  internal interface PerfMonitorUpdateListener {