react-native-queue-player 1.0.2 → 1.0.4

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 (99) hide show
  1. package/android/src/main/cpp/CMakeLists.txt +11 -0
  2. package/android/src/main/cpp/airplay_jni.cpp +5 -2
  3. package/android/src/main/java/com/margelo/nitro/queueplayer/BufferStateTranslator.kt +1 -1
  4. package/android/src/main/java/com/margelo/nitro/queueplayer/CarConnectionState.kt +46 -0
  5. package/android/src/main/java/com/margelo/nitro/queueplayer/Equalizer.kt +1 -3
  6. package/android/src/main/java/com/margelo/nitro/queueplayer/HeadlessJsMediaService.kt +2 -4
  7. package/android/src/main/java/com/margelo/nitro/queueplayer/LookaheadCacheWriter.kt +7 -9
  8. package/android/src/main/java/com/margelo/nitro/queueplayer/MilestoneTracker.kt +1 -2
  9. package/android/src/main/java/com/margelo/nitro/queueplayer/PlaybackService.kt +5 -6
  10. package/android/src/main/java/com/margelo/nitro/queueplayer/PlaybackServiceCallback.kt +8 -1
  11. package/android/src/main/java/com/margelo/nitro/queueplayer/ProgressEmissionGate.kt +1 -1
  12. package/android/src/main/java/com/margelo/nitro/queueplayer/QueueMutationArithmetic.kt +1 -1
  13. package/android/src/main/java/com/margelo/nitro/queueplayer/QueueSkipArithmetic.kt +1 -1
  14. package/android/src/main/java/com/margelo/nitro/queueplayer/RemoteCommandDeduper.kt +1 -1
  15. package/android/src/main/java/com/margelo/nitro/queueplayer/SleepTimerCore.kt +29 -6
  16. package/android/src/main/java/com/margelo/nitro/queueplayer/TrackPlayer.kt +51 -27
  17. package/android/src/main/java/com/margelo/nitro/queueplayer/TransportStateTranslator.kt +2 -2
  18. package/android/src/test/java/com/margelo/nitro/queueplayer/AudioPipelineRenderersFactoryTest.kt +2 -5
  19. package/android/src/test/java/com/margelo/nitro/queueplayer/BrowseCallbackRegistryTest.kt +1 -4
  20. package/android/src/test/java/com/margelo/nitro/queueplayer/CrossfadeEngineLifecycleTest.kt +1 -2
  21. package/android/src/test/java/com/margelo/nitro/queueplayer/CrossfadeEngineReplayGainTest.kt +3 -7
  22. package/android/src/test/java/com/margelo/nitro/queueplayer/EqualizerEngineTest.kt +1 -2
  23. package/android/src/test/java/com/margelo/nitro/queueplayer/EqualizerKtTest.kt +1 -3
  24. package/android/src/test/java/com/margelo/nitro/queueplayer/EqualizerLegacyEngineTest.kt +2 -3
  25. package/android/src/test/java/com/margelo/nitro/queueplayer/FFTProcessorTeeTest.kt +1 -2
  26. package/android/src/test/java/com/margelo/nitro/queueplayer/GaplessEngineLifecycleTest.kt +0 -2
  27. package/android/src/test/java/com/margelo/nitro/queueplayer/GaplessEngineReplayGainTest.kt +3 -8
  28. package/android/src/test/java/com/margelo/nitro/queueplayer/HeadlessJsMediaServiceTest.kt +2 -4
  29. package/android/src/test/java/com/margelo/nitro/queueplayer/MediaItemBuilderTest.kt +2 -3
  30. package/android/src/test/java/com/margelo/nitro/queueplayer/MilestoneTrackerTest.kt +1 -3
  31. package/android/src/test/java/com/margelo/nitro/queueplayer/NowPlayingFormatExtractorTest.kt +1 -2
  32. package/android/src/test/java/com/margelo/nitro/queueplayer/PitchAwareAudioProcessorChainTest.kt +1 -1
  33. package/android/src/test/java/com/margelo/nitro/queueplayer/PitchCorrectionTest.kt +2 -2
  34. package/android/src/test/java/com/margelo/nitro/queueplayer/PlaybackServiceCallbackTest.kt +76 -7
  35. package/android/src/test/java/com/margelo/nitro/queueplayer/ProgressEmissionGateTest.kt +1 -3
  36. package/android/src/test/java/com/margelo/nitro/queueplayer/SleepTimerCoreTest.kt +41 -0
  37. package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerEventsTest.kt +1 -2
  38. package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerMutationTest.kt +2 -4
  39. package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerPitchCorrectionTest.kt +1 -2
  40. package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerPlaybackModeTest.kt +2 -3
  41. package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerReplayGainTest.kt +1 -3
  42. package/android/src/test/java/com/margelo/nitro/queueplayer/TrackPlayerTransportTest.kt +2 -5
  43. package/android/src/test/java/com/margelo/nitro/queueplayer/VisualizerKtTest.kt +1 -2
  44. package/ios/AVPlayerItemQueueItemId.swift +2 -2
  45. package/ios/AVQueueBuilder.swift +12 -14
  46. package/ios/AudioCategoryMapping.swift +1 -2
  47. package/ios/CarPlayCoordinator.swift +28 -0
  48. package/ios/CarPlaySceneDelegate.swift +2 -0
  49. package/ios/CrossfadeEngine.swift +4 -5
  50. package/ios/InputGuards.swift +3 -3
  51. package/ios/LookaheadCache.swift +4 -6
  52. package/ios/LookaheadCachePrefetcher.swift +1 -1
  53. package/ios/MilestoneTracker.swift +1 -2
  54. package/ios/PlaybackErrorMapping.swift +6 -7
  55. package/ios/PlayerStateDerivation.swift +1 -2
  56. package/ios/ProgressEmissionGate.swift +1 -1
  57. package/ios/QueueMutationArithmetic.swift +2 -2
  58. package/ios/QueueSkipArithmetic.swift +8 -12
  59. package/ios/Siri/PlayMediaIntentHandler.swift +1 -5
  60. package/ios/SleepTimerCore.swift +26 -6
  61. package/ios/Tests/AudioTapProviderReplayGainTests.swift +5 -9
  62. package/ios/Tests/CarPlayBridgeTests.swift +2 -6
  63. package/ios/Tests/CarPlayBrowseBuilderTests.swift +1 -2
  64. package/ios/Tests/CarPlayCoordinatorTests.swift +35 -0
  65. package/ios/Tests/EQProcessorTests.swift +1 -4
  66. package/ios/Tests/EQTapTests.swift +1 -2
  67. package/ios/Tests/EqualizerAudioMixProviderTests.swift +3 -4
  68. package/ios/Tests/EqualizerHybridTests.swift +1 -3
  69. package/ios/Tests/FFTProcessorTests.swift +9 -8
  70. package/ios/Tests/GaplessEngineLifecycleTests.swift +0 -2
  71. package/ios/Tests/LookaheadCacheEvictionTests.swift +1 -4
  72. package/ios/Tests/MetadataReaderTests.swift +0 -2
  73. package/ios/Tests/MilestoneTrackerTests.swift +1 -3
  74. package/ios/Tests/NowPlayingFormatExtractorTests.swift +3 -4
  75. package/ios/Tests/PlaybackErrorMappingTests.swift +0 -3
  76. package/ios/Tests/PlaybackModeStateMachineTests.swift +5 -9
  77. package/ios/Tests/PlayerStateDerivationTests.swift +1 -2
  78. package/ios/Tests/ProgressEmissionGateTests.swift +1 -3
  79. package/ios/Tests/QueueMutationArithmeticTests.swift +0 -3
  80. package/ios/Tests/RemoteCommandsTests.swift +2 -5
  81. package/ios/Tests/ReplayGainExtractorTests.swift +0 -5
  82. package/ios/Tests/SkipCapabilityTests.swift +4 -7
  83. package/ios/Tests/SleepTimerCoreTests.swift +39 -0
  84. package/ios/Tests/VoiceDonationTests.swift +4 -4
  85. package/ios/TrackPlayer.swift +47 -22
  86. package/lib/typescript/TrackPlayer.nitro.d.ts +17 -0
  87. package/lib/typescript/TrackPlayer.nitro.d.ts.map +1 -1
  88. package/nitrogen/generated/android/c++/JHybridTrackPlayerSpec.cpp +5 -0
  89. package/nitrogen/generated/android/c++/JHybridTrackPlayerSpec.hpp +1 -0
  90. package/nitrogen/generated/android/kotlin/com/margelo/nitro/queueplayer/HybridTrackPlayerSpec.kt +4 -0
  91. package/nitrogen/generated/ios/c++/HybridTrackPlayerSpecSwift.hpp +8 -0
  92. package/nitrogen/generated/ios/swift/HybridTrackPlayerSpec.swift +1 -0
  93. package/nitrogen/generated/ios/swift/HybridTrackPlayerSpec_cxx.swift +12 -0
  94. package/nitrogen/generated/shared/c++/HybridTrackPlayerSpec.cpp +1 -0
  95. package/nitrogen/generated/shared/c++/HybridTrackPlayerSpec.hpp +1 -0
  96. package/package.json +1 -1
  97. package/src/TrackPlayer.nitro.ts +18 -0
  98. package/ios/InterruptionEventMapping.swift +0 -51
  99. package/ios/Tests/InterruptionEventMappingTests.swift +0 -91
