@iternio/react-native-auto-play 0.6.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (265) hide show
  1. package/README.md +59 -10
  2. package/android/src/automotive/AndroidManifest-nonnav.xml +0 -2
  3. package/android/src/automotive/AndroidManifest.xml +0 -2
  4. package/android/src/main/AndroidManifest-nonnav.xml +0 -2
  5. package/android/src/main/AndroidManifest.xml +0 -2
  6. package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/AndroidAutoService.kt +3 -27
  7. package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/HybridAutoPlayTiming.kt +122 -0
  8. package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/template/Parser.kt +49 -14
  9. package/installTimers.ts +3 -0
  10. package/installTimers.web.ts +2 -0
  11. package/ios/hybrid/HybridAutoPlayTiming.swift +123 -0
  12. package/jest.js +2 -0
  13. package/lib/components/SafeAreaView.js +1 -1
  14. package/lib/hybrid/HybridAutoPlayTiming.d.ts +2 -0
  15. package/lib/hybrid/HybridAutoPlayTiming.js +2 -0
  16. package/lib/hybrid/HybridVoice.js +2 -2
  17. package/lib/index.js +0 -2
  18. package/lib/index.web.d.ts +75 -0
  19. package/lib/index.web.js +72 -1
  20. package/lib/installTimers.d.ts +1 -0
  21. package/lib/installTimers.js +8 -0
  22. package/lib/installTimers.web.d.ts +1 -0
  23. package/lib/installTimers.web.js +2 -0
  24. package/lib/scenes/CarPlayDashboardScene.d.ts +3 -3
  25. package/lib/specs/AutoPlayTiming.nitro.d.ts +27 -0
  26. package/lib/specs/AutoPlayTiming.nitro.js +1 -0
  27. package/lib/types/Image.d.ts +6 -1
  28. package/lib/types/Telemetry.d.ts +1 -1
  29. package/lib/utils/AutoPlayTimers.d.ts +21 -0
  30. package/lib/utils/AutoPlayTimers.js +45 -0
  31. package/lib/utils/NitroColor.d.ts +1 -0
  32. package/lib/utils/NitroColor.js +8 -0
  33. package/lib/utils/NitroImage.d.ts +5 -2
  34. package/lib/utils/NitroImage.js +2 -2
  35. package/lib/utils/NitroManeuver.js +1 -3
  36. package/lib-cjs/Constants.js +9 -0
  37. package/lib-cjs/components/MapTemplateContext.js +10 -0
  38. package/lib-cjs/components/SafeAreaInsetsContext.js +21 -0
  39. package/lib-cjs/components/SafeAreaView.js +22 -0
  40. package/lib-cjs/components/WindowInformationWrapper.js +20 -0
  41. package/lib-cjs/hooks/useAndroidAutoTelemetry.js +115 -0
  42. package/lib-cjs/hooks/useFocusedEffect.js +35 -0
  43. package/lib-cjs/hooks/useMapTemplate.js +13 -0
  44. package/lib-cjs/hooks/useSafeAreaInsets.js +9 -0
  45. package/lib-cjs/hooks/useVoiceInput.js +42 -0
  46. package/lib-cjs/hybrid/HybridAndroidAutoTelemetry.js +4 -0
  47. package/lib-cjs/hybrid/HybridAndroidWindowInformation.js +4 -0
  48. package/lib-cjs/hybrid/HybridAutoPlay.js +5 -0
  49. package/lib-cjs/hybrid/HybridVoice.js +61 -0
  50. package/lib-cjs/index.js +71 -0
  51. package/lib-cjs/index.web.js +98 -0
  52. package/lib-cjs/scenes/AutoPlayCluster.js +140 -0
  53. package/lib-cjs/scenes/CarPlayDashboardScene.js +100 -0
  54. package/lib-cjs/specs/AndroidAutoTelemetry.nitro.js +2 -0
  55. package/lib-cjs/specs/AndroidAutomotive.nitro.js +16 -0
  56. package/lib-cjs/specs/AndroidWindowInformation.nitro.js +2 -0
  57. package/lib-cjs/specs/AutoPlay.nitro.js +2 -0
  58. package/lib-cjs/specs/CarPlayDashboard.nitro.js +2 -0
  59. package/lib-cjs/specs/Cluster.nitro.js +2 -0
  60. package/lib-cjs/specs/GridTemplate.nitro.js +2 -0
  61. package/lib-cjs/specs/InformationTemplate.nitro.js +2 -0
  62. package/lib-cjs/specs/ListTemplate.nitro.js +2 -0
  63. package/lib-cjs/specs/MapTemplate.nitro.js +2 -0
  64. package/lib-cjs/specs/MessageTemplate.nitro.js +2 -0
  65. package/lib-cjs/specs/SearchTemplate.nitro.js +2 -0
  66. package/lib-cjs/specs/SignInTemplate.nitro.js +2 -0
  67. package/lib-cjs/specs/Voice.nitro.js +2 -0
  68. package/lib-cjs/templates/GridTemplate.js +41 -0
  69. package/lib-cjs/templates/InformationTemplate.js +49 -0
  70. package/lib-cjs/templates/ListTemplate.js +33 -0
  71. package/lib-cjs/templates/MapTemplate.js +168 -0
  72. package/lib-cjs/templates/MessageTemplate.js +50 -0
  73. package/lib-cjs/templates/SearchTemplate.js +32 -0
  74. package/lib-cjs/templates/SignInTemplate.js +55 -0
  75. package/lib-cjs/templates/Template.js +40 -0
  76. package/lib-cjs/types/Button.js +12 -0
  77. package/lib-cjs/types/Event.js +2 -0
  78. package/lib-cjs/types/Image.js +2 -0
  79. package/lib-cjs/types/Maneuver.js +77 -0
  80. package/lib-cjs/types/RootComponent.js +2 -0
  81. package/lib-cjs/types/SignInMethod.js +22 -0
  82. package/lib-cjs/types/Telemetry.js +24 -0
  83. package/lib-cjs/types/Text.js +8 -0
  84. package/lib-cjs/types/Trip.js +2 -0
  85. package/lib-cjs/types/Voice.js +2 -0
  86. package/lib-cjs/utils/ErrorUtil.js +34 -0
  87. package/lib-cjs/utils/NitroAction.js +129 -0
  88. package/lib-cjs/utils/NitroAlert.js +19 -0
  89. package/lib-cjs/utils/NitroAttributedString.js +14 -0
  90. package/lib-cjs/utils/NitroColor.js +32 -0
  91. package/lib-cjs/utils/NitroGrid.js +12 -0
  92. package/lib-cjs/utils/NitroImage.js +97 -0
  93. package/lib-cjs/utils/NitroManeuver.js +79 -0
  94. package/lib-cjs/utils/NitroMapButton.js +33 -0
  95. package/lib-cjs/utils/NitroOptionsPanel.js +66 -0
  96. package/lib-cjs/utils/NitroSection.js +112 -0
  97. package/nitro.json +10 -0
  98. package/nitrogen/generated/android/ReactNativeAutoPlay+autolinking.cmake +2 -0
  99. package/nitrogen/generated/android/ReactNativeAutoPlayOnLoad.cpp +16 -0
  100. package/nitrogen/generated/android/c++/JActiveCarUxRestrictions.hpp +1 -1
  101. package/nitrogen/generated/android/c++/JAlertActionStyle.hpp +1 -1
  102. package/nitrogen/generated/android/c++/JAlertDismissalReason.hpp +1 -1
  103. package/nitrogen/generated/android/c++/JAppFocusState.hpp +1 -1
  104. package/nitrogen/generated/android/c++/JAssetImage.hpp +18 -18
  105. package/nitrogen/generated/android/c++/JAutoText.hpp +1 -1
  106. package/nitrogen/generated/android/c++/JBooleanTelemetryItem.hpp +1 -1
  107. package/nitrogen/generated/android/c++/JCarUxRestrictions.hpp +1 -1
  108. package/nitrogen/generated/android/c++/JChargingConnector.hpp +1 -1
  109. package/nitrogen/generated/android/c++/JClusterEventName.hpp +1 -1
  110. package/nitrogen/generated/android/c++/JColorScheme.hpp +1 -1
  111. package/nitrogen/generated/android/c++/JDistance.hpp +1 -1
  112. package/nitrogen/generated/android/c++/JDistanceUnits.hpp +1 -1
  113. package/nitrogen/generated/android/c++/JDurationWithTimeZone.hpp +1 -1
  114. package/nitrogen/generated/android/c++/JEventName.hpp +1 -1
  115. package/nitrogen/generated/android/c++/JForkType.hpp +1 -1
  116. package/nitrogen/generated/android/c++/JGlyphImage.hpp +1 -1
  117. package/nitrogen/generated/android/c++/JGoogleSignIn.hpp +1 -1
  118. package/nitrogen/generated/android/c++/JGoogleSignInAccount.hpp +1 -1
  119. package/nitrogen/generated/android/c++/JGridImageSize.hpp +1 -1
  120. package/nitrogen/generated/android/c++/JGridTemplateConfig.hpp +1 -1
  121. package/nitrogen/generated/android/c++/JHybridAutoPlayTimingSpec.cpp +59 -0
  122. package/nitrogen/generated/android/c++/JHybridAutoPlayTimingSpec.hpp +64 -0
  123. package/nitrogen/generated/android/c++/JImageLane.hpp +1 -1
  124. package/nitrogen/generated/android/c++/JInformationTemplateConfig.hpp +1 -1
  125. package/nitrogen/generated/android/c++/JInputSignIn.hpp +1 -1
  126. package/nitrogen/generated/android/c++/JKeepType.hpp +1 -1
  127. package/nitrogen/generated/android/c++/JKeyboardType.hpp +1 -1
  128. package/nitrogen/generated/android/c++/JLaneGuidance.hpp +1 -1
  129. package/nitrogen/generated/android/c++/JListImageType.hpp +1 -1
  130. package/nitrogen/generated/android/c++/JListTemplateConfig.hpp +1 -1
  131. package/nitrogen/generated/android/c++/JLocation.hpp +1 -1
  132. package/nitrogen/generated/android/c++/JManeuverState.hpp +1 -1
  133. package/nitrogen/generated/android/c++/JManeuverType.hpp +1 -1
  134. package/nitrogen/generated/android/c++/JMapTemplateConfig.hpp +1 -1
  135. package/nitrogen/generated/android/c++/JMessageTemplateConfig.hpp +1 -1
  136. package/nitrogen/generated/android/c++/JNavigationAlertAction.hpp +1 -1
  137. package/nitrogen/generated/android/c++/JNitroAction.hpp +1 -1
  138. package/nitrogen/generated/android/c++/JNitroActionType.hpp +1 -1
  139. package/nitrogen/generated/android/c++/JNitroAlignment.hpp +1 -1
  140. package/nitrogen/generated/android/c++/JNitroAttributedString.hpp +1 -1
  141. package/nitrogen/generated/android/c++/JNitroAttributedStringImage.hpp +1 -1
  142. package/nitrogen/generated/android/c++/JNitroBaseMapTemplateConfig.hpp +1 -1
  143. package/nitrogen/generated/android/c++/JNitroButtonStyle.hpp +1 -1
  144. package/nitrogen/generated/android/c++/JNitroChargerLocation.hpp +1 -1
  145. package/nitrogen/generated/android/c++/JNitroChargerOutlet.hpp +1 -1
  146. package/nitrogen/generated/android/c++/JNitroColor.hpp +9 -5
  147. package/nitrogen/generated/android/c++/JNitroGridButton.hpp +1 -1
  148. package/nitrogen/generated/android/c++/JNitroLoadingManeuver.hpp +1 -1
  149. package/nitrogen/generated/android/c++/JNitroMapButton.hpp +1 -1
  150. package/nitrogen/generated/android/c++/JNitroMapButtonType.hpp +1 -1
  151. package/nitrogen/generated/android/c++/JNitroMessageManeuver.hpp +1 -1
  152. package/nitrogen/generated/android/c++/JNitroNavigationAlert.hpp +1 -1
  153. package/nitrogen/generated/android/c++/JNitroOptionsPanelChargerSection.hpp +1 -1
  154. package/nitrogen/generated/android/c++/JNitroOptionsPanelConfig.hpp +1 -1
  155. package/nitrogen/generated/android/c++/JNitroOptionsPanelGridSection.hpp +1 -1
  156. package/nitrogen/generated/android/c++/JNitroRoutingManeuver.hpp +1 -1
  157. package/nitrogen/generated/android/c++/JNitroRow.hpp +1 -1
  158. package/nitrogen/generated/android/c++/JNitroSection.hpp +1 -1
  159. package/nitrogen/generated/android/c++/JNitroSectionType.hpp +1 -1
  160. package/nitrogen/generated/android/c++/JNumericTelemetryItem.hpp +1 -1
  161. package/nitrogen/generated/android/c++/JOffRampType.hpp +1 -1
  162. package/nitrogen/generated/android/c++/JOnRampType.hpp +1 -1
  163. package/nitrogen/generated/android/c++/JPermissionRequestResult.hpp +1 -1
  164. package/nitrogen/generated/android/c++/JPinSignIn.hpp +1 -1
  165. package/nitrogen/generated/android/c++/JPoint.hpp +1 -1
  166. package/nitrogen/generated/android/c++/JPreferredImageLane.hpp +1 -1
  167. package/nitrogen/generated/android/c++/JQrSignIn.hpp +1 -1
  168. package/nitrogen/generated/android/c++/JRemoteImage.hpp +1 -1
  169. package/nitrogen/generated/android/c++/JRouteChoice.hpp +1 -1
  170. package/nitrogen/generated/android/c++/JSafeAreaInsets.hpp +1 -1
  171. package/nitrogen/generated/android/c++/JSearchTemplateConfig.hpp +1 -1
  172. package/nitrogen/generated/android/c++/JSignInMethods.hpp +1 -1
  173. package/nitrogen/generated/android/c++/JSignInTemplateConfig.hpp +1 -1
  174. package/nitrogen/generated/android/c++/JStringTelemetryItem.hpp +1 -1
  175. package/nitrogen/generated/android/c++/JTelemetry.hpp +1 -1
  176. package/nitrogen/generated/android/c++/JTextInputType.hpp +1 -1
  177. package/nitrogen/generated/android/c++/JTrafficSide.hpp +1 -1
  178. package/nitrogen/generated/android/c++/JTravelEstimates.hpp +1 -1
  179. package/nitrogen/generated/android/c++/JTripConfig.hpp +1 -1
  180. package/nitrogen/generated/android/c++/JTripPoint.hpp +1 -1
  181. package/nitrogen/generated/android/c++/JTripPreviewTextConfiguration.hpp +1 -1
  182. package/nitrogen/generated/android/c++/JTripSelectorCallback.hpp +1 -1
  183. package/nitrogen/generated/android/c++/JTripsConfig.hpp +1 -1
  184. package/nitrogen/generated/android/c++/JTurnType.hpp +1 -1
  185. package/nitrogen/generated/android/c++/JVehicleTelemetryItem.hpp +1 -1
  186. package/nitrogen/generated/android/c++/JVisibilityState.hpp +1 -1
  187. package/nitrogen/generated/android/c++/JVisibleTravelEstimate.hpp +1 -1
  188. package/nitrogen/generated/android/c++/JVoiceAudioEncoding.hpp +1 -1
  189. package/nitrogen/generated/android/c++/JVoiceInputChunk.hpp +1 -1
  190. package/nitrogen/generated/android/c++/JVoiceInputResult.hpp +1 -1
  191. package/nitrogen/generated/android/c++/JWaypointCoordinate.hpp +1 -1
  192. package/nitrogen/generated/android/c++/JWindowInformation.hpp +1 -1
  193. package/nitrogen/generated/android/c++/JZoomEvent.hpp +1 -1
  194. package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/AssetImage.kt +15 -15
  195. package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/Func_void.kt +0 -2
  196. package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/Func_void_ActiveCarUxRestrictions.kt +0 -2
  197. package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/Func_void_AlertDismissalReason.kt +0 -2
  198. package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/Func_void_AppFocusState.kt +0 -2
  199. package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/Func_void_ColorScheme.kt +0 -2
  200. package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/Func_void_Point.kt +0 -2
  201. package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/Func_void_Point_double.kt +0 -2
  202. package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/Func_void_Point_std__optional_Point_.kt +0 -2
  203. package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/Func_void_SafeAreaInsets.kt +0 -2
  204. package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/Func_void_VisibilityState.kt +0 -2
  205. package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/Func_void_VoiceInputChunk.kt +0 -2
  206. package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/Func_void_WindowInformation.kt +0 -2
  207. package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/Func_void_bool.kt +0 -2
  208. package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/Func_void_std__optional_Location__std__optional_std__string_.kt +0 -2
  209. package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/Func_void_std__optional_Telemetry_.kt +0 -2
  210. package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/Func_void_std__optional_bool_.kt +0 -2
  211. package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/Func_void_std__optional_std__string__std__optional_GoogleSignInAccount_.kt +0 -2
  212. package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/Func_void_std__string.kt +0 -2
  213. package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/Func_void_std__string_ColorScheme.kt +0 -2
  214. package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/Func_void_std__string_ZoomEvent.kt +0 -2
  215. package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/Func_void_std__string_bool.kt +0 -2
  216. package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/Func_void_std__string_std__string.kt +0 -2
  217. package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/HybridAndroidAutoTelemetrySpec.kt +2 -0
  218. package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/HybridAndroidAutomotiveSpec.kt +2 -0
  219. package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/HybridAndroidWindowInformationSpec.kt +2 -0
  220. package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/HybridAutoPlaySpec.kt +2 -0
  221. package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/HybridAutoPlayTimingSpec.kt +65 -0
  222. package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/HybridClusterSpec.kt +2 -0
  223. package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/HybridGridTemplateSpec.kt +2 -0
  224. package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/HybridInformationTemplateSpec.kt +2 -0
  225. package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/HybridListTemplateSpec.kt +2 -0
  226. package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/HybridMapTemplateSpec.kt +2 -0
  227. package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/HybridMessageTemplateSpec.kt +2 -0
  228. package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/HybridSearchTemplateSpec.kt +2 -0
  229. package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/HybridSignInTemplateSpec.kt +2 -0
  230. package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/HybridVoiceSpec.kt +2 -0
  231. package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/NitroColor.kt +9 -4
  232. package/nitrogen/generated/ios/ReactNativeAutoPlay-Swift-Cxx-Bridge.cpp +17 -0
  233. package/nitrogen/generated/ios/ReactNativeAutoPlay-Swift-Cxx-Bridge.hpp +35 -9
  234. package/nitrogen/generated/ios/ReactNativeAutoPlay-Swift-Cxx-Umbrella.hpp +5 -0
  235. package/nitrogen/generated/ios/ReactNativeAutoPlayAutolinking.mm +8 -0
  236. package/nitrogen/generated/ios/ReactNativeAutoPlayAutolinking.swift +12 -0
  237. package/nitrogen/generated/ios/c++/HybridAutoPlayTimingSpecSwift.cpp +11 -0
  238. package/nitrogen/generated/ios/c++/HybridAutoPlayTimingSpecSwift.hpp +88 -0
  239. package/nitrogen/generated/ios/swift/AssetImage.swift +13 -13
  240. package/nitrogen/generated/ios/swift/HybridAutoPlayTimingSpec.swift +56 -0
  241. package/nitrogen/generated/ios/swift/HybridAutoPlayTimingSpec_cxx.swift +154 -0
  242. package/nitrogen/generated/ios/swift/NitroColor.swift +20 -2
  243. package/nitrogen/generated/shared/c++/AssetImage.hpp +18 -18
  244. package/nitrogen/generated/shared/c++/HybridAutoPlayTimingSpec.cpp +22 -0
  245. package/nitrogen/generated/shared/c++/HybridAutoPlayTimingSpec.hpp +63 -0
  246. package/nitrogen/generated/shared/c++/NitroColor.hpp +7 -3
  247. package/package.json +12 -6
  248. package/src/components/SafeAreaView.tsx +1 -1
  249. package/src/hybrid/HybridAutoPlayTiming.ts +5 -0
  250. package/src/hybrid/HybridVoice.ts +2 -2
  251. package/src/index.ts +0 -3
  252. package/src/index.web.ts +166 -0
  253. package/src/installTimers.ts +9 -0
  254. package/src/installTimers.web.ts +2 -0
  255. package/src/specs/AutoPlayTiming.nitro.ts +25 -0
  256. package/src/types/Image.ts +6 -1
  257. package/src/types/Telemetry.ts +1 -1
  258. package/src/utils/AutoPlayTimers.ts +60 -0
  259. package/src/utils/NitroColor.ts +10 -1
  260. package/src/utils/NitroImage.ts +14 -8
  261. package/src/utils/NitroManeuver.ts +1 -4
  262. package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/HeadlessTaskService.kt +0 -36
  263. package/lib/AutoPlayHeadlessJsTask.d.ts +0 -5
  264. package/lib/AutoPlayHeadlessJsTask.js +0 -14
  265. package/src/AutoPlayHeadlessJsTask.ts +0 -22
