react-native-tvos 0.83.9-0 → 0.83.10-1

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 (187) hide show
  1. package/Libraries/ActionSheetIOS/React-RCTActionSheet.podspec +1 -1
  2. package/Libraries/Animated/components/AnimatedScrollView.js +1 -1
  3. package/Libraries/AppDelegate/React-RCTAppDelegate.podspec +1 -1
  4. package/Libraries/Blob/React-RCTBlob.podspec +1 -1
  5. package/Libraries/Components/Button.js +2 -2
  6. package/Libraries/Components/ScrollView/ScrollView.d.ts +1 -1
  7. package/Libraries/Components/ScrollView/ScrollView.js +1 -1
  8. package/Libraries/Components/TV/TVViewPropTypes.js +9 -0
  9. package/Libraries/Components/TextInput/AndroidTextInputNativeComponent.js +1 -1
  10. package/Libraries/Components/TextInput/TextInput.flow.js +1 -1
  11. package/Libraries/Components/Touchable/Touchable.d.ts +1 -1
  12. package/Libraries/Components/View/View.js +7 -3
  13. package/Libraries/Components/View/ViewAccessibility.d.ts +1 -1
  14. package/Libraries/Components/View/ViewAccessibility.js +1 -1
  15. package/Libraries/Core/ReactNativeVersion.js +2 -2
  16. package/Libraries/Core/Timers/JSTimers.js +1 -1
  17. package/Libraries/Core/setUpNavigator.js +1 -1
  18. package/Libraries/EventEmitter/RCTNativeAppEventEmitter.d.ts +1 -1
  19. package/Libraries/FBLazyVector/FBLazyVector.podspec +1 -1
  20. package/Libraries/Image/ImageSource.d.ts +1 -1
  21. package/Libraries/Image/RCTImageLoader.mm +1 -1
  22. package/Libraries/Image/React-RCTImage.podspec +1 -1
  23. package/Libraries/Interaction/PanResponder.js +1 -1
  24. package/Libraries/LinkingIOS/React-RCTLinking.podspec +1 -1
  25. package/Libraries/NativeAnimation/React-RCTAnimation.podspec +1 -1
  26. package/Libraries/NativeComponent/TVViewConfig.js +1 -0
  27. package/Libraries/Network/React-RCTNetwork.podspec +1 -1
  28. package/Libraries/PushNotificationIOS/React-RCTPushNotification.podspec +1 -1
  29. package/Libraries/Renderer/README.md +2 -2
  30. package/Libraries/Required/RCTRequired.podspec +1 -1
  31. package/Libraries/Settings/React-RCTSettings.podspec +1 -1
  32. package/Libraries/Text/React-RCTText.podspec +1 -1
  33. package/Libraries/TypeSafety/RCTTypeSafety.podspec +1 -1
  34. package/Libraries/Utilities/PolyfillFunctions.js +1 -1
  35. package/Libraries/Vibration/React-RCTVibration.podspec +1 -1
  36. package/README-core.md +6 -6
  37. package/README.md +13 -1
  38. package/React/Base/RCTVersion.m +2 -2
  39. package/React/CoreModules/React-CoreModules.podspec +1 -1
  40. package/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm +49 -17
  41. package/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm +12 -1
  42. package/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm +34 -5
  43. package/React/React-RCTFBReactNativeSpec.podspec +1 -1
  44. package/React/React-RCTFabric.podspec +1 -1
  45. package/React/Runtime/React-RCTRuntime.podspec +1 -1
  46. package/React/Tests/Mounting/RCTViewComponentViewTests.mm +145 -0
  47. package/React/Views/ScrollView/RCTScrollView.m +1 -1
  48. package/React-Core.podspec +1 -1
  49. package/React.podspec +1 -1
  50. package/ReactAndroid/build.gradle.kts +1 -1
  51. package/ReactAndroid/gradle.properties +1 -1
  52. package/ReactAndroid/hermes-engine/build.gradle.kts +6 -0
  53. package/ReactAndroid/publish.gradle +5 -5
  54. package/ReactAndroid/src/main/AndroidManifest.xml +1 -1
  55. package/ReactAndroid/src/main/java/com/facebook/react/DebugCorePackage.kt +1 -1
  56. package/ReactAndroid/src/main/java/com/facebook/react/ReactActivityDelegate.java +5 -1
  57. package/ReactAndroid/src/main/java/com/facebook/react/ReactFragment.kt +11 -2
  58. package/ReactAndroid/src/main/java/com/facebook/react/bridge/queue/MessageQueueThreadImpl.kt +5 -1
  59. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/BundleDownloader.kt +2 -1
  60. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/CxxInspectorPackagerConnection.kt +99 -9
  61. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/DebugOverlayController.kt +8 -2
  62. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/MultipartStreamReader.kt +2 -1
  63. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/inspector/FrameTimingsObserver.kt +6 -0
  64. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/inspector/InspectorNetworkHelper.kt +1 -1
  65. package/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/SurfaceMountingManager.java +2 -2
  66. package/ReactAndroid/src/main/java/com/facebook/react/modules/core/JavaTimerManager.kt +1 -1
  67. package/ReactAndroid/src/main/java/com/facebook/react/modules/core/ReactAndroidHWInputDeviceHelper.java +1 -0
  68. package/ReactAndroid/src/main/java/com/facebook/react/modules/i18nmanager/I18nManagerModule.kt +8 -1
  69. package/ReactAndroid/src/main/java/com/facebook/react/modules/intent/IntentModule.kt +1 -1
  70. package/ReactAndroid/src/main/java/com/facebook/react/modules/network/NetworkingModule.kt +3 -3
  71. package/ReactAndroid/src/main/java/com/facebook/react/modules/permissions/PermissionsModule.kt +17 -3
  72. package/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/ReactNativeVersion.kt +2 -2
  73. package/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.kt +6 -1
  74. package/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactInstance.kt +1 -1
  75. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManager.java +1 -1
  76. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModuleConstantsHelper.kt +2 -1
  77. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/BackgroundDrawable.kt +0 -1
  78. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/BackgroundImageDrawable.kt +0 -1
  79. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/BorderDrawable.kt +0 -1
  80. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/CompositeBackgroundDrawable.kt +4 -1
  81. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/Drawable.kt +30 -0
  82. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/LayerDrawable.kt +32 -0
  83. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/OutlineDrawable.kt +0 -1
  84. package/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java +14 -4
  85. package/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java +14 -4
  86. package/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewHelper.kt +46 -10
  87. package/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewManager.kt +1 -1
  88. package/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactBaseTextShadowNode.kt +12 -2
  89. package/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextAnchorViewManager.kt +5 -0
  90. package/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextShadowNode.kt +38 -28
  91. package/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextView.java +23 -8
  92. package/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManager.kt +7 -0
  93. package/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.kt +9 -4
  94. package/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputLocalData.kt +13 -2
  95. package/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.kt +2 -2
  96. package/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputShadowNode.kt +13 -2
  97. package/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextSelectionWatcher.kt +1 -1
  98. package/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactDrawableHelper.kt +11 -2
  99. package/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.kt +1 -0
  100. package/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewManager.kt +13 -0
  101. package/ReactAndroid/src/main/jni/react/devsupport/JCxxInspectorPackagerConnectionWebSocket.cpp +29 -2
  102. package/ReactApple/Libraries/RCTFoundation/RCTDeprecation/RCTDeprecation.podspec +1 -1
  103. package/ReactApple/RCTSwiftUI/RCTSwiftUI.podspec +1 -1
  104. package/ReactApple/RCTSwiftUIWrapper/RCTSwiftUIWrapper.podspec +1 -1
  105. package/ReactCommon/React-Fabric.podspec +1 -1
  106. package/ReactCommon/React-FabricComponents.podspec +1 -1
  107. package/ReactCommon/React-FabricImage.podspec +1 -1
  108. package/ReactCommon/React-Mapbuffer.podspec +1 -1
  109. package/ReactCommon/ReactCommon.podspec +1 -1
  110. package/ReactCommon/callinvoker/React-callinvoker.podspec +1 -1
  111. package/ReactCommon/cxxreact/React-cxxreact.podspec +1 -1
  112. package/ReactCommon/cxxreact/ReactNativeVersion.h +3 -3
  113. package/ReactCommon/hermes/React-hermes.podspec +1 -1
  114. package/ReactCommon/hermes/executor/React-jsitracing.podspec +1 -1
  115. package/ReactCommon/jserrorhandler/React-jserrorhandler.podspec +1 -1
  116. package/ReactCommon/jsi/React-jsi.podspec +1 -1
  117. package/ReactCommon/jsiexecutor/React-jsiexecutor.podspec +1 -1
  118. package/ReactCommon/jsinspector-modern/InspectorInterfaces.cpp +7 -3
  119. package/ReactCommon/jsinspector-modern/React-jsinspector.podspec +1 -1
  120. package/ReactCommon/jsinspector-modern/TracingAgent.cpp +1 -5
  121. package/ReactCommon/jsinspector-modern/cdp/React-jsinspectorcdp.podspec +1 -1
  122. package/ReactCommon/jsinspector-modern/network/React-jsinspectornetwork.podspec +1 -1
  123. package/ReactCommon/jsinspector-modern/tracing/React-jsinspectortracing.podspec +1 -1
  124. package/ReactCommon/jsitooling/React-jsitooling.podspec +1 -1
  125. package/ReactCommon/logger/React-logger.podspec +1 -1
  126. package/ReactCommon/oscompat/React-oscompat.podspec +1 -1
  127. package/ReactCommon/react/debug/React-debug.podspec +1 -1
  128. package/ReactCommon/react/debug/redbox/JscSafeUrl.h +1 -1
  129. package/ReactCommon/react/featureflags/React-featureflags.podspec +1 -1
  130. package/ReactCommon/react/nativemodule/core/platform/android/ReactCommon/JavaTurboModule.cpp +1 -1
  131. package/ReactCommon/react/nativemodule/core/platform/ios/React-NativeModulesApple.podspec +1 -1
  132. package/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTInteropTurboModule.mm +1 -1
  133. package/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModule.mm +1 -1
  134. package/ReactCommon/react/nativemodule/defaults/React-defaultsnativemodule.podspec +1 -1
  135. package/ReactCommon/react/nativemodule/dom/React-domnativemodule.podspec +1 -1
  136. package/ReactCommon/react/nativemodule/featureflags/React-featureflagsnativemodule.podspec +1 -1
  137. package/ReactCommon/react/nativemodule/idlecallbacks/React-idlecallbacksnativemodule.podspec +1 -1
  138. package/ReactCommon/react/nativemodule/intersectionobserver/React-intersectionobservernativemodule.podspec +1 -1
  139. package/ReactCommon/react/nativemodule/microtasks/React-microtasksnativemodule.podspec +1 -1
  140. package/ReactCommon/react/nativemodule/mutationobserver/React-mutationobservernativemodule.podspec +1 -1
  141. package/ReactCommon/react/nativemodule/samples/ReactCommon-Samples.podspec +1 -1
  142. package/ReactCommon/react/nativemodule/webperformance/React-webperformancenativemodule.podspec +1 -1
  143. package/ReactCommon/react/networking/React-networking.podspec +1 -1
  144. package/ReactCommon/react/performance/cdpmetrics/React-performancecdpmetrics.podspec +1 -1
  145. package/ReactCommon/react/performance/timeline/React-performancetimeline.podspec +1 -1
  146. package/ReactCommon/react/renderer/animated/internal/primitives.h +1 -1
  147. package/ReactCommon/react/renderer/components/view/BaseViewProps.cpp +7 -0
  148. package/ReactCommon/react/renderer/components/view/BaseViewProps.h +1 -0
  149. package/ReactCommon/react/renderer/components/view/platform/android/react/renderer/components/view/HostPlatformViewProps.cpp +18 -0
  150. package/ReactCommon/react/renderer/components/view/platform/android/react/renderer/components/view/HostPlatformViewProps.h +1 -0
  151. package/ReactCommon/react/renderer/consistency/React-rendererconsistency.podspec +1 -1
  152. package/ReactCommon/react/renderer/css/React-renderercss.podspec +1 -1
  153. package/ReactCommon/react/renderer/debug/React-rendererdebug.podspec +1 -1
  154. package/ReactCommon/react/renderer/graphics/React-graphics.podspec +1 -1
  155. package/ReactCommon/react/renderer/imagemanager/platform/ios/React-ImageManager.podspec +1 -1
  156. package/ReactCommon/react/renderer/mounting/internal/CullingContext.cpp +1 -1
  157. package/ReactCommon/react/renderer/runtimescheduler/React-runtimescheduler.podspec +1 -1
  158. package/ReactCommon/react/runtime/React-RuntimeCore.podspec +1 -1
  159. package/ReactCommon/react/runtime/React-RuntimeHermes.podspec +1 -1
  160. package/ReactCommon/react/runtime/platform/ios/React-RuntimeApple.podspec +1 -1
  161. package/ReactCommon/react/timing/React-timing.podspec +1 -1
  162. package/ReactCommon/react/utils/React-utils.podspec +1 -1
  163. package/ReactCommon/reactperflogger/React-perflogger.podspec +1 -1
  164. package/ReactCommon/runtimeexecutor/React-runtimeexecutor.podspec +1 -1
  165. package/ReactCommon/yoga/Yoga.podspec +2 -2
  166. package/ReactCommon/yoga/yoga/algorithm/AbsoluteLayout.cpp +2 -0
  167. package/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp +11 -7
  168. package/ReactCommon/yoga/yoga/algorithm/CalculateLayout.h +2 -0
  169. package/ReactCommon/yoga/yoga/node/Node.cpp +6 -1
  170. package/gradle/libs.versions.toml +1 -1
  171. package/package.json +9 -9
  172. package/scripts/cocoapods/rncore.rb +26 -8
  173. package/scripts/cocoapods/rndependencies.rb +26 -5
  174. package/scripts/cocoapods/spm.rb +1 -1
  175. package/scripts/cocoapods/utils.rb +2 -2
  176. package/scripts/codegen/templates/ReactAppDependencyProvider.podspec.template +1 -1
  177. package/scripts/codegen/templates/ReactCodegen.podspec.template +1 -1
  178. package/scripts/ios-configure-glog.sh +1 -1
  179. package/sdks/hermes-engine/hermes-engine.podspec +6 -1
  180. package/sdks/hermes-engine/hermes-utils.rb +27 -5
  181. package/src/private/types/HostInstance.js +1 -1
  182. package/src/types/globals.d.ts +2 -2
  183. package/third-party-podspecs/RCT-Folly.podspec +1 -1
  184. package/third-party-podspecs/ReactNativeDependencies.podspec +1 -1
  185. package/third-party-podspecs/glog.podspec +1 -1
  186. package/types/public/ReactNativeTVTypes.d.ts +9 -0
  187. package/types/public/ReactNativeTypes.d.ts +2 -2
