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
@@ -103,6 +103,12 @@ internal class FrameTimingsObserver(
103
103
  if (!isTracing) {
104
104
  return@OnFrameMetricsAvailableListener
105
105
  }
106
+ // FrameMetrics#getMetric requires API 24 (N). This listener is only ever registered on
107
+ // API 24+ (see isSupported / the guarded construction in ReactHostImpl), so this is a
108
+ // defensive no-op that also makes the API level explicit to the linter.
109
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
110
+ return@OnFrameMetricsAvailableListener
111
+ }
106
112
  val beginTimestamp = frameMetrics.getMetric(FrameMetrics.VSYNC_TIMESTAMP)
107
113
  val endTimestamp = beginTimestamp + frameMetrics.getMetric(FrameMetrics.TOTAL_DURATION)
108
114
  emitFrameTiming(beginTimestamp, endTimestamp)
@@ -55,7 +55,7 @@ internal object InspectorNetworkHelper {
55
55
  response.body().use { responseBody ->
56
56
  if (responseBody != null) {
57
57
  val inputStream = responseBody.byteStream()
58
- val chunkSize = 1024
58
+ val chunkSize = 8 * 1024 // 8Kb
59
59
  val buffer = ByteArray(chunkSize)
60
60
  var bytesRead: Int
61
61
 
@@ -1190,8 +1190,8 @@ public class SurfaceMountingManager {
1190
1190
  // If the view that went offscreen is still being touched, we can't delete it yet.
1191
1191
  // We have to delay the deletion till the touch is completed.
1192
1192
  // This is causing bugs like those otherwise:
1193
- // - https://github.com/facebook/react-native/issues/44610
1194
- // - https://github.com/facebook/react-native/issues/45126
1193
+ // - https://github.com/react/react-native/issues/44610
1194
+ // - https://github.com/react/react-native/issues/45126
1195
1195
  mViewsToDeleteAfterTouchFinishes.add(reactTag);
1196
1196
  } else {
1197
1197
  // To delete we simply remove the tag from the registry.
@@ -326,7 +326,7 @@ public open class JavaTimerManager(
326
326
 
327
327
  // If the JS thread is busy for multiple frames we cancel any other pending runnable.
328
328
  // We also capture the idleCallbackRunnable to tentatively fix:
329
- // https://github.com/facebook/react-native/issues/44842
329
+ // https://github.com/react/react-native/issues/44842
330
330
  currentIdleCallbackRunnable?.cancel()
331
331
  currentIdleCallbackRunnable = IdleCallbackRunnable(frameTimeNanos)
332
332
  reactApplicationContext.runOnJSQueueThread(currentIdleCallbackRunnable)
@@ -63,6 +63,7 @@ public class ReactAndroidHWInputDeviceHelper {
63
63
  .put(KeyEvent.KEYCODE_9, "9")
64
64
  .put(KeyEvent.KEYCODE_CHANNEL_DOWN, "channelDown")
65
65
  .put(KeyEvent.KEYCODE_CHANNEL_UP, "channelUp")
66
+ .put(KeyEvent.KEYCODE_DEL, "delete")
66
67
  .put(KeyEvent.KEYCODE_BOOKMARK, "bookmark")
67
68
  .put(KeyEvent.KEYCODE_AVR_INPUT, "avrInput")
68
69
  .put(KeyEvent.KEYCODE_AVR_POWER, "avrPower")
@@ -7,6 +7,7 @@
7
7
 
8
8
  package com.facebook.react.modules.i18nmanager
9
9
 
10
+ import android.os.Build
10
11
  import com.facebook.fbreact.specs.NativeI18nManagerSpec
11
12
  import com.facebook.react.bridge.ReactApplicationContext
12
13
  import com.facebook.react.module.annotations.ReactModule
@@ -17,7 +18,13 @@ internal class I18nManagerModule(context: ReactApplicationContext?) :
17
18
  NativeI18nManagerSpec(context) {
18
19
  override fun getTypedExportedConstants(): Map<String, Any> {
19
20
  val context = reactApplicationContext
20
- val locale = context.resources.configuration.locales[0]
21
+ val configuration = context.resources.configuration
22
+ val locale =
23
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
24
+ configuration.locales[0]
25
+ } else {
26
+ @Suppress("DEPRECATION") configuration.locale
27
+ }
21
28
 
22
29
  return mapOf(
23
30
  "isRTL" to I18nUtil.instance.isRTL(context),
@@ -223,7 +223,7 @@ public open class IntentModule(reactContext: ReactApplicationContext) :
223
223
  }
224
224
  ReadableType.Number -> {
225
225
  // We cannot know from JS if is an Integer or Double
226
- // See: https://github.com/facebook/react-native/issues/4141
226
+ // See: https://github.com/react/react-native/issues/4141
227
227
  // We might need to find a workaround if this is really an issue
228
228
  val number = map.getDouble(EXTRA_MAP_KEY_FOR_VALUE)
229
229
  intent.putExtra(name, number)
@@ -165,7 +165,7 @@ public class NetworkingModule(
165
165
 
166
166
  @Deprecated(
167
167
  """To be removed in a future release. See
168
- https://github.com/facebook/react-native/pull/37798#pullrequestreview-1518338914"""
168
+ https://github.com/react/react-native/pull/37798#pullrequestreview-1518338914"""
169
169
  )
170
170
  public interface CustomClientBuilder : com.facebook.react.modules.network.CustomClientBuilder
171
171
 
@@ -479,7 +479,7 @@ public class NetworkingModule(
479
479
  } else {
480
480
  // Use getBytes() to convert the body into a byte[], preventing okhttp from
481
481
  // appending the character set to the Content-Type header when otherwise unspecified
482
- // https://github.com/facebook/react-native/issues/8237
482
+ // https://github.com/react/react-native/issues/8237
483
483
  val charset =
484
484
  if (contentMediaType == null) {
485
485
  StandardCharsets.UTF_8
@@ -636,7 +636,7 @@ public class NetworkingModule(
636
636
  reactApplicationContext,
637
637
  requestId,
638
638
  devToolsRequestId,
639
- url,
639
+ response.request().url().toString(),
640
640
  response.code(),
641
641
  NetworkEventUtil.okHttpHeadersToMap(response.headers()),
642
642
  response.body()?.contentLength() ?: 0L,
@@ -8,7 +8,10 @@
8
8
  package com.facebook.react.modules.permissions
9
9
 
10
10
  import android.app.Activity
11
+ import android.content.Context
11
12
  import android.content.pm.PackageManager
13
+ import android.os.Build
14
+ import android.os.Process
12
15
  import android.util.SparseArray
13
16
  import com.facebook.common.logging.FLog
14
17
  import com.facebook.fbreact.specs.NativePermissionsAndroidSpec
@@ -39,9 +42,20 @@ public class PermissionsModule(reactContext: ReactApplicationContext?) :
39
42
  */
40
43
  public override fun checkPermission(permission: String, promise: Promise) {
41
44
  val context = reactApplicationContext.baseContext
42
- promise.resolve(context.checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED)
45
+ promise.resolve(checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED)
43
46
  }
44
47
 
48
+ /**
49
+ * [Context.checkSelfPermission] was introduced in API 23 (M). On older platforms permissions are
50
+ * granted at install time, so fall back to [Context.checkPermission] for the current process.
51
+ */
52
+ private fun checkSelfPermission(context: Context, permission: String): Int =
53
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
54
+ context.checkSelfPermission(permission)
55
+ } else {
56
+ context.checkPermission(permission, Process.myPid(), Process.myUid())
57
+ }
58
+
45
59
  /**
46
60
  * Check whether the app should display a message explaining why a certain permission is needed.
47
61
  * successCallback is called with true if the app should display a message, false otherwise. This
@@ -66,7 +80,7 @@ public class PermissionsModule(reactContext: ReactApplicationContext?) :
66
80
  */
67
81
  public override fun requestPermission(permission: String, promise: Promise) {
68
82
  val context = reactApplicationContext.baseContext
69
- if (context.checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED) {
83
+ if (checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED) {
70
84
  promise.resolve(GRANTED)
71
85
  return
72
86
  }
@@ -104,7 +118,7 @@ public class PermissionsModule(reactContext: ReactApplicationContext?) :
104
118
  val context = reactApplicationContext.baseContext
105
119
  for (i in 0 until permissions.size()) {
106
120
  val perm = permissions.getString(i) ?: continue
107
- if (context.checkSelfPermission(perm) == PackageManager.PERMISSION_GRANTED) {
121
+ if (checkSelfPermission(context, perm) == PackageManager.PERMISSION_GRANTED) {
108
122
  grantedPermissions.putString(perm, GRANTED)
109
123
  checkedPermissionsCount++
110
124
  } else {
@@ -14,7 +14,7 @@ public object ReactNativeVersion {
14
14
  public val VERSION: Map<String, Any?> = mapOf(
15
15
  "major" to 0,
16
16
  "minor" to 83,
17
- "patch" to 9,
18
- "prerelease" to "0"
17
+ "patch" to 10,
18
+ "prerelease" to "1"
19
19
  )
20
20
  }
@@ -11,6 +11,7 @@ import android.app.Activity
11
11
  import android.content.Context
12
12
  import android.content.Intent
13
13
  import android.nfc.NfcAdapter
14
+ import android.os.Build
14
15
  import android.os.Bundle
15
16
  import androidx.core.graphics.createBitmap
16
17
  import com.facebook.common.logging.FLog
@@ -1611,7 +1612,11 @@ public class ReactHostImpl(
1611
1612
  when (state) {
1612
1613
  TracingState.ENABLED_IN_BACKGROUND_MODE,
1613
1614
  TracingState.ENABLED_IN_CDP_MODE -> {
1614
- if (InspectorFlags.getFrameRecordingEnabled()) {
1615
+ // FrameMetrics-based frame recording requires API 24 (N). FrameTimingsObserver's
1616
+ // listener implements Window.OnFrameMetricsAvailableListener (an API-24 interface),
1617
+ // which would crash at construction on older platforms.
1618
+ if (InspectorFlags.getFrameRecordingEnabled() &&
1619
+ Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
1615
1620
  val observer =
1616
1621
  FrameTimingsObserver(
1617
1622
  _screenshotsEnabled,
@@ -563,7 +563,7 @@ internal class ReactInstance(
563
563
  // We need to null check here because some Java implementation of the
564
564
  // `ViewManagerOnDemandReactPackage` interface could still return null even
565
565
  // if the method is marked as returning a non-nullable collection in Kotlin.
566
- // See https://github.com/facebook/react-native/issues/52014
566
+ // See https://github.com/react/react-native/issues/52014
567
567
  @Suppress("SENSELESS_COMPARISON")
568
568
  if (names == null) {
569
569
  RNLog.w(
@@ -631,7 +631,7 @@ public abstract class BaseViewManager<T extends View, C extends LayoutShadowNode
631
631
  // The native Android implementation removed the screen density from the
632
632
  // calculation, so squaring and a normalization value of
633
633
  // sqrt(5) produces an exact replica with iOS.
634
- // For more information, see https://github.com/facebook/react-native/pull/18302
634
+ // For more information, see https://github.com/react/react-native/pull/18302
635
635
  float normalizedCameraDistance =
636
636
  sanitizeFloatPropertyValue(
637
637
  scale * scale * cameraDistance * CAMERA_DISTANCE_NORMALIZATION_MULTIPLIER);
@@ -237,7 +237,8 @@ internal object UIManagerModuleConstantsHelper {
237
237
  // Since event maps are client based Map interface, it could be immutable
238
238
  if (destValue !is HashMap<*, *>) {
239
239
  destValue = HashMap(destValue)
240
- dest.replace(key, destValue as MutableMap<*, *>)
240
+ // Map.replace requires API 24; the key is already present, so put (API 1) is equivalent.
241
+ dest[key] = destValue as MutableMap<*, *>
241
242
  }
242
243
  @Suppress("UNCHECKED_CAST")
243
244
  recursiveMerge(destValue as MutableMap<String, Any>, sourceValue as MutableMap<String, Any>)
@@ -16,7 +16,6 @@ import android.graphics.Path
16
16
  import android.graphics.PixelFormat
17
17
  import android.graphics.Rect
18
18
  import android.graphics.RectF
19
- import android.graphics.drawable.Drawable
20
19
  import com.facebook.react.uimanager.PixelUtil.dpToPx
21
20
  import com.facebook.react.uimanager.PixelUtil.pxToDp
22
21
  import com.facebook.react.uimanager.style.BorderInsets
@@ -15,7 +15,6 @@ import android.graphics.Path
15
15
  import android.graphics.PixelFormat
16
16
  import android.graphics.Rect
17
17
  import android.graphics.RectF
18
- import android.graphics.drawable.Drawable
19
18
  import com.facebook.react.uimanager.FloatUtil
20
19
  import com.facebook.react.uimanager.LengthPercentage
21
20
  import com.facebook.react.uimanager.LengthPercentageType
@@ -20,7 +20,6 @@ import android.graphics.PointF
20
20
  import android.graphics.Rect
21
21
  import android.graphics.RectF
22
22
  import android.graphics.Region
23
- import android.graphics.drawable.Drawable
24
23
  import android.os.Build
25
24
  import com.facebook.react.uimanager.FloatUtil.floatsEqual
26
25
  import com.facebook.react.uimanager.LengthPercentage
@@ -12,6 +12,9 @@ import android.graphics.Outline
12
12
  import android.graphics.Path
13
13
  import android.graphics.RectF
14
14
  import android.graphics.drawable.Drawable
15
+ // Framework LayerDrawable, kept for LayerDrawable.PADDING_MODE_STACK and the Array<Drawable?> type.
16
+ // The superclass below is the package-local proxy (fully qualified) so getLayoutDirection() is
17
+ // runtime-safe on API 22 — see LayerDrawable.kt.
15
18
  import android.graphics.drawable.LayerDrawable
16
19
  import android.os.Build
17
20
  import com.facebook.react.common.annotations.UnstableReactNativeAPI
@@ -59,7 +62,7 @@ internal class CompositeBackgroundDrawable(
59
62
  // Holder value for currently set border radius
60
63
  var borderRadius: BorderRadiusStyle? = null,
61
64
  ) :
62
- LayerDrawable(
65
+ com.facebook.react.uimanager.drawable.LayerDrawable(
63
66
  createLayersArray(
64
67
  originalBackground,
65
68
  outerShadows,
@@ -0,0 +1,30 @@
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.uimanager.drawable
9
+
10
+ import android.annotation.TargetApi
11
+ import android.os.Build
12
+ import android.view.View
13
+
14
+ /**
15
+ * Package-local base [android.graphics.drawable.Drawable] for React Native's drawable subsystem.
16
+ *
17
+ * [android.graphics.drawable.Drawable.getLayoutDirection] was only introduced in API 23 (M). The
18
+ * drawables in this package read `layoutDirection` internally, which would throw a
19
+ * [NoSuchMethodError] on API 22. By declaring the override here (and guarding the `super` call),
20
+ * subclasses that extend this proxy instead of the framework class stay runtime-safe on API 22.
21
+ */
22
+ internal abstract class Drawable : android.graphics.drawable.Drawable() {
23
+ @TargetApi(Build.VERSION_CODES.M)
24
+ override fun getLayoutDirection(): Int =
25
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
26
+ super.getLayoutDirection()
27
+ } else {
28
+ View.LAYOUT_DIRECTION_LTR
29
+ }
30
+ }
@@ -0,0 +1,32 @@
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.uimanager.drawable
9
+
10
+ import android.annotation.TargetApi
11
+ import android.os.Build
12
+ import android.view.View
13
+
14
+ /**
15
+ * Package-local base [android.graphics.drawable.LayerDrawable] for React Native's drawable
16
+ * subsystem.
17
+ *
18
+ * [android.graphics.drawable.Drawable.getLayoutDirection] was only introduced in API 23 (M).
19
+ * [CompositeBackgroundDrawable] reads `layoutDirection` internally, which would throw a
20
+ * [NoSuchMethodError] on API 22. By declaring the override here (and guarding the `super` call),
21
+ * it stays runtime-safe on API 22 while remaining a real framework [LayerDrawable].
22
+ */
23
+ internal abstract class LayerDrawable(layers: Array<android.graphics.drawable.Drawable?>) :
24
+ android.graphics.drawable.LayerDrawable(layers) {
25
+ @TargetApi(Build.VERSION_CODES.M)
26
+ override fun getLayoutDirection(): Int =
27
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
28
+ super.getLayoutDirection()
29
+ } else {
30
+ View.LAYOUT_DIRECTION_LTR
31
+ }
32
+ }
@@ -17,7 +17,6 @@ import android.graphics.Path
17
17
  import android.graphics.PathEffect
18
18
  import android.graphics.PixelFormat
19
19
  import android.graphics.RectF
20
- import android.graphics.drawable.Drawable
21
20
  import com.facebook.react.uimanager.PixelUtil.pxToDp
22
21
  import com.facebook.react.uimanager.style.BorderRadiusStyle
23
22
  import com.facebook.react.uimanager.style.ComputedBorderRadius
@@ -567,29 +567,39 @@ public class ReactHorizontalScrollView extends HorizontalScrollView
567
567
  }
568
568
 
569
569
  /**
570
- * Attempts to scroll-snap to the focused child based on snapToAlignment/scrollSnapAlign.
571
- * Returns true if snap scrolling was performed, false otherwise.
570
+ * Attempts to scroll-snap to the focused child based on snapToAlignment/scrollSnapAlign
571
+ * or scrollSnapOffset. Returns true if snap scrolling was performed, false otherwise.
572
572
  */
573
573
  private boolean tryScrollSnapToChild(View focused) {
574
574
  if (mSnapToAlignment != SNAP_ALIGNMENT_ITEM) {
575
575
  return false;
576
576
  }
577
577
 
578
- kotlin.Pair<View, String> result = ReactScrollViewHelper.findScrollSnapAlign(focused, this);
578
+ kotlin.Triple<View, String, Integer> result =
579
+ ReactScrollViewHelper.findScrollSnap(focused, this);
579
580
  if (result == null) {
580
581
  return false;
581
582
  }
582
583
 
583
584
  View snapTarget = result.getFirst();
584
585
  String alignment = result.getSecond();
586
+ Integer snapOffset = result.getThird();
585
587
 
586
588
  Rect rect = new Rect();
587
589
  snapTarget.getDrawingRect(rect);
588
590
  offsetDescendantRectToMyCoords(snapTarget, rect);
589
591
 
590
- int viewportWidth = getWidth() - getPaddingLeft() - getPaddingRight();
591
592
  int maxScrollX = Math.max(0, computeHorizontalScrollRange() - getWidth());
592
593
 
594
+ if (snapOffset != null) {
595
+ int targetOffset = ReactScrollViewHelper.computeScrollSnapTargetForOffset(
596
+ rect.left, snapOffset, mSnapInterval, maxScrollX);
597
+ reactSmoothScrollTo(targetOffset, getScrollY());
598
+ return true;
599
+ }
600
+
601
+ int viewportWidth = getWidth() - getPaddingLeft() - getPaddingRight();
602
+
593
603
  Integer targetOffset = ReactScrollViewHelper.computeScrollSnapOffset(
594
604
  rect.left, rect.right, viewportWidth, alignment, mSnapInterval, mSnapToItemPadding, maxScrollX);
595
605
  if (targetOffset == null) {
@@ -514,29 +514,39 @@ public class ReactScrollView extends ScrollView
514
514
  }
515
515
 
516
516
  /**
517
- * Attempts to scroll-snap to the focused child based on snapToAlignment/scrollSnapAlign.
518
- * Returns true if snap scrolling was performed, false otherwise.
517
+ * Attempts to scroll-snap to the focused child based on snapToAlignment/scrollSnapAlign
518
+ * or scrollSnapOffset. Returns true if snap scrolling was performed, false otherwise.
519
519
  */
520
520
  private boolean tryScrollSnapToChild(View focused) {
521
521
  if (mSnapToAlignment != SNAP_ALIGNMENT_ITEM) {
522
522
  return false;
523
523
  }
524
524
 
525
- kotlin.Pair<View, String> result = ReactScrollViewHelper.findScrollSnapAlign(focused, this);
525
+ kotlin.Triple<View, String, Integer> result =
526
+ ReactScrollViewHelper.findScrollSnap(focused, this);
526
527
  if (result == null) {
527
528
  return false;
528
529
  }
529
530
 
530
531
  View snapTarget = result.getFirst();
531
532
  String alignment = result.getSecond();
533
+ Integer snapOffset = result.getThird();
532
534
 
533
535
  Rect rect = new Rect();
534
536
  snapTarget.getDrawingRect(rect);
535
537
  offsetDescendantRectToMyCoords(snapTarget, rect);
536
538
 
537
- int viewportHeight = getHeight() - getPaddingTop() - getPaddingBottom();
538
539
  int maxScrollY = getMaxScrollY();
539
540
 
541
+ if (snapOffset != null) {
542
+ int targetOffset = ReactScrollViewHelper.computeScrollSnapTargetForOffset(
543
+ rect.top, snapOffset, mSnapInterval, maxScrollY);
544
+ reactSmoothScrollTo(getScrollX(), targetOffset);
545
+ return true;
546
+ }
547
+
548
+ int viewportHeight = getHeight() - getPaddingTop() - getPaddingBottom();
549
+
540
550
  Integer targetOffset = ReactScrollViewHelper.computeScrollSnapOffset(
541
551
  rect.top, rect.bottom, viewportHeight, alignment, mSnapInterval, mSnapToItemPadding, maxScrollY);
542
552
  if (targetOffset == null) {
@@ -12,11 +12,9 @@ import android.animation.ValueAnimator
12
12
  import android.content.Context
13
13
  import android.graphics.Point
14
14
  import android.graphics.Rect
15
- import android.os.Build
16
15
  import android.view.View
17
16
  import android.view.ViewGroup
18
17
  import android.widget.OverScroller
19
- import androidx.annotation.RequiresApi
20
18
  import androidx.core.view.ViewCompat.FocusDirection
21
19
  import androidx.core.view.ViewCompat.FocusRealDirection
22
20
  import com.facebook.common.logging.FLog
@@ -248,7 +246,6 @@ public object ReactScrollViewHelper {
248
246
  scrollListeners.add(WeakReference(listener))
249
247
  }
250
248
 
251
- @RequiresApi(Build.VERSION_CODES.N)
252
249
  @JvmStatic
253
250
  public fun removeScrollListener(listener: ScrollListener) {
254
251
  // Avoid using removeIf, only available in API 26+
@@ -267,7 +264,6 @@ public object ReactScrollViewHelper {
267
264
  layoutChangeListeners.add(WeakReference(listener))
268
265
  }
269
266
 
270
- @RequiresApi(Build.VERSION_CODES.N)
271
267
  @JvmStatic
272
268
  public fun removeLayoutChangeListener(listener: LayoutChangeListener) {
273
269
  // Avoid using removeIf, only available in API 26+
@@ -576,27 +572,67 @@ public object ReactScrollViewHelper {
576
572
 
577
573
  /**
578
574
  * Walks up the view hierarchy from the focused view to find a ReactViewGroup with
579
- * scrollSnapAlign set. Returns a Pair of (snapTarget, alignment) or null if not found.
575
+ * either scrollSnapAlign or scrollSnapOffset set. Returns a Triple of (snapTarget,
576
+ * alignment, offsetPx) or null if neither marker was found. Exactly one of
577
+ * alignment/offsetPx is non-null on return.
578
+ *
579
+ * Walk is inner→outer, latest marker wins. On a single view declaring both,
580
+ * scrollSnapOffset wins as the more specific config.
580
581
  *
581
582
  * Shared by [ReactScrollView] and [ReactHorizontalScrollView].
582
583
  */
583
584
  @JvmStatic
584
- public fun findScrollSnapAlign(focused: View, scrollView: ViewGroup): Pair<View, String>? {
585
+ public fun findScrollSnap(focused: View, scrollView: ViewGroup): Triple<View, String?, Int?>? {
585
586
  var view: View? = focused
586
587
  var snapTarget: View? = null
587
588
  var alignment: String? = null
589
+ var offset: Int? = null
588
590
  while (view != null && view !== scrollView) {
589
591
  if (view is ReactViewGroup) {
590
- val snap = view.scrollSnapAlign
591
- if (snap != null) {
592
- alignment = snap
592
+ val o = view.scrollSnapOffset
593
+ val a = view.scrollSnapAlign
594
+ if (o != null) {
595
+ offset = o
596
+ alignment = null
597
+ snapTarget = view
598
+ } else if (a != null) {
599
+ alignment = a
600
+ offset = null
593
601
  snapTarget = view
594
602
  }
595
603
  }
596
604
  val parent = view.parent
597
605
  view = if (parent is View) parent else null
598
606
  }
599
- return if (alignment != null && snapTarget != null) Pair(snapTarget, alignment) else null
607
+ return if (snapTarget != null && (alignment != null || offset != null))
608
+ Triple(snapTarget, alignment, offset) else null
609
+ }
610
+
611
+ /**
612
+ * Computes the target scroll offset for the per-item scrollSnapOffset path:
613
+ * land the snap target's leading edge at `snapOffset` pixels from the viewport origin.
614
+ *
615
+ * Returns the clamped target offset.
616
+ *
617
+ * Shared by [ReactScrollView] and [ReactHorizontalScrollView].
618
+ *
619
+ * @param focusedStart the start coordinate of the snap target in scroll view coordinates
620
+ * @param snapOffset the per-item pixel offset from the viewport origin
621
+ * @param snapInterval the snap interval (0 if not set)
622
+ * @param maxScrollOffset the maximum scroll offset for clamping
623
+ */
624
+ @JvmStatic
625
+ public fun computeScrollSnapTargetForOffset(
626
+ focusedStart: Int,
627
+ snapOffset: Int,
628
+ snapInterval: Int,
629
+ maxScrollOffset: Int,
630
+ ): Int {
631
+ var targetOffset = focusedStart - snapOffset
632
+ if (snapInterval > 0) {
633
+ targetOffset = (Math.floor(targetOffset.toDouble() / snapInterval) * snapInterval).toInt()
634
+ }
635
+ return Math.max(0, Math.min(targetOffset, maxScrollOffset))
600
636
  }
601
637
 
602
638
  /**
@@ -437,7 +437,7 @@ constructor(private val fpsListener: FpsListener? = null) :
437
437
  // be on the wrong side. Thus we are moving it to the other side, when the list
438
438
  // is inverted.
439
439
  // See also:
440
- // - https://github.com/facebook/react-native/issues/35350
440
+ // - https://github.com/react/react-native/issues/35350
441
441
  // - https://issuetracker.google.com/issues/287304310
442
442
  if (applyFix) {
443
443
  view.verticalScrollbarPosition = View.SCROLLBAR_POSITION_LEFT
@@ -9,6 +9,7 @@
9
9
 
10
10
  package com.facebook.react.views.text
11
11
 
12
+ import android.annotation.TargetApi
12
13
  import android.graphics.Color
13
14
  import android.os.Build
14
15
  import android.text.Layout
@@ -65,6 +66,9 @@ import com.facebook.yoga.YogaUnit
65
66
  @Deprecated(
66
67
  message = "This class is part of Legacy Architecture and will be removed in a future release"
67
68
  )
69
+ // The break-strategy / hyphenation-frequency Layout constants used below were added in API 23 (M).
70
+ // They are compile-time int constants (runtime-safe), and the pre-M fallbacks are inlined literals.
71
+ @TargetApi(Build.VERSION_CODES.M)
68
72
  public abstract class ReactBaseTextShadowNode
69
73
  @JvmOverloads
70
74
  public constructor(
@@ -81,8 +85,10 @@ public constructor(
81
85
  protected var numberOfLines: Int = ReactConstants.UNSET
82
86
  private set
83
87
 
84
- protected var textBreakStrategy: Int = Layout.BREAK_STRATEGY_HIGH_QUALITY
85
- protected var hyphenationFrequency: Int = Layout.HYPHENATION_FREQUENCY_NONE
88
+ protected var textBreakStrategy: Int =
89
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) Layout.BREAK_STRATEGY_HIGH_QUALITY else 0
90
+ protected var hyphenationFrequency: Int =
91
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) Layout.HYPHENATION_FREQUENCY_NONE else 0
86
92
  protected var justificationMode: Int =
87
93
  if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
88
94
  0
@@ -408,6 +414,10 @@ public constructor(
408
414
 
409
415
  @ReactProp(name = ViewProps.TEXT_BREAK_STRATEGY)
410
416
  public open fun setTextBreakStrategy(textBreakStrategy: String?) {
417
+ // Layout break strategies were introduced in API 23 (M); they are unused before then.
418
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
419
+ return
420
+ }
411
421
  this.textBreakStrategy =
412
422
  when (textBreakStrategy) {
413
423
  null,
@@ -7,6 +7,7 @@
7
7
 
8
8
  package com.facebook.react.views.text
9
9
 
10
+ import android.os.Build
10
11
  import android.text.Layout
11
12
  import android.text.TextUtils
12
13
  import android.text.util.Linkify
@@ -110,6 +111,10 @@ public abstract class ReactTextAnchorViewManager<
110
111
 
111
112
  @ReactProp(name = "android_hyphenationFrequency")
112
113
  internal fun setAndroidHyphenationFrequency(view: ReactTextView, frequency: String?) {
114
+ // Hyphenation frequency was introduced in API 23 (M).
115
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
116
+ return
117
+ }
113
118
  when (frequency) {
114
119
  null,
115
120
  "none" -> view.hyphenationFrequency = Layout.HYPHENATION_FREQUENCY_NONE