package/README.md CHANGED
@@ -25,6 +25,7 @@
25
25
  ## Requirements
26
26
 
27
27
  - **iOS builds require Xcode 27+** (the iOS 27 SDK), even for apps that don't use any `mapConfig`/panel features — the library references `CPMapPanel`/`CPPanel` types internally behind `@available(iOS 27.0, *)` checks, but `@available` only defers *runtime* execution, not compile-time symbol resolution, so the SDK must be present to build at all.
28
+ - **`react-native-nitro-modules` 0.37.1 or newer** — the generated native bindings target that runtime shape; an older nitro-modules install fails at native build time.
28
29
 
29
30
  ## Installation
30
31
 
@@ -48,8 +49,8 @@
48
49
 
49
50
  #### Bundle identifier
50
51
  To get the CarPlay app showing up you need to set a proper Bundle Identifier:
51
- - Open `example.xcodeproj`
52
- - Select the example target, go to the **Signing & Capabilities** tab.
52
+ - Open your app's `.xcodeproj` in Xcode.
53
+ - Select your app target, go to the **Signing & Capabilities** tab.
53
54
  - Under **Signing > Bundle Identifier**, enter your unique bundle ID (e.g., `at.g4rb4g3.autoplay.example`).
54
55
 
55
56
  #### Entitlements
