react-native-tvos 0.85.0-0rc5 → 0.85.3-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.
- package/Libraries/Components/ScrollView/AndroidHorizontalScrollViewNativeComponent.js +1 -0
- package/Libraries/Components/ScrollView/ScrollView.d.ts +7 -0
- package/Libraries/Components/ScrollView/ScrollView.js +6 -0
- package/Libraries/Components/ScrollView/ScrollViewNativeComponent.js +2 -0
- package/Libraries/Components/ScrollView/ScrollViewNativeComponentType.js +1 -0
- package/Libraries/Components/TextInput/AndroidTextInputNativeComponent.js +5 -1
- package/Libraries/Components/TextInput/TextInput.flow.js +1 -0
- package/Libraries/Core/ReactNativeVersion.js +2 -2
- package/Libraries/Utilities/HMRClient.js +28 -1
- package/README.md +52 -0
- package/React/Base/RCTVersion.m +2 -2
- package/React/CoreModules/RCTDevLoadingView.mm +17 -0
- package/React/CoreModules/RCTJscSafeUrl+Internal.h +23 -0
- package/React/CoreModules/RCTJscSafeUrl.mm +38 -0
- package/React/CoreModules/RCTRedBox+Internal.h +42 -0
- package/React/CoreModules/RCTRedBox.mm +30 -471
- package/React/CoreModules/RCTRedBox2AnsiParser+Internal.h +22 -0
- package/React/CoreModules/RCTRedBox2AnsiParser.mm +55 -0
- package/React/CoreModules/RCTRedBox2Controller+Internal.h +34 -0
- package/React/CoreModules/RCTRedBox2Controller.mm +764 -0
- package/React/CoreModules/RCTRedBox2ErrorParser+Internal.h +46 -0
- package/React/CoreModules/RCTRedBox2ErrorParser.mm +57 -0
- package/React/CoreModules/RCTRedBoxController+Internal.h +31 -0
- package/React/CoreModules/RCTRedBoxController.mm +447 -0
- package/React/CoreModules/RCTRedBoxHMRClient+Internal.h +26 -0
- package/React/CoreModules/RCTRedBoxHMRClient.mm +125 -0
- package/React/CoreModules/React-CoreModules.podspec +1 -0
- package/React/DevSupport/RCTFrameTimingsObserver.h +24 -0
- package/React/DevSupport/RCTFrameTimingsObserver.mm +298 -0
- package/React/FBReactNativeSpec/FBReactNativeSpecJSI.h +40 -0
- package/React/Fabric/Mounting/ComponentViews/ScrollView/RCTEnhancedScrollView.h +1 -0
- package/React/Fabric/Mounting/ComponentViews/ScrollView/RCTEnhancedScrollView.mm +78 -0
- package/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm +32 -6
- package/React/Views/ScrollView/RCTScrollViewManager.m +1 -0
- package/ReactAndroid/build.gradle.kts +2 -0
- package/ReactAndroid/gradle.properties +1 -1
- package/ReactAndroid/hermes-engine/build.gradle.kts +17 -0
- package/ReactAndroid/publish.gradle +20 -46
- package/ReactAndroid/src/main/java/com/facebook/react/devsupport/InspectorFlags.kt +4 -0
- package/ReactAndroid/src/main/java/com/facebook/react/devsupport/inspector/FrameTimingSequence.kt +1 -1
- package/ReactAndroid/src/main/java/com/facebook/react/devsupport/inspector/FrameTimingsObserver.kt +127 -26
- package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt +31 -1
- package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt +51 -1
- package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt +11 -1
- package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt +12 -2
- package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt +56 -1
- package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsOverrides_RNOSS_Experimental_Android.kt +5 -1
- package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt +11 -1
- package/ReactAndroid/src/main/java/com/facebook/react/internal/tracing/PerformanceTracer.kt +39 -0
- package/ReactAndroid/src/main/java/com/facebook/react/modules/network/NetworkEventUtil.kt +8 -0
- package/ReactAndroid/src/main/java/com/facebook/react/modules/network/RequestBodyUtil.kt +2 -0
- package/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/ReactNativeVersion.kt +2 -2
- package/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.kt +50 -10
- package/ReactAndroid/src/main/java/com/facebook/react/views/common/UiModeUtils.kt +20 -0
- package/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java +57 -8
- package/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollViewManager.kt +5 -0
- package/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java +48 -2
- package/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewManager.kt +5 -0
- package/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextView.java +28 -3
- package/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.kt +5 -0
- package/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputSubmitEditingEvent.kt +6 -1
- package/ReactAndroid/src/main/jni/CMakeLists.txt +7 -0
- package/ReactAndroid/src/main/jni/react/devsupport/JInspectorFlags.cpp +22 -0
- package/ReactAndroid/src/main/jni/react/devsupport/JInspectorFlags.h +2 -0
- package/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp +71 -1
- package/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h +16 -1
- package/ReactAndroid/src/main/jni/react/runtime/jni/JReactHostInspectorTarget.cpp +14 -0
- package/ReactAndroid/src/main/jni/react/runtime/jni/JReactHostInspectorTarget.h +18 -4
- package/ReactCommon/React-Fabric.podspec +7 -0
- package/ReactCommon/cxxreact/ReactNativeVersion.h +3 -3
- package/ReactCommon/jsinspector-modern/HostAgent.cpp +36 -0
- package/ReactCommon/jsinspector-modern/HostTarget.cpp +7 -1
- package/ReactCommon/jsinspector-modern/HostTarget.h +25 -0
- package/ReactCommon/jsinspector-modern/HostTargetTracing.cpp +1 -1
- package/ReactCommon/jsinspector-modern/HostTargetTracing.h +4 -4
- package/ReactCommon/jsinspector-modern/InspectorFlags.cpp +12 -0
- package/ReactCommon/jsinspector-modern/InspectorFlags.h +12 -0
- package/ReactCommon/jsinspector-modern/NetworkIOAgent.cpp +1 -1
- package/ReactCommon/jsinspector-modern/RuntimeAgent.cpp +19 -0
- package/ReactCommon/jsinspector-modern/RuntimeAgent.h +7 -0
- package/ReactCommon/jsinspector-modern/RuntimeTarget.cpp +33 -0
- package/ReactCommon/jsinspector-modern/RuntimeTarget.h +6 -0
- package/ReactCommon/jsinspector-modern/tests/HostTargetTest.cpp +12 -0
- package/ReactCommon/jsinspector-modern/tests/InspectorMocks.h +3 -2
- package/ReactCommon/jsinspector-modern/tests/JsiIntegrationTest.cpp +1 -0
- package/ReactCommon/jsinspector-modern/tests/NetworkReporterTest.cpp +1 -1
- package/ReactCommon/jsinspector-modern/tests/TracingTest.cpp +1 -1
- package/ReactCommon/jsinspector-modern/tests/utils/InspectorFlagOverridesGuard.cpp +10 -0
- package/ReactCommon/jsinspector-modern/tests/utils/InspectorFlagOverridesGuard.h +3 -1
- package/ReactCommon/jsinspector-modern/tracing/CMakeLists.txt +1 -0
- package/ReactCommon/jsinspector-modern/tracing/FrameTimingSequence.h +7 -3
- package/ReactCommon/jsinspector-modern/tracing/HostTracingProfileSerializer.cpp +52 -29
- package/ReactCommon/jsinspector-modern/tracing/HostTracingProfileSerializer.h +6 -6
- package/ReactCommon/jsinspector-modern/tracing/PerformanceTracerSection.h +113 -0
- package/ReactCommon/jsinspector-modern/tracing/React-jsinspectortracing.podspec +1 -0
- package/ReactCommon/jsinspector-modern/tracing/TraceEventGenerator.cpp +12 -5
- package/ReactCommon/jsinspector-modern/tracing/TraceEventGenerator.h +3 -1
- package/ReactCommon/jsinspector-modern/tracing/TraceEventSerializer.cpp +42 -0
- package/ReactCommon/jsinspector-modern/tracing/TraceEventSerializer.h +7 -0
- package/ReactCommon/react/debug/CMakeLists.txt +2 -1
- package/ReactCommon/react/debug/React-debug.podspec +7 -1
- package/ReactCommon/react/debug/redbox/AnsiParser.cpp +139 -0
- package/ReactCommon/react/debug/redbox/AnsiParser.h +35 -0
- package/ReactCommon/react/debug/redbox/JscSafeUrl.cpp +179 -0
- package/ReactCommon/react/debug/redbox/JscSafeUrl.h +27 -0
- package/ReactCommon/react/debug/redbox/RedBoxErrorParser.cpp +171 -0
- package/ReactCommon/react/debug/redbox/RedBoxErrorParser.h +40 -0
- package/ReactCommon/react/debug/redbox/tests/AnsiParserTest.cpp +97 -0
- package/ReactCommon/react/debug/redbox/tests/JscSafeUrlTest.cpp +173 -0
- package/ReactCommon/react/debug/redbox/tests/RedBoxErrorParserTest.cpp +107 -0
- package/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp +21 -1
- package/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h +26 -1
- package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp +135 -45
- package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h +12 -2
- package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h +22 -2
- package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h +46 -1
- package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsOverridesOSSExperimental.h +9 -1
- package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h +6 -1
- package/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModule.mm +3 -1
- package/ReactCommon/react/nativemodule/defaults/CMakeLists.txt +1 -0
- package/ReactCommon/react/nativemodule/defaults/DefaultTurboModules.cpp +7 -0
- package/ReactCommon/react/nativemodule/defaults/React-defaultsnativemodule.podspec +1 -0
- package/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp +26 -1
- package/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h +11 -1
- package/ReactCommon/react/nativemodule/mutationobserver/NativeMutationObserver.h +4 -0
- package/ReactCommon/react/nativemodule/mutationobserver/React-mutationobservernativemodule.podspec +66 -0
- package/ReactCommon/react/performance/timeline/PerformanceObserver.cpp +18 -6
- package/ReactCommon/react/performance/timeline/PerformanceObserver.h +2 -0
- package/ReactCommon/react/renderer/animated/NativeAnimatedNodesManager.cpp +4 -1
- package/ReactCommon/react/renderer/animationbackend/AnimationBackend.cpp +58 -25
- package/ReactCommon/react/renderer/animationbackend/AnimationBackend.h +9 -0
- package/ReactCommon/react/renderer/animationbackend/AnimationChoreographer.h +5 -0
- package/ReactCommon/react/renderer/components/scrollview/BaseScrollViewProps.cpp +10 -0
- package/ReactCommon/react/renderer/components/scrollview/BaseScrollViewProps.h +1 -0
- package/ReactCommon/react/renderer/uimanager/UIManagerAnimationBackend.h +1 -0
- package/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHost.mm +115 -0
- package/ReactCommon/{jsinspector-modern → react/utils}/Base64.h +2 -2
- package/package.json +11 -11
- package/scripts/cocoapods/utils.rb +1 -0
- package/scripts/codegen/generate-artifacts-executor/generateAppDependencyProvider.js +4 -4
- package/scripts/codegen/generate-artifacts-executor/generateCustomURLHandlers.js +3 -3
- package/scripts/codegen/generate-artifacts-executor/generateNativeCode.js +2 -3
- package/scripts/codegen/generate-artifacts-executor/generatePackageSwift.js +2 -2
- package/scripts/codegen/generate-artifacts-executor/generateRCTModuleProviders.js +3 -2
- package/scripts/codegen/generate-artifacts-executor/generateRCTThirdPartyComponents.js +3 -2
- package/scripts/codegen/generate-artifacts-executor/generateReactCodegenPodspec.js +2 -2
- package/scripts/codegen/generate-artifacts-executor/generateUnstableModulesRequiringMainQueueSetupProvider.js +3 -3
- package/scripts/codegen/generate-artifacts-executor/utils.js +48 -0
- package/scripts/react_native_pods.rb +1 -0
- package/scripts/replace-rncore-version.js +72 -15
- package/src/private/featureflags/ReactNativeFeatureFlags.js +27 -2
- package/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js +6 -1
- package/src/private/setup/setUpDefaultReactNativeEnvironment.js +6 -0
- package/types/public/ReactNativeTVTypes.d.ts +8 -0
|
@@ -434,6 +434,9 @@ static inline UIViewAnimationOptions animationOptionsWithCurve(UIViewAnimationCu
|
|
|
434
434
|
|
|
435
435
|
scrollView.snapToStart = newScrollViewProps.snapToStart;
|
|
436
436
|
scrollView.snapToEnd = newScrollViewProps.snapToEnd;
|
|
437
|
+
#if TARGET_OS_TV
|
|
438
|
+
scrollView.scrollAnimationEnabled = newScrollViewProps.scrollAnimationEnabled;
|
|
439
|
+
#endif
|
|
437
440
|
|
|
438
441
|
if (oldScrollViewProps.snapToOffsets != newScrollViewProps.snapToOffsets) {
|
|
439
442
|
NSMutableArray<NSNumber *> *snapToOffsets = [NSMutableArray array];
|
|
@@ -1252,7 +1255,7 @@ static inline UIViewAnimationOptions animationOptionsWithCurve(UIViewAnimationCu
|
|
|
1252
1255
|
? CGPointMake(targetOffset, scrollView.contentOffset.y)
|
|
1253
1256
|
: CGPointMake(scrollView.contentOffset.x, targetOffset);
|
|
1254
1257
|
self.preferredContentOffset = targetContentOffset;
|
|
1255
|
-
[_scrollView setContentOffset:targetContentOffset animated:
|
|
1258
|
+
[_scrollView setContentOffset:targetContentOffset animated:scrollProps.scrollAnimationEnabled];
|
|
1256
1259
|
}
|
|
1257
1260
|
|
|
1258
1261
|
- (void)didUpdateFocusInContext:(UIFocusUpdateContext *)context
|
|
@@ -1261,7 +1264,18 @@ static inline UIViewAnimationOptions animationOptionsWithCurve(UIViewAnimationCu
|
|
|
1261
1264
|
self.preferredContentOffset = NO_PREFERRED_CONTENT_OFFSET;
|
|
1262
1265
|
const auto &scrollProps = static_cast<const ScrollViewProps &>(*_props);
|
|
1263
1266
|
BOOL hasItemSnapAlignment = scrollProps.snapToAlignment == ScrollViewSnapToAlignment::Item;
|
|
1264
|
-
if (context.previouslyFocusedView == context.nextFocusedView
|
|
1267
|
+
if (context.previouslyFocusedView == context.nextFocusedView) {
|
|
1268
|
+
return;
|
|
1269
|
+
}
|
|
1270
|
+
if (!_props->isTVSelectable && !hasItemSnapAlignment) {
|
|
1271
|
+
if (!scrollProps.scrollAnimationEnabled && [context.nextFocusedView isDescendantOfView:_scrollView]) {
|
|
1272
|
+
// When animations are disabled and there's no snap alignment, manually scroll
|
|
1273
|
+
// the focused view into view instantly. We can't let UIScrollView's default
|
|
1274
|
+
// focus handling do this because it uses deceleration (timer-based) that can't
|
|
1275
|
+
// be blocked by the animation-blocking layer.
|
|
1276
|
+
CGRect targetRect = [context.nextFocusedView convertRect:context.nextFocusedView.bounds toView:_scrollView];
|
|
1277
|
+
[_scrollView scrollRectToVisible:targetRect animated:NO];
|
|
1278
|
+
}
|
|
1265
1279
|
return;
|
|
1266
1280
|
}
|
|
1267
1281
|
if (_props->isTVSelectable && context.nextFocusedView == self) {
|
|
@@ -1429,10 +1443,16 @@ static inline UIViewAnimationOptions animationOptionsWithCurve(UIViewAnimationCu
|
|
|
1429
1443
|
limitedOffset = MAX(limitedOffset, 0.0);
|
|
1430
1444
|
limitedOffset = MIN(limitedOffset, maxOffset);
|
|
1431
1445
|
|
|
1432
|
-
|
|
1446
|
+
const auto &scrollProps = static_cast<const ScrollViewProps &>(*self->_props);
|
|
1447
|
+
if (scrollProps.scrollAnimationEnabled) {
|
|
1448
|
+
[UIView animateWithDuration:[self swipeDuration] animations:^{
|
|
1449
|
+
self.scrollView.contentOffset =
|
|
1450
|
+
CGPointMake(self.scrollView.contentOffset.x, limitedOffset);
|
|
1451
|
+
}];
|
|
1452
|
+
} else {
|
|
1433
1453
|
self.scrollView.contentOffset =
|
|
1434
1454
|
CGPointMake(self.scrollView.contentOffset.x, limitedOffset);
|
|
1435
|
-
}
|
|
1455
|
+
}
|
|
1436
1456
|
});
|
|
1437
1457
|
}
|
|
1438
1458
|
|
|
@@ -1453,10 +1473,16 @@ static inline UIViewAnimationOptions animationOptionsWithCurve(UIViewAnimationCu
|
|
|
1453
1473
|
limitedOffset = MAX(limitedOffset, 0.0);
|
|
1454
1474
|
limitedOffset = MIN(limitedOffset, maxOffset);
|
|
1455
1475
|
|
|
1456
|
-
|
|
1476
|
+
const auto &scrollProps = static_cast<const ScrollViewProps &>(*self->_props);
|
|
1477
|
+
if (scrollProps.scrollAnimationEnabled) {
|
|
1478
|
+
[UIView animateWithDuration:[self swipeDuration] animations:^{
|
|
1479
|
+
self.scrollView.contentOffset =
|
|
1480
|
+
CGPointMake(limitedOffset, self.scrollView.contentOffset.y);
|
|
1481
|
+
}];
|
|
1482
|
+
} else {
|
|
1457
1483
|
self.scrollView.contentOffset =
|
|
1458
1484
|
CGPointMake(limitedOffset, self.scrollView.contentOffset.y);
|
|
1459
|
-
}
|
|
1485
|
+
}
|
|
1460
1486
|
});
|
|
1461
1487
|
}
|
|
1462
1488
|
|
|
@@ -106,6 +106,7 @@ RCT_EXPORT_VIEW_PROPERTY(onMomentumScrollEnd, RCTDirectEventBlock)
|
|
|
106
106
|
RCT_EXPORT_VIEW_PROPERTY(inverted, BOOL)
|
|
107
107
|
#if TARGET_OS_TV
|
|
108
108
|
RCT_EXPORT_VIEW_PROPERTY(showsScrollIndex, BOOL)
|
|
109
|
+
RCT_EXPORT_VIEW_PROPERTY(scrollAnimationEnabled, BOOL)
|
|
109
110
|
#endif
|
|
110
111
|
RCT_EXPORT_VIEW_PROPERTY(automaticallyAdjustsScrollIndicatorInsets, BOOL)
|
|
111
112
|
RCT_EXPORT_VIEW_PROPERTY(contentInsetAdjustmentBehavior, UIScrollViewContentInsetAdjustmentBehavior)
|
|
@@ -102,6 +102,8 @@ val preparePrefab by
|
|
|
102
102
|
Pair("../ReactCommon/hermes/inspector-modern/", "hermes/inspector-modern/"),
|
|
103
103
|
// fabricjni
|
|
104
104
|
Pair("src/main/jni/react/fabric", "react/fabric/"),
|
|
105
|
+
// uimanagerjni
|
|
106
|
+
Pair("src/main/jni/react/uimanager", "react/uimanager/"),
|
|
105
107
|
// glog
|
|
106
108
|
Pair(File(buildDir, "third-party-ndk/glog/exported/").absolutePath, ""),
|
|
107
109
|
// jsiinpsector
|
|
@@ -441,6 +441,17 @@ android {
|
|
|
441
441
|
}
|
|
442
442
|
|
|
443
443
|
prefab { create("hermesvm") { headers = prefabHeadersDir.absolutePath } }
|
|
444
|
+
|
|
445
|
+
// Mirror ReactAndroid's multi-variant publishing setup so consumers can
|
|
446
|
+
// pick a debug / debugOptimized / release variant of the hermes-engine
|
|
447
|
+
// AAR. Required by `apply(from = "../publish.gradle")` below, which uses
|
|
448
|
+
// `from components.default` and therefore needs a multi-variant component.
|
|
449
|
+
publishing {
|
|
450
|
+
multipleVariants {
|
|
451
|
+
withSourcesJar()
|
|
452
|
+
allVariants()
|
|
453
|
+
}
|
|
454
|
+
}
|
|
444
455
|
}
|
|
445
456
|
|
|
446
457
|
afterEvaluate {
|
|
@@ -460,3 +471,9 @@ tasks.withType<JavaCompile>().configureEach {
|
|
|
460
471
|
options.compilerArgs.add("-Xlint:deprecation,unchecked")
|
|
461
472
|
options.compilerArgs.add("-Werror")
|
|
462
473
|
}
|
|
474
|
+
|
|
475
|
+
/* Publishing Configuration */
|
|
476
|
+
// Reuses the publish.gradle template applied to ReactAndroid; the file is
|
|
477
|
+
// generated by the build-android-artifacts EAS workflow. Resulting artifact
|
|
478
|
+
// coordinate: io.github.react-native-tvos:hermes-engine:<version>.
|
|
479
|
+
apply(from = "../publish.gradle")
|
|
@@ -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 =
|
|
16
|
-
|
|
17
|
-
def
|
|
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 =
|
|
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(
|
|
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 +
|
|
32
|
+
version = this.version + "-SNAPSHOT"
|
|
41
33
|
} else {
|
|
42
34
|
version = this.version
|
|
43
35
|
}
|
|
44
36
|
|
|
45
37
|
pom {
|
|
46
|
-
name =
|
|
47
|
-
description =
|
|
48
|
-
url =
|
|
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 =
|
|
53
|
-
name =
|
|
44
|
+
id = "facebook"
|
|
45
|
+
name = "Facebook"
|
|
54
46
|
}
|
|
55
47
|
}
|
|
56
48
|
|
|
57
49
|
licenses {
|
|
58
50
|
license {
|
|
59
|
-
name =
|
|
60
|
-
url =
|
|
61
|
-
distribution =
|
|
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 =
|
|
67
|
-
connection =
|
|
68
|
-
developerConnection =
|
|
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 =
|
|
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(
|
|
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(
|
|
80
|
+
logger.info("Signing disabled as the PGP key was not found")
|
|
107
81
|
}
|
|
108
82
|
}
|
|
@@ -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
|
}
|
package/ReactAndroid/src/main/java/com/facebook/react/devsupport/inspector/FrameTimingsObserver.kt
CHANGED
|
@@ -12,14 +12,18 @@ import android.os.Build
|
|
|
12
12
|
import android.os.Handler
|
|
13
13
|
import android.os.Looper
|
|
14
14
|
import android.os.Process
|
|
15
|
-
import android.util.Base64
|
|
16
15
|
import android.view.FrameMetrics
|
|
17
16
|
import android.view.PixelCopy
|
|
18
17
|
import android.view.Window
|
|
19
18
|
import com.facebook.proguard.annotations.DoNotStripAny
|
|
20
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
|
|
21
24
|
import kotlinx.coroutines.CoroutineScope
|
|
22
25
|
import kotlinx.coroutines.Dispatchers
|
|
26
|
+
import kotlinx.coroutines.asCoroutineDispatcher
|
|
23
27
|
import kotlinx.coroutines.launch
|
|
24
28
|
|
|
25
29
|
@DoNotStripAny
|
|
@@ -30,20 +34,39 @@ internal class FrameTimingsObserver(
|
|
|
30
34
|
private val isSupported = Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
|
|
31
35
|
private val mainHandler = Handler(Looper.getMainLooper())
|
|
32
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
|
+
|
|
33
46
|
private var frameCounter: Int = 0
|
|
47
|
+
private val encodingInProgress = AtomicBoolean(false)
|
|
34
48
|
@Volatile private var isTracing: Boolean = false
|
|
35
49
|
@Volatile private var currentWindow: Window? = null
|
|
36
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
|
+
|
|
37
59
|
fun start() {
|
|
38
60
|
if (!isSupported) {
|
|
39
61
|
return
|
|
40
62
|
}
|
|
41
63
|
|
|
42
64
|
frameCounter = 0
|
|
65
|
+
encodingInProgress.set(false)
|
|
66
|
+
lastFrameBuffer.set(null)
|
|
43
67
|
isTracing = true
|
|
44
68
|
|
|
45
|
-
//
|
|
46
|
-
// recorded at the start of tracing, even if no UI changes occur
|
|
69
|
+
// Emit initial frame event
|
|
47
70
|
val timestamp = System.nanoTime()
|
|
48
71
|
emitFrameTiming(timestamp, timestamp)
|
|
49
72
|
|
|
@@ -59,6 +82,7 @@ internal class FrameTimingsObserver(
|
|
|
59
82
|
|
|
60
83
|
currentWindow?.removeOnFrameMetricsAvailableListener(frameMetricsListener)
|
|
61
84
|
mainHandler.removeCallbacksAndMessages(null)
|
|
85
|
+
lastFrameBuffer.getAndSet(null)?.bitmap?.recycle()
|
|
62
86
|
}
|
|
63
87
|
|
|
64
88
|
fun setCurrentWindow(window: Window?) {
|
|
@@ -75,8 +99,7 @@ internal class FrameTimingsObserver(
|
|
|
75
99
|
|
|
76
100
|
private val frameMetricsListener =
|
|
77
101
|
Window.OnFrameMetricsAvailableListener { _, frameMetrics, _ ->
|
|
78
|
-
// Guard against calls
|
|
79
|
-
// previous frames will still finish.
|
|
102
|
+
// Guard against calls after stop()
|
|
80
103
|
if (!isTracing) {
|
|
81
104
|
return@OnFrameMetricsAvailableListener
|
|
82
105
|
}
|
|
@@ -89,34 +112,107 @@ internal class FrameTimingsObserver(
|
|
|
89
112
|
val frameId = frameCounter++
|
|
90
113
|
val threadId = Process.myTid()
|
|
91
114
|
|
|
92
|
-
if (screenshotsEnabled) {
|
|
93
|
-
//
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
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
|
+
}
|
|
100
140
|
}
|
|
141
|
+
} else {
|
|
142
|
+
// Failed to capture (e.g. timeout) - emit without screenshot
|
|
143
|
+
emitFrameEvent(frameId, threadId, beginTimestamp, endTimestamp, null)
|
|
101
144
|
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
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,
|
|
106
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
|
+
}
|
|
107
195
|
}
|
|
108
196
|
}
|
|
109
197
|
}
|
|
110
198
|
|
|
111
199
|
// Must be called from the main thread so that PixelCopy captures the current frame.
|
|
112
|
-
private fun captureScreenshot(
|
|
200
|
+
private fun captureScreenshot(
|
|
201
|
+
frameId: Int,
|
|
202
|
+
threadId: Int,
|
|
203
|
+
beginTimestamp: Long,
|
|
204
|
+
endTimestamp: Long,
|
|
205
|
+
callback: (FrameData?) -> Unit,
|
|
206
|
+
) {
|
|
113
207
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
|
|
208
|
+
// PixelCopy not available
|
|
114
209
|
callback(null)
|
|
115
210
|
return
|
|
116
211
|
}
|
|
117
212
|
|
|
118
213
|
val window = currentWindow
|
|
119
214
|
if (window == null) {
|
|
215
|
+
// No window
|
|
120
216
|
callback(null)
|
|
121
217
|
return
|
|
122
218
|
}
|
|
@@ -131,9 +227,7 @@ internal class FrameTimingsObserver(
|
|
|
131
227
|
bitmap,
|
|
132
228
|
{ copyResult ->
|
|
133
229
|
if (copyResult == PixelCopy.SUCCESS) {
|
|
134
|
-
|
|
135
|
-
callback(encodeScreenshot(window, bitmap, width, height))
|
|
136
|
-
}
|
|
230
|
+
callback(FrameData(bitmap, frameId, threadId, beginTimestamp, endTimestamp))
|
|
137
231
|
} else {
|
|
138
232
|
bitmap.recycle()
|
|
139
233
|
callback(null)
|
|
@@ -143,9 +237,12 @@ internal class FrameTimingsObserver(
|
|
|
143
237
|
)
|
|
144
238
|
}
|
|
145
239
|
|
|
146
|
-
private fun encodeScreenshot(
|
|
240
|
+
private fun encodeScreenshot(bitmap: Bitmap): ByteArray? {
|
|
147
241
|
var scaledBitmap: Bitmap? = null
|
|
148
242
|
return try {
|
|
243
|
+
val window = currentWindow ?: return null
|
|
244
|
+
val width = bitmap.width
|
|
245
|
+
val height = bitmap.height
|
|
149
246
|
val density = window.context.resources.displayMetrics.density
|
|
150
247
|
val scaledWidth = (width / density * SCREENSHOT_SCALE_FACTOR).toInt()
|
|
151
248
|
val scaledHeight = (height / density * SCREENSHOT_SCALE_FACTOR).toInt()
|
|
@@ -155,20 +252,24 @@ internal class FrameTimingsObserver(
|
|
|
155
252
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) Bitmap.CompressFormat.WEBP_LOSSY
|
|
156
253
|
else Bitmap.CompressFormat.JPEG
|
|
157
254
|
|
|
158
|
-
ByteArrayOutputStream().use { outputStream ->
|
|
255
|
+
ByteArrayOutputStream(SCREENSHOT_OUTPUT_SIZE_HINT).use { outputStream ->
|
|
159
256
|
scaledBitmap.compress(compressFormat, SCREENSHOT_QUALITY, outputStream)
|
|
160
|
-
|
|
257
|
+
outputStream.toByteArray()
|
|
161
258
|
}
|
|
162
259
|
} catch (e: Exception) {
|
|
163
260
|
null
|
|
164
261
|
} finally {
|
|
165
262
|
scaledBitmap?.recycle()
|
|
166
|
-
bitmap.recycle()
|
|
167
263
|
}
|
|
168
264
|
}
|
|
169
265
|
|
|
170
266
|
companion object {
|
|
171
|
-
private const val SCREENSHOT_SCALE_FACTOR =
|
|
267
|
+
private const val SCREENSHOT_SCALE_FACTOR = 1.0f
|
|
172
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
|
|
173
274
|
}
|
|
174
275
|
}
|
|
@@ -4,7 +4,7 @@
|
|
|
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
6
|
*
|
|
7
|
-
* @generated SignedSource<<
|
|
7
|
+
* @generated SignedSource<<dcedc4c1eba9ea605d96850aebecaf06>>
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
/**
|
|
@@ -276,6 +276,12 @@ public object ReactNativeFeatureFlags {
|
|
|
276
276
|
@JvmStatic
|
|
277
277
|
public fun enableModuleArgumentNSNullConversionIOS(): Boolean = accessor.enableModuleArgumentNSNullConversionIOS()
|
|
278
278
|
|
|
279
|
+
/**
|
|
280
|
+
* Enables the MutationObserver Web API in React Native.
|
|
281
|
+
*/
|
|
282
|
+
@JvmStatic
|
|
283
|
+
public fun enableMutationObserverByDefault(): Boolean = accessor.enableMutationObserverByDefault()
|
|
284
|
+
|
|
279
285
|
/**
|
|
280
286
|
* Parse CSS strings using the Fabric CSS parser instead of ViewConfig processing
|
|
281
287
|
*/
|
|
@@ -384,12 +390,24 @@ public object ReactNativeFeatureFlags {
|
|
|
384
390
|
@JvmStatic
|
|
385
391
|
public fun fuseboxEnabledRelease(): Boolean = accessor.fuseboxEnabledRelease()
|
|
386
392
|
|
|
393
|
+
/**
|
|
394
|
+
* Enable frame timings and screenshots support in the React Native DevTools CDP backend. This flag is global and should not be changed across React Host lifetimes.
|
|
395
|
+
*/
|
|
396
|
+
@JvmStatic
|
|
397
|
+
public fun fuseboxFrameRecordingEnabled(): Boolean = accessor.fuseboxFrameRecordingEnabled()
|
|
398
|
+
|
|
387
399
|
/**
|
|
388
400
|
* Enable network inspection support in the React Native DevTools CDP backend. Requires `enableBridgelessArchitecture`. This flag is global and should not be changed across React Host lifetimes.
|
|
389
401
|
*/
|
|
390
402
|
@JvmStatic
|
|
391
403
|
public fun fuseboxNetworkInspectionEnabled(): Boolean = accessor.fuseboxNetworkInspectionEnabled()
|
|
392
404
|
|
|
405
|
+
/**
|
|
406
|
+
* Enable Page.captureScreenshot CDP method support in the React Native DevTools CDP backend. This flag is global and should not be changed across React Host lifetimes.
|
|
407
|
+
*/
|
|
408
|
+
@JvmStatic
|
|
409
|
+
public fun fuseboxScreenshotCaptureEnabled(): Boolean = accessor.fuseboxScreenshotCaptureEnabled()
|
|
410
|
+
|
|
393
411
|
/**
|
|
394
412
|
* Hides offscreen VirtualViews on iOS by setting hidden = YES to avoid extra cost of views
|
|
395
413
|
*/
|
|
@@ -426,6 +444,18 @@ public object ReactNativeFeatureFlags {
|
|
|
426
444
|
@JvmStatic
|
|
427
445
|
public fun preventShadowTreeCommitExhaustion(): Boolean = accessor.preventShadowTreeCommitExhaustion()
|
|
428
446
|
|
|
447
|
+
/**
|
|
448
|
+
* Use the redesigned RedBox error overlay on Android, styled to match the LogBox visual language.
|
|
449
|
+
*/
|
|
450
|
+
@JvmStatic
|
|
451
|
+
public fun redBoxV2Android(): Boolean = accessor.redBoxV2Android()
|
|
452
|
+
|
|
453
|
+
/**
|
|
454
|
+
* Use the redesigned RedBox error overlay on iOS, styled to match the LogBox visual language.
|
|
455
|
+
*/
|
|
456
|
+
@JvmStatic
|
|
457
|
+
public fun redBoxV2IOS(): Boolean = accessor.redBoxV2IOS()
|
|
458
|
+
|
|
429
459
|
/**
|
|
430
460
|
* Function used to enable / disable Pressibility from using W3C Pointer Events for its hover callbacks
|
|
431
461
|
*/
|