react-native-queue-player 1.1.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -762,8 +762,15 @@ class PlaybackService : HeadlessJsMediaService() {
|
|
|
762
762
|
* (the same one ExoPlayer drives for HTTP playback), so consumer
|
|
763
763
|
* `userAgent` + custom HTTP headers configured on the player's
|
|
764
764
|
* `MediaSource.Factory` propagate into artwork fetches without a
|
|
765
|
-
* second HTTP client.
|
|
766
|
-
*
|
|
765
|
+
* second HTTP client. It mirrors Media3's own default loader config:
|
|
766
|
+
* `setMaximumOutputDimension(MediaSession.getBitmapDimensionLimit(...))`
|
|
767
|
+
* downsamples an oversized consumer image during decode (device-adaptive
|
|
768
|
+
* cap; no full-resolution bitmap for a small control), and
|
|
769
|
+
* `setMakeShared(true)` puts the bitmap in shared memory so the System UI
|
|
770
|
+
* process reuses it instead of copying. Supplying our own loader (for the
|
|
771
|
+
* placeholder guarantee below) had otherwise dropped both defaults, which
|
|
772
|
+
* is what left artwork decoding unbounded. `CacheBitmapLoader` deduplicates
|
|
773
|
+
* repeat requests for the same URI inside a single foreground session.
|
|
767
774
|
* The outer [PlaceholderFallbackBitmapLoader] guarantees a bitmap
|
|
768
775
|
* always reaches the notification — the OEM-skin failure mode
|
|
769
776
|
* where a null bitmap drops the transport controls is closed.
|
|
@@ -776,7 +783,12 @@ class PlaybackService : HeadlessJsMediaService() {
|
|
|
776
783
|
@VisibleForTesting
|
|
777
784
|
internal fun buildBitmapLoader(): PlaceholderFallbackBitmapLoader =
|
|
778
785
|
PlaceholderFallbackBitmapLoader(
|
|
779
|
-
delegate = CacheBitmapLoader(
|
|
786
|
+
delegate = CacheBitmapLoader(
|
|
787
|
+
DataSourceBitmapLoader.Builder(this)
|
|
788
|
+
.setMaximumOutputDimension(MediaSession.getBitmapDimensionLimit(this))
|
|
789
|
+
.setMakeShared(true)
|
|
790
|
+
.build()
|
|
791
|
+
),
|
|
780
792
|
// Read on each fallback so a placeholder set at `configure` (after
|
|
781
793
|
// this loader was built in onCreate) is reflected — `PlaceholderArtwork`
|
|
782
794
|
// returns the consumer image when one is configured, else the built-in.
|
package/android/src/test/java/com/margelo/nitro/queueplayer/PlaybackServiceArtworkLoaderTest.kt
CHANGED
|
@@ -3,7 +3,9 @@ package com.margelo.nitro.queueplayer
|
|
|
3
3
|
import androidx.media3.common.util.UnstableApi
|
|
4
4
|
import androidx.media3.datasource.DataSourceBitmapLoader
|
|
5
5
|
import androidx.media3.session.CacheBitmapLoader
|
|
6
|
+
import androidx.media3.session.MediaSession
|
|
6
7
|
import org.junit.After
|
|
8
|
+
import org.junit.Assert.assertEquals
|
|
7
9
|
import org.junit.Assert.assertNotNull
|
|
8
10
|
import org.junit.Assert.assertSame
|
|
9
11
|
import org.junit.Assert.assertTrue
|
|
@@ -78,6 +80,32 @@ class PlaybackServiceArtworkLoaderTest {
|
|
|
78
80
|
)
|
|
79
81
|
}
|
|
80
82
|
|
|
83
|
+
@Test
|
|
84
|
+
fun `DataSourceBitmapLoader mirrors Media3's default cap + shared-memory bitmap`() {
|
|
85
|
+
val loader = service.buildBitmapLoader()
|
|
86
|
+
val cached = loader.javaClass.getDeclaredField("delegate")
|
|
87
|
+
.apply { isAccessible = true }.get(loader) as CacheBitmapLoader
|
|
88
|
+
val backing = cached.javaClass.getDeclaredField("bitmapLoader")
|
|
89
|
+
.apply { isAccessible = true }.get(cached) as DataSourceBitmapLoader
|
|
90
|
+
val maxDim = DataSourceBitmapLoader::class.java
|
|
91
|
+
.getDeclaredField("maximumOutputDimension")
|
|
92
|
+
.apply { isAccessible = true }
|
|
93
|
+
.getInt(backing)
|
|
94
|
+
assertEquals(
|
|
95
|
+
"artwork decode is capped to Media3's device-adaptive limit (no full-res allocation)",
|
|
96
|
+
MediaSession.getBitmapDimensionLimit(service),
|
|
97
|
+
maxDim
|
|
98
|
+
)
|
|
99
|
+
val makeShared = DataSourceBitmapLoader::class.java
|
|
100
|
+
.getDeclaredField("makeShared")
|
|
101
|
+
.apply { isAccessible = true }
|
|
102
|
+
.getBoolean(backing)
|
|
103
|
+
assertTrue(
|
|
104
|
+
"decoded bitmap is shared-memory so the System UI process reuses it instead of copying",
|
|
105
|
+
makeShared
|
|
106
|
+
)
|
|
107
|
+
}
|
|
108
|
+
|
|
81
109
|
@Test
|
|
82
110
|
fun `repeat builds reuse the same placeholder bitmap`() {
|
|
83
111
|
// The loader holds a placeholder *provider* closure; invoking it
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-queue-player",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"description": "Nitro Modules audio playback library for React Native — gapless, EQ, crossfade, automotive, voice, casting",
|
|
5
5
|
"main": "./lib/module/index.js",
|
|
6
6
|
"types": "./lib/typescript/index.d.ts",
|