@@ -424,6 +424,9 @@ class TrackPlayer: HybridTrackPlayerSpec {
424
424
  // first track needs the same initial-buffer leniency.
425
425
  private var currentItemObserver: NSKeyValueObservation?
426
426
  private var currentItemStatusObserver: NSKeyValueObservation?
427
+ // Duration can resolve a beat AFTER `.status` reaches `.readyToPlay`; observe
428
+ // it so the lock-screen duration lands even in that race.
429
+ private var currentItemDurationObserver: NSKeyValueObservation?
427
430
  private var gaplessFlipArmed: Bool = true
428
431
 
429
432
  /// Set to true by the `AVPlayerItemDidPlayToEndTime` notification
@@ -666,24 +669,11 @@ class TrackPlayer: HybridTrackPlayerSpec {
666
669
  break
667
670
  }
668
671
 
669
- // Surface the interruption kind as a typed non-fatal
670
- // `PlaybackError` so JS consumers can branch on the resume
671
- // hint without inspecting a boolean. Wire literals + messages
672
- // come from `InterruptionEventMapping` (single source of
673
- // truth for the three nativeDomain strings).
674
- let domain = InterruptionEventMapping.nativeDomain(for: kind)
675
- let message = InterruptionEventMapping.message(for: kind)
676
- let err = PlaybackError(
677
- code: .unknown,
678
- message: message,
679
- fatal: false,
680
- nativeCode: 0,
681
- nativeDomain: domain,
682
- nativeMessage: message,
683
- queueItemId: "",
684
- url: ""
685
- )
686
- self.errorListeners.forEach { $0(err) }
672
+ // An interruption is a normal lifecycle signal (call / Siri / a route
673
+ // handoff), NOT a playback error surfacing it on the `onError` stream
674
+ // makes consumers render an error banner for a routine pause. The pause
675
+ // is already reported via the `.paused` state stamped with
676
+ // `reason = .interruption`, which is the correct, non-error signal.
687
677
  }
