react-native-audio-browser 0.2.0-next.9 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AudioBrowser.podspec +1 -1
- package/README.md +2 -180
- package/android/build.gradle +1 -17
- package/android/gradle.properties +1 -1
- package/android/src/main/AndroidManifest.xml +0 -15
- package/android/src/main/java/com/audiobrowser/AudioBrowser.kt +148 -433
- package/android/src/main/java/com/audiobrowser/Callbacks.kt +6 -4
- package/android/src/main/java/com/audiobrowser/Service.kt +18 -67
- package/android/src/main/java/com/audiobrowser/browser/BrowserManager.kt +178 -442
- package/android/src/main/java/com/audiobrowser/browser/JsonModels.kt +4 -41
- package/android/src/main/java/com/audiobrowser/browser/TrackLoadHandler.kt +4 -4
- package/android/src/main/java/com/audiobrowser/http/RequestConfigBuilder.kt +97 -109
- package/android/src/main/java/com/audiobrowser/model/PlaybackMetadata.kt +10 -6
- package/android/src/main/java/com/audiobrowser/model/PlayerSetupOptions.kt +8 -40
- package/android/src/main/java/com/audiobrowser/model/PlayerUpdateOptions.kt +46 -40
- package/android/src/main/java/com/audiobrowser/player/AutomaticBufferManager.kt +1 -4
- package/android/src/main/java/com/audiobrowser/player/DynamicLoadControl.kt +1 -18
- package/android/src/main/java/com/audiobrowser/player/MediaFactory.kt +3 -15
- package/android/src/main/java/com/audiobrowser/player/MediaSessionCallback.kt +134 -422
- package/android/src/main/java/com/audiobrowser/player/MediaSessionCommandManager.kt +404 -248
- package/android/src/main/java/com/audiobrowser/player/PlaybackProgressUpdateManager.kt +59 -0
- package/android/src/main/java/com/audiobrowser/player/PlaybackStateStore.kt +5 -25
- package/android/src/main/java/com/audiobrowser/player/Player.kt +582 -469
- package/android/src/main/java/com/audiobrowser/player/PlayerListener.kt +67 -190
- package/android/src/main/java/com/audiobrowser/player/RetryLoadErrorHandlingPolicy.kt +53 -118
- package/android/src/main/java/com/audiobrowser/player/SleepTimer.kt +3 -37
- package/android/src/main/java/com/audiobrowser/player/TransformingDataSource.kt +40 -85
- package/android/src/main/java/com/audiobrowser/util/BrowserPathHelper.kt +0 -24
- package/android/src/main/java/com/audiobrowser/util/CoilBitmapLoader.kt +300 -23
- package/android/src/main/java/com/audiobrowser/util/EqualizerManager.kt +23 -13
- package/android/src/main/java/com/audiobrowser/util/MediaExtrasBuilder.kt +2 -2
- package/android/src/main/java/com/audiobrowser/util/MetadataAdapter.kt +3 -4
- package/android/src/main/java/com/audiobrowser/util/PlayingStateFactory.kt +1 -2
- package/android/src/main/java/com/audiobrowser/util/RatingFactory.kt +72 -0
- package/android/src/main/java/com/audiobrowser/util/ResolvedTrackFactory.kt +36 -0
- package/android/src/main/java/com/audiobrowser/util/SvgArtworkRenderer.kt +111 -6
- package/android/src/main/java/com/audiobrowser/util/SystemVolumeMonitor.kt +8 -22
- package/android/src/main/java/com/audiobrowser/util/TrackFactory.kt +80 -112
- package/android/src/main/res/values/strings.xml +0 -4
- package/android/src/test/java/com/audiobrowser/browser/BrowserManagerTest.kt +0 -4
- package/android/src/test/java/com/audiobrowser/browser/SimpleRouterTest.kt +2 -1
- package/android/src/test/java/com/audiobrowser/http/RequestConfigBuilderTest.kt +0 -72
- package/android/src/test/java/com/audiobrowser/player/PlaybackProgressUpdateManagerTest.kt +146 -0
- package/ios/Browser/BrowserConfig.swift +11 -41
- package/ios/Browser/BrowserManager+URLResolution.swift +93 -213
- package/ios/Browser/BrowserManager.swift +110 -303
- package/ios/Browser/BrowserPathHelper.swift +3 -32
- package/ios/Browser/JsonModels.swift +66 -287
- package/ios/CarPlay/CarPlayArtworkResolver.swift +6 -6
- package/ios/CarPlay/CarPlayController.swift +149 -739
- package/ios/CarPlay/CarPlayImageLoader.swift +8 -57
- package/ios/CarPlay/CarPlayListItemFactory.swift +35 -44
- package/ios/CarPlay/CarPlayNowPlayingManager.swift +36 -180
- package/ios/CarPlay/RNABAudioBrowser.h +10 -15
- package/ios/CarPlay/RNABAudioBrowser.m +14 -15
- package/ios/CarPlay/RNABCarPlaySceneDelegate.m +0 -2
- package/ios/CarPlay/RNABMediaIntentHandler.swift +43 -53
- package/ios/CarPlay/Track+CarPlay.swift +63 -0
- package/ios/Extension/Capability+RemoteCommand.swift +9 -7
- package/ios/Extension/ChapterMetadata+AVFoundation.swift +1 -1
- package/ios/Extension/NavigationError+Conversion.swift +1 -8
- package/ios/Extension/ResolvedTrack+Copying.swift +4 -10
- package/ios/Extension/TimedMetadata+AVFoundation.swift +1 -1
- package/ios/Extension/Track+AVPlayer.swift +4 -4
- package/ios/Extension/Track+Copying.swift +3 -9
- package/ios/Extension/TrackMetadata+AVFoundation.swift +1 -1
- package/ios/HybridAudioBrowser.swift +196 -804
- package/ios/Model/NitroTypeStubs.swift +224 -299
- package/ios/Model/PlayerUpdateOptions.swift +23 -23
- package/ios/Model/RemoteCommand.swift +6 -24
- package/ios/Model/TrackPlayerError.swift +18 -82
- package/ios/NowPlayingInfo/NowPlayingInfoCenter.swift +9 -0
- package/ios/NowPlayingInfo/NowPlayingInfoController.swift +121 -99
- package/ios/Observer/PlayerItemNotificationObserver.swift +5 -45
- package/ios/Observer/PlayerItemPropertyObserver.swift +4 -27
- package/ios/Observer/PlayerTimeObserver.swift +53 -3
- package/ios/Option/SessionCategories.swift +11 -34
- package/ios/Player/LoadSeekCoordinator.swift +1 -16
- package/ios/Player/MediaLoader.swift +11 -31
- package/ios/Player/NowPlayingUpdater.swift +26 -119
- package/ios/Player/PlaybackCoordinator.swift +51 -285
- package/ios/Player/PlaybackCoordinatorCallbacks.swift +1 -6
- package/ios/Player/PlaybackEffectHandler.swift +9 -19
- package/ios/Player/PlaybackErrorHandler.swift +13 -97
- package/ios/Player/PlaybackProgressUpdateManager.swift +68 -0
- package/ios/Player/PlaybackStateMachine.swift +13 -18
- package/ios/Player/PlayingStateManager.swift +2 -3
- package/ios/Player/QueueManager.swift +61 -67
- package/ios/Player/RetryManager.swift +21 -98
- package/ios/Player/SleepTimerHandling.swift +0 -8
- package/ios/Player/SleepTimerManager.swift +11 -72
- package/ios/RemoteCommand/RemoteCommandController.swift +21 -40
- package/ios/Tests/BrowserPathHelperTests.swift +0 -28
- package/ios/Tests/CarPlayArtworkResolverTests.swift +39 -39
- package/ios/Tests/ChapterMetadataAVFoundationTests.swift +2 -2
- package/ios/Tests/LoadSeekCoordinatorTests.swift +7 -40
- package/ios/Tests/MediaLoaderTests.swift +20 -32
- package/ios/Tests/PlaybackCoordinatorTests.swift +13 -787
- package/ios/Tests/PlaybackErrorHandlerTests.swift +46 -380
- package/ios/Tests/PlaybackProgressUpdateManagerTests.swift +166 -0
- package/ios/Tests/PlaybackStateMachineTests.swift +8 -33
- package/ios/Tests/QueueManagerTests.swift +18 -149
- package/ios/Tests/ResolvedTrackCopyingTests.swift +8 -15
- package/ios/Tests/Support/TestTypes.swift +20 -61
- package/ios/Tests/TrackSelectorTests.swift +15 -15
- package/ios/TrackPlayer.swift +58 -380
- package/ios/TrackPlayerCallbacks.swift +44 -5
- package/ios/TrackSelector.swift +5 -5
- package/ios/Util/ArtworkImageFetcher.swift +2 -4
- package/ios/Util/NetworkMonitor.swift +3 -7
- package/ios/Util/OnceValue.swift +0 -34
- package/lib/commonjs/AudioBrowser.js +11 -0
- package/lib/commonjs/AudioBrowser.js.map +1 -1
- package/lib/commonjs/features/browser.js +158 -59
- package/lib/commonjs/features/browser.js.map +1 -1
- package/lib/commonjs/features/equalizer.js +1 -1
- package/lib/commonjs/features/errors.js +5 -37
- package/lib/commonjs/features/errors.js.map +1 -1
- package/lib/commonjs/features/favorites.js +1 -1
- package/lib/commonjs/features/index.js +0 -22
- package/lib/commonjs/features/index.js.map +1 -1
- package/lib/commonjs/features/metadata.js +3 -3
- package/lib/commonjs/features/metadata.js.map +1 -1
- package/lib/commonjs/features/network.js +1 -1
- package/lib/commonjs/features/nowPlaying.js +1 -36
- package/lib/commonjs/features/nowPlaying.js.map +1 -1
- package/lib/commonjs/features/output.js +23 -37
- package/lib/commonjs/features/output.js.map +1 -1
- package/lib/commonjs/features/playback/controls.js +0 -9
- package/lib/commonjs/features/playback/controls.js.map +1 -1
- package/lib/commonjs/features/playback/index.js +0 -11
- package/lib/commonjs/features/playback/index.js.map +1 -1
- package/lib/commonjs/features/playback/playWhenReady.js +1 -1
- package/lib/commonjs/features/playback/playing.js +1 -1
- package/lib/commonjs/features/playback/progress.js +13 -29
- package/lib/commonjs/features/playback/progress.js.map +1 -1
- package/lib/commonjs/features/playback/state.js +1 -1
- package/lib/commonjs/features/playback/volume.js +2 -2
- package/lib/commonjs/features/player/options.js +29 -79
- package/lib/commonjs/features/player/options.js.map +1 -1
- package/lib/commonjs/features/player/setup.js +3 -256
- package/lib/commonjs/features/player/setup.js.map +1 -1
- package/lib/commonjs/features/queue/activeTrack.js +1 -1
- package/lib/commonjs/features/queue/queue.js +5 -12
- package/lib/commonjs/features/queue/queue.js.map +1 -1
- package/lib/commonjs/features/queue/repeatMode.js +1 -1
- package/lib/commonjs/features/queue/shuffle.js +1 -1
- package/lib/commonjs/features/rating.js +2 -0
- package/lib/commonjs/features/rating.js.map +1 -0
- package/lib/commonjs/features/remoteControls.js +104 -14
- package/lib/commonjs/features/remoteControls.js.map +1 -1
- package/lib/commonjs/features/sleepTimer.js +5 -10
- package/lib/commonjs/features/sleepTimer.js.map +1 -1
- package/lib/commonjs/native.js +0 -5
- package/lib/commonjs/native.js.map +1 -1
- package/lib/commonjs/native.web.js +1 -4
- package/lib/commonjs/native.web.js.map +1 -1
- package/lib/commonjs/types/player.js +2 -0
- package/lib/commonjs/types/player.js.map +1 -0
- package/lib/commonjs/utils/LazyNativeEmitter.js +8 -8
- package/lib/commonjs/utils/LazyNativeEmitter.js.map +1 -1
- package/lib/commonjs/utils/NativeUpdatedValue.js +3 -0
- package/lib/commonjs/utils/NativeUpdatedValue.js.map +1 -1
- package/lib/commonjs/web/NativeAudioBrowser.js +124 -301
- package/lib/commonjs/web/NativeAudioBrowser.js.map +1 -1
- package/lib/commonjs/web/SimpleRouter.test.js +174 -0
- package/lib/commonjs/web/SimpleRouter.test.js.map +1 -0
- package/lib/commonjs/web/TrackPlayer/Player.js +26 -90
- package/lib/commonjs/web/TrackPlayer/Player.js.map +1 -1
- package/lib/commonjs/web/TrackPlayer/PlaylistPlayer.js +293 -0
- package/lib/commonjs/web/TrackPlayer/PlaylistPlayer.js.map +1 -0
- package/lib/commonjs/web/TrackPlayer/RepeatMode.js +1 -1
- package/lib/commonjs/web/TrackPlayer/RepeatMode.js.map +1 -1
- package/lib/commonjs/web/TrackPlayer/SleepTimer.js +3 -34
- package/lib/commonjs/web/TrackPlayer/SleepTimer.js.map +1 -1
- package/lib/commonjs/web/TrackPlayer/index.js +5 -13
- package/lib/commonjs/web/TrackPlayer/index.js.map +1 -1
- package/lib/commonjs/web/browser/BrowserManager.js +50 -176
- package/lib/commonjs/web/browser/BrowserManager.js.map +1 -1
- package/lib/commonjs/web/browser/NavigationErrorManager.js +1 -3
- package/lib/commonjs/web/browser/NavigationErrorManager.js.map +1 -1
- package/lib/commonjs/web/browser/SearchManager.js +9 -11
- package/lib/commonjs/web/browser/SearchManager.js.map +1 -1
- package/lib/commonjs/web/http/HttpClient.js +23 -4
- package/lib/commonjs/web/http/HttpClient.js.map +1 -1
- package/lib/commonjs/web/http/RequestConfigBuilder.js +58 -107
- package/lib/commonjs/web/http/RequestConfigBuilder.js.map +1 -1
- package/lib/commonjs/web/player/NowPlayingManager.js +5 -6
- package/lib/commonjs/web/player/NowPlayingManager.js.map +1 -1
- package/lib/commonjs/web/player/OptionsManager.js +17 -9
- package/lib/commonjs/web/player/OptionsManager.js.map +1 -1
- package/lib/module/AudioBrowser.js +1 -4
- package/lib/module/AudioBrowser.js.map +1 -1
- package/lib/module/features/browser.js +156 -53
- package/lib/module/features/browser.js.map +1 -1
- package/lib/module/features/equalizer.js +1 -1
- package/lib/module/features/errors.js +5 -37
- package/lib/module/features/errors.js.map +1 -1
- package/lib/module/features/favorites.js +1 -1
- package/lib/module/features/index.js +0 -2
- package/lib/module/features/index.js.map +1 -1
- package/lib/module/features/metadata.js +3 -3
- package/lib/module/features/metadata.js.map +1 -1
- package/lib/module/features/network.js +1 -1
- package/lib/module/features/nowPlaying.js +1 -34
- package/lib/module/features/nowPlaying.js.map +1 -1
- package/lib/module/features/output.js +19 -32
- package/lib/module/features/output.js.map +1 -1
- package/lib/module/features/playback/controls.js +0 -8
- package/lib/module/features/playback/controls.js.map +1 -1
- package/lib/module/features/playback/index.js +0 -1
- package/lib/module/features/playback/index.js.map +1 -1
- package/lib/module/features/playback/playWhenReady.js +1 -1
- package/lib/module/features/playback/playing.js +1 -1
- package/lib/module/features/playback/progress.js +13 -29
- package/lib/module/features/playback/progress.js.map +1 -1
- package/lib/module/features/playback/state.js +1 -1
- package/lib/module/features/playback/volume.js +2 -2
- package/lib/module/features/player/options.js +29 -79
- package/lib/module/features/player/options.js.map +1 -1
- package/lib/module/features/player/setup.js +3 -256
- package/lib/module/features/player/setup.js.map +1 -1
- package/lib/module/features/queue/activeTrack.js +1 -1
- package/lib/module/features/queue/queue.js +5 -12
- package/lib/module/features/queue/queue.js.map +1 -1
- package/lib/module/features/queue/repeatMode.js +1 -1
- package/lib/module/features/queue/shuffle.js +1 -1
- package/lib/module/features/rating.js +2 -0
- package/lib/module/features/rating.js.map +1 -0
- package/lib/module/features/remoteControls.js +103 -13
- package/lib/module/features/remoteControls.js.map +1 -1
- package/lib/module/features/sleepTimer.js +5 -10
- package/lib/module/features/sleepTimer.js.map +1 -1
- package/lib/module/native.js +0 -5
- package/lib/module/native.js.map +1 -1
- package/lib/module/native.web.js +1 -4
- package/lib/module/native.web.js.map +1 -1
- package/lib/module/types/player.js +2 -0
- package/lib/module/types/player.js.map +1 -0
- package/lib/module/utils/LazyNativeEmitter.js +8 -8
- package/lib/module/utils/LazyNativeEmitter.js.map +1 -1
- package/lib/module/utils/NativeUpdatedValue.js +3 -0
- package/lib/module/utils/NativeUpdatedValue.js.map +1 -1
- package/lib/module/web/NativeAudioBrowser.js +125 -302
- package/lib/module/web/NativeAudioBrowser.js.map +1 -1
- package/lib/module/web/SimpleRouter.test.js +174 -0
- package/lib/module/web/SimpleRouter.test.js.map +1 -0
- package/lib/module/web/TrackPlayer/Player.js +26 -90
- package/lib/module/web/TrackPlayer/Player.js.map +1 -1
- package/lib/module/web/TrackPlayer/PlaylistPlayer.js +288 -0
- package/lib/module/web/TrackPlayer/PlaylistPlayer.js.map +1 -0
- package/lib/module/web/TrackPlayer/RepeatMode.js +1 -1
- package/lib/module/web/TrackPlayer/RepeatMode.js.map +1 -1
- package/lib/module/web/TrackPlayer/SleepTimer.js +3 -34
- package/lib/module/web/TrackPlayer/SleepTimer.js.map +1 -1
- package/lib/module/web/TrackPlayer/index.js +1 -2
- package/lib/module/web/TrackPlayer/index.js.map +1 -1
- package/lib/module/web/browser/BrowserManager.js +50 -176
- package/lib/module/web/browser/BrowserManager.js.map +1 -1
- package/lib/module/web/browser/NavigationErrorManager.js +1 -3
- package/lib/module/web/browser/NavigationErrorManager.js.map +1 -1
- package/lib/module/web/browser/SearchManager.js +9 -11
- package/lib/module/web/browser/SearchManager.js.map +1 -1
- package/lib/module/web/http/HttpClient.js +23 -4
- package/lib/module/web/http/HttpClient.js.map +1 -1
- package/lib/module/web/http/RequestConfigBuilder.js +58 -107
- package/lib/module/web/http/RequestConfigBuilder.js.map +1 -1
- package/lib/module/web/player/NowPlayingManager.js +5 -7
- package/lib/module/web/player/NowPlayingManager.js.map +1 -1
- package/lib/module/web/player/OptionsManager.js +17 -9
- package/lib/module/web/player/OptionsManager.js.map +1 -1
- package/lib/typescript/src/AudioBrowser.d.ts +1 -0
- package/lib/typescript/src/AudioBrowser.d.ts.map +1 -1
- package/lib/typescript/src/features/browser.d.ts +1 -40
- package/lib/typescript/src/features/browser.d.ts.map +1 -1
- package/lib/typescript/src/features/equalizer.d.ts +1 -1
- package/lib/typescript/src/features/errors.d.ts +6 -61
- package/lib/typescript/src/features/errors.d.ts.map +1 -1
- package/lib/typescript/src/features/favorites.d.ts +1 -1
- package/lib/typescript/src/features/index.d.ts +0 -2
- package/lib/typescript/src/features/index.d.ts.map +1 -1
- package/lib/typescript/src/features/metadata.d.ts +7 -9
- package/lib/typescript/src/features/metadata.d.ts.map +1 -1
- package/lib/typescript/src/features/network.d.ts +1 -1
- package/lib/typescript/src/features/nowPlaying.d.ts +1 -28
- package/lib/typescript/src/features/nowPlaying.d.ts.map +1 -1
- package/lib/typescript/src/features/output.d.ts +18 -28
- package/lib/typescript/src/features/output.d.ts.map +1 -1
- package/lib/typescript/src/features/playback/controls.d.ts +0 -5
- package/lib/typescript/src/features/playback/controls.d.ts.map +1 -1
- package/lib/typescript/src/features/playback/index.d.ts +0 -1
- package/lib/typescript/src/features/playback/index.d.ts.map +1 -1
- package/lib/typescript/src/features/playback/playWhenReady.d.ts +1 -1
- package/lib/typescript/src/features/playback/playing.d.ts +1 -1
- package/lib/typescript/src/features/playback/progress.d.ts +1 -4
- package/lib/typescript/src/features/playback/progress.d.ts.map +1 -1
- package/lib/typescript/src/features/playback/state.d.ts +1 -1
- package/lib/typescript/src/features/playback/volume.d.ts +2 -2
- package/lib/typescript/src/features/player/options.d.ts +127 -176
- package/lib/typescript/src/features/player/options.d.ts.map +1 -1
- package/lib/typescript/src/features/player/setup.d.ts +167 -213
- package/lib/typescript/src/features/player/setup.d.ts.map +1 -1
- package/lib/typescript/src/features/queue/activeTrack.d.ts +1 -1
- package/lib/typescript/src/features/queue/queue.d.ts +4 -11
- package/lib/typescript/src/features/queue/queue.d.ts.map +1 -1
- package/lib/typescript/src/features/queue/repeatMode.d.ts +1 -1
- package/lib/typescript/src/features/queue/shuffle.d.ts +1 -1
- package/lib/typescript/src/features/rating.d.ts +14 -0
- package/lib/typescript/src/features/rating.d.ts.map +1 -0
- package/lib/typescript/src/features/remoteControls.d.ts +35 -23
- package/lib/typescript/src/features/remoteControls.d.ts.map +1 -1
- package/lib/typescript/src/features/sleepTimer.d.ts +4 -19
- package/lib/typescript/src/features/sleepTimer.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/native.d.ts +2 -1
- package/lib/typescript/src/native.d.ts.map +1 -1
- package/lib/typescript/src/native.web.d.ts +3 -0
- package/lib/typescript/src/native.web.d.ts.map +1 -0
- package/lib/typescript/src/specs/audio-browser.nitro.d.ts +225 -17
- package/lib/typescript/src/specs/audio-browser.nitro.d.ts.map +1 -1
- package/lib/typescript/src/types/browser-native.d.ts +3 -9
- package/lib/typescript/src/types/browser-native.d.ts.map +1 -1
- package/lib/typescript/src/types/browser-nodes.d.ts +13 -145
- package/lib/typescript/src/types/browser-nodes.d.ts.map +1 -1
- package/lib/typescript/src/types/browser.d.ts +85 -349
- package/lib/typescript/src/types/browser.d.ts.map +1 -1
- package/lib/typescript/src/types/player.d.ts +64 -0
- package/lib/typescript/src/types/player.d.ts.map +1 -0
- package/lib/typescript/src/utils/LazyNativeEmitter.d.ts +6 -8
- package/lib/typescript/src/utils/LazyNativeEmitter.d.ts.map +1 -1
- package/lib/typescript/src/utils/NativeUpdatedValue.d.ts +2 -0
- package/lib/typescript/src/utils/NativeUpdatedValue.d.ts.map +1 -1
- package/lib/typescript/src/utils/resolveAssetSource.d.ts.map +1 -1
- package/lib/typescript/src/web/NativeAudioBrowser.d.ts +188 -0
- package/lib/typescript/src/web/NativeAudioBrowser.d.ts.map +1 -0
- package/lib/typescript/src/web/SimpleRouter.d.ts +40 -0
- package/lib/typescript/src/web/SimpleRouter.d.ts.map +1 -0
- package/lib/typescript/src/web/SimpleRouter.test.d.ts +2 -0
- package/lib/typescript/src/web/SimpleRouter.test.d.ts.map +1 -0
- package/lib/typescript/src/web/TrackPlayer/Event.d.ts +11 -0
- package/lib/typescript/src/web/TrackPlayer/Event.d.ts.map +1 -0
- package/lib/typescript/src/web/TrackPlayer/Player.d.ts +59 -0
- package/lib/typescript/src/web/TrackPlayer/Player.d.ts.map +1 -0
- package/lib/typescript/src/web/TrackPlayer/PlaylistPlayer.d.ts +39 -0
- package/lib/typescript/src/web/TrackPlayer/PlaylistPlayer.d.ts.map +1 -0
- package/lib/typescript/src/web/TrackPlayer/RepeatMode.d.ts +6 -0
- package/lib/typescript/src/web/TrackPlayer/RepeatMode.d.ts.map +1 -0
- package/lib/typescript/src/web/TrackPlayer/SetupNotCalledError.d.ts +4 -0
- package/lib/typescript/src/web/TrackPlayer/SetupNotCalledError.d.ts.map +1 -0
- package/lib/typescript/src/web/TrackPlayer/SleepTimer.d.ts +34 -0
- package/lib/typescript/src/web/TrackPlayer/SleepTimer.d.ts.map +1 -0
- package/lib/typescript/src/web/TrackPlayer/State.d.ts +13 -0
- package/lib/typescript/src/web/TrackPlayer/State.d.ts.map +1 -0
- package/lib/typescript/src/web/TrackPlayer/index.d.ts +5 -0
- package/lib/typescript/src/web/TrackPlayer/index.d.ts.map +1 -0
- package/lib/typescript/src/web/browser/BrowserManager.d.ts +154 -0
- package/lib/typescript/src/web/browser/BrowserManager.d.ts.map +1 -0
- package/lib/typescript/src/web/browser/FavoriteManager.d.ts +42 -0
- package/lib/typescript/src/web/browser/FavoriteManager.d.ts.map +1 -0
- package/lib/typescript/src/web/browser/NavigationErrorManager.d.ts +40 -0
- package/lib/typescript/src/web/browser/NavigationErrorManager.d.ts.map +1 -0
- package/lib/typescript/src/web/browser/SearchManager.d.ts +22 -0
- package/lib/typescript/src/web/browser/SearchManager.d.ts.map +1 -0
- package/lib/typescript/src/web/http/HttpClient.d.ts +25 -0
- package/lib/typescript/src/web/http/HttpClient.d.ts.map +1 -0
- package/lib/typescript/src/web/http/RequestConfigBuilder.d.ts +98 -0
- package/lib/typescript/src/web/http/RequestConfigBuilder.d.ts.map +1 -0
- package/lib/typescript/src/web/player/NowPlayingManager.d.ts +34 -0
- package/lib/typescript/src/web/player/NowPlayingManager.d.ts.map +1 -0
- package/lib/typescript/src/web/player/OptionsManager.d.ts +32 -0
- package/lib/typescript/src/web/player/OptionsManager.d.ts.map +1 -0
- package/lib/typescript/src/web/util/BrowserPathHelper.d.ts +69 -0
- package/lib/typescript/src/web/util/BrowserPathHelper.d.ts.map +1 -0
- package/lib/typescript/src/web/util/shuffle.d.ts +8 -0
- package/lib/typescript/src/web/util/shuffle.d.ts.map +1 -0
- package/nitrogen/generated/android/AudioBrowser+autolinking.cmake +2 -4
- package/nitrogen/generated/android/AudioBrowserOnLoad.cpp +10 -24
- package/nitrogen/generated/android/c++/JAndroidAudioContentType.hpp +6 -6
- package/nitrogen/generated/android/c++/JAndroidOptions.hpp +20 -10
- package/nitrogen/generated/android/c++/JAndroidUpdateOptions.hpp +86 -0
- package/nitrogen/generated/android/c++/JArtworkRequestConfig.hpp +1 -33
- package/nitrogen/generated/android/c++/JBrowseResult.hpp +0 -5
- package/nitrogen/generated/android/c++/JCarPlayNowPlayingButton.hpp +3 -3
- package/nitrogen/generated/android/c++/JFavoriteChangedEvent.hpp +0 -6
- package/nitrogen/generated/android/c++/JFormattedNavigationError.hpp +2 -3
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_RequestConfig_____Track.hpp +0 -6
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError______BrowserSourceCallbackParam.hpp +147 -0
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_std__vector_Track______SearchParams.hpp +0 -8
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_void_____TrackLoadEvent.hpp +0 -6
- package/nitrogen/generated/android/c++/JFunc_void_FavoriteChangedEvent.hpp +0 -6
- package/nitrogen/generated/android/c++/JFunc_void_IosOutput.hpp +80 -0
- package/nitrogen/generated/android/c++/JFunc_void_NowPlayingMetadata.hpp +10 -0
- package/nitrogen/generated/android/c++/JFunc_void_Options.hpp +9 -14
- package/nitrogen/generated/android/c++/JFunc_void_Playback.hpp +0 -2
- package/nitrogen/generated/android/c++/JFunc_void_PlaybackActiveTrackChangedEvent.hpp +0 -6
- package/nitrogen/generated/android/c++/JFunc_void_PlaybackErrorEvent.hpp +0 -2
- package/nitrogen/generated/android/c++/JFunc_void_RemoteSetRatingEvent.hpp +87 -0
- package/nitrogen/generated/android/c++/JFunc_void_bool.hpp +10 -10
- package/nitrogen/generated/android/c++/JFunc_void_std__optional_ResolvedTrack_.hpp +0 -6
- package/nitrogen/generated/android/c++/JFunc_void_std__vector_Track_.hpp +0 -6
- package/nitrogen/generated/android/c++/JHeartRating.hpp +57 -0
- package/nitrogen/generated/android/c++/JHybridAudioBrowserSpec.cpp +221 -245
- package/nitrogen/generated/android/c++/JHybridAudioBrowserSpec.hpp +22 -25
- package/nitrogen/generated/android/c++/JImageRowItem.hpp +3 -33
- package/nitrogen/generated/android/c++/{JOutput.hpp → JIosOutput.hpp} +15 -15
- package/nitrogen/generated/android/c++/JIosOutputType.hpp +85 -0
- package/nitrogen/generated/android/c++/JMediaRequestConfig.hpp +1 -33
- package/nitrogen/generated/android/c++/JNativeBrowserConfiguration.hpp +28 -61
- package/nitrogen/generated/android/c++/JNativeRouteEntry.hpp +9 -20
- package/nitrogen/generated/android/c++/JNativeUpdateOptions.hpp +24 -21
- package/nitrogen/generated/android/c++/JNavigationErrorType.hpp +0 -6
- package/nitrogen/generated/android/c++/JNitroAndroidUpdateOptions.hpp +20 -10
- package/nitrogen/generated/android/c++/{JRemoteButton.hpp → JNotificationButton.hpp} +20 -20
- package/nitrogen/generated/android/c++/JNotificationButtonLayout.hpp +94 -0
- package/nitrogen/generated/android/c++/JNowPlayingMetadata.hpp +17 -3
- package/nitrogen/generated/android/c++/JNowPlayingUpdate.hpp +3 -7
- package/nitrogen/generated/android/c++/JOptions.hpp +14 -19
- package/nitrogen/generated/android/c++/{JNativeAndroidSetupOptions.hpp → JPartialAndroidSetupPlayerOptions.hpp} +10 -10
- package/nitrogen/generated/android/c++/{JNativeIOSSetupOptions.hpp → JPartialIOSSetupPlayerOptions.hpp} +10 -10
- package/nitrogen/generated/android/c++/JPartialSetupPlayerOptions.hpp +96 -0
- package/nitrogen/generated/android/c++/JPercentageRating.hpp +57 -0
- package/nitrogen/generated/android/c++/JPlayback.hpp +0 -2
- package/nitrogen/generated/android/c++/JPlaybackActiveTrackChangedEvent.hpp +0 -6
- package/nitrogen/generated/android/c++/JPlaybackError.hpp +3 -18
- package/nitrogen/generated/android/c++/JPlaybackErrorEvent.hpp +0 -2
- package/nitrogen/generated/android/c++/JPlaybackState.hpp +3 -3
- package/nitrogen/generated/android/c++/JPlayerCapabilities.hpp +5 -11
- package/nitrogen/generated/android/c++/JRatingType.hpp +73 -0
- package/nitrogen/generated/android/c++/JRemoteSetRatingEvent.hpp +66 -0
- package/nitrogen/generated/android/c++/JResolvedTrack.hpp +5 -23
- package/nitrogen/generated/android/c++/JRetryConfig.hpp +7 -11
- package/nitrogen/generated/android/c++/JSearchMode.hpp +9 -27
- package/nitrogen/generated/android/c++/JSearchParams.hpp +3 -9
- package/nitrogen/generated/android/c++/JStarRating.hpp +57 -0
- package/nitrogen/generated/android/c++/{JGateEvent.hpp → JThumbsRating.hpp} +15 -16
- package/nitrogen/generated/android/c++/JTrack.hpp +5 -23
- package/nitrogen/generated/android/c++/JTrackLoadEvent.hpp +0 -6
- package/nitrogen/generated/android/c++/JTransformableRequestConfig.hpp +1 -14
- package/nitrogen/generated/android/c++/JUpdateOptions.hpp +105 -0
- package/nitrogen/generated/android/c++/JVariant_HeartRating_ThumbsRating_StarRating_PercentageRating.cpp +34 -0
- package/nitrogen/generated/android/c++/JVariant_HeartRating_ThumbsRating_StarRating_PercentageRating.hpp +105 -0
- package/nitrogen/generated/android/c++/JVariant_NullType_NotificationButtonLayout.cpp +26 -0
- package/nitrogen/generated/android/c++/JVariant_NullType_NotificationButtonLayout.hpp +75 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/AndroidAudioContentType.kt +4 -4
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/AndroidOptions.kt +9 -3
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/AndroidUpdateOptions.kt +50 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/ArtworkRequestConfig.kt +4 -10
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/CarPlayNowPlayingButton.kt +3 -3
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/FormattedNavigationError.kt +2 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{Func_std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError__std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError_______BrowserSourceCallbackParam.kt → Func_std__shared_ptr_Promise_std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError______BrowserSourceCallbackParam.kt} +12 -12
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{Func_void_Output.kt → Func_void_IosOutput.kt} +9 -9
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{Func_void_GateEvent.kt → Func_void_RemoteSetRatingEvent.kt} +9 -9
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_void_bool.kt +9 -9
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{Gate.kt → HeartRating.kt} +6 -9
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/HybridAudioBrowserSpec.kt +109 -103
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/ImageRowItem.kt +3 -24
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{Output.kt → IosOutput.kt} +6 -6
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/IosOutputType.kt +32 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/MediaRequestConfig.kt +4 -10
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NativeBrowserConfiguration.kt +6 -18
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NativeRouteEntry.kt +4 -4
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NativeUpdateOptions.kt +6 -6
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NavigationErrorType.kt +1 -3
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NitroAndroidUpdateOptions.kt +9 -3
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{FavoritesMatchMode.kt → NotificationButton.kt} +8 -5
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NotificationButtonLayout.kt +50 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NowPlayingMetadata.kt +6 -3
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NowPlayingUpdate.kt +3 -6
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Options.kt +3 -3
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{NativeAndroidSetupOptions.kt → PartialAndroidSetupPlayerOptions.kt} +5 -5
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{NativeIOSSetupOptions.kt → PartialIOSSetupPlayerOptions.kt} +5 -5
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PartialSetupPlayerOptions.kt +47 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{GateDecision.kt → PercentageRating.kt} +6 -9
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PlaybackError.kt +3 -12
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PlaybackState.kt +6 -6
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PlayerCapabilities.kt +2 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{GateReason.kt → RatingType.kt} +10 -5
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{ArtworkVariants.kt → RemoteSetRatingEvent.kt} +6 -9
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/ResolvedTrack.kt +3 -12
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/RetryConfig.kt +4 -7
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/SearchMode.kt +6 -12
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/SearchParams.kt +3 -6
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{GateEvent.kt → StarRating.kt} +6 -6
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{FavoriteConfig.kt → ThumbsRating.kt} +6 -6
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Track.kt +3 -12
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/TransformableRequestConfig.kt +4 -7
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/UpdateOptions.kt +53 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Variant_HeartRating_ThumbsRating_StarRating_PercentageRating.kt +77 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/{Variant_NullType_RemoteButtonLayout.kt → Variant_NullType_NotificationButtonLayout.kt} +9 -9
- package/nitrogen/generated/ios/AudioBrowser-Swift-Cxx-Bridge.cpp +28 -139
- package/nitrogen/generated/ios/AudioBrowser-Swift-Cxx-Bridge.hpp +489 -1125
- package/nitrogen/generated/ios/AudioBrowser-Swift-Cxx-Umbrella.hpp +45 -66
- package/nitrogen/generated/ios/c++/HybridAudioBrowserSpecSwift.hpp +118 -176
- package/nitrogen/generated/ios/swift/AndroidAudioContentType.swift +8 -8
- package/nitrogen/generated/ios/swift/AndroidOptions.swift +22 -12
- package/nitrogen/generated/ios/swift/AndroidUpdateOptions.swift +119 -0
- package/nitrogen/generated/ios/swift/ArtworkRequestConfig.swift +1 -95
- package/nitrogen/generated/ios/swift/CarPlayNowPlayingButton.swift +4 -4
- package/nitrogen/generated/ios/swift/FormattedNavigationError.swift +4 -17
- package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError______BrowserSourceCallbackParam.swift +68 -0
- package/nitrogen/generated/ios/swift/{Func_void_Output.swift → Func_void_IosOutput.swift} +10 -10
- package/nitrogen/generated/ios/swift/{Func_void_GateEvent.swift → Func_void_RemoteSetRatingEvent.swift} +10 -10
- package/nitrogen/generated/ios/swift/Func_void_bool.swift +5 -5
- package/nitrogen/generated/ios/swift/{Func_void_std__shared_ptr_Promise_GateDecision__.swift → Func_void_std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError___.swift} +17 -17
- package/nitrogen/generated/ios/swift/HeartRating.swift +29 -0
- package/nitrogen/generated/ios/swift/HybridAudioBrowserSpec.swift +14 -20
- package/nitrogen/generated/ios/swift/HybridAudioBrowserSpec_cxx.swift +197 -230
- package/nitrogen/generated/ios/swift/ImageRowItem.swift +2 -121
- package/nitrogen/generated/ios/swift/{Output.swift → IosOutput.swift} +7 -7
- package/nitrogen/generated/ios/swift/IosOutputType.swift +76 -0
- package/nitrogen/generated/ios/swift/MediaRequestConfig.swift +1 -107
- package/nitrogen/generated/ios/swift/NativeBrowserConfiguration.swift +22 -161
- package/nitrogen/generated/ios/swift/NativeRouteEntry.swift +19 -19
- package/nitrogen/generated/ios/swift/NativeUpdateOptions.swift +25 -12
- package/nitrogen/generated/ios/swift/NavigationErrorType.swift +0 -8
- package/nitrogen/generated/ios/swift/NitroAndroidUpdateOptions.swift +41 -12
- package/nitrogen/generated/ios/swift/{RemoteButton.swift → NotificationButton.swift} +10 -10
- package/nitrogen/generated/ios/swift/NotificationButtonLayout.swift +92 -0
- package/nitrogen/generated/ios/swift/NowPlayingMetadata.swift +48 -1
- package/nitrogen/generated/ios/swift/NowPlayingUpdate.swift +1 -19
- package/nitrogen/generated/ios/swift/Options.swift +4 -10
- package/nitrogen/generated/ios/swift/{NativeAndroidSetupOptions.swift → PartialAndroidSetupPlayerOptions.swift} +5 -5
- package/nitrogen/generated/ios/swift/{NativeIOSSetupOptions.swift → PartialIOSSetupPlayerOptions.swift} +5 -5
- package/nitrogen/generated/ios/swift/PartialSetupPlayerOptions.swift +101 -0
- package/nitrogen/generated/ios/swift/PercentageRating.swift +29 -0
- package/nitrogen/generated/ios/swift/PlaybackError.swift +2 -43
- package/nitrogen/generated/ios/swift/PlaybackState.swift +4 -4
- package/nitrogen/generated/ios/swift/PlayerCapabilities.swift +8 -27
- package/nitrogen/generated/ios/swift/RatingType.swift +60 -0
- package/nitrogen/generated/ios/swift/RemoteSetRatingEvent.swift +58 -0
- package/nitrogen/generated/ios/swift/ResolvedTrack.swift +8 -74
- package/nitrogen/generated/ios/swift/RetryConfig.swift +4 -35
- package/nitrogen/generated/ios/swift/SearchMode.swift +12 -36
- package/nitrogen/generated/ios/swift/SearchParams.swift +2 -7
- package/nitrogen/generated/ios/swift/StarRating.swift +29 -0
- package/nitrogen/generated/ios/swift/ThumbsRating.swift +29 -0
- package/nitrogen/generated/ios/swift/Track.swift +8 -74
- package/nitrogen/generated/ios/swift/TransformableRequestConfig.swift +1 -60
- package/nitrogen/generated/ios/swift/UpdateOptions.swift +143 -0
- package/nitrogen/generated/ios/swift/Variant_HeartRating_ThumbsRating_StarRating_PercentageRating.swift +20 -0
- package/nitrogen/generated/ios/swift/{Variant_NullType_RemoteButtonLayout.swift → Variant_NullType_NotificationButtonLayout.swift} +3 -3
- package/nitrogen/generated/shared/c++/AndroidAudioContentType.hpp +10 -10
- package/nitrogen/generated/shared/c++/AndroidOptions.hpp +19 -8
- package/nitrogen/generated/shared/c++/AndroidUpdateOptions.hpp +109 -0
- package/nitrogen/generated/shared/c++/ArtworkRequestConfig.hpp +2 -10
- package/nitrogen/generated/shared/c++/CarPlayNowPlayingButton.hpp +6 -6
- package/nitrogen/generated/shared/c++/EqualizerSettings.hpp +2 -0
- package/nitrogen/generated/shared/c++/FormattedNavigationError.hpp +5 -6
- package/nitrogen/generated/shared/c++/{GateEvent.hpp → HeartRating.hpp} +17 -18
- package/nitrogen/generated/shared/c++/HybridAudioBrowserSpec.cpp +18 -21
- package/nitrogen/generated/shared/c++/HybridAudioBrowserSpec.hpp +35 -44
- package/nitrogen/generated/shared/c++/ImageRowItem.hpp +2 -33
- package/nitrogen/generated/shared/c++/{Output.hpp → IosOutput.hpp} +18 -18
- package/nitrogen/generated/shared/c++/IosOutputType.hpp +112 -0
- package/nitrogen/generated/shared/c++/MediaRequestConfig.hpp +2 -10
- package/nitrogen/generated/shared/c++/NativeBrowserConfiguration.hpp +15 -31
- package/nitrogen/generated/shared/c++/NativeRouteEntry.hpp +5 -5
- package/nitrogen/generated/shared/c++/NativeUpdateOptions.hpp +7 -9
- package/nitrogen/generated/shared/c++/NavigationErrorType.hpp +0 -8
- package/nitrogen/generated/shared/c++/NitroAndroidUpdateOptions.hpp +19 -8
- package/nitrogen/generated/shared/c++/{RemoteButton.hpp → NotificationButton.hpp} +25 -25
- package/nitrogen/generated/shared/c++/NotificationButtonLayout.hpp +102 -0
- package/nitrogen/generated/shared/c++/NowPlayingMetadata.hpp +19 -3
- package/nitrogen/generated/shared/c++/NowPlayingUpdate.hpp +2 -6
- package/nitrogen/generated/shared/c++/Options.hpp +8 -8
- package/nitrogen/generated/shared/c++/{NativeAndroidSetupOptions.hpp → PartialAndroidSetupPlayerOptions.hpp} +11 -11
- package/nitrogen/generated/shared/c++/{NativeIOSSetupOptions.hpp → PartialIOSSetupPlayerOptions.hpp} +11 -11
- package/nitrogen/generated/shared/c++/PartialSetupPlayerOptions.hpp +104 -0
- package/nitrogen/generated/shared/c++/{FavoriteConfig.hpp → PercentageRating.hpp} +17 -18
- package/nitrogen/generated/shared/c++/PlaybackError.hpp +3 -18
- package/nitrogen/generated/shared/c++/PlaybackState.hpp +9 -9
- package/nitrogen/generated/shared/c++/PlayerCapabilities.hpp +6 -9
- package/nitrogen/generated/shared/c++/RatingType.hpp +96 -0
- package/nitrogen/generated/shared/c++/RemoteSetRatingEvent.hpp +94 -0
- package/nitrogen/generated/shared/c++/ResolvedTrack.hpp +5 -24
- package/nitrogen/generated/shared/c++/RetryConfig.hpp +6 -10
- package/nitrogen/generated/shared/c++/SearchMode.hpp +15 -39
- package/nitrogen/generated/shared/c++/SearchParams.hpp +2 -9
- package/nitrogen/generated/shared/c++/{Gate.hpp → StarRating.hpp} +16 -21
- package/nitrogen/generated/shared/c++/{GateDecision.hpp → ThumbsRating.hpp} +17 -23
- package/nitrogen/generated/shared/c++/Track.hpp +5 -24
- package/nitrogen/generated/shared/c++/TransformableRequestConfig.hpp +2 -6
- package/nitrogen/generated/shared/c++/UpdateOptions.hpp +111 -0
- package/package.json +5 -12
- package/src/AudioBrowser.ts +1 -4
- package/src/features/browser.ts +201 -58
- package/src/features/equalizer.ts +1 -1
- package/src/features/errors.ts +5 -71
- package/src/features/favorites.ts +1 -1
- package/src/features/index.ts +0 -2
- package/src/features/metadata.ts +15 -9
- package/src/features/network.ts +1 -1
- package/src/features/nowPlaying.ts +1 -37
- package/src/features/output.ts +22 -35
- package/src/features/playback/controls.ts +0 -8
- package/src/features/playback/index.ts +0 -1
- package/src/features/playback/playWhenReady.ts +1 -1
- package/src/features/playback/playing.ts +1 -1
- package/src/features/playback/progress.ts +13 -32
- package/src/features/playback/state.ts +1 -1
- package/src/features/playback/volume.ts +2 -2
- package/src/features/player/options.ts +110 -217
- package/src/features/player/setup.ts +175 -397
- package/src/features/queue/activeTrack.ts +1 -1
- package/src/features/queue/queue.ts +6 -17
- package/src/features/queue/repeatMode.ts +1 -1
- package/src/features/queue/shuffle.ts +1 -1
- package/src/features/rating.ts +17 -0
- package/src/features/remoteControls.ts +115 -13
- package/src/features/sleepTimer.ts +5 -24
- package/src/native.ts +0 -5
- package/src/native.web.ts +1 -4
- package/src/specs/audio-browser.nitro.ts +41 -131
- package/src/types/browser-native.ts +6 -19
- package/src/types/browser-nodes.ts +13 -160
- package/src/types/browser.ts +89 -377
- package/src/types/player.ts +69 -0
- package/src/utils/LazyNativeEmitter.ts +8 -9
- package/src/utils/NativeUpdatedValue.ts +2 -0
- package/src/web/NativeAudioBrowser.ts +158 -365
- package/src/web/TrackPlayer/Player.ts +39 -113
- package/src/web/TrackPlayer/PlaylistPlayer.ts +346 -0
- package/src/web/TrackPlayer/RepeatMode.ts +1 -1
- package/src/web/TrackPlayer/SleepTimer.ts +3 -38
- package/src/web/TrackPlayer/index.ts +1 -2
- package/src/web/browser/BrowserManager.ts +62 -231
- package/src/web/browser/NavigationErrorManager.ts +1 -3
- package/src/web/browser/SearchManager.ts +15 -11
- package/src/web/http/HttpClient.ts +35 -5
- package/src/web/http/RequestConfigBuilder.ts +63 -120
- package/src/web/player/NowPlayingManager.ts +5 -6
- package/src/web/player/OptionsManager.ts +18 -12
- package/android/src/main/java/com/audiobrowser/ServiceBinding.kt +0 -46
- package/android/src/main/java/com/audiobrowser/browser/ArtworkResolutionRegistry.kt +0 -37
- package/android/src/main/java/com/audiobrowser/browser/BrowseArtworkRegistry.kt +0 -34
- package/android/src/main/java/com/audiobrowser/browser/BrowserUrlResolution.kt +0 -299
- package/android/src/main/java/com/audiobrowser/browser/JsonArtwork.kt +0 -79
- package/android/src/main/java/com/audiobrowser/browser/SectionScope.kt +0 -42
- package/android/src/main/java/com/audiobrowser/extension/ResolvedTrackExt.kt +0 -35
- package/android/src/main/java/com/audiobrowser/player/CapabilityControls.kt +0 -172
- package/android/src/main/java/com/audiobrowser/player/EqualizerController.kt +0 -153
- package/android/src/main/java/com/audiobrowser/player/InterceptingPlayer.kt +0 -141
- package/android/src/main/java/com/audiobrowser/player/NowPlayingUpdater.kt +0 -347
- package/android/src/main/java/com/audiobrowser/player/PlaybackErrorClassifier.kt +0 -129
- package/android/src/main/java/com/audiobrowser/player/PlaybackStateMachine.kt +0 -85
- package/android/src/main/java/com/audiobrowser/player/PlaybackTimer.kt +0 -56
- package/android/src/main/java/com/audiobrowser/player/PlayerCapabilitiesExt.kt +0 -20
- package/android/src/main/java/com/audiobrowser/player/PlayerEngineFactory.kt +0 -130
- package/android/src/main/java/com/audiobrowser/player/SleepTimerManager.kt +0 -80
- package/android/src/main/java/com/audiobrowser/player/StuckRecoveryPolicy.kt +0 -50
- package/android/src/main/java/com/audiobrowser/player/VolumeFader.kt +0 -81
- package/android/src/main/java/com/audiobrowser/tls/AiaCertChaser.kt +0 -141
- package/android/src/main/java/com/audiobrowser/tls/AiaChasingTrustManager.kt +0 -37
- package/android/src/main/java/com/audiobrowser/tls/AiaTls.kt +0 -41
- package/android/src/main/java/com/audiobrowser/tls/CachingCertificateFetcher.kt +0 -209
- package/android/src/main/java/com/audiobrowser/util/ArtworkContentProvider.kt +0 -161
- package/android/src/main/java/com/audiobrowser/util/ArtworkUris.kt +0 -28
- package/android/src/main/java/com/audiobrowser/util/ArtworkVariant.kt +0 -24
- package/android/src/main/java/com/audiobrowser/util/CoilArtworkLoader.kt +0 -49
- package/android/src/main/java/com/audiobrowser/util/CoilArtworkLoaderHolder.kt +0 -36
- package/android/src/main/java/com/audiobrowser/util/OutputMonitor.kt +0 -211
- package/android/src/main/java/com/audiobrowser/util/OutputSwitcher.kt +0 -58
- package/android/src/main/java/com/audiobrowser/util/RatingFavorites.kt +0 -14
- package/android/src/test/java/com/audiobrowser/ServiceBindingTest.kt +0 -68
- package/android/src/test/java/com/audiobrowser/TestFixtures.kt +0 -165
- package/android/src/test/java/com/audiobrowser/browser/ArtworkResolutionRegistryTest.kt +0 -46
- package/android/src/test/java/com/audiobrowser/browser/BrowseArtworkRegistryTest.kt +0 -39
- package/android/src/test/java/com/audiobrowser/browser/BrowserManagerBuildApiRequestTest.kt +0 -114
- package/android/src/test/java/com/audiobrowser/browser/BrowserManagerLayerResolutionTest.kt +0 -141
- package/android/src/test/java/com/audiobrowser/browser/BrowserUrlResolutionTest.kt +0 -177
- package/android/src/test/java/com/audiobrowser/browser/JsonArtworkTest.kt +0 -55
- package/android/src/test/java/com/audiobrowser/browser/SectionScopeTest.kt +0 -94
- package/android/src/test/java/com/audiobrowser/player/CapabilityControlsTest.kt +0 -203
- package/android/src/test/java/com/audiobrowser/player/DynamicLoadControlTest.kt +0 -56
- package/android/src/test/java/com/audiobrowser/player/EqualizerControllerTest.kt +0 -216
- package/android/src/test/java/com/audiobrowser/player/MediaSessionSlotMappingTest.kt +0 -45
- package/android/src/test/java/com/audiobrowser/player/NowPlayingUpdaterTest.kt +0 -442
- package/android/src/test/java/com/audiobrowser/player/PlaybackErrorClassifierTest.kt +0 -190
- package/android/src/test/java/com/audiobrowser/player/PlaybackStateMachineTest.kt +0 -198
- package/android/src/test/java/com/audiobrowser/player/PlaybackTimerTest.kt +0 -137
- package/android/src/test/java/com/audiobrowser/player/PlayerEngineFactoryTest.kt +0 -36
- package/android/src/test/java/com/audiobrowser/player/RetryLoadErrorHandlingPolicyTest.kt +0 -268
- package/android/src/test/java/com/audiobrowser/player/SessionErrorMaskTest.kt +0 -68
- package/android/src/test/java/com/audiobrowser/player/StuckRecoveryPolicyTest.kt +0 -40
- package/android/src/test/java/com/audiobrowser/player/TransformingDataSourceTest.kt +0 -193
- package/android/src/test/java/com/audiobrowser/tls/AiaCertChaserTest.kt +0 -107
- package/android/src/test/java/com/audiobrowser/tls/AiaChasingTrustManagerTest.kt +0 -73
- package/android/src/test/java/com/audiobrowser/tls/CachingCertificateFetcherTest.kt +0 -75
- package/android/src/test/java/com/audiobrowser/tls/CertFixtures.kt +0 -18
- package/android/src/test/java/com/audiobrowser/util/ArtworkContentProviderTest.kt +0 -163
- package/android/src/test/java/com/audiobrowser/util/ArtworkUrisTest.kt +0 -34
- package/android/src/test/java/com/audiobrowser/util/BrowserPathHelperTest.kt +0 -28
- package/android/src/test/java/com/audiobrowser/util/CoilArtworkLoaderHolderTest.kt +0 -53
- package/android/src/test/java/com/audiobrowser/util/CoilArtworkLoaderTest.kt +0 -58
- package/android/src/test/java/com/audiobrowser/util/FakeImageLoader.kt +0 -57
- package/android/src/test/java/com/audiobrowser/util/PlayingStateFactoryTest.kt +0 -40
- package/android/src/test/java/com/audiobrowser/util/RatingFavoritesTest.kt +0 -34
- package/android/src/test/java/com/audiobrowser/util/TrackFactoryBrowseTest.kt +0 -50
- package/android/src/test/java/com/audiobrowser/util/TrackFactoryMediaIdTest.kt +0 -63
- package/android/src/test/java/com/audiobrowser/util/TrackFactoryRatingTest.kt +0 -35
- package/android/src/test/resources/certs/isrg-root-x1.pem +0 -31
- package/android/src/test/resources/certs/letsencrypt-r13.der +0 -0
- package/android/src/test/resources/certs/letsencrypt-r13.pem +0 -29
- package/android/src/test/resources/certs/stationplaylist-leaf.pem +0 -34
- package/ios/Browser/MediaResolveComposer.swift +0 -114
- package/ios/Browser/SearchDrillIn.swift +0 -44
- package/ios/Browser/SectionScope.swift +0 -35
- package/ios/Browser/TabBarEntries.swift +0 -15
- package/ios/CarPlay/CPInterfaceController+Safe.swift +0 -126
- package/ios/CarPlay/ImageRowItem+CarPlay.swift +0 -19
- package/ios/CarPlay/RNABMediaAddHandler.swift +0 -75
- package/ios/CarPlay/RNABMediaAffinityHandler.swift +0 -69
- package/ios/Extension/PlayerCapabilities+Favorite.swift +0 -20
- package/ios/Extension/RequestConfig+Copying.swift +0 -31
- package/ios/Extension/Variant+Artwork.swift +0 -49
- package/ios/NowPlayingInfo/SilentAudioPrimer.swift +0 -73
- package/ios/Player/AirPlayStallJudgement.swift +0 -25
- package/ios/Player/EndOfTrackJudgement.swift +0 -32
- package/ios/Player/MediaIntentCriteria.swift +0 -139
- package/ios/Player/PersistedPlaybackState.swift +0 -11
- package/ios/Player/PlaybackStateStore.swift +0 -27
- package/ios/Player/PlaybackTimer.swift +0 -61
- package/ios/Player/VolumeFader.swift +0 -77
- package/ios/RemoteCommand/RemoteCommandCallbacks.swift +0 -47
- package/ios/Tests/AirPlayStallJudgementTests.swift +0 -52
- package/ios/Tests/EndOfTrackJudgementTests.swift +0 -35
- package/ios/Tests/JsonModelsTests.swift +0 -58
- package/ios/Tests/MediaIntentCriteriaTests.swift +0 -170
- package/ios/Tests/MediaLoaderAssetOptionsTests.swift +0 -46
- package/ios/Tests/MediaResolveTests.swift +0 -126
- package/ios/Tests/OnceValueTests.swift +0 -79
- package/ios/Tests/PlaybackStateStoreTests.swift +0 -48
- package/ios/Tests/PlaybackTimerTests.swift +0 -55
- package/ios/Tests/PlayingStateManagerTests.swift +0 -57
- package/ios/Tests/RemoteCommandControllerTests.swift +0 -156
- package/ios/Tests/RemoteCommandTests.swift +0 -67
- package/ios/Tests/RetryManagerTests.swift +0 -89
- package/ios/Tests/SearchDrillInTests.swift +0 -63
- package/ios/Tests/SectionScopeTests.swift +0 -82
- package/ios/Tests/SleepTimerManagerTests.swift +0 -107
- package/ios/Tests/Support/ManualSleepTimerScheduler.swift +0 -47
- package/ios/Tests/TabBarEntriesTests.swift +0 -71
- package/lib/commonjs/features/browser-config.js +0 -227
- package/lib/commonjs/features/browser-config.js.map +0 -1
- package/lib/commonjs/features/carConnection.js +0 -42
- package/lib/commonjs/features/carConnection.js.map +0 -1
- package/lib/commonjs/features/gate.js +0 -149
- package/lib/commonjs/features/gate.js.map +0 -1
- package/lib/commonjs/features/playback/trackPlaybackTime.js +0 -86
- package/lib/commonjs/features/playback/trackPlaybackTime.js.map +0 -1
- package/lib/commonjs/features/player/validateOptions.js +0 -24
- package/lib/commonjs/features/player/validateOptions.js.map +0 -1
- package/lib/commonjs/utils/artwork.js +0 -31
- package/lib/commonjs/utils/artwork.js.map +0 -1
- package/lib/commonjs/web/TrackPlayer/PlaybackStateMachine.js +0 -71
- package/lib/commonjs/web/TrackPlayer/PlaybackStateMachine.js.map +0 -1
- package/lib/commonjs/web/TrackPlayer/PlaybackTimer.js +0 -34
- package/lib/commonjs/web/TrackPlayer/PlaybackTimer.js.map +0 -1
- package/lib/commonjs/web/TrackPlayer/PlayingStateFactory.js +0 -21
- package/lib/commonjs/web/TrackPlayer/PlayingStateFactory.js.map +0 -1
- package/lib/commonjs/web/TrackPlayer/QueueManager.js +0 -273
- package/lib/commonjs/web/TrackPlayer/QueueManager.js.map +0 -1
- package/lib/commonjs/web/TrackPlayer/QueuePlayer.js +0 -158
- package/lib/commonjs/web/TrackPlayer/QueuePlayer.js.map +0 -1
- package/lib/commonjs/web/TrackPlayer/VolumeFader.js +0 -75
- package/lib/commonjs/web/TrackPlayer/VolumeFader.js.map +0 -1
- package/lib/commonjs/web/browser/assertBrowsePageShape.js +0 -22
- package/lib/commonjs/web/browser/assertBrowsePageShape.js.map +0 -1
- package/lib/commonjs/web/browser/classifyTrackNavigation.js +0 -41
- package/lib/commonjs/web/browser/classifyTrackNavigation.js.map +0 -1
- package/lib/commonjs/web/browser/parseSearchResponse.js +0 -20
- package/lib/commonjs/web/browser/parseSearchResponse.js.map +0 -1
- package/lib/commonjs/web/playbackErrorKind.js +0 -57
- package/lib/commonjs/web/playbackErrorKind.js.map +0 -1
- package/lib/commonjs/web/player/MediaSessionManager.js +0 -121
- package/lib/commonjs/web/player/MediaSessionManager.js.map +0 -1
- package/lib/commonjs/web/player/RemoteCommandController.js +0 -96
- package/lib/commonjs/web/player/RemoteCommandController.js.map +0 -1
- package/lib/module/features/browser-config.js +0 -221
- package/lib/module/features/browser-config.js.map +0 -1
- package/lib/module/features/carConnection.js +0 -37
- package/lib/module/features/carConnection.js.map +0 -1
- package/lib/module/features/gate.js +0 -144
- package/lib/module/features/gate.js.map +0 -1
- package/lib/module/features/playback/trackPlaybackTime.js +0 -83
- package/lib/module/features/playback/trackPlaybackTime.js.map +0 -1
- package/lib/module/features/player/validateOptions.js +0 -20
- package/lib/module/features/player/validateOptions.js.map +0 -1
- package/lib/module/utils/artwork.js +0 -26
- package/lib/module/utils/artwork.js.map +0 -1
- package/lib/module/web/TrackPlayer/PlaybackStateMachine.js +0 -67
- package/lib/module/web/TrackPlayer/PlaybackStateMachine.js.map +0 -1
- package/lib/module/web/TrackPlayer/PlaybackTimer.js +0 -29
- package/lib/module/web/TrackPlayer/PlaybackTimer.js.map +0 -1
- package/lib/module/web/TrackPlayer/PlayingStateFactory.js +0 -17
- package/lib/module/web/TrackPlayer/PlayingStateFactory.js.map +0 -1
- package/lib/module/web/TrackPlayer/QueueManager.js +0 -269
- package/lib/module/web/TrackPlayer/QueueManager.js.map +0 -1
- package/lib/module/web/TrackPlayer/QueuePlayer.js +0 -154
- package/lib/module/web/TrackPlayer/QueuePlayer.js.map +0 -1
- package/lib/module/web/TrackPlayer/VolumeFader.js +0 -70
- package/lib/module/web/TrackPlayer/VolumeFader.js.map +0 -1
- package/lib/module/web/browser/assertBrowsePageShape.js +0 -18
- package/lib/module/web/browser/assertBrowsePageShape.js.map +0 -1
- package/lib/module/web/browser/classifyTrackNavigation.js +0 -38
- package/lib/module/web/browser/classifyTrackNavigation.js.map +0 -1
- package/lib/module/web/browser/parseSearchResponse.js +0 -16
- package/lib/module/web/browser/parseSearchResponse.js.map +0 -1
- package/lib/module/web/playbackErrorKind.js +0 -52
- package/lib/module/web/playbackErrorKind.js.map +0 -1
- package/lib/module/web/player/MediaSessionManager.js +0 -116
- package/lib/module/web/player/MediaSessionManager.js.map +0 -1
- package/lib/module/web/player/RemoteCommandController.js +0 -92
- package/lib/module/web/player/RemoteCommandController.js.map +0 -1
- package/lib/typescript/src/features/browser-config.d.ts +0 -12
- package/lib/typescript/src/features/browser-config.d.ts.map +0 -1
- package/lib/typescript/src/features/carConnection.d.ts +0 -20
- package/lib/typescript/src/features/carConnection.d.ts.map +0 -1
- package/lib/typescript/src/features/gate.d.ts +0 -78
- package/lib/typescript/src/features/gate.d.ts.map +0 -1
- package/lib/typescript/src/features/playback/trackPlaybackTime.d.ts +0 -34
- package/lib/typescript/src/features/playback/trackPlaybackTime.d.ts.map +0 -1
- package/lib/typescript/src/features/player/validateOptions.d.ts +0 -2
- package/lib/typescript/src/features/player/validateOptions.d.ts.map +0 -1
- package/lib/typescript/src/utils/artwork.d.ts +0 -19
- package/lib/typescript/src/utils/artwork.d.ts.map +0 -1
- package/nitrogen/generated/android/c++/JArtworkVariants.hpp +0 -61
- package/nitrogen/generated/android/c++/JFavoriteConfig.hpp +0 -58
- package/nitrogen/generated/android/c++/JFavoritesMatchMode.hpp +0 -58
- package/nitrogen/generated/android/c++/JFormatNowPlayingParams.hpp +0 -100
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_RequestConfig___MediaTransformParams.hpp +0 -112
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_RequestConfig___RequestConfig_std__optional_std__unordered_map_std__string__std__string__.hpp +0 -121
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_RequestConfig___Track.hpp +0 -123
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__optional_NowPlayingUpdate____FormatNowPlayingParams.hpp +0 -133
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__optional_std__string____Track.hpp +0 -121
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_GateDecision_____NativeGateRequest.hpp +0 -139
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_TransformableRequestConfig____.hpp +0 -134
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError__std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError_______BrowserSourceCallbackParam.hpp +0 -131
- package/nitrogen/generated/android/c++/JFunc_void_GateEvent.hpp +0 -79
- package/nitrogen/generated/android/c++/JFunc_void_Output.hpp +0 -80
- package/nitrogen/generated/android/c++/JGate.hpp +0 -62
- package/nitrogen/generated/android/c++/JGateDecision.hpp +0 -64
- package/nitrogen/generated/android/c++/JGateReason.hpp +0 -58
- package/nitrogen/generated/android/c++/JIOSOptions.hpp +0 -95
- package/nitrogen/generated/android/c++/JMediaReference.hpp +0 -58
- package/nitrogen/generated/android/c++/JNativeGateRequest.hpp +0 -74
- package/nitrogen/generated/android/c++/JNativeSetupPlayerOptions.hpp +0 -182
- package/nitrogen/generated/android/c++/JNitroIOSUpdateOptions.hpp +0 -96
- package/nitrogen/generated/android/c++/JOutputType.hpp +0 -82
- package/nitrogen/generated/android/c++/JPlaybackErrorKind.hpp +0 -76
- package/nitrogen/generated/android/c++/JRemoteButtonLayout.hpp +0 -86
- package/nitrogen/generated/android/c++/JStallReason.hpp +0 -58
- package/nitrogen/generated/android/c++/JTrackRequest.hpp +0 -93
- package/nitrogen/generated/android/c++/JVariant_Boolean_FavoriteConfig.cpp +0 -26
- package/nitrogen/generated/android/c++/JVariant_Boolean_FavoriteConfig.hpp +0 -71
- package/nitrogen/generated/android/c++/JVariant_NullType_RemoteButtonLayout.cpp +0 -26
- package/nitrogen/generated/android/c++/JVariant_NullType_RemoteButtonLayout.hpp +0 -75
- package/nitrogen/generated/android/c++/JVariant_ResolvedTrack_BrowseError_Promise_BrowseResult_.cpp +0 -41
- package/nitrogen/generated/android/c++/JVariant_ResolvedTrack_BrowseError_Promise_BrowseResult_.hpp +0 -121
- package/nitrogen/generated/android/c++/JVariant_String_ArtworkVariants.cpp +0 -26
- package/nitrogen/generated/android/c++/JVariant_String_ArtworkVariants.hpp +0 -70
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/FormatNowPlayingParams.kt +0 -50
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_RequestConfig___MediaTransformParams.kt +0 -80
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_RequestConfig___RequestConfig_std__optional_std__unordered_map_std__string__std__string__.kt +0 -80
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_RequestConfig___Track.kt +0 -80
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_std__optional_NowPlayingUpdate____FormatNowPlayingParams.kt +0 -80
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_std__optional_std__string____Track.kt +0 -80
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_GateDecision_____NativeGateRequest.kt +0 -80
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_TransformableRequestConfig____.kt +0 -80
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/IOSOptions.kt +0 -44
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/MediaReference.kt +0 -23
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NativeGateRequest.kt +0 -44
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NativeSetupPlayerOptions.kt +0 -66
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/NitroIOSUpdateOptions.kt +0 -44
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/OutputType.kt +0 -31
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/PlaybackErrorKind.kt +0 -29
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/RemoteButton.kt +0 -26
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/RemoteButtonLayout.kt +0 -44
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/StallReason.kt +0 -23
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/TrackRequest.kt +0 -44
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Variant_Boolean_FavoriteConfig.kt +0 -53
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Variant_ResolvedTrack_BrowseError_Promise_BrowseResult_.kt +0 -65
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/audiobrowser/Variant_String_ArtworkVariants.kt +0 -53
- package/nitrogen/generated/ios/swift/ArtworkVariants.swift +0 -34
- package/nitrogen/generated/ios/swift/FavoriteConfig.swift +0 -29
- package/nitrogen/generated/ios/swift/FavoritesMatchMode.swift +0 -40
- package/nitrogen/generated/ios/swift/FormatNowPlayingParams.swift +0 -67
- package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_RequestConfig___MediaTransformParams.swift +0 -54
- package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_RequestConfig___RequestConfig_std__optional_std__unordered_map_std__string__std__string__.swift +0 -69
- package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_RequestConfig___Track.swift +0 -54
- package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_std__optional_NowPlayingUpdate____FormatNowPlayingParams.swift +0 -60
- package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_std__optional_std__string____Track.swift +0 -60
- package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_GateDecision_____NativeGateRequest.swift +0 -61
- package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_TransformableRequestConfig____.swift +0 -61
- package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError__std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError_______BrowserSourceCallbackParam.swift +0 -77
- package/nitrogen/generated/ios/swift/Func_void_GateDecision.swift +0 -46
- package/nitrogen/generated/ios/swift/Func_void_TransformableRequestConfig.swift +0 -46
- package/nitrogen/generated/ios/swift/Func_void_std__optional_NowPlayingUpdate_.swift +0 -46
- package/nitrogen/generated/ios/swift/Func_void_std__optional_std__string_.swift +0 -53
- package/nitrogen/generated/ios/swift/Func_void_std__shared_ptr_Promise_TransformableRequestConfig__.swift +0 -66
- package/nitrogen/generated/ios/swift/Func_void_std__variant_ResolvedTrack__BrowseError__std__shared_ptr_Promise_std__variant_ResolvedTrack__BrowseError____.swift +0 -81
- package/nitrogen/generated/ios/swift/Gate.swift +0 -47
- package/nitrogen/generated/ios/swift/GateDecision.swift +0 -40
- package/nitrogen/generated/ios/swift/GateEvent.swift +0 -29
- package/nitrogen/generated/ios/swift/GateReason.swift +0 -40
- package/nitrogen/generated/ios/swift/IOSOptions.swift +0 -51
- package/nitrogen/generated/ios/swift/MediaReference.swift +0 -40
- package/nitrogen/generated/ios/swift/NativeGateRequest.swift +0 -58
- package/nitrogen/generated/ios/swift/NativeSetupPlayerOptions.swift +0 -206
- package/nitrogen/generated/ios/swift/NitroIOSUpdateOptions.swift +0 -90
- package/nitrogen/generated/ios/swift/OutputType.swift +0 -72
- package/nitrogen/generated/ios/swift/PlaybackErrorKind.swift +0 -64
- package/nitrogen/generated/ios/swift/RemoteButtonLayout.swift +0 -57
- package/nitrogen/generated/ios/swift/StallReason.swift +0 -40
- package/nitrogen/generated/ios/swift/TrackRequest.swift +0 -106
- package/nitrogen/generated/ios/swift/Variant_Bool_FavoriteConfig.swift +0 -18
- package/nitrogen/generated/ios/swift/Variant_ResolvedTrack_BrowseError_Promise_BrowseResult_.swift +0 -19
- package/nitrogen/generated/ios/swift/Variant_String_ArtworkVariants.swift +0 -18
- package/nitrogen/generated/shared/c++/ArtworkVariants.hpp +0 -87
- package/nitrogen/generated/shared/c++/FavoritesMatchMode.hpp +0 -76
- package/nitrogen/generated/shared/c++/FormatNowPlayingParams.hpp +0 -110
- package/nitrogen/generated/shared/c++/GateReason.hpp +0 -76
- package/nitrogen/generated/shared/c++/IOSOptions.hpp +0 -91
- package/nitrogen/generated/shared/c++/MediaReference.hpp +0 -76
- package/nitrogen/generated/shared/c++/NativeGateRequest.hpp +0 -97
- package/nitrogen/generated/shared/c++/NativeSetupPlayerOptions.hpp +0 -138
- package/nitrogen/generated/shared/c++/NitroIOSUpdateOptions.hpp +0 -92
- package/nitrogen/generated/shared/c++/OutputType.hpp +0 -108
- package/nitrogen/generated/shared/c++/PlaybackErrorKind.hpp +0 -100
- package/nitrogen/generated/shared/c++/RemoteButtonLayout.hpp +0 -94
- package/nitrogen/generated/shared/c++/StallReason.hpp +0 -76
- package/nitrogen/generated/shared/c++/TrackRequest.hpp +0 -93
- package/src/codegen-no-config-variant.test.ts +0 -70
- package/src/features/browser-config.test.ts +0 -110
- package/src/features/browser-config.ts +0 -293
- package/src/features/browser.test.ts +0 -19
- package/src/features/carConnection.ts +0 -36
- package/src/features/gate.test.ts +0 -72
- package/src/features/gate.ts +0 -155
- package/src/features/playback/trackPlaybackTime.test.ts +0 -80
- package/src/features/playback/trackPlaybackTime.ts +0 -101
- package/src/features/player/options.test.ts +0 -38
- package/src/features/player/setup.test.ts +0 -125
- package/src/features/player/validateOptions.ts +0 -22
- package/src/features/queue/queue.test.ts +0 -36
- package/src/public-surface.test.ts +0 -123
- package/src/utils/artwork.ts +0 -30
- package/src/web/NativeAudioBrowser.playWhenReady.test.ts +0 -301
- package/src/web/TrackPlayer/PlaybackStateMachine.test.ts +0 -139
- package/src/web/TrackPlayer/PlaybackStateMachine.ts +0 -82
- package/src/web/TrackPlayer/PlaybackTimer.test.ts +0 -67
- package/src/web/TrackPlayer/PlaybackTimer.ts +0 -33
- package/src/web/TrackPlayer/Player.dispatch.test.ts +0 -229
- package/src/web/TrackPlayer/Player.load.test.ts +0 -86
- package/src/web/TrackPlayer/PlayingStateFactory.test.ts +0 -51
- package/src/web/TrackPlayer/PlayingStateFactory.ts +0 -24
- package/src/web/TrackPlayer/QueueManager.test.ts +0 -289
- package/src/web/TrackPlayer/QueueManager.ts +0 -302
- package/src/web/TrackPlayer/QueuePlayer.ts +0 -188
- package/src/web/TrackPlayer/VolumeFader.ts +0 -74
- package/src/web/browser/__tests__/layer-resolver.test.ts +0 -69
- package/src/web/browser/assertBrowsePageShape.test.ts +0 -27
- package/src/web/browser/assertBrowsePageShape.ts +0 -27
- package/src/web/browser/classifyTrackNavigation.test.ts +0 -41
- package/src/web/browser/classifyTrackNavigation.ts +0 -35
- package/src/web/browser/parseSearchResponse.test.ts +0 -25
- package/src/web/browser/parseSearchResponse.ts +0 -15
- package/src/web/http/RequestConfigBuilder.test.ts +0 -59
- package/src/web/playbackErrorKind.test.ts +0 -55
- package/src/web/playbackErrorKind.ts +0 -56
- package/src/web/player/MediaSessionManager.test.ts +0 -220
- package/src/web/player/MediaSessionManager.ts +0 -151
- package/src/web/player/NowPlayingManager.test.ts +0 -46
- package/src/web/player/RemoteCommandController.test.ts +0 -171
- package/src/web/player/RemoteCommandController.ts +0 -166
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
package com.audiobrowser.tls
|
|
2
|
-
|
|
3
|
-
import java.security.cert.X509Certificate
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Fills in missing intermediate CA certificates by following the Authority Information Access (AIA)
|
|
7
|
-
* "CA Issuers" pointer in a certificate, the way Apple's Secure Transport does automatically but
|
|
8
|
-
* Android's default trust manager does not.
|
|
9
|
-
*
|
|
10
|
-
* Many servers (a common misconfiguration) present only their leaf certificate and omit the
|
|
11
|
-
* intermediate(s) needed to chain up to a trusted root. Browsers and iOS fetch the missing
|
|
12
|
-
* intermediate from the URL in the leaf's AIA extension; Android's `X509TrustManager` validates
|
|
13
|
-
* only what the server sent, so such streams fail with "Trust anchor for certification path not
|
|
14
|
-
* found".
|
|
15
|
-
*/
|
|
16
|
-
object AiaCertChaser {
|
|
17
|
-
/** Authority Information Access extension. */
|
|
18
|
-
private const val AIA_OID = "1.3.6.1.5.5.7.1.1"
|
|
19
|
-
|
|
20
|
-
/** DER-encoded OID value of id-ad-caIssuers (1.3.6.1.5.5.7.48.2). */
|
|
21
|
-
private val CA_ISSUERS_OID = byteArrayOf(0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02)
|
|
22
|
-
|
|
23
|
-
private const val TAG_SEQUENCE = 0x30
|
|
24
|
-
private const val TAG_OID = 0x06
|
|
25
|
-
private const val TAG_OCTET_STRING = 0x04
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* GeneralName.uniformResourceIdentifier = [6] IMPLICIT IA5String (context-specific, primitive).
|
|
29
|
-
*/
|
|
30
|
-
private const val TAG_URI = 0x86
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Returns the "CA Issuers" URLs from the certificate's AIA extension (the locations from which
|
|
34
|
-
* the issuing CA certificate can be fetched), or an empty list if the extension is absent or
|
|
35
|
-
* unparseable.
|
|
36
|
-
*/
|
|
37
|
-
fun extractCaIssuerUrls(cert: X509Certificate): List<String> {
|
|
38
|
-
val raw = cert.getExtensionValue(AIA_OID) ?: return emptyList()
|
|
39
|
-
return try {
|
|
40
|
-
// getExtensionValue() returns the extension value wrapped in an OCTET STRING.
|
|
41
|
-
val wrapper = DerReader(raw).read()
|
|
42
|
-
if (wrapper.tag != TAG_OCTET_STRING) return emptyList()
|
|
43
|
-
|
|
44
|
-
// AuthorityInfoAccessSyntax ::= SEQUENCE OF AccessDescription
|
|
45
|
-
val aiaSeq = DerReader(wrapper.content()).read()
|
|
46
|
-
if (aiaSeq.tag != TAG_SEQUENCE) return emptyList()
|
|
47
|
-
|
|
48
|
-
val urls = mutableListOf<String>()
|
|
49
|
-
val descriptions = DerReader(aiaSeq.content())
|
|
50
|
-
while (descriptions.hasNext()) {
|
|
51
|
-
// AccessDescription ::= SEQUENCE { accessMethod OID, accessLocation GeneralName }
|
|
52
|
-
val desc = descriptions.read()
|
|
53
|
-
if (desc.tag != TAG_SEQUENCE) continue
|
|
54
|
-
val fields = DerReader(desc.content())
|
|
55
|
-
val method = fields.read()
|
|
56
|
-
if (method.tag != TAG_OID || !method.content().contentEquals(CA_ISSUERS_OID)) continue
|
|
57
|
-
if (!fields.hasNext()) continue
|
|
58
|
-
val location = fields.read()
|
|
59
|
-
if (location.tag == TAG_URI) {
|
|
60
|
-
urls.add(String(location.content(), Charsets.US_ASCII))
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
urls
|
|
64
|
-
} catch (e: Exception) {
|
|
65
|
-
// Malformed DER: treat as "no AIA" rather than crashing the handshake.
|
|
66
|
-
emptyList()
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Walks up from the presented chain, fetching each missing issuer via its predecessor's AIA "CA
|
|
72
|
-
* Issuers" pointer, until it reaches a self-signed certificate, an issuer that cannot be fetched,
|
|
73
|
-
* or [maxIntermediates] additions. Returns the (possibly extended) chain.
|
|
74
|
-
*
|
|
75
|
-
* Only ever *adds* certificates — the caller is still responsible for validating the completed
|
|
76
|
-
* chain against the system trust anchors, so this can never cause an untrusted chain to be
|
|
77
|
-
* accepted. From each URL's candidates the genuine issuer of the preceding certificate is
|
|
78
|
-
* selected (defends against an AIA pointer to an unrelated certificate, and picks the right one
|
|
79
|
-
* out of a multi-certificate PKCS#7 bundle).
|
|
80
|
-
*
|
|
81
|
-
* @param fetch resolves a CA-Issuers URL to its candidate certificates (e.g. every certificate in
|
|
82
|
-
* a PKCS#7 bundle); empty if nothing could be retrieved.
|
|
83
|
-
*/
|
|
84
|
-
fun completeChain(
|
|
85
|
-
presented: List<X509Certificate>,
|
|
86
|
-
maxIntermediates: Int = 5,
|
|
87
|
-
fetch: (url: String) -> List<X509Certificate>,
|
|
88
|
-
): List<X509Certificate> {
|
|
89
|
-
if (presented.isEmpty()) return presented
|
|
90
|
-
val chain = presented.toMutableList()
|
|
91
|
-
val seen = HashSet(chain)
|
|
92
|
-
var added = 0
|
|
93
|
-
while (added < maxIntermediates) {
|
|
94
|
-
val last = chain.last()
|
|
95
|
-
if (last.subjectX500Principal == last.issuerX500Principal) break // self-signed root
|
|
96
|
-
val issuer =
|
|
97
|
-
extractCaIssuerUrls(last)
|
|
98
|
-
.asSequence()
|
|
99
|
-
.flatMap { url -> runCatching { fetch(url) }.getOrElse { emptyList() } }
|
|
100
|
-
.firstOrNull { it.subjectX500Principal == last.issuerX500Principal } ?: break
|
|
101
|
-
if (!seen.add(issuer)) break // cycle guard
|
|
102
|
-
chain.add(issuer)
|
|
103
|
-
added++
|
|
104
|
-
}
|
|
105
|
-
return chain
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Minimal DER TLV reader over a byte buffer. Does no bounds-checking by design: truncated or
|
|
110
|
-
* malformed input throws (e.g. [IndexOutOfBoundsException]), which the callers above expect and
|
|
111
|
-
* turn into "no AIA".
|
|
112
|
-
*/
|
|
113
|
-
private class DerReader(private val buf: ByteArray) {
|
|
114
|
-
private var pos = 0
|
|
115
|
-
|
|
116
|
-
fun hasNext(): Boolean = pos < buf.size
|
|
117
|
-
|
|
118
|
-
fun read(): Tlv {
|
|
119
|
-
val tag = buf[pos++].toInt() and 0xFF
|
|
120
|
-
var len = buf[pos++].toInt() and 0xFF
|
|
121
|
-
if (len and 0x80 != 0) {
|
|
122
|
-
val numBytes = len and 0x7F
|
|
123
|
-
len = 0
|
|
124
|
-
repeat(numBytes) { len = (len shl 8) or (buf[pos++].toInt() and 0xFF) }
|
|
125
|
-
}
|
|
126
|
-
val tlv = Tlv(buf, tag, pos, len)
|
|
127
|
-
pos += len
|
|
128
|
-
return tlv
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
/** A parsed tag-length-value: the tag and a view of its content bytes. */
|
|
133
|
-
private class Tlv(
|
|
134
|
-
private val buf: ByteArray,
|
|
135
|
-
val tag: Int,
|
|
136
|
-
private val offset: Int,
|
|
137
|
-
private val length: Int,
|
|
138
|
-
) {
|
|
139
|
-
fun content(): ByteArray = buf.copyOfRange(offset, offset + length)
|
|
140
|
-
}
|
|
141
|
-
}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
package com.audiobrowser.tls
|
|
2
|
-
|
|
3
|
-
import java.security.cert.CertificateException
|
|
4
|
-
import java.security.cert.X509Certificate
|
|
5
|
-
import javax.net.ssl.X509TrustManager
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* An [X509TrustManager] that retries validation after filling in missing intermediate certificates
|
|
9
|
-
* via the leaf's Authority Information Access (AIA) "CA Issuers" pointer.
|
|
10
|
-
*
|
|
11
|
-
* Wraps a [delegate] (typically the platform default trust manager). On the happy path the delegate
|
|
12
|
-
* accepts the server-presented chain on the first try and this adds nothing. Only when the delegate
|
|
13
|
-
* rejects the chain does it attempt AIA chasing — and the *completed* chain is still validated by
|
|
14
|
-
* the same delegate against the system trust anchors, so trust can never be weakened: an untrusted
|
|
15
|
-
* root still fails. See [AiaCertChaser].
|
|
16
|
-
*/
|
|
17
|
-
class AiaChasingTrustManager(
|
|
18
|
-
private val delegate: X509TrustManager,
|
|
19
|
-
private val fetch: (url: String) -> List<X509Certificate>,
|
|
20
|
-
) : X509TrustManager {
|
|
21
|
-
|
|
22
|
-
override fun checkServerTrusted(chain: Array<X509Certificate>, authType: String) {
|
|
23
|
-
try {
|
|
24
|
-
delegate.checkServerTrusted(chain, authType)
|
|
25
|
-
} catch (original: CertificateException) {
|
|
26
|
-
val completed = AiaCertChaser.completeChain(chain.toList(), fetch = fetch)
|
|
27
|
-
// Nothing could be added — the original failure stands (don't re-check an unchanged chain).
|
|
28
|
-
if (completed.size == chain.size) throw original
|
|
29
|
-
delegate.checkServerTrusted(completed.toTypedArray(), authType)
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
override fun checkClientTrusted(chain: Array<X509Certificate>, authType: String) =
|
|
34
|
-
delegate.checkClientTrusted(chain, authType)
|
|
35
|
-
|
|
36
|
-
override fun getAcceptedIssuers(): Array<X509Certificate> = delegate.acceptedIssuers
|
|
37
|
-
}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
package com.audiobrowser.tls
|
|
2
|
-
|
|
3
|
-
import java.security.KeyStore
|
|
4
|
-
import javax.net.ssl.SSLContext
|
|
5
|
-
import javax.net.ssl.SSLSocketFactory
|
|
6
|
-
import javax.net.ssl.TrustManagerFactory
|
|
7
|
-
import javax.net.ssl.X509TrustManager
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Builds TLS components that recover from servers which omit intermediate CA certificates, by
|
|
11
|
-
* following the leaf's Authority Information Access (AIA) "CA Issuers" pointer — the behaviour
|
|
12
|
-
* Apple's Secure Transport has by default but Android's lacks.
|
|
13
|
-
*
|
|
14
|
-
* The returned components are side-effect-free: they wrap the platform default trust manager and
|
|
15
|
-
* only ever *add* a missing intermediate before re-validating against the same system trust
|
|
16
|
-
* anchors, so they cannot weaken trust. Installing them as a process default (e.g.
|
|
17
|
-
* `HttpsURLConnection.setDefaultSSLSocketFactory(AiaTls.socketFactory())`) is the caller's
|
|
18
|
-
* decision.
|
|
19
|
-
*/
|
|
20
|
-
object AiaTls {
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* An [SSLSocketFactory] whose handshake validation chases missing intermediates via AIA. Intended
|
|
24
|
-
* to be built once (e.g. installed as the process default at startup); each call gets its own
|
|
25
|
-
* fetched-intermediate cache.
|
|
26
|
-
*/
|
|
27
|
-
fun socketFactory(): SSLSocketFactory =
|
|
28
|
-
SSLContext.getInstance("TLS").apply { init(null, arrayOf(trustManager()), null) }.socketFactory
|
|
29
|
-
|
|
30
|
-
/** An [X509TrustManager] wrapping the platform default with AIA intermediate chasing. */
|
|
31
|
-
fun trustManager(): X509TrustManager {
|
|
32
|
-
val fetcher = CachingCertificateFetcher()
|
|
33
|
-
return AiaChasingTrustManager(systemTrustManager()) { fetcher.fetch(it) }
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
private fun systemTrustManager(): X509TrustManager {
|
|
37
|
-
val factory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm())
|
|
38
|
-
factory.init(null as KeyStore?)
|
|
39
|
-
return factory.trustManagers.filterIsInstance<X509TrustManager>().first()
|
|
40
|
-
}
|
|
41
|
-
}
|
|
@@ -1,209 +0,0 @@
|
|
|
1
|
-
package com.audiobrowser.tls
|
|
2
|
-
|
|
3
|
-
import java.io.ByteArrayInputStream
|
|
4
|
-
import java.io.ByteArrayOutputStream
|
|
5
|
-
import java.net.InetSocketAddress
|
|
6
|
-
import java.net.Socket
|
|
7
|
-
import java.net.URL
|
|
8
|
-
import java.security.cert.CertificateFactory
|
|
9
|
-
import java.security.cert.X509Certificate
|
|
10
|
-
import java.util.concurrent.ConcurrentHashMap
|
|
11
|
-
import javax.net.ssl.HttpsURLConnection
|
|
12
|
-
import javax.net.ssl.SSLContext
|
|
13
|
-
import javax.net.ssl.SSLSocketFactory
|
|
14
|
-
import timber.log.Timber
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Fetches and caches issuer certificates from AIA "CA Issuers" URLs. Used by
|
|
18
|
-
* [AiaChasingTrustManager] to fill in intermediates a server failed to send.
|
|
19
|
-
*
|
|
20
|
-
* Runs on the TLS handshake thread, so it uses short timeouts and never throws — a failed or slow
|
|
21
|
-
* fetch resolves to an empty list (the handshake then fails exactly as it would have without AIA
|
|
22
|
-
* chasing). Only non-empty results are cached, so the (typically `http`) round-trip happens at most
|
|
23
|
-
* once per intermediate for the process lifetime while transient failures stay retryable.
|
|
24
|
-
*
|
|
25
|
-
* `http` fetches go over a raw [Socket] rather than `HttpURLConnection`. CA "CA Issuers" URLs are
|
|
26
|
-
* virtually always plain `http` (the CA/Browser Forum Baseline Requirements mandate it, to avoid a
|
|
27
|
-
* chicken-and-egg TLS dependency when fetching the cert needed to complete a TLS chain), but
|
|
28
|
-
* Android blocks cleartext `HttpURLConnection` traffic by default on apps targeting API 28+. A raw
|
|
29
|
-
* socket is not subject to `NetworkSecurityPolicy`, so the fetch succeeds regardless of the host
|
|
30
|
-
* app's cleartext setting — safely, because the fetched certificate is still cryptographically
|
|
31
|
-
* verified to be the real issuer before [AiaChasingTrustManager] trusts it.
|
|
32
|
-
*/
|
|
33
|
-
class CachingCertificateFetcher(
|
|
34
|
-
private val connectTimeoutMs: Int = 5_000,
|
|
35
|
-
private val readTimeoutMs: Int = 5_000,
|
|
36
|
-
) {
|
|
37
|
-
private val cache = ConcurrentHashMap<String, List<X509Certificate>>()
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* A plain system-default socket factory for `https` AIA fetches. Without it the fetch would use
|
|
41
|
-
* the process default — which, once this library's AIA factory is installed there, would recurse
|
|
42
|
-
* into AIA chasing during the fetch's own handshake.
|
|
43
|
-
*/
|
|
44
|
-
private val plainSslSocketFactory: SSLSocketFactory by lazy {
|
|
45
|
-
SSLContext.getInstance("TLS").apply { init(null, null, null) }.socketFactory
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
fun fetch(url: String): List<X509Certificate> {
|
|
49
|
-
cache[url]?.let {
|
|
50
|
-
return it
|
|
51
|
-
}
|
|
52
|
-
val certs = download(url)?.let { parseCertificates(it) }.orEmpty()
|
|
53
|
-
if (certs.isNotEmpty()) cache[url] = certs
|
|
54
|
-
return certs
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
private fun download(url: String, redirectsLeft: Int = MAX_REDIRECTS): ByteArray? =
|
|
58
|
-
try {
|
|
59
|
-
val parsed = URL(url)
|
|
60
|
-
when (parsed.protocol) {
|
|
61
|
-
"http" -> downloadCleartext(parsed, redirectsLeft)
|
|
62
|
-
"https" -> downloadHttps(parsed)
|
|
63
|
-
else -> null // restrict to http/https — file:, ftp: etc. are never valid CA-issuer sources
|
|
64
|
-
}
|
|
65
|
-
} catch (e: Exception) {
|
|
66
|
-
Timber.w(e, "AIA CA-issuer fetch failed: %s", url)
|
|
67
|
-
null
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* `https` AIA fetch over the platform HTTP stack. `https` is never subject to Android's cleartext
|
|
72
|
-
* policy, so `HttpsURLConnection` is fine here; the plain socket factory keeps the fetch's own
|
|
73
|
-
* handshake from recursing into AIA chasing.
|
|
74
|
-
*/
|
|
75
|
-
private fun downloadHttps(url: URL): ByteArray? {
|
|
76
|
-
val connection = url.openConnection() as? HttpsURLConnection ?: return null
|
|
77
|
-
connection.connectTimeout = connectTimeoutMs
|
|
78
|
-
connection.readTimeout = readTimeoutMs
|
|
79
|
-
connection.sslSocketFactory = plainSslSocketFactory
|
|
80
|
-
return connection.inputStream.use { it.readBytes() }
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* `http` AIA fetch over a raw socket — see the class doc for why this bypasses
|
|
85
|
-
* `HttpURLConnection`.
|
|
86
|
-
*/
|
|
87
|
-
private fun downloadCleartext(url: URL, redirectsLeft: Int): ByteArray? {
|
|
88
|
-
val host = url.host
|
|
89
|
-
val port = if (url.port != -1) url.port else 80
|
|
90
|
-
val path = url.file.ifEmpty { "/" } // URL.file is path + query
|
|
91
|
-
val raw =
|
|
92
|
-
Socket().use { socket ->
|
|
93
|
-
socket.connect(InetSocketAddress(host, port), connectTimeoutMs)
|
|
94
|
-
socket.soTimeout = readTimeoutMs
|
|
95
|
-
// HTTP/1.0 + `Connection: close` so the server closes after the body and we can read to EOF
|
|
96
|
-
// without parsing Content-Length.
|
|
97
|
-
val request =
|
|
98
|
-
"GET $path HTTP/1.0\r\n" +
|
|
99
|
-
"Host: $host\r\n" +
|
|
100
|
-
"Connection: close\r\n" +
|
|
101
|
-
"User-Agent: react-native-audio-browser\r\n" +
|
|
102
|
-
"Accept: */*\r\n\r\n"
|
|
103
|
-
socket.getOutputStream().apply {
|
|
104
|
-
write(request.toByteArray(Charsets.ISO_8859_1))
|
|
105
|
-
flush()
|
|
106
|
-
}
|
|
107
|
-
socket.getInputStream().use { it.readBytes() }
|
|
108
|
-
}
|
|
109
|
-
val response = parseHttpResponse(raw) ?: return null
|
|
110
|
-
return when {
|
|
111
|
-
response.status in 200..299 -> response.body
|
|
112
|
-
response.status in 300..399 && response.location != null && redirectsLeft > 0 ->
|
|
113
|
-
// Follow CA-issuer redirects (rare). A redirect to `https` falls through to the https path.
|
|
114
|
-
download(URL(url, response.location).toString(), redirectsLeft - 1)
|
|
115
|
-
else -> null
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
companion object {
|
|
120
|
-
private const val MAX_REDIRECTS = 5
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* Parses every certificate from the bytes a CA-Issuers URL serves — a single DER certificate
|
|
124
|
-
* (e.g. Let's Encrypt), a PEM file, or a PKCS#7 "certs-only" bundle. Empty if the bytes are not
|
|
125
|
-
* parseable certificates.
|
|
126
|
-
*/
|
|
127
|
-
fun parseCertificates(bytes: ByteArray): List<X509Certificate> =
|
|
128
|
-
try {
|
|
129
|
-
CertificateFactory.getInstance("X.509")
|
|
130
|
-
.generateCertificates(ByteArrayInputStream(bytes))
|
|
131
|
-
.filterIsInstance<X509Certificate>()
|
|
132
|
-
} catch (e: Exception) {
|
|
133
|
-
emptyList()
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
/** Status code, `Location` header (if any), and decoded body of a raw HTTP response. */
|
|
137
|
-
data class HttpResponse(val status: Int, val location: String?, val body: ByteArray)
|
|
138
|
-
|
|
139
|
-
/**
|
|
140
|
-
* Splits a raw HTTP/1.0 response into its status code, `Location` header, and body, decoding a
|
|
141
|
-
* `Transfer-Encoding: chunked` body if present. Returns null if the bytes are not a
|
|
142
|
-
* recognisable HTTP response.
|
|
143
|
-
*/
|
|
144
|
-
fun parseHttpResponse(raw: ByteArray): HttpResponse? {
|
|
145
|
-
val headerEnd = indexOfCrlfCrlf(raw)
|
|
146
|
-
if (headerEnd < 0) return null
|
|
147
|
-
val lines = String(raw, 0, headerEnd, Charsets.ISO_8859_1).split("\r\n")
|
|
148
|
-
// Status line: "HTTP/1.1 200 OK" — the code is the second token.
|
|
149
|
-
val status = lines.firstOrNull()?.split(' ')?.getOrNull(1)?.toIntOrNull() ?: return null
|
|
150
|
-
var location: String? = null
|
|
151
|
-
var chunked = false
|
|
152
|
-
for (i in 1 until lines.size) {
|
|
153
|
-
val colon = lines[i].indexOf(':')
|
|
154
|
-
if (colon < 0) continue
|
|
155
|
-
val name = lines[i].substring(0, colon).trim().lowercase()
|
|
156
|
-
val value = lines[i].substring(colon + 1).trim()
|
|
157
|
-
when (name) {
|
|
158
|
-
"location" -> location = value
|
|
159
|
-
"transfer-encoding" -> if (value.lowercase().contains("chunked")) chunked = true
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
val body = raw.copyOfRange(headerEnd + 4, raw.size)
|
|
163
|
-
return HttpResponse(status, location, if (chunked) dechunk(body) else body)
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
private fun dechunk(body: ByteArray): ByteArray {
|
|
167
|
-
val out = ByteArrayOutputStream()
|
|
168
|
-
var pos = 0
|
|
169
|
-
while (pos < body.size) {
|
|
170
|
-
val eol = indexOfCrlf(body, pos)
|
|
171
|
-
if (eol < 0) break
|
|
172
|
-
// chunk-size line may carry a `;chunk-extension` suffix; the size is hex before the `;`.
|
|
173
|
-
val size =
|
|
174
|
-
String(body, pos, eol - pos, Charsets.ISO_8859_1)
|
|
175
|
-
.substringBefore(';')
|
|
176
|
-
.trim()
|
|
177
|
-
.toIntOrNull(16) ?: break
|
|
178
|
-
if (size == 0) break // last chunk
|
|
179
|
-
val dataStart = eol + 2
|
|
180
|
-
if (dataStart + size > body.size) break
|
|
181
|
-
out.write(body, dataStart, size)
|
|
182
|
-
pos = dataStart + size + 2 // skip the chunk data and its trailing CRLF
|
|
183
|
-
}
|
|
184
|
-
return out.toByteArray()
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
private fun indexOfCrlfCrlf(bytes: ByteArray): Int {
|
|
188
|
-
var i = 0
|
|
189
|
-
while (i + 3 < bytes.size) {
|
|
190
|
-
if (bytes[i] == CR && bytes[i + 1] == LF && bytes[i + 2] == CR && bytes[i + 3] == LF)
|
|
191
|
-
return i
|
|
192
|
-
i++
|
|
193
|
-
}
|
|
194
|
-
return -1
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
private fun indexOfCrlf(bytes: ByteArray, from: Int): Int {
|
|
198
|
-
var i = from
|
|
199
|
-
while (i + 1 < bytes.size) {
|
|
200
|
-
if (bytes[i] == CR && bytes[i + 1] == LF) return i
|
|
201
|
-
i++
|
|
202
|
-
}
|
|
203
|
-
return -1
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
private const val CR = '\r'.code.toByte()
|
|
207
|
-
private const val LF = '\n'.code.toByte()
|
|
208
|
-
}
|
|
209
|
-
}
|
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
package com.audiobrowser.util
|
|
2
|
-
|
|
3
|
-
import android.content.ContentProvider
|
|
4
|
-
import android.content.ContentValues
|
|
5
|
-
import android.database.Cursor
|
|
6
|
-
import android.graphics.Bitmap
|
|
7
|
-
import android.net.Uri
|
|
8
|
-
import android.os.ParcelFileDescriptor
|
|
9
|
-
import com.audiobrowser.browser.ResolvedArtwork
|
|
10
|
-
import java.io.File
|
|
11
|
-
import java.io.IOException
|
|
12
|
-
import java.util.concurrent.Semaphore
|
|
13
|
-
import java.util.concurrent.TimeUnit
|
|
14
|
-
import kotlinx.coroutines.runBlocking
|
|
15
|
-
import kotlinx.coroutines.withTimeout
|
|
16
|
-
import timber.log.Timber
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Exported, token-gated provider serving browse artwork to Android Auto / AAOS (which run in a
|
|
20
|
-
* different uid and cannot read a non-exported provider; Media3 issues no URI grant — verified). It
|
|
21
|
-
* NEVER fetches a caller-supplied URL: the content URI carries an opaque token, looked up in
|
|
22
|
-
* [com.audiobrowser.browser.BrowseArtworkRegistry]; an unknown token returns null. So it cannot be
|
|
23
|
-
* used as a fetch proxy / SSRF vector. http(s)-only on the registered finalUrl is defense-in-depth.
|
|
24
|
-
*
|
|
25
|
-
* Serve design: a real on-disk file via [ParcelFileDescriptor.open] — seekable, no pipe, no writer
|
|
26
|
-
* coroutine. The file is keyed by SHA-256 token so identical URLs always reuse the same file.
|
|
27
|
-
*
|
|
28
|
-
* Bug fixes over the previous pipe/coroutine design: B (FD leak): eliminated — no coroutine
|
|
29
|
-
* launched from deps.scope; no writer that could fail to close the write-end of a pipe when the
|
|
30
|
-
* scope is already cancelled. C (wedge DoS): eliminated — the Semaphore permit is released in a
|
|
31
|
-
* try/finally BEFORE the file is opened for the caller; no blocking write to a pipe while holding
|
|
32
|
-
* the permit. D (per-request re-encode): eliminated — on-disk file IS the cache; re-requests are a
|
|
33
|
-
* cheap file open (fast path, zero decode, zero network). E (non-seekable pipe): eliminated —
|
|
34
|
-
* ParcelFileDescriptor.open returns a regular file FD; statSize is valid; the car's image loader
|
|
35
|
-
* can seek.
|
|
36
|
-
*/
|
|
37
|
-
class ArtworkContentProvider : ContentProvider() {
|
|
38
|
-
|
|
39
|
-
// java.util.concurrent.Semaphore — works on binder threads without a coroutine scope.
|
|
40
|
-
private val gate = Semaphore(MAX_CONCURRENT)
|
|
41
|
-
|
|
42
|
-
override fun onCreate(): Boolean = true
|
|
43
|
-
|
|
44
|
-
override fun getType(uri: Uri): String = "image/png"
|
|
45
|
-
|
|
46
|
-
override fun openFile(uri: Uri, mode: String): ParcelFileDescriptor? {
|
|
47
|
-
val token = ArtworkUris.parseToken(uri) ?: return null
|
|
48
|
-
val deps = CoilArtworkLoaderHolder.get() ?: return null
|
|
49
|
-
val art: ResolvedArtwork = deps.registry.lookup(token) ?: return null
|
|
50
|
-
val scheme = Uri.parse(art.finalUrl).scheme?.lowercase()
|
|
51
|
-
if (scheme != "http" && scheme != "https") return null
|
|
52
|
-
|
|
53
|
-
val artworkDir = File(context!!.cacheDir, ARTWORK_SUBDIR)
|
|
54
|
-
val file = File(artworkDir, "$token.png")
|
|
55
|
-
|
|
56
|
-
// Fast path: file already cached on disk — no permit, no decode, no network.
|
|
57
|
-
if (file.exists() && file.length() > 0) {
|
|
58
|
-
return try {
|
|
59
|
-
ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY)
|
|
60
|
-
} catch (e: Throwable) {
|
|
61
|
-
Timber.w(e, "Artwork fast-path open failed for token=$token")
|
|
62
|
-
null
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// Produce path (cache miss): bound concurrency, block on binder thread (UAMP pattern).
|
|
67
|
-
if (!gate.tryAcquire(1, GATE_TIMEOUT_SECONDS, TimeUnit.SECONDS)) {
|
|
68
|
-
Timber.w("Artwork gate timeout for token=$token — returning null")
|
|
69
|
-
return null
|
|
70
|
-
}
|
|
71
|
-
try {
|
|
72
|
-
// Re-check after acquiring — a concurrent producer may have written the file.
|
|
73
|
-
if (file.exists() && file.length() > 0) {
|
|
74
|
-
val fd =
|
|
75
|
-
try {
|
|
76
|
-
ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY)
|
|
77
|
-
} catch (e: Throwable) {
|
|
78
|
-
Timber.w(e, "Artwork cache file vanished before re-check open; producing")
|
|
79
|
-
null
|
|
80
|
-
}
|
|
81
|
-
if (fd != null) return fd
|
|
82
|
-
// else: file was pruned/deleted concurrently — fall through to produce
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
artworkDir.mkdirs()
|
|
86
|
-
val tmp = File.createTempFile(token, ".png.tmp", artworkDir)
|
|
87
|
-
|
|
88
|
-
val bitmap: Bitmap =
|
|
89
|
-
try {
|
|
90
|
-
runBlocking {
|
|
91
|
-
withTimeout(LOAD_TIMEOUT_MS) {
|
|
92
|
-
deps.loader.load(art.finalUrl, art.headers, deps.artworkSizeHint(), art.isSvg)
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
} catch (e: Throwable) {
|
|
96
|
-
Timber.w(e, "Artwork load failed for token=$token")
|
|
97
|
-
tmp.delete()
|
|
98
|
-
return null
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
try {
|
|
102
|
-
val ok =
|
|
103
|
-
tmp.outputStream().use { out -> bitmap.compress(Bitmap.CompressFormat.PNG, 100, out) }
|
|
104
|
-
if (!ok) throw IOException("PNG encode failed for token=$token")
|
|
105
|
-
if (!tmp.renameTo(file)) {
|
|
106
|
-
Timber.w("Artwork rename failed for token=$token")
|
|
107
|
-
tmp.delete()
|
|
108
|
-
return null
|
|
109
|
-
}
|
|
110
|
-
pruneCache(artworkDir)
|
|
111
|
-
} catch (e: Throwable) {
|
|
112
|
-
Timber.w(e, "Artwork write failed for token=$token")
|
|
113
|
-
tmp.delete()
|
|
114
|
-
return null
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
return try {
|
|
118
|
-
ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY)
|
|
119
|
-
} catch (e: Throwable) {
|
|
120
|
-
Timber.w(e, "Artwork final open failed for token=$token")
|
|
121
|
-
null
|
|
122
|
-
}
|
|
123
|
-
} finally {
|
|
124
|
-
gate.release()
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
override fun query(
|
|
129
|
-
uri: Uri,
|
|
130
|
-
p: Array<String>?,
|
|
131
|
-
s: String?,
|
|
132
|
-
a: Array<String>?,
|
|
133
|
-
o: String?,
|
|
134
|
-
): Cursor? = null
|
|
135
|
-
|
|
136
|
-
override fun insert(uri: Uri, values: ContentValues?): Uri? = null
|
|
137
|
-
|
|
138
|
-
override fun update(uri: Uri, v: ContentValues?, s: String?, a: Array<String>?): Int = 0
|
|
139
|
-
|
|
140
|
-
override fun delete(uri: Uri, s: String?, a: Array<String>?): Int = 0
|
|
141
|
-
|
|
142
|
-
companion object {
|
|
143
|
-
private const val MAX_CONCURRENT = 6
|
|
144
|
-
private const val GATE_TIMEOUT_SECONDS = 5L
|
|
145
|
-
private const val LOAD_TIMEOUT_MS = 8_000L
|
|
146
|
-
internal const val ARTWORK_SUBDIR = "audiobrowser-artwork"
|
|
147
|
-
const val MAX_CACHE_FILES = 512
|
|
148
|
-
/** Overridable in tests only. Production code must not change this. */
|
|
149
|
-
@JvmField internal var maxCacheFilesOverride: Int? = null
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
private fun pruneCache(dir: File) {
|
|
153
|
-
val limit = maxCacheFilesOverride ?: MAX_CACHE_FILES
|
|
154
|
-
val files = dir.listFiles { f -> f.isFile && f.name.endsWith(".png") } ?: return
|
|
155
|
-
if (files.size <= limit) return
|
|
156
|
-
files
|
|
157
|
-
.sortedBy { it.lastModified() }
|
|
158
|
-
.take(files.size - limit)
|
|
159
|
-
.forEach { runCatching { it.delete() } }
|
|
160
|
-
}
|
|
161
|
-
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
package com.audiobrowser.util
|
|
2
|
-
|
|
3
|
-
import android.net.Uri
|
|
4
|
-
import java.security.MessageDigest
|
|
5
|
-
|
|
6
|
-
/** Builds and parses the opaque `content://<pkg>.audiobrowser.artwork/art/<token>` URIs. */
|
|
7
|
-
object ArtworkUris {
|
|
8
|
-
const val AUTHORITY_SUFFIX = "audiobrowser.artwork"
|
|
9
|
-
private const val PATH = "art"
|
|
10
|
-
|
|
11
|
-
fun authorityFor(packageName: String): String = "$packageName.$AUTHORITY_SUFFIX"
|
|
12
|
-
|
|
13
|
-
/** Stable, opaque token for a resolved artwork URL (SHA-256 hex). */
|
|
14
|
-
fun tokenFor(url: String): String {
|
|
15
|
-
val digest = MessageDigest.getInstance("SHA-256").digest(url.toByteArray(Charsets.UTF_8))
|
|
16
|
-
return digest.joinToString("") { "%02x".format(it) }
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
fun contentUri(authority: String, token: String): String = "content://$authority/$PATH/$token"
|
|
20
|
-
|
|
21
|
-
/** The `<token>` for a `…/art/<token>` content URI, or null if the shape is wrong. */
|
|
22
|
-
fun parseToken(uri: Uri): String? {
|
|
23
|
-
if (uri.scheme != "content") return null
|
|
24
|
-
val segments = uri.pathSegments
|
|
25
|
-
if (segments.size != 2 || segments[0] != PATH) return null
|
|
26
|
-
return segments[1].takeIf { it.isNotEmpty() }
|
|
27
|
-
}
|
|
28
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
package com.audiobrowser.util
|
|
2
|
-
|
|
3
|
-
import com.margelo.nitro.audiobrowser.Variant_String_ArtworkVariants
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Reading `Track.artwork`, which is either one URL or a URL per appearance.
|
|
7
|
-
*
|
|
8
|
-
* Android Auto is dark-only, so there is nothing here to choose: a pair always resolves to its dark
|
|
9
|
-
* URL, which is also what a single-URL track would have shipped. The per-appearance half of the
|
|
10
|
-
* feature is iOS/CarPlay only — see `ios/Extension/Variant+Artwork.swift`, where both URLs are kept
|
|
11
|
-
* so a `UIImageAsset` can swap them without a re-fetch.
|
|
12
|
-
*/
|
|
13
|
-
val Variant_String_ArtworkVariants.url: String
|
|
14
|
-
get() = match(first = { it }, second = { it.dark })
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Wraps a plain URL as the single-URL side of the union.
|
|
18
|
-
*
|
|
19
|
-
* For the places that build a `Track` from something that only ever has one image — restored
|
|
20
|
-
* persistence, a `MediaMetadata` handed back by the platform. Restoring collapses a pair to its
|
|
21
|
-
* dark URL, which costs nothing here: Android Auto would have rendered that one anyway.
|
|
22
|
-
*/
|
|
23
|
-
fun artworkOf(url: String?): Variant_String_ArtworkVariants? =
|
|
24
|
-
url?.let { Variant_String_ArtworkVariants.First(it) }
|