@@ -178,7 +179,7 @@ This is an example that works for bare react-native (>= 0.82) and Expo SDK 57, c
178
179
  It is recommended to attach a listener to MapTemplate.onAppearanceDidChange and send maneuver updates based on this to make sure the colors are applied properly.
179
180
  Reason for this is that CarPlay does not allow for color updates on maneuvers shown on the screen. You need to send maneuvers with a new id to get them updated properly on the screen.
180
181
  The color properties do not need to handle the mode change, best practice is to use ThemedColor whenever possible and set appropriate light and dark mode colors.
181
- This is mainly required on CarPlay for now since Android Auto lacks light mode.
182
+ This is mainly required on CarPlay. Android Auto redraws on its own when the day/night state changes, but note that Android Auto 17.8 introduced white templates in day mode while older versions always show dark templates. The car's day/night state (`isDarkMode`) is the same on both, so it does not tell you which template color you are drawn on. Use the `'default'` color for icons that have to stay readable in both cases, see **Icon colors and Android Auto light templates**.
182
183
 
183
184
  #### CPListTemplate day/night header
184
185
 
@@ -293,13 +294,21 @@ This library also supports Android Automotive. To enable Android Automotive supp
293
294
 
294
295
  - **`isAutomotiveApp` flag**: You need to inform the library if this is an Automotive app by setting the `isAutomotiveApp` property to `true`. For Android Auto, it should be `false`.