688
678
 
689
679
  self.audioSession.onRouteChange = { [weak self] kind in
@@ -992,6 +982,8 @@ class TrackPlayer: HybridTrackPlayerSpec {
992
982
  private func attachStatusObserverIfArmed() {
993
983
  currentItemStatusObserver?.invalidate()
994
984
  currentItemStatusObserver = nil
985
+ currentItemDurationObserver?.invalidate()
986
+ currentItemDurationObserver = nil
995
987
  tearDownBufferObservers()
996
988
  guard let item = self.player?.currentItem else {
997
989
  // No current item (empty queue / torn down) — settle to empty.
@@ -1034,6 +1026,14 @@ class TrackPlayer: HybridTrackPlayerSpec {
1034
1026
  }
1035
1027
  }
1036
1028
  self.dispatchItemStatus(item)
1029
+ currentItemDurationObserver = item.observe(
1030
+ \.duration, options: [.new]
1031
+ ) { [weak self] _, _ in
1032
+ guard let self else { return }
1033
+ DispatchQueue.main.async {
1034
+ self.nowPlayingInfo.refreshPositionAndRate()
1035
+ }
1036
+ }
1037
1037
  installBufferObservers(on: item)
1038
1038
  }
1039
1039
 
@@ -1086,6 +1086,11 @@ class TrackPlayer: HybridTrackPlayerSpec {
1086
1086
  // idempotent on items that already carry a tap, so a double-
1087
1087
  // fire is harmless.
1088
1088
  AudioTapProvider.shared.refreshActiveItemMixes()
1089
+ // Duration is only reliably readable once the item is `.readyToPlay`.
1090
+ // Re-publish now-playing so the lock-screen scrubber gets a duration on
1091
+ // first load + auto-advance (not just after a manual skip, which is the
1092
+ // only path that otherwise forces a state change that re-publishes it).
1093
+ self.nowPlayingInfo.refreshPositionAndRate()
1089
1094
  case .failed:
1090
1095
  // Pause synchronously BEFORE surfacing the typed error. Without
1091
1096
  // this, AVQueuePlayer treats `.failed` as end-of-item and chain-
@@ -1191,6 +1196,8 @@ class TrackPlayer: HybridTrackPlayerSpec {
1191
1196
  currentItemObserver = nil
1192
1197
  currentItemStatusObserver?.invalidate()
1193
1198
  currentItemStatusObserver = nil
1199
+ currentItemDurationObserver?.invalidate()
1200
+ currentItemDurationObserver = nil
1194
1201
  tearDownBufferObservers()
1195
1202
  }
1196
1203
 
@@ -2043,8 +2050,7 @@ class TrackPlayer: HybridTrackPlayerSpec {
2043
2050
 
2044
2051
  /// Map the Nitrogen-generated `RepeatMode` enum onto the pure-Swift
2045
2052
  /// `QueueSkipRepeatMode` so `QueueSkipArithmetic` can stay off the
2046
- /// Swift ↔ C++ interop path (needed so XCTest targets reach the
2047
- /// arithmetic without C++-interop friction).
2053
+ /// Swift ↔ C++ interop path.
2048
2054
  private func repeatModeAsSkipMode() -> QueueSkipRepeatMode {
2049
2055
  switch self.repeatModeState {
2050
2056
  case .off: return .off
@@ -2591,6 +2597,13 @@ class TrackPlayer: HybridTrackPlayerSpec {
2591
2597
  nowMs: Self.nowEpochMs(),
2592
2598
  trackDurationSec: durationSec,
2593
2599
  trackPositionSec: positionSec)
2600
+ applySleepTimerResult(result)
2601
+ }
2602
+
2603
+ /// Apply a `SleepTimerCore.Tick` decision to the engine — fade, state emit,
2604
+ /// and the boundary pause. Shared by the polling tick and the real track-end
2605
+ /// signal (`handlePlayerItemDidPlayToEndTime`).
2606
+ private func applySleepTimerResult(_ result: SleepTimerCore.Tick) {
2594
2607
  applySleepTimerFade(result.fadeFraction)
2595
2608
  if result.stateChanged { emitSleepTimerChanged() }
2596
2609
  if result.pauseNow {
@@ -3766,6 +3779,12 @@ class TrackPlayer: HybridTrackPlayerSpec {
3766
3779
  @objc private func handlePlayerItemDidPlayToEndTime(_ notification: Notification) {
3767
3780
  DispatchQueue.main.async { [weak self] in
3768
3781
  guard let self else { return }
3782
+ // End-of-track sleep timer: pause at the current track's real end —
3783
+ // before the repeat-track rewind or the auto-advance — so the pause
3784
+ // lands exactly at the boundary and fires even when the track duration
3785
+ // was never known. Under repeat-one this pauses at the first natural end.
3786
+ let sleepFired = self.sleepTimerCore.fireAtTrackEnd()
3787
+ if sleepFired.pauseNow { self.applySleepTimerResult(sleepFired) }
3769
3788
  // Branch on repeat-track FIRST, separately from the
3770
3789
  // currentItem === item check. The notification dispatches
3771
3790
  // async to main but AVQueuePlayer
@@ -3796,8 +3815,10 @@ class TrackPlayer: HybridTrackPlayerSpec {
3796
3815
  player.currentItem === item {
3797
3816
  item.seek(to: .zero, completionHandler: nil)
3798
3817
  // Replay through the engine so the user's playback speed is
3799
- // restored (a raw AVPlayer.play() resets rate to 1.0).
3800
- self.engine?.play()
3818
+ // restored (a raw AVPlayer.play() resets rate to 1.0) — unless the
3819
+ // end-of-track sleep timer just fired, in which case we pause at
3820
+ // this natural end instead of looping.
3821
+ if !sleepFired.pauseNow { self.engine?.play() }
3801
3822
  }
3802
3823
  }
3803
3824
  // If the rewind window was lost (player chain-advanced
@@ -4162,6 +4183,10 @@ class TrackPlayer: HybridTrackPlayerSpec {
4162
4183
  return CarPlayCoordinator.shared.bridge.registerOnCarDisconnect(callback)
4163
4184
  }
4164
4185
 
4186
+ func isCarConnected() throws -> Bool {
4187
+ return CarPlayCoordinator.shared.isCarConnected
4188
+ }
4189
+
4165
4190
  // MARK: - Lookahead cache — runtime config + status surface
4166
4191
  func setLookaheadCache(config: LookaheadCacheConfig) throws -> Promise<Void> {
4167
4192
  return Promise<Void>.async {
@@ -473,6 +473,23 @@ export interface TrackPlayer extends HybridObject<{
473
473
  * automotive-specific subscriptions the consumer set up on connect.
474
474
  */
475
475
  onCarDisconnect(callback: () => void): () => void;
476
+ /**
477
+ * Whether an automotive controller is connected right now. The
478
+ * pull-based counterpart to `onCarConnect` / `onCarDisconnect`: it holds
479
+ * the same state those events transition between, so a consumer that
480
+ * missed the connect event — e.g. it fired before the consumer registered
481
+ * its handler in this app process — can still gate car-only work, like
482
+ * pushing browse snapshots, on the current connection.
483
+ *
484
+ * `true` between the first automotive controller connecting and the last
485
+ * one dropping. "Automotive controller" is the same classification the
486
+ * connect/disconnect events use: the CarPlay scene on iOS; the headless
487
+ * Android Auto / Wear / Assistant controllers on Android. Returns `false`
488
+ * before the first connection and after a full disconnect. The state is
489
+ * process-scoped: a fresh app process starts disconnected until a
490
+ * controller connects within it.
491
+ */
492
+ isCarConnected(): boolean;
476
493
  /**
477
494
  * Fires when the platform's media service is freshly bound to the JS
478
495
  * side. `reason = 'first-bind'` for the initial bind during a JS-
@@ -1 +1 @@
1
- {"version":3,"file":"TrackPlayer.nitro.d.ts","sourceRoot":"","sources":["../../src/TrackPlayer.nitro.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TrackPlayer.nitro.d.ts","sourceRoot":"","sources":["../../src/TrackPlayer.nitro.ts"],"names":[],"mappings":"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"}
@@ -949,6 +949,11 @@ namespace margelo::nitro::queueplayer {
949
949
  }
950
950
  }();
951
951
  }
952
+ bool JHybridTrackPlayerSpec::isCarConnected() {
953
+ static const auto method = _javaPart->javaClassStatic()->getMethod<jboolean()>("isCarConnected");
954
+ auto __result = method(_javaPart);
955
+ return static_cast<bool>(__result);
956
+ }
952
957
  std::function<void()> JHybridTrackPlayerSpec::onServiceReady(const std::function<void(ServiceReadyReason /* reason */)>& callback) {
953
958
  static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JFunc_void::javaobject>(jni::alias_ref<JFunc_void_ServiceReadyReason::javaobject> /* callback */)>("onServiceReady_cxx");
954
959
  auto __result = method(_javaPart, JFunc_void_ServiceReadyReason_cxx::fromCpp(callback));
@@ -113,6 +113,7 @@ namespace margelo::nitro::queueplayer {
113
113
  void donateVoiceVocabulary(const VoiceVocabulary& vocabulary) override;
114
114
  std::function<void()> onCarConnect(const std::function<void()>& callback) override;
115
115
  std::function<void()> onCarDisconnect(const std::function<void()>& callback) override;
116
+ bool isCarConnected() override;
116
117
  std::function<void()> onServiceReady(const std::function<void(ServiceReadyReason /* reason */)>& callback) override;
117
118
  std::shared_ptr<Promise<void>> setLookaheadCache(const LookaheadCacheConfig& config) override;
118
119
  CacheStatus getLookaheadCacheStatus() override;
@@ -346,6 +346,10 @@ abstract class HybridTrackPlayerSpec: HybridObject() {
346
346
  return Func_void_java(__result)
347
347
  }
348
348
 
349
+ @DoNotStrip
350
+ @Keep
351
+ abstract fun isCarConnected(): Boolean
352
+
349
353
  abstract fun onServiceReady(callback: (reason: ServiceReadyReason) -> Unit): () -> Unit
350
354
 
351
355
  @DoNotStrip
@@ -669,6 +669,14 @@ namespace margelo::nitro::queueplayer {
669
669
  auto __value = std::move(__result.value());
670
670
  return __value;
671
671
  }
672
+ inline bool isCarConnected() override {
673
+ auto __result = _swiftPart.isCarConnected();
674
+ if (__result.hasError()) [[unlikely]] {
675
+ std::rethrow_exception(__result.error());
676
+ }
677
+ auto __value = std::move(__result.value());
678
+ return __value;
679
+ }
672
680
  inline std::function<void()> onServiceReady(const std::function<void(ServiceReadyReason /* reason */)>& callback) override {
673
681
  auto __result = _swiftPart.onServiceReady(callback);
674
682
  if (__result.hasError()) [[unlikely]] {
@@ -72,6 +72,7 @@ public protocol HybridTrackPlayerSpec_protocol: HybridObject {
72
72
  func donateVoiceVocabulary(vocabulary: VoiceVocabulary) throws -> Void
73
73
  func onCarConnect(callback: @escaping () -> Void) throws -> () -> Void
74
74
  func onCarDisconnect(callback: @escaping () -> Void) throws -> () -> Void
75
+ func isCarConnected() throws -> Bool
75
76
  func onServiceReady(callback: @escaping (_ reason: ServiceReadyReason) -> Void) throws -> () -> Void
76
77
  func setLookaheadCache(config: LookaheadCacheConfig) throws -> Promise<Void>
77
78
  func getLookaheadCacheStatus() throws -> CacheStatus
@@ -1255,6 +1255,18 @@ open class HybridTrackPlayerSpec_cxx {
1255
1255
  }
1256
1256
  }
1257
1257
 
1258
+ @inline(__always)
1259
+ public final func isCarConnected() -> bridge.Result_bool_ {
1260
+ do {
1261
+ let __result = try self.__implementation.isCarConnected()
1262
+ let __resultCpp = __result
1263
+ return bridge.create_Result_bool_(__resultCpp)
1264
+ } catch (let __error) {
1265
+ let __exceptionPtr = __error.toCpp()
1266
+ return bridge.create_Result_bool_(__exceptionPtr)
1267
+ }
1268
+ }
1269
+
1258
1270
  @inline(__always)
1259
1271
  public final func onServiceReady(callback: bridge.Func_void_ServiceReadyReason) -> bridge.Result_std__function_void____ {
1260
1272
  do {
@@ -73,6 +73,7 @@ namespace margelo::nitro::queueplayer {
73
73
  prototype.registerHybridMethod("donateVoiceVocabulary", &HybridTrackPlayerSpec::donateVoiceVocabulary);
74
74
  prototype.registerHybridMethod("onCarConnect", &HybridTrackPlayerSpec::onCarConnect);
75
75
  prototype.registerHybridMethod("onCarDisconnect", &HybridTrackPlayerSpec::onCarDisconnect);
76
+ prototype.registerHybridMethod("isCarConnected", &HybridTrackPlayerSpec::isCarConnected);
76
77
  prototype.registerHybridMethod("onServiceReady", &HybridTrackPlayerSpec::onServiceReady);
77
78
  prototype.registerHybridMethod("setLookaheadCache", &HybridTrackPlayerSpec::setLookaheadCache);
78
79
  prototype.registerHybridMethod("getLookaheadCacheStatus", &HybridTrackPlayerSpec::getLookaheadCacheStatus);
@@ -187,6 +187,7 @@ namespace margelo::nitro::queueplayer {
187
187
  virtual void donateVoiceVocabulary(const VoiceVocabulary& vocabulary) = 0;
188
188
  virtual std::function<void()> onCarConnect(const std::function<void()>& callback) = 0;
189
189
  virtual std::function<void()> onCarDisconnect(const std::function<void()>& callback) = 0;
190
+ virtual bool isCarConnected() = 0;
190
191
  virtual std::function<void()> onServiceReady(const std::function<void(ServiceReadyReason /* reason */)>& callback) = 0;
191
192
  virtual std::shared_ptr<Promise<void>> setLookaheadCache(const LookaheadCacheConfig& config) = 0;
192
193
  virtual CacheStatus getLookaheadCacheStatus() = 0;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-queue-player",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "Nitro Modules audio playback library for React Native — gapless, EQ, crossfade, automotive, voice, casting",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/index.d.ts",
@@ -549,6 +549,24 @@ export interface TrackPlayer
549
549
  */
550
550
  onCarDisconnect(callback: () => void): () => void;
551
551
 
552
+ /**
553
+ * Whether an automotive controller is connected right now. The
554
+ * pull-based counterpart to `onCarConnect` / `onCarDisconnect`: it holds
555
+ * the same state those events transition between, so a consumer that
556
+ * missed the connect event — e.g. it fired before the consumer registered
557
+ * its handler in this app process — can still gate car-only work, like
558
+ * pushing browse snapshots, on the current connection.
559
+ *
560
+ * `true` between the first automotive controller connecting and the last
561
+ * one dropping. "Automotive controller" is the same classification the
562
+ * connect/disconnect events use: the CarPlay scene on iOS; the headless
563
+ * Android Auto / Wear / Assistant controllers on Android. Returns `false`
564
+ * before the first connection and after a full disconnect. The state is
565
+ * process-scoped: a fresh app process starts disconnected until a
566
+ * controller connects within it.
567
+ */
568
+ isCarConnected(): boolean;
569
+
552
570
  /**
553
571
  * Fires when the platform's media service is freshly bound to the JS
554
572
  * side. `reason = 'first-bind'` for the initial bind during a JS-
@@ -1,51 +0,0 @@
1
- import Foundation
2
-
3
- /// Maps `AudioSession.InterruptionKind` to the lib-standardized
4
- /// `nativeDomain` string + a stable human-readable message used by
5
- /// `TrackPlayer.wireAudioSession()` when firing the corresponding
6
- /// non-fatal `PlaybackError` through `errorListeners`.
7
- ///
8
- /// Pure function; no instance state. Mirrors `PlaybackErrorMapping`.
9
- ///
10
- /// Three `nativeDomain` strings — all share the
11
- /// `AUDIO_SESSION_INTERRUPTION_` prefix so JS consumers can branch
12
- /// on `nativeDomain.startsWith(...)` and treat any
13
- /// audio-session-interruption variant as a single category when they
14
- /// don't care about the resume-hint sub-state. `.endedShouldNotResume`
15
- /// maps to the bare `..._ENDED` (no `_SHOULD_NOT_RESUME` suffix) so
16
- /// consumers that ignore the resume-hint variant default to the
17
- /// "stop" semantics.
18
- enum InterruptionEventMapping {
19
-
20
- /// Shared prefix for the three interruption `nativeDomain` strings.
21
- static let nativeDomainPrefix = "AUDIO_SESSION_INTERRUPTION_"
22
-
23
- /// `nativeDomain` for the supplied interruption kind.
24
- static func nativeDomain(for kind: AudioSession.InterruptionKind) -> String {
25
- switch kind {
26
- case .began:
27
- return nativeDomainPrefix + "BEGAN"
28
- case .endedShouldResume:
29
- return nativeDomainPrefix + "ENDED_SHOULD_RESUME"
30
- case .endedShouldNotResume:
31
- return nativeDomainPrefix + "ENDED"
32
- }
33
- }
34
-
35
- /// Human-readable message for the supplied interruption kind.
36
- /// Same string is fired as both `message` and `nativeMessage` on
37
- /// the resulting `PlaybackError` — there's no lib-mapped vs native
38
- /// distinction at this layer (session-scope event, not track-
39
- /// scope error).
40
- static func message(for kind: AudioSession.InterruptionKind) -> String {
41
- switch kind {
42
- case .began:
43
- return "Audio session interruption began"
44
- case .endedShouldResume:
45
- return "Audio session interruption ended; system suggests resume"
46
- case .endedShouldNotResume:
47
- return "Audio session interruption ended"
48
- }
49
- }
50
-
51
- }
@@ -1,91 +0,0 @@
1
- import XCTest
2
- @testable import QueuePlayer
3
-
4
- /// `InterruptionEventMapping` is a pure-function namespace mapping
5
- /// `AudioSession.InterruptionKind` to the lib-standardized
6
- /// `nativeDomain` string + a stable human-readable message + the
7
- /// non-fatal `PlaybackError` that `TrackPlayer.wireAudioSession()`
8
- /// fires through `errorListeners`.
9
- final class InterruptionEventMappingTests: XCTestCase {
10
-
11
- // MARK: - nativeDomain
12
-
13
- func testNativeDomainBeganIsBeganLiteral() {
14
- XCTAssertEqual(
15
- InterruptionEventMapping.nativeDomain(for: .began),
16
- "AUDIO_SESSION_INTERRUPTION_BEGAN"
17
- )
18
- }
19
-
20
- func testNativeDomainEndedShouldResumeIsResumeHintLiteral() {
21
- XCTAssertEqual(
22
- InterruptionEventMapping.nativeDomain(for: .endedShouldResume),
23
- "AUDIO_SESSION_INTERRUPTION_ENDED_SHOULD_RESUME"
24
- )
25
- }
26
-
27
- func testNativeDomainEndedShouldNotResumeIsBareEndedLiteral() {
28
- XCTAssertEqual(
29
- InterruptionEventMapping.nativeDomain(for: .endedShouldNotResume),
30
- "AUDIO_SESSION_INTERRUPTION_ENDED"
31
- )
32
- }
33
-
34
- func testAllInterruptionDomainsShareTheBranchablePrefix() {
35
- let kinds: [AudioSession.InterruptionKind] = [
36
- .began, .endedShouldResume, .endedShouldNotResume,
37
- ]
38
- for kind in kinds {
39
- let domain = InterruptionEventMapping.nativeDomain(for: kind)
40
- XCTAssertTrue(
41
- domain.hasPrefix(InterruptionEventMapping.nativeDomainPrefix),
42
- "domain for \(kind) must use the consumer-branchable prefix; got \(domain)"
43
- )
44
- }
45
- }
46
-
47
- func testTheThreeDomainsAreExactlyTheSetOfWireLiterals() {
48
- let domains: Set<String> = [
49
- InterruptionEventMapping.nativeDomain(for: .began),
50
- InterruptionEventMapping.nativeDomain(for: .endedShouldResume),
51
- InterruptionEventMapping.nativeDomain(for: .endedShouldNotResume),
52
- ]
53
- XCTAssertEqual(domains, [
54
- "AUDIO_SESSION_INTERRUPTION_BEGAN",
55
- "AUDIO_SESSION_INTERRUPTION_ENDED_SHOULD_RESUME",
56
- "AUDIO_SESSION_INTERRUPTION_ENDED",
57
- ], "wire-protocol literals must not drift; rename = breaking change for JS consumers")
58
- }
59
-
60
- // MARK: - message
61
-
62
- func testMessagesAreNonEmpty() {
63
- let kinds: [AudioSession.InterruptionKind] = [
64
- .began, .endedShouldResume, .endedShouldNotResume,
65
- ]
66
- for kind in kinds {
67
- XCTAssertFalse(
68
- InterruptionEventMapping.message(for: kind).isEmpty,
69
- "message for \(kind) must be non-empty"
70
- )
71
- }
72
- }
73
-
74
- func testMessagesAreDistinctPerKind() {
75
- let began = InterruptionEventMapping.message(for: .began)
76
- let resume = InterruptionEventMapping.message(for: .endedShouldResume)
77
- let ended = InterruptionEventMapping.message(for: .endedShouldNotResume)
78
- XCTAssertNotEqual(began, resume)
79
- XCTAssertNotEqual(began, ended)
80
- XCTAssertNotEqual(resume, ended)
81
- }
82
-
83
- // PlaybackError construction lives inline at the call site in
84
- // `TrackPlayer.wireAudioSession()` — Swift cxx-interop excludes
85
- // internal helpers that return C++-bridged types like
86
- // `PlaybackError` from the `@testable import` swiftmodule export,
87
- // so the construction can't be invoked from an XCTest target. The
88
- // wire literals + messages are pinned by the tests above; full-
89
- // path coverage lives in the Maestro `interruption-handling`
90
- // suite.
91
- }