@@ -775,12 +775,23 @@ static NSSet<NSNumber *> *returnKeyTypesSet;
775
775
 
776
776
  - (void)_setAttributedString:(NSAttributedString *)attributedString
777
777
  {
778
+ #if TARGET_OS_TV
779
+ // Attribute-free string prevents the tvOS keyboard from inheriting the component's small font.
780
+ if ([attributedString.string isEqualToString:_backedTextInputView.attributedText.string]) {
781
+ return;
782
+ }
783
+ #else
778
784
  if ([self _textOf:attributedString equals:_backedTextInputView.attributedText]) {
779
785
  return;
780
786
  }
787
+ #endif
781
788
  UITextRange *selectedRange = _backedTextInputView.selectedTextRange;
782
789
  NSInteger oldTextLength = _backedTextInputView.attributedText.string.length;
790
+ #if TARGET_OS_TV
791
+ _backedTextInputView.attributedText = [[NSAttributedString alloc] initWithString:attributedString.string];
792
+ #else
783
793
  _backedTextInputView.attributedText = attributedString;
794
+ #endif
784
795
  // Updating the UITextView attributedText, for example changing the lineHeight, the color or adding
785
796
  // a new paragraph with \n, causes the cursor to move to the end of the Text and scroll.
786
797
  // This is fixed by restoring the cursor position and scrolling to that position (iOS issue 652653).
@@ -805,7 +816,7 @@ static NSSet<NSNumber *> *returnKeyTypesSet;
805
816
  // Ensure that newly typed text will inherit any custom attributes. We follow the logic of RN Android, where attributes
806
817
  // to the left of the cursor are copied into new text, unless we are at the start of the field, in which case we will
807
818
  // copy the attributes from text to the right. This allows consistency between backed input and new AttributedText
808
- // https://github.com/facebook/react-native/blob/3102a58df38d96f3dacef0530e4dbb399037fcd2/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/internal/span/SetSpanOperation.kt#L30
819
+ // https://github.com/react/react-native/blob/3102a58df38d96f3dacef0530e4dbb399037fcd2/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/internal/span/SetSpanOperation.kt#L30
809
820
  - (void)_updateTypingAttributes
810
821
  {
811
822
  if (_backedTextInputView.attributedText.length > 0 && _backedTextInputView.selectedTextRange != nil) {
@@ -697,11 +697,18 @@ const CGFloat BACKGROUND_COLOR_ZPOSITION = -1024.0f;
697
697
  [_reactSubviews removeObjectAtIndex:index];
698
698
  } else {
699
699
  RCTAssert(
700
- childComponentView.superview == self.currentContainerView,
701
- @"Attempt to unmount a view which is mounted inside different view. (parent: %@, child: %@, index: %@)",
700
+ childComponentView.superview != nil,
701
+ @"Attempt to unmount a view which is not mounted. (parent: %@, child: %@, index: %@)",
702
702
  self,
703
703
  childComponentView,
704
704
  @(index));
705
+ RCTAssert(
706
+ childComponentView.superview == self.currentContainerView,
707
+ @"Attempt to unmount a view which is mounted inside a different view. (parent: %@, child: %@, index: %@, existing parent: %@)",
708
+ self,
709
+ childComponentView,
710
+ @(index),
711
+ @([childComponentView.superview tag]));
705
712
  RCTAssert(
706
713
  (self.currentContainerView.subviews.count > index) &&
707
714
  [self.currentContainerView.subviews objectAtIndex:index] == childComponentView,
@@ -716,6 +723,30 @@ const CGFloat BACKGROUND_COLOR_ZPOSITION = -1024.0f;
716
723
  [childComponentView removeFromSuperview];
717
724
  }
718
725
 
726
+ - (void)_updateRemoveClippedSubviewsState
727
+ {
728
+ if (_removeClippedSubviews) {
729
+ // Toggled ON: populate _reactSubviews from the current view hierarchy.
730
+ // Actual clipping will happen on the next scroll event.
731
+ RCTAssert(
732
+ _reactSubviews.count == 0,
733
+ @"_reactSubviews should be empty when toggling removeClippedSubviews on. (view: %@, count: %@)",
734
+ self,
735
+ @(_reactSubviews.count));
736
+ if (self.currentContainerView.subviews.count > 0) {
737
+ _reactSubviews = [NSMutableArray arrayWithArray:self.currentContainerView.subviews];
738
+ }
739
+ } else {
740
+ // Toggled OFF: re-mount all children in the correct order, then clear the tracking array.
741
+ // addSubview: on an already-present child moves it to the front, so iterating in order
742
+ // produces the correct subview ordering.
743
+ for (UIView *view in _reactSubviews) {
744
+ [self.currentContainerView addSubview:view];
745
+ }
746
+ [_reactSubviews removeAllObjects];
747
+ }
748
+ }
749
+
719
750
  - (void)updateClippedSubviewsWithClipRect:(CGRect)clipRect relativeToView:(UIView *)clipView
720
751
  {
721
752
  if (!_removeClippedSubviews) {
@@ -781,9 +812,7 @@ const CGFloat BACKGROUND_COLOR_ZPOSITION = -1024.0f;
781
812
  if (!ReactNativeFeatureFlags::enableViewCulling()) {
782
813
  if (oldViewProps.removeClippedSubviews != newViewProps.removeClippedSubviews) {
783
814
  _removeClippedSubviews = newViewProps.removeClippedSubviews;
784
- if (_removeClippedSubviews && self.currentContainerView.subviews.count > 0) {
785
- _reactSubviews = [NSMutableArray arrayWithArray:self.currentContainerView.subviews];
786
- }
815
+ [self _updateRemoveClippedSubviewsState];
787
816
  }
788
817
  }
789
818
 
@@ -11,7 +11,7 @@ require "json"
11
11
  package = JSON.parse(File.read(File.join(__dir__, "..", "package.json")))
12
12
  version = package['version']
13
13
 
14
- source = { :git => 'https://github.com/facebook/react-native.git' }
14
+ source = { :git => 'https://github.com/react/react-native.git' }
15
15
  if version == '1000.0.0'
16
16
  # This is an unpublished version, use the latest commit hash of the react-native repo, which we’re presumably in.
17
17
  source[:commit] = `git rev-parse HEAD`.strip if system("git rev-parse --git-dir > /dev/null 2>&1")
@@ -8,7 +8,7 @@ require "json"
8
8
  package = JSON.parse(File.read(File.join(__dir__, "..", "package.json")))
9
9
  version = package['version']
10
10
 
11
- source = { :git => 'https://github.com/facebook/react-native.git' }
11
+ source = { :git => 'https://github.com/react/react-native.git' }
12
12
  if version == '1000.0.0'
13
13
  # This is an unpublished version, use the latest commit hash of the react-native repo, which we’re presumably in.
14
14
  source[:commit] = `git rev-parse HEAD`.strip if system("git rev-parse --git-dir > /dev/null 2>&1")
@@ -8,7 +8,7 @@ require "json"
8
8
  package = JSON.parse(File.read(File.join(__dir__, "..", "..", "package.json")))
9
9
  version = package['version']
10
10
 
11
- source = { :git => 'https://github.com/facebook/react-native.git' }
11
+ source = { :git => 'https://github.com/react/react-native.git' }
12
12
  if version == '1000.0.0'
13
13
  # This is an unpublished version, use the latest commit hash of the react-native repo, which we’re presumably in.
14
14
  source[:commit] = `git rev-parse HEAD`.strip if system("git rev-parse --git-dir > /dev/null 2>&1")
@@ -0,0 +1,145 @@
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
+ #import <React/RCTViewComponentView.h>
9
+ #import <XCTest/XCTest.h>
10
+ #import <react/renderer/components/view/ViewProps.h>
11
+ #import <react/renderer/components/view/ViewShadowNode.h>
12
+
13
+ using namespace facebook::react;
14
+
15
+ static Props::Shared makeViewProps(bool removeClippedSubviews)
16
+ {
17
+ auto props = std::make_shared<ViewProps>();
18
+ props->removeClippedSubviews = removeClippedSubviews;
19
+ return props;
20
+ }
21
+
22
+ @interface RCTViewComponentViewTests : XCTestCase
23
+ @end
24
+
25
+ @implementation RCTViewComponentViewTests
26
+
27
+ #pragma mark - removeClippedSubviews toggle
28
+
29
+ - (void)testToggleRemoveClippedSubviewsOffRemountsClippedChildren
30
+ {
31
+ RCTViewComponentView *parent = [RCTViewComponentView new];
32
+ UIView *child1 = [UIView new];
33
+ child1.frame = CGRectMake(0, 0, 50, 50);
34
+ UIView *child2 = [UIView new];
35
+ child2.frame = CGRectMake(0, 200, 50, 50);
36
+ UIView *child3 = [UIView new];
37
+ child3.frame = CGRectMake(0, 400, 50, 50);
38
+
39
+ // Mount children normally
40
+ [parent mountChildComponentView:(id)child1 index:0];
41
+ [parent mountChildComponentView:(id)child2 index:1];
42
+ [parent mountChildComponentView:(id)child3 index:2];
43
+
44
+ XCTAssertEqual(parent.subviews.count, 3u);
45
+
46
+ // Toggle removeClippedSubviews ON via props
47
+ auto propsOn = makeViewProps(true);
48
+ [parent updateProps:propsOn oldProps:ViewShadowNode::defaultSharedProps()];
49
+
50
+ // Simulate clipping: remove child2 and child3 from superview (as updateClippedSubviewsWithClipRect would)
51
+ [child2 removeFromSuperview];
52
+ [child3 removeFromSuperview];
53
+ XCTAssertEqual(parent.subviews.count, 1u);
54
+ XCTAssertNil(child2.superview);
55
+ XCTAssertNil(child3.superview);
56
+
57
+ // Toggle removeClippedSubviews OFF via props
58
+ auto propsOff = makeViewProps(false);
59
+ [parent updateProps:propsOff oldProps:propsOn];
60
+
61
+ // All children should be re-mounted
62
+ XCTAssertEqual(parent.subviews.count, 3u);
63
+ XCTAssertEqual(child1.superview, parent);
64
+ XCTAssertEqual(child2.superview, parent);
65
+ XCTAssertEqual(child3.superview, parent);
66
+ }
67
+
68
+ - (void)testToggleRemoveClippedSubviewsOffPreservesOrder
69
+ {
70
+ RCTViewComponentView *parent = [RCTViewComponentView new];
71
+ UIView *child1 = [UIView new];
72
+ child1.frame = CGRectMake(0, 0, 50, 50);
73
+ UIView *child2 = [UIView new];
74
+ child2.frame = CGRectMake(0, 100, 50, 50);
75
+ UIView *child3 = [UIView new];
76
+ child3.frame = CGRectMake(0, 200, 50, 50);
77
+
78
+ [parent mountChildComponentView:(id)child1 index:0];
79
+ [parent mountChildComponentView:(id)child2 index:1];
80
+ [parent mountChildComponentView:(id)child3 index:2];
81
+
82
+ // Toggle ON and clip child1 (first child)
83
+ auto propsOn = makeViewProps(true);
84
+ [parent updateProps:propsOn oldProps:ViewShadowNode::defaultSharedProps()];
85
+ [child1 removeFromSuperview];
86
+ XCTAssertEqual(parent.subviews.count, 2u);
87
+
88
+ // Toggle OFF — all children re-mounted in correct order
89
+ auto propsOff = makeViewProps(false);
90
+ [parent updateProps:propsOff oldProps:propsOn];
91
+
92
+ XCTAssertEqual(parent.subviews.count, 3u);
93
+ XCTAssertEqual(parent.subviews[0], child1);
94
+ XCTAssertEqual(parent.subviews[1], child2);
95
+ XCTAssertEqual(parent.subviews[2], child3);
96
+ }
97
+
98
+ - (void)testToggleRemoveClippedSubviewsOffClearsReactSubviews
99
+ {
100
+ RCTViewComponentView *parent = [RCTViewComponentView new];
101
+ UIView *child1 = [UIView new];
102
+ child1.frame = CGRectMake(0, 0, 50, 50);
103
+
104
+ [parent mountChildComponentView:(id)child1 index:0];
105
+
106
+ // Toggle ON
107
+ auto propsOn = makeViewProps(true);
108
+ [parent updateProps:propsOn oldProps:ViewShadowNode::defaultSharedProps()];
109
+
110
+ // Toggle OFF
111
+ auto propsOff = makeViewProps(false);
112
+ [parent updateProps:propsOff oldProps:propsOn];
113
+
114
+ // _reactSubviews should be cleared
115
+ NSMutableArray *reactSubviews = [parent valueForKey:@"_reactSubviews"];
116
+ XCTAssertEqual(reactSubviews.count, 0u);
117
+ }
118
+
119
+ - (void)testUnmountAfterToggleOffCleansUpReactSubviews
120
+ {
121
+ RCTViewComponentView *parent = [RCTViewComponentView new];
122
+ UIView *child1 = [UIView new];
123
+ child1.frame = CGRectMake(0, 0, 50, 50);
124
+ UIView *child2 = [UIView new];
125
+ child2.frame = CGRectMake(0, 100, 50, 50);
126
+
127
+ // Toggle ON first, then mount children
128
+ auto propsOn = makeViewProps(true);
129
+ [parent updateProps:propsOn oldProps:ViewShadowNode::defaultSharedProps()];
130
+ [parent mountChildComponentView:(id)child1 index:0];
131
+ [parent mountChildComponentView:(id)child2 index:1];
132
+
133
+ // Toggle OFF — re-mounts children
134
+ auto propsOff = makeViewProps(false);
135
+ [parent updateProps:propsOff oldProps:propsOn];
136
+
137
+ XCTAssertEqual(parent.subviews.count, 2u);
138
+
139
+ // Unmount child2 — should succeed without assert failures
140
+ [parent unmountChildComponentView:(id)child2 index:1];
141
+ XCTAssertEqual(parent.subviews.count, 1u);
142
+ XCTAssertNil(child2.superview);
143
+ }
144
+
145
+ @end
@@ -366,7 +366,7 @@ static inline UIViewAnimationOptions animationOptionsWithCurve(UIViewAnimationCu
366
366
  if (@available(iOS 14.0, *)) {
367
367
  // On iOS when Prefer Cross-Fade Transitions is enabled, the keyboard position
368
368
  // & height is reported differently (0 instead of Y position value matching height of frame)
369
- // Fixes similar issue we saw with https://github.com/facebook/react-native/pull/34503
369
+ // Fixes similar issue we saw with https://github.com/react/react-native/pull/34503
370
370
  if (UIAccessibilityPrefersCrossFadeTransitions() && endFrame.size.height == 0) {
371
371
  newContentOffset.y = 0;
372
372
  newEdgeInsets.bottom = 0;
@@ -8,7 +8,7 @@ require "json"
8
8
  package = JSON.parse(File.read(File.join(__dir__, "package.json")))
9
9
  version = package['version']
10
10
 
11
- source = { :git => 'https://github.com/facebook/react-native.git' }
11
+ source = { :git => 'https://github.com/react/react-native.git' }
12
12
  if version == '1000.0.0'
13
13
  # This is an unpublished version, use the latest commit hash of the react-native repo, which we’re presumably in.
14
14
  source[:commit] = `git rev-parse HEAD`.strip if system("git rev-parse --git-dir > /dev/null 2>&1")
package/React.podspec CHANGED
@@ -8,7 +8,7 @@ require "json"
8
8
  package = JSON.parse(File.read(File.join(__dir__, "package.json")))
9
9
  version = package['version']
10
10
 
11
- source = { :git => 'https://github.com/facebook/react-native.git' }
11
+ source = { :git => 'https://github.com/react/react-native.git' }
12
12
  if version == '1000.0.0'
13
13
  # This is an unpublished version, use the latest commit hash of the react-native repo, which we’re presumably in.
14
14
  source[:commit] = `git rev-parse HEAD`.strip if system("git rev-parse --git-dir > /dev/null 2>&1")
@@ -749,7 +749,7 @@ apply(from = "./publish.gradle")
749
749
  // We need to override the artifact ID as this project is called `ReactAndroid` but
750
750
  // the maven coordinates are on `react-android`.
751
751
  // Please note that the original coordinates, `react-native`, have been voided
752
- // as they caused https://github.com/facebook/react-native/issues/35210
752
+ // as they caused https://github.com/react/react-native/issues/35210
753
753
  publishing {
754
754
  publications { getByName("release", MavenPublication::class) { artifactId = "react-android" } }
755
755
  }
@@ -1,4 +1,4 @@
1
- VERSION_NAME=0.83.9-0
1
+ VERSION_NAME=0.83.10-1
2
2
  react.internal.publishingGroup=io.github.react-native-tvos
3
3
  react.internal.hermesPublishingGroup=com.facebook.hermes
4
4
 
@@ -392,3 +392,9 @@ tasks.withType<JavaCompile>().configureEach {
392
392
  options.compilerArgs.add("-Xlint:deprecation,unchecked")
393
393
  options.compilerArgs.add("-Werror")
394
394
  }
395
+
396
+ /* Publishing Configuration */
397
+ // Reuses the publish.gradle template applied to ReactAndroid; the file is
398
+ // generated by the build-android-artifacts EAS workflow. Resulting artifact
399
+ // coordinate: io.github.react-native-tvos:hermes-engine:<version>.
400
+ apply(from = "../publish.gradle")
@@ -37,7 +37,7 @@ publishing {
37
37
  pom {
38
38
  name = "react-native"
39
39
  description = "A framework for building native apps with React"
40
- url = "https://github.com/facebook/react-native"
40
+ url = "https://github.com/react/react-native"
41
41
 
42
42
  developers {
43
43
  developer {
@@ -49,15 +49,15 @@ publishing {
49
49
  licenses {
50
50
  license {
51
51
  name = "MIT License"
52
- url = "https://github.com/facebook/react-native/blob/HEAD/LICENSE"
52
+ url = "https://github.com/react/react-native/blob/HEAD/LICENSE"
53
53
  distribution = "repo"
54
54
  }
55
55
  }
56
56
 
57
57
  scm {
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"
58
+ url = "https://github.com/react/react-native.git"
59
+ connection = "scm:git:https://github.com/react/react-native.git"
60
+ developerConnection = "scm:git:git@github.com:react/react-native.git"
61
61
  }
62
62
  }
63
63
  }
@@ -8,7 +8,7 @@
8
8
  up from the file to lint until it find an AndroidManifest with a minSdkVersion. This is then used
9
9
  as the min SDK to lint the file.-->
10
10
  <uses-sdk
11
- android:minSdkVersion="24"
11
+ android:minSdkVersion="22"
12
12
  android:targetSdkVersion="36"
13
13
  />
14
14
 
@@ -49,5 +49,5 @@ public class DebugCorePackage public constructor() :
49
49
  reactContext: ReactApplicationContext,
50
50
  viewManagerName: String,
51
51
  ): ViewManager<*, *>? =
52
- viewManagersMap.getOrDefault(viewManagerName, null)?.provider?.get() as? ViewManager<*, *>
52
+ viewManagersMap[viewManagerName]?.provider?.get() as? ViewManager<*, *>
53
53
  }
@@ -252,7 +252,11 @@ public class ReactActivityDelegate {
252
252
  public void requestPermissions(
253
253
  String[] permissions, int requestCode, @Nullable PermissionListener listener) {
254
254
  mPermissionListener = listener;
255
- getPlainActivity().requestPermissions(permissions, requestCode);
255
+ // Runtime permissions were introduced in API 23 (M). On older platforms permissions are
256
+ // granted at install time, so there is nothing to request.
257
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
258
+ getPlainActivity().requestPermissions(permissions, requestCode);
259
+ }
256
260
  }
257
261
 
258
262
  public void onRequestPermissionsResult(
@@ -9,7 +9,9 @@ package com.facebook.react
9
9
 
10
10
  import android.app.Activity
11
11
  import android.content.Intent
12
+ import android.os.Build
12
13
  import android.os.Bundle
14
+ import android.os.Process
13
15
  import android.view.KeyEvent
14
16
  import android.view.LayoutInflater
15
17
  import android.view.View
@@ -160,7 +162,11 @@ public open class ReactFragment : Fragment(), PermissionAwareActivity {
160
162
  activity?.checkPermission(permission, pid, uid) ?: 0
161
163
 
162
164
  override fun checkSelfPermission(permission: String): Int =
163
- activity?.checkSelfPermission(permission) ?: 0
165
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
166
+ activity?.checkSelfPermission(permission) ?: 0
167
+ } else {
168
+ activity?.checkPermission(permission, Process.myPid(), Process.myUid()) ?: 0
169
+ }
164
170
 
165
171
  @Suppress("DEPRECATION")
166
172
  override fun requestPermissions(
@@ -169,7 +175,10 @@ public open class ReactFragment : Fragment(), PermissionAwareActivity {
169
175
  listener: PermissionListener?,
170
176
  ) {
171
177
  permissionListener = listener
172
- requestPermissions(permissions, requestCode)
178
+ // Runtime permissions were introduced in API 23 (M); on older platforms they are install-time.
179
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
180
+ requestPermissions(permissions, requestCode)
181
+ }
173
182
  }
174
183
 
175
184
  /** Builder class to help instantiate a ReactFragment. */
@@ -7,6 +7,7 @@
7
7
 
8
8
  package com.facebook.react.bridge.queue
9
9
 
10
+ import android.os.Build
10
11
  import android.os.Looper
11
12
  import android.os.Process
12
13
  import com.facebook.common.logging.FLog
@@ -104,7 +105,10 @@ private constructor(
104
105
  }
105
106
  }
106
107
 
107
- public override fun isIdle(): Boolean = looper.queue.isIdle
108
+ public override fun isIdle(): Boolean =
109
+ // Looper.getQueue()/MessageQueue.isIdle() require API 23 (M); there is no pre-M way to
110
+ // introspect another thread's queue, so report idle to avoid blocking instrumentation.
111
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) looper.queue.isIdle else true
108
112
 
109
113
  public companion object {
110
114
  @JvmStatic
@@ -200,7 +200,8 @@ public class BundleDownloader public constructor(private val client: OkHttpClien
200
200
  // The http status code for each separate chunk is in the X-Http-Status header.
201
201
  var status = response.code()
202
202
  if (headers.containsKey("X-Http-Status")) {
203
- status = headers.getOrDefault("X-Http-Status", "0").toInt()
203
+ // Map.getOrDefault requires API 24; use Kotlin get-with-default (API 1).
204
+ status = (headers["X-Http-Status"] ?: "0").toInt()
204
205
  }
205
206
  processBundleResult(
206
207
  url,
@@ -9,12 +9,18 @@ package com.facebook.react.devsupport
9
9
 
10
10
  import android.os.Handler
11
11
  import android.os.Looper
12
+ import com.facebook.common.logging.FLog
12
13
  import com.facebook.jni.HybridData
13
14
  import com.facebook.proguard.annotations.DoNotStrip
14
15
  import com.facebook.proguard.annotations.DoNotStripAny
16
+ import com.facebook.react.common.annotations.VisibleForTesting
15
17
  import com.facebook.react.devsupport.inspector.DevSupportHttpClient
16
18
  import com.facebook.soloader.SoLoader
17
19
  import java.io.Closeable
20
+ import java.nio.ByteBuffer
21
+ import java.nio.charset.StandardCharsets
22
+ import java.util.ArrayDeque
23
+ import java.util.Queue
18
24
  import okhttp3.Request
19
25
  import okhttp3.Response
20
26
  import okhttp3.WebSocket
@@ -66,7 +72,7 @@ internal class CxxInspectorPackagerConnection(
66
72
  */
67
73
  @DoNotStripAny
68
74
  private interface IWebSocket : Closeable {
69
- fun send(message: String)
75
+ fun send(chunk: ByteBuffer)
70
76
 
71
77
  /**
72
78
  * Close the WebSocket connection. NOTE: There is no close() method in the C++ interface.
@@ -75,6 +81,95 @@ internal class CxxInspectorPackagerConnection(
75
81
  override fun close()
76
82
  }
77
83
 
84
+ /**
85
+ * A simple WebSocket wrapper that prevents having more than 16MiB of messages queued
86
+ * simultaneously. This is done to stop OkHttp from closing the WebSocket connection.
87
+ *
88
+ * https://github.com/react/react-native/issues/39651.
89
+ * https://github.com/square/okhttp/blob/4e7dbec1ea6c9cf8d80422ac9d44b9b185c749a3/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/ws/RealWebSocket.kt#L684.
90
+ */
91
+ private class InspectorPackagerWebSocketImpl(
92
+ private val nativeWebSocket: WebSocket,
93
+ private val handler: Handler,
94
+ ) : IWebSocket {
95
+ private val messageQueue: Queue<Pair<String, Int>> = ArrayDeque()
96
+ private val queueLock = Any()
97
+ private val drainRunnable =
98
+ object : Runnable {
99
+ override fun run() {
100
+ FLog.d(TAG, "Attempting to drain the message queue after ${drainDelayMs}ms")
101
+ tryDrainQueue()
102
+ }
103
+ }
104
+
105
+ /**
106
+ * We are providing a String to OkHttp's WebSocket, because there is no guarantee that all CDP
107
+ * clients will support binary data format.
108
+ */
109
+ override fun send(chunk: ByteBuffer) {
110
+ synchronized(queueLock) {
111
+ val messageSize = chunk.capacity()
112
+ val message = StandardCharsets.UTF_8.decode(chunk).toString()
113
+ val currentQueueSize = nativeWebSocket.queueSize()
114
+
115
+ if (currentQueueSize + messageSize > MAX_QUEUE_SIZE) {
116
+ FLog.d(TAG, "Reached queue size limit. Queueing the message.")
117
+ messageQueue.offer(Pair(message, messageSize))
118
+ scheduleDrain()
119
+ } else {
120
+ if (messageQueue.isEmpty()) {
121
+ nativeWebSocket.send(message)
122
+ } else {
123
+ messageQueue.offer(Pair(message, messageSize))
124
+ tryDrainQueue()
125
+ }
126
+ }
127
+ }
128
+ }
129
+
130
+ override fun close() {
131
+ synchronized(queueLock) {
132
+ handler.removeCallbacks(drainRunnable)
133
+ messageQueue.clear()
134
+ nativeWebSocket.close(1000, "End of session")
135
+ }
136
+ }
137
+
138
+ private fun tryDrainQueue() {
139
+ synchronized(queueLock) {
140
+ while (messageQueue.isNotEmpty()) {
141
+ val (nextMessage, nextMessageSize) = messageQueue.peek() ?: break
142
+ val currentQueueSize = nativeWebSocket.queueSize()
143
+
144
+ if (currentQueueSize + nextMessageSize <= MAX_QUEUE_SIZE) {
145
+ messageQueue.poll()
146
+ if (!nativeWebSocket.send(nextMessage)) {
147
+ // The WebSocket is closing, closed, or cancelled.
148
+ handler.removeCallbacks(drainRunnable)
149
+ messageQueue.clear()
150
+
151
+ break
152
+ }
153
+ } else {
154
+ scheduleDrain()
155
+ break
156
+ }
157
+ }
158
+ }
159
+ }
160
+
161
+ private fun scheduleDrain() {
162
+ FLog.d(TAG, "Scheduled a task to drain messages queue.")
163
+ handler.removeCallbacks(drainRunnable)
164
+ handler.postDelayed(drainRunnable, drainDelayMs)
165
+ }
166
+
167
+ companion object {
168
+ private val TAG: String = InspectorPackagerWebSocketImpl::class.java.simpleName
169
+ private const val drainDelayMs: Long = 100
170
+ }
171
+ }
172
+
78
173
  /** Java implementation of the C++ InspectorPackagerConnectionDelegate interface. */
79
174
  private class DelegateImpl {
80
175
  private val httpClient = DevSupportHttpClient.websocketClient
@@ -124,15 +219,8 @@ internal class CxxInspectorPackagerConnection(
124
219
  }
125
220
  },
126
221
  )
127
- return object : IWebSocket {
128
- override fun send(message: String) {
129
- webSocket.send(message)
130
- }
131
222
 
132
- override fun close() {
133
- webSocket.close(1000, "End of session")
134
- }
135
- }
223
+ return InspectorPackagerWebSocketImpl(webSocket, handler)
136
224
  }
137
225
 
138
226
  @DoNotStrip
@@ -146,6 +234,8 @@ internal class CxxInspectorPackagerConnection(
146
234
  SoLoader.loadLibrary("react_devsupportjni")
147
235
  }
148
236
 
237
+ @VisibleForTesting internal const val MAX_QUEUE_SIZE = 16L * 1024 * 1024 // 16MiB
238
+
149
239
  @JvmStatic
150
240
  private external fun initHybrid(
151
241
  url: String,
@@ -11,6 +11,7 @@ import android.content.Context
11
11
  import android.content.Intent
12
12
  import android.graphics.PixelFormat
13
13
  import android.net.Uri
14
+ import android.os.Build
14
15
  import android.provider.Settings
15
16
  import android.view.WindowManager
16
17
  import android.widget.FrameLayout
@@ -60,6 +61,11 @@ internal class DebugOverlayController(private val reactContext: ReactContext) {
60
61
  @JvmStatic
61
62
  fun requestPermission(context: Context) {
62
63
  // Get permission to show debug overlay in dev builds.
64
+ // Settings.canDrawOverlays / ACTION_MANAGE_OVERLAY_PERMISSION were introduced in API 23 (M);
65
+ // on older platforms the overlay permission is granted at install time.
66
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
67
+ return
68
+ }
63
69
  if (!Settings.canDrawOverlays(context)) {
64
70
  val intent =
65
71
  Intent(
@@ -79,8 +85,8 @@ internal class DebugOverlayController(private val reactContext: ReactContext) {
79
85
 
80
86
  private fun permissionCheck(context: Context): Boolean {
81
87
  // Get permission to show debug overlay in dev builds.
82
- // overlay permission not yet granted
83
- return Settings.canDrawOverlays(context)
88
+ // overlay permission not yet granted (always granted at install time before API 23 (M))
89
+ return Build.VERSION.SDK_INT < Build.VERSION_CODES.M || Settings.canDrawOverlays(context)
84
90
  }
85
91
 
86
92
  private fun canHandleIntent(context: Context, intent: Intent): Boolean {
@@ -155,7 +155,8 @@ internal class MultipartStreamReader(
155
155
  val currentTime = System.currentTimeMillis()
156
156
  if (currentTime - lastProgressEvent > 16 || isFinal) {
157
157
  lastProgressEvent = currentTime
158
- val headersContentLength = headers.getOrDefault("Content-Length", "0").toLong()
158
+ // Map.getOrDefault requires API 24; use Kotlin's get-with-default (API 1) instead.
159
+ val headersContentLength = (headers["Content-Length"] ?: "0").toLong()
159
160
  listener.onChunkProgress(headers, contentLength, headersContentLength)
160
161
  }
161
162
  }