295
296
 
296
- You can set these properties directly in your `android/gradle.properties` file:
297
+ You can set these properties directly in your `android/gradle.properties` file. **Note the
298
+ `ReactNativeAutoPlay_` prefix** — the library reads `rootProject.ext.<name>` first and falls
299
+ back to the prefixed project property, so an unprefixed `isAutomotiveApp=true` in
300
+ `gradle.properties` is silently ignored and you get an Android Auto build instead:
301
+
297
302
  ```properties
298
303
  # For Android Automotive
299
- minSdkVersion=29
300
- isAutomotiveApp=true
304
+ ReactNativeAutoPlay_minSdkVersion=29
305
+ ReactNativeAutoPlay_isAutomotiveApp=true
301
306
  ```
302
307
 
308
+ If your app's `android/build.gradle` already defines `ext.minSdkVersion` (the React Native
309
+ template does), that `rootProject.ext` value wins over the property above — raise it there
310
+ instead.
311
+
303
312
  Alternatively, if you need to support different build variants (e.g., for both Android Auto and Android Automotive from the same codebase), using `react-native-config` is the recommended approach.
304
313
 
305
314
  1. Install `react-native-config`:
@@ -443,14 +452,34 @@ It is also possible to use custom bundled images (e.g. PNG, WEBP or Vector Drawa
443
452
  - iOS: Add to your `Images.xcassets`
444
453
  - Android: Add to `res/drawable`
445
454
 
455
+ ### Icon colors and Android Auto light templates
456
+
457
+ Starting with **Android Auto 17.8** the host can show white (light) templates in day mode. Older versions (e.g. 17.6) always use dark templates, even in day mode. Both report the same car app API level, so an app cannot tell them apart, and a fixed icon color that is readable on one (white on dark) can be invisible on the other (white on white).
458
+
459
+ Use the color `'default'` for every monochrome icon that has to stay readable in both cases:
460
+
461
+ ```ts
462
+ { type: 'glyph', name: 'search', color: 'default' }
463
+ { type: 'asset', image: require('./icon.png'), color: 'default' }
464
+ { type: 'remote', uri: 'https://example.com/icon.png', color: 'default' }
465
+ ```
466
+
467
+ - **Android Auto**: the host tints the icon with its own default icon color for the template it is currently showing, so it follows dark and light templates on every Android Auto version.
468
+ - **CarPlay**: `'default'` resolves to black in light mode and white in dark mode, so it is safe to use on iOS and does not change anything there.
469
+ - **Glyphs** use `'default'` automatically when no `color` is set. Exception on Android Auto: a glyph with a non-transparent `backgroundColor` is not tinted, since the tint would recolor the background as well. It keeps the plain white (dark mode) / black (light mode) glyph color, so set `color` explicitly if that does not contrast with your background.
470
+ - **Asset and remote images** are not tinted unless you set a `color`, so colorful images such as a logo keep their original colors. Only pass `'default'` for monochrome icons.
471
+ - Any other color (a string or a `ThemedColor`) is applied as specified. Only use those where the color works on both dark and light templates, e.g. a colored icon.
472
+ - Known limitation: the host may not apply the tint to header action icons on Android Auto 17.8. That is an issue in Android Auto itself, not something the library can work around.
473
+
446
474
  ## Usage
447
475
 
448
476
  ### 1. Register the AutoPlay Components
449
477
 
450
- You need to register your AutoPlay components in your app's entry file (e.g., `index.js`). This includes setting up the headless task that runs when CarPlay or Android Auto is connected.
478
+ You need to register your AutoPlay components in your app's entry file (e.g., `index.js`). Import `@iternio/react-native-auto-play/installTimers` — a side-effect-only module that replaces the global `setTimeout`/`setInterval`/`requestAnimationFrame` (and their `clear*`/`cancel*` counterparts) with versions that keep running while CarPlay/Android Auto is actively driving the car screen, even if the phone itself is backgrounded or its screen is locked. React Native's own timers throttle or pause in that state regardless of whether the app process is actually still alive, which would otherwise stall ETA updates and telemetry polling. It must run before any other module has a chance to capture a reference to the original globals, which means it must be your entry file's **first import** — ES import declarations are hoisted and evaluated in source order, so it needs to come before everything else, including `react-native` itself:
451
479
 
452
480
  ```javascript
453
481
  // index.js
482
+ import '@iternio/react-native-auto-play/installTimers';
454
483
  import { AppRegistry } from 'react-native';
455
484
  import { name as appName } from './app.json';
456
485
  import App from './src/App';
@@ -576,7 +605,7 @@ All root components rendered by templates/scenes receive `RootComponentInitialPr
576
605
 
577
606
  - `id`: Module identifier (e.g. `AutoPlayRoot`, `CarPlayDashboard`, or a cluster UUID).
578
607
  - `rootTag`: React Native root tag.
579
- - `colorScheme`: `'light' | 'dark'` initial color scheme (listen to `onAppearanceDidChange` on `MapTemplate` for updates).
608
+ - `colorScheme`: `'light' | 'dark'` initial color scheme (listen to `onAppearanceDidChange` on `MapTemplate` for updates). On Android Auto this is the car's day/night state and does not tell you whether the templates are dark or white (17.8+ can show white templates in day mode, older versions never do).
580
609
  - `window`: `{ width, height, scale }`.
581
610
 
582
611
  ### Template Configs (Props)
@@ -1259,14 +1288,34 @@ CarPlayDashboard.setButtons([
1259
1288
  - `setAttributedInactiveDescriptionVariants(variants)` — iOS only inactive text.
1260
1289
  - `addListenerColorScheme(cb)` / `addListenerZoom(cb)` / `addListenerCompass(cb)` / `addListenerSpeedLimit(cb)`.
1261
1290
 
1291
+ ## Testing with Jest
1292
+
1293
+ The real package needs native modules and ships ESM, so it can't run under Jest. Use the bundled CommonJS mock instead, one line in your Jest setup file:
1294
+
1295
+ ```js
1296
+ // jest.setup.js
1297
+ jest.mock('@iternio/react-native-auto-play', () =>
1298
+ require('@iternio/react-native-auto-play/jest')
1299
+ );
1300
+ ```
1301
+
1302
+ Templates, `HybridAutoPlay`, `HybridVoice`, `AutoPlayCluster`, `CarPlayDashboard` and the hooks that need a car surface are safe no-ops (any method call returns `undefined`), `Constants.isIos27OrGreater` is `false`, and all types are unchanged. Tests that need to record constructions or assert on calls should extend it per test file:
1303
+
1304
+ ```ts
1305
+ jest.mock('@iternio/react-native-auto-play', () => {
1306
+ const actual = jest.requireActual('@iternio/react-native-auto-play/jest');
1307
+ return { ...actual, ListTemplate: class { push = jest.fn(() => Promise.resolve()); } };
1308
+ });
1309
+ ```
1310
+
1311
+ The same no-op surface is what `react-native-web` builds get automatically via `index.web.ts`.
1312
+
1262
1313
  ## Known Issues
1263
1314
 
1264
1315
  ### iOS
1265
1316
 
1266
1317
  - **Broken exceptions with `react-native-skia`**: When using `react-native-skia` exceptions on iOS are not reported correctly. This is fixed since version `2.4.19` of `react-native-skia`. For more details, see this [pull request](https://github.com/Shopify/react-native-skia/pull/3595) and [issue](https://github.com/Shopify/react-native-skia/issues/3635).
1267
1318
  - **AppState on iOS**: The `AppState` module from React Native does not work correctly on iOS because this library uses scenes, which are not supported by the stock `AppState` module. This library provides a custom state listener that works for both Android and iOS. Use `HybridAutoPlay.addListenerRenderState` instead of `AppState`.
1268
- - **Timers stop on screen lock**: iOS stops all timers when the device main screen is turned off. To ensure timers continue to run (which is often necessary for background tasks related to autoplay), a patch for `react-native` is required. A patch is included in the root `patches/` directory and can be applied using `patch-package`.
1269
- In case you are using Expo SDK >= 56 make sure to set `buildReactNativeFromSource` to `true` in your app config for [expo-build-properties](https://docs.expo.dev/versions/latest/sdk/build-properties/#sharedbuildconfigfields), otherwise the patch can't be applied.
1270
1319
  - **expo-splash-screen stuck on iOS**: The `expo-splash-screen` module is broken on iOS because it does not support scenes, which are used by this library. This can cause the splash screen to be stuck on either the mobile device or on CarPlay. To fix this, a patch for `expo-splash-screen` is included in the root `patches/` directory and can be applied using `patch-package`. After applying the patch, you can hide the splash screen for a specific scene by passing the module name to the `hide` or `hideAsync` function. The module name can be one of the values from the `AutoPlayModules` enum or the UUID of a cluster screen.
1271
1320
  ```tsx
1272
1321
  import { hideAsync } from 'expo-splash-screen';
@@ -58,8 +58,6 @@
58
58
  </intent-filter>
59
59
  </service>
60
60
 
61
- <service android:name="com.margelo.nitro.swe.iternio.reactnativeautoplay.HeadlessTaskService" />
62
-
63
61
  <activity android:name="com.margelo.nitro.swe.iternio.reactnativeautoplay.SignInWithGoogleActivity" />
64
62
 
65
63
  <provider
@@ -74,8 +74,6 @@
74
74
  </intent-filter>
75
75
  </service>
76
76
 
77
- <service android:name="com.margelo.nitro.swe.iternio.reactnativeautoplay.HeadlessTaskService" />
78
-
79
77
  <activity android:name="com.margelo.nitro.swe.iternio.reactnativeautoplay.SignInWithGoogleActivity" />
80
78
 
81
79
  <provider
@@ -28,8 +28,6 @@
28
28
  <meta-data android:name="com.google.android.gms.car.application" android:resource="@xml/automotive_app_desc" tools:ignore="MetadataTagInsideApplicationTag" />
29
29
  <meta-data android:name="androidx.car.app.minCarApiLevel" android:value="1" />
30
30
 
31
- <service android:name="com.margelo.nitro.swe.iternio.reactnativeautoplay.HeadlessTaskService" />
32
-
33
31
  <provider android:name="com.margelo.nitro.swe.iternio.reactnativeautoplay.ActivityRenderStateProvider" android:authorities="${applicationId}.ActivityRenderStateProvider" android:exported="false" />
34
32
  </application>
35
33
  </manifest>
@@ -37,8 +37,6 @@
37
37
  <meta-data android:name="com.google.android.gms.car.application" android:resource="@xml/automotive_app_desc" tools:ignore="MetadataTagInsideApplicationTag" />
38
38
  <meta-data android:name="androidx.car.app.minCarApiLevel" android:value="1" />
39
39
 
40
- <service android:name="com.margelo.nitro.swe.iternio.reactnativeautoplay.HeadlessTaskService" />
41
-
42
40
  <provider android:name="com.margelo.nitro.swe.iternio.reactnativeautoplay.ActivityRenderStateProvider" android:authorities="${applicationId}.ActivityRenderStateProvider" android:exported="false" />
43
41
  </application>
44
42
  </manifest>
@@ -5,14 +5,10 @@ import android.annotation.SuppressLint
5
5
  import android.app.Notification
6
6
  import android.app.NotificationChannel
7
7
  import android.app.NotificationManager
8
- import android.content.ComponentName
9
- import android.content.Intent
10
- import android.content.ServiceConnection
11
8
  import android.content.pm.ApplicationInfo
12
9
  import android.content.pm.PackageManager
13
10
  import android.graphics.Bitmap
14
11
  import android.os.Build
15
- import android.os.IBinder
16
12
  import android.util.Log
17
13
  import androidx.car.app.CarAppService
18
14
  import androidx.car.app.Session
@@ -23,6 +19,7 @@ import androidx.core.app.NotificationCompat
23
19
  import androidx.core.app.NotificationManagerCompat
24
20
  import androidx.lifecycle.DefaultLifecycleObserver
25
21
  import androidx.lifecycle.LifecycleOwner
22
+ import com.facebook.react.ReactApplication
26
23
  import com.facebook.react.bridge.LifecycleEventListener
27
24
  import com.margelo.nitro.NitroModules
28
25
  import com.margelo.nitro.swe.iternio.reactnativeautoplay.utils.AppInfo
@@ -30,7 +27,6 @@ import com.margelo.nitro.swe.iternio.reactnativeautoplay.utils.AppInfo
30
27
  class AndroidAutoService : CarAppService() {
31
28
  private lateinit var notificationManager: NotificationManager
32
29
 
33
- private var isServiceBound = false
34
30
  private var isSessionStarted = false
35
31
  private var isReactAppStarted = false
36
32
 
@@ -48,6 +44,8 @@ class AndroidAutoService : CarAppService() {
48
44
  super.onCreate()
49
45
  instance = this
50
46
 
47
+ (application as? ReactApplication)?.reactHost?.start()
48
+
51
49
  NitroModules.applicationContext?.addLifecycleEventListener(reactLifecycleObserver)
52
50
 
53
51
  notificationManager = getSystemService(NotificationManager::class.java)
@@ -98,11 +96,6 @@ class AndroidAutoService : CarAppService() {
98
96
  }
99
97
 
100
98
  private val sessionLifecycleObserver = object : DefaultLifecycleObserver {
101
- override fun onCreate(owner: LifecycleOwner) {
102
- val serviceIntent = Intent(applicationContext, HeadlessTaskService::class.java)
103
- bindService(serviceIntent, connection, BIND_AUTO_CREATE)
104
- }
105
-
106
99
  override fun onResume(owner: LifecycleOwner) {
107
100
  isSessionStarted = true
108
101
  }
@@ -112,27 +105,10 @@ class AndroidAutoService : CarAppService() {
112
105
  }
113
106
 
114
107
  override fun onDestroy(owner: LifecycleOwner) {
115
- if (isServiceBound) {
116
- unbindService(connection)
117
- isServiceBound = false
118
- }
119
-
120
108
  this@AndroidAutoService.stopForeground(STOP_FOREGROUND_REMOVE)
121
109
  }
122
110
  }
123
111
 
124
- private val connection: ServiceConnection = object : ServiceConnection {
125
- override fun onServiceConnected(
126
- className: ComponentName, service: IBinder
127
- ) {
128
- isServiceBound = true
129
- }
130
-
131
- override fun onServiceDisconnected(arg0: ComponentName) {
132
- isServiceBound = false
133
- }
134
- }
135
-
136
112
  private fun createNotification(
137
113
  title: String?, text: String?, largeIcon: Bitmap?
138
114
  ): Notification {
@@ -0,0 +1,122 @@
1
+ package com.margelo.nitro.swe.iternio.reactnativeautoplay
2
+
3
+ import android.os.Handler
4
+ import android.os.Looper
5
+ import android.os.SystemClock
6
+ import java.lang.ref.WeakReference
7
+ import java.util.concurrent.ConcurrentHashMap
8
+ import java.util.concurrent.atomic.AtomicBoolean
9
+ import java.util.concurrent.atomic.AtomicLong
10
+
11
+ private class ScheduledTimer(
12
+ val callback: () -> Unit,
13
+ val interval: Long,
14
+ val repeats: Boolean,
15
+ var target: Long,
16
+ )
17
+
18
+ // Weak ref, so a stale instance (dev reload / host restart) can't tick forever in the queue.
19
+ private class TickRunnable(target: HybridAutoPlayTiming) : Runnable {
20
+ private val ref = WeakReference(target)
21
+
22
+ override fun run() {
23
+ ref.get()?.tick()
24
+ }
25
+ }
26
+
27
+ /**
28
+ * Backs setTimeout/setInterval (see AutoPlayTimers.ts) with a plain Handler loop on the main
29
+ * Looper -- not Choreographer, which JavaTimerManager itself uses and only keeps ticking while
30
+ * the host is resumed or a headless JS task is running. See AutoPlayTiming.nitro.ts.
31
+ *
32
+ * Ticks at a fixed ~60Hz while any timer is pending and stops entirely once idle, rather than
33
+ * scheduling a delay to the next due target: postDelayed's dispatch is gated on uptimeMillis(),
34
+ * which pauses during deep sleep, so a long pre-sleep delay would need that much *awake* time
35
+ * after waking. A short, repeated delay only needs ~16ms of awake time, so it fires within
36
+ * about one frame of the device waking regardless of sleep length -- due timers are then found
37
+ * correctly because target/now use elapsedRealtime(), which counts straight through sleep.
38
+ */
39
+ class HybridAutoPlayTiming : HybridAutoPlayTimingSpec() {
40
+ companion object {
41
+ private const val FRAME_DURATION_MS = 1000L / 60L
42
+
43
+ // RN's TimerManager also numbers ids from 1; offsetting avoids collisions with ids a
44
+ // pre-install caller (e.g. React's own scheduler) still holds against the original
45
+ // clearTimeout, now replaced.
46
+ private const val ID_OFFSET = 1_000_000_000L
47
+ }
48
+
49
+ private val handler = Handler(Looper.getMainLooper())
50
+ private val timers = ConcurrentHashMap<Double, ScheduledTimer>()
51
+ private val nextId = AtomicLong(ID_OFFSET)
52
+ private val isTicking = AtomicBoolean(false)
53
+ private val tickRunnable = TickRunnable(this)
54
+
55
+ private fun ensureTicking() {
56
+ if (isTicking.compareAndSet(false, true)) {
57
+ handler.postDelayed(tickRunnable, FRAME_DURATION_MS)
58
+ }
59
+ }
60
+
61
+ internal fun tick() {
62
+ // elapsedRealtime(), not uptimeMillis(): both are immune to NTP/manual clock changes,
63
+ // but unlike uptimeMillis() this one keeps counting through deep sleep.
64
+ val now = SystemClock.elapsedRealtime()
65
+
66
+ // Sort by (target, id): ConcurrentHashMap iteration order is unspecified, so
67
+ // setTimeout(a, 0); setTimeout(b, 0) could otherwise fire b before a.
68
+ val dueIds = timers.entries.filter { it.value.target <= now }
69
+ .sortedWith(compareBy({ it.value.target }, { it.key }))
70
+ .map { it.key }
71
+
72
+ for (id in dueIds) {
73
+ // Re-check membership: a same-tick callback may have cleared a later timer in
74
+ // this snapshotted list (e.g. `clearTimeout(t); t = setTimeout(...)`).
75
+ val timer = timers[id] ?: continue
76
+
77
+ if (timer.repeats) {
78
+ timer.target = now + timer.interval
79
+ } else {
80
+ timers.remove(id)
81
+ }
82
+
83
+ timer.callback()
84
+ }
85
+
86
+ if (timers.isNotEmpty()) {
87
+ handler.postDelayed(tickRunnable, FRAME_DURATION_MS)
88
+ return
89
+ }
90
+
91
+ isTicking.set(false)
92
+ // Reclaim: a concurrent createTimer() may have inserted an entry and found `isTicking`
93
+ // still true (skipping its own post) in the gap before the flag was cleared above.
94
+ if (timers.isNotEmpty()) {
95
+ ensureTicking()
96
+ }
97
+ }
98
+
99
+ override fun createTimer(callback: () -> Unit, durationMs: Double, repeats: Boolean): Double {
100
+ val interval = durationMs.toLong().coerceAtLeast(0)
101
+ val id = nextId.getAndIncrement().toDouble()
102
+ timers[id] = ScheduledTimer(
103
+ callback = callback,
104
+ interval = interval,
105
+ repeats = repeats,
106
+ target = SystemClock.elapsedRealtime() + interval,
107
+ )
108
+ ensureTicking()
109
+ return id
110
+ }
111
+
112
+ override fun deleteTimer(id: Double) {
113
+ timers.remove(id)
114
+ }
115
+
116
+ override fun dispose() {
117
+ handler.removeCallbacks(tickRunnable)
118
+ isTicking.set(false)
119
+ timers.clear()
120
+ super.dispose()
121
+ }
122
+ }
@@ -36,6 +36,7 @@ import androidx.car.app.navigation.model.TravelEstimate
36
36
  import androidx.core.graphics.createBitmap
37
37
  import androidx.core.graphics.drawable.IconCompat
38
38
  import androidx.core.graphics.drawable.toBitmap
39
+ import androidx.core.net.toUri
39
40
  import com.facebook.datasource.DataSources
40
41
  import com.facebook.drawee.backends.pipeline.Fresco
41
42
  import com.facebook.imagepipeline.image.CloseableBitmap
@@ -51,8 +52,8 @@ import com.margelo.nitro.swe.iternio.reactnativeautoplay.DurationWithTimeZone
51
52
  import com.margelo.nitro.swe.iternio.reactnativeautoplay.ForkType
52
53
  import com.margelo.nitro.swe.iternio.reactnativeautoplay.GlyphImage
53
54
  import com.margelo.nitro.swe.iternio.reactnativeautoplay.KeepType
54
- import com.margelo.nitro.swe.iternio.reactnativeautoplay.ListTemplateConfig
55
55
  import com.margelo.nitro.swe.iternio.reactnativeautoplay.ListImageType
56
+ import com.margelo.nitro.swe.iternio.reactnativeautoplay.ListTemplateConfig
56
57
  import com.margelo.nitro.swe.iternio.reactnativeautoplay.ManeuverType
57
58
  import com.margelo.nitro.swe.iternio.reactnativeautoplay.NitroAction
58
59
  import com.margelo.nitro.swe.iternio.reactnativeautoplay.NitroActionType
@@ -82,7 +83,6 @@ import java.util.Calendar
82
83
  import java.util.Locale
83
84
  import java.util.TimeZone
84
85
  import kotlin.math.abs
85
- import androidx.core.net.toUri
86
86
 
87
87
  object Parser {
88
88
  // IMAGE_TYPE_MEDIUM was added to androidx.car.app in 1.8.0. Keep the protocol value here
@@ -182,7 +182,11 @@ object Parser {
182
182
  }.build()
183
183
  }
184
184
 
185
- fun parseAction(context: CarContext, action: NitroAction, useParkedOnlyClickListener: Boolean = false): Action {
185
+ fun parseAction(
186
+ context: CarContext,
187
+ action: NitroAction,
188
+ useParkedOnlyClickListener: Boolean = false
189
+ ): Action {
186
190
  if (action.type == NitroActionType.APPICON) {
187
191
  return Action.APP_ICON
188
192
  }
@@ -219,11 +223,21 @@ object Parser {
219
223
  }
220
224
 
221
225
  fun parseImage(context: CarContext, image: Variant_GlyphImage_AssetImage_RemoteImage): CarIcon {
222
- return parseImage(context, image.asFirstOrNull(), image.asSecondOrNull(), image.asThirdOrNull())
226
+ return parseImage(
227
+ context,
228
+ image.asFirstOrNull(),
229
+ image.asSecondOrNull(),
230
+ image.asThirdOrNull()
231
+ )
223
232
  }
224
233
 
225
234
  fun parseImage(context: CarContext, image: NitroImage): CarIcon {
226
- return parseImage(context, image.asFirstOrNull(), image.asSecondOrNull(), image.asThirdOrNull())
235
+ return parseImage(
236
+ context,
237
+ image.asFirstOrNull(),
238
+ image.asSecondOrNull(),
239
+ image.asThirdOrNull()
240
+ )
227
241
  }
228
242
 
229
243
  fun parseImage(
@@ -234,8 +248,19 @@ object Parser {
234
248
  ): CarIcon {
235
249
  val bitmap = parseImageToBitmap(context, glyphImage, assetImage, remoteImage)
236
250
 
251
+ // the tint recolors every opaque pixel, so it would also fill the background drawn in SymbolFont
252
+ val hasGlyphBackground =
253
+ glyphImage != null && (glyphImage.backgroundColor.get(context) ushr 24) != 0
254
+
255
+ val applyDefaultTint = !hasGlyphBackground && (glyphImage?.color?.isDefault
256
+ ?: assetImage?.color?.isDefault ?: remoteImage?.color?.isDefault ?: false)
257
+
237
258
  bitmap?.let {
238
- return CarIcon.Builder(IconCompat.createWithBitmap(it)).build()
259
+ return CarIcon.Builder(IconCompat.createWithBitmap(it)).apply {
260
+ if (applyDefaultTint) {
261
+ setTint(CarColor.DEFAULT)
262
+ }
263
+ }.build()
239
264
  }
240
265
 
241
266
  // remote images might fail to load so we provide some placeholder then
@@ -353,7 +378,7 @@ object Parser {
353
378
  }
354
379
  row.onPress?.let {
355
380
  setOnClickListener {
356
- row.onPress(null)
381
+ it(null)
357
382
  }
358
383
  }
359
384
  row.browsable?.let {
@@ -610,10 +635,14 @@ object Parser {
610
635
  private fun fetchSync(context: CarContext, imageRequest: ImageRequest): Bitmap? {
611
636
  val dataSource = try {
612
637
  Fresco.getImagePipeline().fetchDecodedImage(imageRequest, context)
613
- } catch (_: Exception) { return null }
638
+ } catch (_: Exception) {
639
+ return null
640
+ }
614
641
  val result = try {
615
642
  DataSources.waitForFinalResult(dataSource)
616
- } catch (_: Exception) { dataSource.close(); return null }
643
+ } catch (_: Exception) {
644
+ dataSource.close(); return null
645
+ }
617
646
  val image = result?.get()
618
647
  try {
619
648
  if (image is CloseableBitmap) {
@@ -624,7 +653,11 @@ object Parser {
624
653
  return image.underlyingBitmap?.copy(Bitmap.Config.ARGB_8888, false)
625
654
  } else if (image is CloseableXml) {
626
655
  val drawable = image.buildDrawable()
627
- return drawable?.toBitmap(width = image.width, height = image.height, Bitmap.Config.ARGB_8888)
656
+ return drawable?.toBitmap(
657
+ width = image.width,
658
+ height = image.height,
659
+ Bitmap.Config.ARGB_8888
660
+ )
628
661
  }
629
662
  } catch (_: Exception) {
630
663
  // Any decode/copy failure (OOM, recycled bitmap, invalid config, …) should
@@ -759,10 +792,12 @@ object Parser {
759
792
  }
760
793
  nitroManeuver.angle?.let { roundaboutExitAngle ->
761
794
  if (nitroManeuver.trafficSide == TrafficSide.LEFT) {
762
- val angle = ((180 + roundaboutExitAngle) % 360).toInt().let { if (it == 0) 360 else it }
795
+ val angle = ((180 + roundaboutExitAngle) % 360).toInt()
796
+ .let { if (it == 0) 360 else it }
763
797
  setRoundaboutExitAngle(angle)
764
798
  } else {
765
- val angle = ((180 - roundaboutExitAngle) % 360).toInt().let { if (it == 0) 360 else it }
799
+ val angle = ((180 - roundaboutExitAngle) % 360).toInt()
800
+ .let { if (it == 0) 360 else it }
766
801
  setRoundaboutExitAngle(angle)
767
802
  }
768
803
  }
@@ -841,7 +876,7 @@ object Parser {
841
876
  mapConfig.mapButtons?.let { mapButtons ->
842
877
  setMapController(
843
878
  MapController.Builder().apply {
844
- setMapActionStrip(Parser.parseMapActions(context, mapButtons)).build()
879
+ setMapActionStrip(parseMapActions(context, mapButtons)).build()
845
880
  setPanModeListener { isInPanMode ->
846
881
  mapConfig.onDidChangePanningInterface?.let {
847
882
  it(isInPanMode)
@@ -851,7 +886,7 @@ object Parser {
851
886
  )
852
887
  }
853
888
  mapConfig.headerActions?.let { headerActions ->
854
- setActionStrip(Parser.parseMapHeaderActions(context, headerActions))
889
+ setActionStrip(parseMapHeaderActions(context, headerActions))
855
890
  }
856
891
  }.build()
857
892
  }
@@ -0,0 +1,3 @@
1
+ // Root re-export so `@iternio/react-native-auto-play/installTimers` is a deliberate, explicitly
2
+ // published public entry point rather than a reach into src/ internals -- see src/installTimers.ts.
3
+ import './src/installTimers';
@@ -0,0 +1,2 @@
1
+ // Web/Jest counterpart to installTimers.ts, picked by Metro's platform resolution.
2
+ import './src/installTimers.web';
@@ -0,0 +1,123 @@
1
+ import Foundation
2
+ import NitroModules
3
+
4
+ private struct ScheduledTimer {
5
+ let callback: () -> Void
6
+ let interval: TimeInterval
7
+ let repeats: Bool
8
+ var target: TimeInterval
9
+ }
10
+
11
+ // Unlike ProcessInfo.systemUptime/mach_absolute_time(), keeps counting through sleep. RAW over
12
+ // plain CLOCK_MONOTONIC: also immune to NTP frequency-discipline adjustments.
13
+ private func now() -> TimeInterval {
14
+ TimeInterval(clock_gettime_nsec_np(CLOCK_MONOTONIC_RAW)) / 1_000_000_000
15
+ }
16
+
17
+ /// Backs setTimeout/setInterval (see AutoPlayTimers.ts) with a plain `Timer` -- not tied to
18
+ /// `CADisplayLink`/screen refresh, so it keeps firing while the phone screen is locked and
19
+ /// CarPlay is actively driving the external screen. See AutoPlayTiming.nitro.ts.
20
+ ///
21
+ /// Ticks at a fixed ~60Hz while any timer is pending and stops entirely once idle, rather than
22
+ /// scheduling a delay to the next due target: a `Timer`'s dispatch is gated on the run loop's
23
+ /// own monotonic clock, which (like `mach_absolute_time()`) pauses during sleep, so a long
24
+ /// pre-sleep delay would need that much *awake* time after waking. A short, repeated delay only
25
+ /// needs ~16ms of awake time, so it fires within about one frame of the device waking
26
+ /// regardless of sleep length.
27
+ class HybridAutoPlayTiming: HybridAutoPlayTimingSpec {
28
+ private static let frameDuration: TimeInterval = 1.0 / 60.0
29
+
30
+ // RN's TimerManager also numbers ids from 1; offsetting avoids collisions with ids a
31
+ // pre-install caller (e.g. React's own scheduler) still holds against the original
32
+ // clearTimeout, now replaced.
33
+ private static let idOffset: Double = 1_000_000_000
34
+
35
+ private let lock = NSLock()
36
+ private var timers = [Double: ScheduledTimer]()
37
+ private var nextId: Double = HybridAutoPlayTiming.idOffset
38
+ private var timer: Timer?
39
+
40
+ deinit {
41
+ timer?.invalidate()
42
+ }
43
+
44
+ private func withLock<T>(_ body: () -> T) -> T {
45
+ lock.lock()
46
+ defer { lock.unlock() }
47
+ return body()
48
+ }
49
+
50
+ // Must be called while already holding `lock`.
51
+ private func scheduleTick() {
52
+ let next = Timer(timeInterval: HybridAutoPlayTiming.frameDuration, repeats: false) { [weak self] _ in
53
+ self?.tick()
54
+ }
55
+ RunLoop.main.add(next, forMode: .common)
56
+ timer = next
57
+ }
58
+
59
+ private func tick() {
60
+ let currentTime = now()
61
+
62
+ // Sort by (target, id): Dictionary iteration order is unspecified, so
63
+ // setTimeout(a, 0); setTimeout(b, 0) could otherwise fire b before a.
64
+ let dueIds = withLock {
65
+ timers.filter { $0.value.target <= currentTime }
66
+ .sorted { lhs, rhs in
67
+ lhs.value.target != rhs.value.target
68
+ ? lhs.value.target < rhs.value.target
69
+ : lhs.key < rhs.key
70
+ }
71
+ .map(\.key)
72
+ }
73
+
74
+ for id in dueIds {
75
+ // Re-check membership: a same-tick callback may have cleared a later timer in
76
+ // this snapshotted list (e.g. `clearTimeout(t); t = setTimeout(...)`).
77
+ let callback: (() -> Void)? = withLock {
78
+ guard var entry = timers[id] else { return nil }
79
+ if entry.repeats {
80
+ entry.target = now() + entry.interval
81
+ timers[id] = entry
82
+ } else {
83
+ timers.removeValue(forKey: id)
84
+ }
85
+ return entry.callback
86
+ }
87
+
88
+ callback?()
89
+ }
90
+
91
+ withLock {
92
+ timer = nil
93
+ if !timers.isEmpty {
94
+ scheduleTick()
95
+ }
96
+ }
97
+ }
98
+
99
+ func createTimer(callback: @escaping () -> Void, durationMs: Double, repeats: Bool) throws -> Double {
100
+ let interval = max(durationMs, 0) / 1000.0
101
+
102
+ return withLock {
103
+ let id = nextId
104
+ nextId += 1
105
+ timers[id] = ScheduledTimer(
106
+ callback: callback,
107
+ interval: interval,
108
+ repeats: repeats,
109
+ target: now() + interval
110
+ )
111
+ if timer == nil {
112
+ scheduleTick()
113
+ }
114
+ return id
115
+ }
116
+ }
117
+
118
+ func deleteTimer(id: Double) throws {
119
+ withLock {
120
+ _ = timers.removeValue(forKey: id)
121
+ }
122
+ }
123
+ }
package/jest.js ADDED
@@ -0,0 +1,2 @@
1
+ // CommonJS entry for Jest, see "Testing with Jest" in the README.
2
+ module.exports = require('./lib-cjs/index.web');