mirror of
https://github.com/Boof2015/astra-mobile.git
synced 2026-08-12 05:10:52 +02:00
487 lines
18 KiB
Diff
487 lines
18 KiB
Diff
diff --git a/node_modules/react-native-track-player/android/src/main/java/com/doublesymmetry/trackplayer/module/MusicModule.kt b/node_modules/react-native-track-player/android/src/main/java/com/doublesymmetry/trackplayer/module/MusicModule.kt
|
|
index b2409a0..4491bad 100644
|
|
--- a/node_modules/react-native-track-player/android/src/main/java/com/doublesymmetry/trackplayer/module/MusicModule.kt
|
|
+++ b/node_modules/react-native-track-player/android/src/main/java/com/doublesymmetry/trackplayer/module/MusicModule.kt
|
|
@@ -18,9 +18,11 @@ import com.doublesymmetry.trackplayer.utils.RejectionException
|
|
import com.facebook.react.bridge.*
|
|
import com.google.android.exoplayer2.DefaultLoadControl.*
|
|
import com.google.android.exoplayer2.Player
|
|
+import kotlinx.coroutines.Dispatchers
|
|
import kotlinx.coroutines.MainScope
|
|
import kotlinx.coroutines.delay
|
|
import kotlinx.coroutines.launch
|
|
+import kotlinx.coroutines.withContext
|
|
import timber.log.Timber
|
|
import java.util.*
|
|
import javax.annotation.Nonnull
|
|
@@ -169,8 +171,12 @@ class MusicModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaM
|
|
return
|
|
}
|
|
|
|
+ val bundledData = Arguments.toBundle(data)
|
|
+ val androidOptions = bundledData?.getBundle(MusicService.ANDROID_OPTIONS_KEY)
|
|
+ val allowBackgroundSetup = androidOptions?.getBoolean("allowBackgroundSetup") ?: false
|
|
+
|
|
// prevent crash Fatal Exception: android.app.RemoteServiceException$ForegroundServiceDidNotStartInTimeException
|
|
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && AppForegroundTracker.backgrounded) {
|
|
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && AppForegroundTracker.backgrounded && !allowBackgroundSetup) {
|
|
promise.reject(
|
|
"android_cannot_setup_player_in_background",
|
|
"On Android the app must be in the foreground when setting up the player."
|
|
@@ -179,7 +185,6 @@ class MusicModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaM
|
|
}
|
|
|
|
// Validate buffer keys.
|
|
- val bundledData = Arguments.toBundle(data)
|
|
val minBuffer =
|
|
bundledData?.getDouble(MusicService.MIN_BUFFER_KEY)?.toMilliseconds()?.toInt()
|
|
?: DEFAULT_MIN_BUFFER_MS
|
|
@@ -251,7 +256,7 @@ class MusicModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaM
|
|
}
|
|
|
|
@ReactMethod
|
|
- fun updateOptions(data: ReadableMap?, callback: Promise) = scope.launch {
|
|
+ fun updateOptions(data: ReadableMap?, callback: Promise) { scope.launch {
|
|
if (verifyServiceBoundOrReject(callback)) return@launch
|
|
|
|
val options = Arguments.toBundle(data)
|
|
@@ -262,13 +267,16 @@ class MusicModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaM
|
|
|
|
callback.resolve(null)
|
|
}
|
|
+ }
|
|
|
|
@ReactMethod
|
|
- fun add(data: ReadableArray?, insertBeforeIndex: Int, callback: Promise) = scope.launch {
|
|
+ fun add(data: ReadableArray?, insertBeforeIndex: Int, callback: Promise) { scope.launch {
|
|
if (verifyServiceBoundOrReject(callback)) return@launch
|
|
|
|
try {
|
|
- val tracks = readableArrayToTrackList(data);
|
|
+ // Track conversion is O(queue) work (Bundle parsing, Uri resolution) —
|
|
+ // keep it off the main thread so long queues don't freeze the UI/ANR.
|
|
+ val tracks = withContext(Dispatchers.Default) { readableArrayToTrackList(data) };
|
|
if (insertBeforeIndex < -1 || insertBeforeIndex > musicService.tracks.size) {
|
|
callback.reject("index_out_of_bounds", "The track index is out of bounds")
|
|
return@launch
|
|
@@ -283,9 +291,10 @@ class MusicModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaM
|
|
rejectWithException(callback, exception)
|
|
}
|
|
}
|
|
+ }
|
|
|
|
@ReactMethod
|
|
- fun load(data: ReadableMap?, callback: Promise) = scope.launch {
|
|
+ fun load(data: ReadableMap?, callback: Promise) { scope.launch {
|
|
if (verifyServiceBoundOrReject(callback)) return@launch
|
|
if (data == null) {
|
|
callback.resolve(null)
|
|
@@ -299,16 +308,18 @@ class MusicModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaM
|
|
callback.reject("invalid_track_object", "Track was not a dictionary type")
|
|
}
|
|
}
|
|
+ }
|
|
|
|
@ReactMethod
|
|
- fun move(fromIndex: Int, toIndex: Int, callback: Promise) = scope.launch {
|
|
+ fun move(fromIndex: Int, toIndex: Int, callback: Promise) { scope.launch {
|
|
if (verifyServiceBoundOrReject(callback)) return@launch
|
|
musicService.move(fromIndex, toIndex)
|
|
callback.resolve(null)
|
|
}
|
|
+ }
|
|
|
|
@ReactMethod
|
|
- fun remove(data: ReadableArray?, callback: Promise) = scope.launch {
|
|
+ fun remove(data: ReadableArray?, callback: Promise) { scope.launch {
|
|
if (verifyServiceBoundOrReject(callback)) return@launch
|
|
val inputIndexes = Arguments.toList(data)
|
|
if (inputIndexes != null) {
|
|
@@ -329,9 +340,10 @@ class MusicModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaM
|
|
}
|
|
callback.resolve(null)
|
|
}
|
|
+ }
|
|
|
|
@ReactMethod
|
|
- fun updateMetadataForTrack(index: Int, map: ReadableMap?, callback: Promise) =
|
|
+ fun updateMetadataForTrack(index: Int, map: ReadableMap?, callback: Promise) {
|
|
scope.launch {
|
|
if (verifyServiceBoundOrReject(callback)) return@launch
|
|
|
|
@@ -346,9 +358,10 @@ class MusicModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaM
|
|
callback.resolve(null)
|
|
}
|
|
}
|
|
+ }
|
|
|
|
@ReactMethod
|
|
- fun updateNowPlayingMetadata(map: ReadableMap?, callback: Promise) = scope.launch {
|
|
+ fun updateNowPlayingMetadata(map: ReadableMap?, callback: Promise) { scope.launch {
|
|
if (verifyServiceBoundOrReject(callback)) return@launch
|
|
|
|
if (musicService.tracks.isEmpty())
|
|
@@ -362,9 +375,10 @@ class MusicModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaM
|
|
|
|
callback.resolve(null)
|
|
}
|
|
+ }
|
|
|
|
@ReactMethod
|
|
- fun clearNowPlayingMetadata(callback: Promise) = scope.launch {
|
|
+ fun clearNowPlayingMetadata(callback: Promise) { scope.launch {
|
|
if (verifyServiceBoundOrReject(callback)) return@launch
|
|
|
|
if (musicService.tracks.isEmpty())
|
|
@@ -373,17 +387,19 @@ class MusicModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaM
|
|
musicService.clearNotificationMetadata()
|
|
callback.resolve(null)
|
|
}
|
|
+ }
|
|
|
|
@ReactMethod
|
|
- fun removeUpcomingTracks(callback: Promise) = scope.launch {
|
|
+ fun removeUpcomingTracks(callback: Promise) { scope.launch {
|
|
if (verifyServiceBoundOrReject(callback)) return@launch
|
|
|
|
musicService.removeUpcomingTracks()
|
|
callback.resolve(null)
|
|
}
|
|
+ }
|
|
|
|
@ReactMethod
|
|
- fun skip(index: Int, initialTime: Float, callback: Promise) = scope.launch {
|
|
+ fun skip(index: Int, initialTime: Float, callback: Promise) { scope.launch {
|
|
if (verifyServiceBoundOrReject(callback)) return@launch
|
|
|
|
musicService.skip(index)
|
|
@@ -394,9 +410,10 @@ class MusicModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaM
|
|
|
|
callback.resolve(null)
|
|
}
|
|
+ }
|
|
|
|
@ReactMethod
|
|
- fun skipToNext(initialTime: Float, callback: Promise) = scope.launch {
|
|
+ fun skipToNext(initialTime: Float, callback: Promise) { scope.launch {
|
|
if (verifyServiceBoundOrReject(callback)) return@launch
|
|
|
|
musicService.skipToNext()
|
|
@@ -407,9 +424,10 @@ class MusicModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaM
|
|
|
|
callback.resolve(null)
|
|
}
|
|
+ }
|
|
|
|
@ReactMethod
|
|
- fun skipToPrevious(initialTime: Float, callback: Promise) = scope.launch {
|
|
+ fun skipToPrevious(initialTime: Float, callback: Promise) { scope.launch {
|
|
if (verifyServiceBoundOrReject(callback)) return@launch
|
|
|
|
musicService.skipToPrevious()
|
|
@@ -420,9 +438,10 @@ class MusicModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaM
|
|
|
|
callback.resolve(null)
|
|
}
|
|
+ }
|
|
|
|
@ReactMethod
|
|
- fun reset(callback: Promise) = scope.launch {
|
|
+ fun reset(callback: Promise) { scope.launch {
|
|
if (verifyServiceBoundOrReject(callback)) return@launch
|
|
|
|
musicService.stop()
|
|
@@ -431,188 +450,222 @@ class MusicModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaM
|
|
|
|
callback.resolve(null)
|
|
}
|
|
+ }
|
|
|
|
@ReactMethod
|
|
- fun play(callback: Promise) = scope.launch {
|
|
+ fun play(callback: Promise) { scope.launch {
|
|
if (verifyServiceBoundOrReject(callback)) return@launch
|
|
|
|
musicService.play()
|
|
callback.resolve(null)
|
|
}
|
|
+ }
|
|
|
|
@ReactMethod
|
|
- fun pause(callback: Promise) = scope.launch {
|
|
+ fun pause(callback: Promise) { scope.launch {
|
|
if (verifyServiceBoundOrReject(callback)) return@launch
|
|
|
|
musicService.pause()
|
|
callback.resolve(null)
|
|
}
|
|
+ }
|
|
+
|
|
+ @ReactMethod
|
|
+ fun setPauseAtEndOfItem(enabled: Boolean, callback: Promise) { scope.launch {
|
|
+ if (verifyServiceBoundOrReject(callback)) return@launch
|
|
+
|
|
+ musicService.setPauseAtEndOfItem(enabled)
|
|
+ callback.resolve(null)
|
|
+ }
|
|
+ }
|
|
|
|
@ReactMethod
|
|
- fun stop(callback: Promise) = scope.launch {
|
|
+ fun stop(callback: Promise) { scope.launch {
|
|
if (verifyServiceBoundOrReject(callback)) return@launch
|
|
|
|
musicService.stop()
|
|
callback.resolve(null)
|
|
}
|
|
+ }
|
|
|
|
@ReactMethod
|
|
- fun seekTo(seconds: Float, callback: Promise) = scope.launch {
|
|
+ fun seekTo(seconds: Float, callback: Promise) { scope.launch {
|
|
if (verifyServiceBoundOrReject(callback)) return@launch
|
|
|
|
musicService.seekTo(seconds)
|
|
callback.resolve(null)
|
|
}
|
|
+ }
|
|
|
|
@ReactMethod
|
|
- fun seekBy(offset: Float, callback: Promise) = scope.launch {
|
|
+ fun seekBy(offset: Float, callback: Promise) { scope.launch {
|
|
if (verifyServiceBoundOrReject(callback)) return@launch
|
|
|
|
musicService.seekBy(offset)
|
|
callback.resolve(null)
|
|
}
|
|
+ }
|
|
|
|
@ReactMethod
|
|
- fun retry(callback: Promise) = scope.launch {
|
|
+ fun retry(callback: Promise) { scope.launch {
|
|
if (verifyServiceBoundOrReject(callback)) return@launch
|
|
|
|
musicService.retry()
|
|
callback.resolve(null)
|
|
}
|
|
+ }
|
|
|
|
@ReactMethod
|
|
- fun setVolume(volume: Float, callback: Promise) = scope.launch {
|
|
+ fun setVolume(volume: Float, callback: Promise) { scope.launch {
|
|
if (verifyServiceBoundOrReject(callback)) return@launch
|
|
|
|
musicService.setVolume(volume)
|
|
callback.resolve(null)
|
|
}
|
|
+ }
|
|
|
|
@ReactMethod
|
|
- fun getVolume(callback: Promise) = scope.launch {
|
|
+ fun getVolume(callback: Promise) { scope.launch {
|
|
if (verifyServiceBoundOrReject(callback)) return@launch
|
|
|
|
callback.resolve(musicService.getVolume())
|
|
}
|
|
+ }
|
|
|
|
@ReactMethod
|
|
- fun setRate(rate: Float, callback: Promise) = scope.launch {
|
|
+ fun setRate(rate: Float, callback: Promise) { scope.launch {
|
|
if (verifyServiceBoundOrReject(callback)) return@launch
|
|
|
|
musicService.setRate(rate)
|
|
callback.resolve(null)
|
|
}
|
|
+ }
|
|
|
|
@ReactMethod
|
|
- fun getRate(callback: Promise) = scope.launch {
|
|
+ fun getRate(callback: Promise) { scope.launch {
|
|
if (verifyServiceBoundOrReject(callback)) return@launch
|
|
|
|
callback.resolve(musicService.getRate())
|
|
}
|
|
+ }
|
|
|
|
@ReactMethod
|
|
- fun setRepeatMode(mode: Int, callback: Promise) = scope.launch {
|
|
+ fun setRepeatMode(mode: Int, callback: Promise) { scope.launch {
|
|
if (verifyServiceBoundOrReject(callback)) return@launch
|
|
|
|
musicService.setRepeatMode(RepeatMode.fromOrdinal(mode))
|
|
callback.resolve(null)
|
|
}
|
|
+ }
|
|
|
|
@ReactMethod
|
|
- fun getRepeatMode(callback: Promise) = scope.launch {
|
|
+ fun getRepeatMode(callback: Promise) { scope.launch {
|
|
if (verifyServiceBoundOrReject(callback)) return@launch
|
|
|
|
callback.resolve(musicService.getRepeatMode().ordinal)
|
|
}
|
|
+ }
|
|
|
|
@ReactMethod
|
|
- fun setPlayWhenReady(playWhenReady: Boolean, callback: Promise) = scope.launch {
|
|
+ fun setPlayWhenReady(playWhenReady: Boolean, callback: Promise) { scope.launch {
|
|
if (verifyServiceBoundOrReject(callback)) return@launch
|
|
|
|
musicService.playWhenReady = playWhenReady
|
|
callback.resolve(null)
|
|
}
|
|
+ }
|
|
|
|
@ReactMethod
|
|
- fun getPlayWhenReady(callback: Promise) = scope.launch {
|
|
+ fun getPlayWhenReady(callback: Promise) { scope.launch {
|
|
if (verifyServiceBoundOrReject(callback)) return@launch
|
|
|
|
callback.resolve(musicService.playWhenReady)
|
|
}
|
|
+ }
|
|
|
|
@ReactMethod
|
|
- fun getTrack(index: Int, callback: Promise) = scope.launch {
|
|
+ fun getTrack(index: Int, callback: Promise) { scope.launch {
|
|
if (verifyServiceBoundOrReject(callback)) return@launch
|
|
|
|
if (index >= 0 && index < musicService.tracks.size) {
|
|
- callback.resolve(Arguments.fromBundle(musicService.tracks[index].originalItem))
|
|
+ callback.resolve(musicService.tracks[index].originalItem?.let { Arguments.fromBundle(it) })
|
|
} else {
|
|
callback.resolve(null)
|
|
}
|
|
}
|
|
+ }
|
|
|
|
@ReactMethod
|
|
- fun getQueue(callback: Promise) = scope.launch {
|
|
+ fun getQueue(callback: Promise) { scope.launch {
|
|
if (verifyServiceBoundOrReject(callback)) return@launch
|
|
|
|
- callback.resolve(Arguments.fromList(musicService.tracks.map { it.originalItem }))
|
|
+ // Clone on main (the service mutates originalItem there), marshal off-main.
|
|
+ val bundles = musicService.tracks.map { track -> track.originalItem?.let(::Bundle) }
|
|
+ callback.resolve(withContext(Dispatchers.Default) { Arguments.fromList(bundles) })
|
|
+ }
|
|
}
|
|
|
|
@ReactMethod
|
|
- fun setQueue(data: ReadableArray?, callback: Promise) = scope.launch {
|
|
+ fun setQueue(data: ReadableArray?, callback: Promise) { scope.launch {
|
|
if (verifyServiceBoundOrReject(callback)) return@launch
|
|
|
|
try {
|
|
+ val tracks = withContext(Dispatchers.Default) { readableArrayToTrackList(data) }
|
|
musicService.clear()
|
|
- musicService.add(readableArrayToTrackList(data))
|
|
+ musicService.add(tracks)
|
|
callback.resolve(null)
|
|
} catch (exception: Exception) {
|
|
rejectWithException(callback, exception)
|
|
}
|
|
}
|
|
+ }
|
|
|
|
@ReactMethod
|
|
- fun getActiveTrackIndex(callback: Promise) = scope.launch {
|
|
+ fun getActiveTrackIndex(callback: Promise) { scope.launch {
|
|
if (verifyServiceBoundOrReject(callback)) return@launch
|
|
callback.resolve(
|
|
if (musicService.tracks.isEmpty()) null else musicService.getCurrentTrackIndex()
|
|
)
|
|
}
|
|
+ }
|
|
|
|
@ReactMethod
|
|
- fun getActiveTrack(callback: Promise) = scope.launch {
|
|
+ fun getActiveTrack(callback: Promise) { scope.launch {
|
|
if (verifyServiceBoundOrReject(callback)) return@launch
|
|
callback.resolve(
|
|
if (musicService.tracks.isEmpty()) null
|
|
- else Arguments.fromBundle(
|
|
- musicService.tracks[musicService.getCurrentTrackIndex()].originalItem
|
|
- )
|
|
+ else musicService.tracks[musicService.getCurrentTrackIndex()].originalItem
|
|
+ ?.let { Arguments.fromBundle(it) }
|
|
)
|
|
}
|
|
+ }
|
|
|
|
@ReactMethod
|
|
- fun getDuration(callback: Promise) = scope.launch {
|
|
+ fun getDuration(callback: Promise) { scope.launch {
|
|
if (verifyServiceBoundOrReject(callback)) return@launch
|
|
|
|
callback.resolve(musicService.getDurationInSeconds())
|
|
}
|
|
+ }
|
|
|
|
@ReactMethod
|
|
- fun getBufferedPosition(callback: Promise) = scope.launch {
|
|
+ fun getBufferedPosition(callback: Promise) { scope.launch {
|
|
if (verifyServiceBoundOrReject(callback)) return@launch
|
|
|
|
callback.resolve(musicService.getBufferedPositionInSeconds())
|
|
}
|
|
+ }
|
|
|
|
@ReactMethod
|
|
- fun getPosition(callback: Promise) = scope.launch {
|
|
+ fun getPosition(callback: Promise) { scope.launch {
|
|
if (verifyServiceBoundOrReject(callback)) return@launch
|
|
|
|
callback.resolve(musicService.getPositionInSeconds())
|
|
}
|
|
+ }
|
|
|
|
@ReactMethod
|
|
- fun getProgress(callback: Promise) = scope.launch {
|
|
+ fun getProgress(callback: Promise) { scope.launch {
|
|
if (verifyServiceBoundOrReject(callback)) return@launch
|
|
var bundle = Bundle()
|
|
bundle.putDouble("duration", musicService.getDurationInSeconds());
|
|
@@ -620,10 +664,12 @@ class MusicModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaM
|
|
bundle.putDouble("buffered", musicService.getBufferedPositionInSeconds());
|
|
callback.resolve(Arguments.fromBundle(bundle))
|
|
}
|
|
+ }
|
|
|
|
@ReactMethod
|
|
- fun getPlaybackState(callback: Promise) = scope.launch {
|
|
+ fun getPlaybackState(callback: Promise) { scope.launch {
|
|
if (verifyServiceBoundOrReject(callback)) return@launch
|
|
callback.resolve(Arguments.fromBundle(musicService.getPlayerStateBundle(musicService.state)))
|
|
}
|
|
+ }
|
|
}
|
|
diff --git a/node_modules/react-native-track-player/android/src/main/java/com/doublesymmetry/trackplayer/service/MusicService.kt b/node_modules/react-native-track-player/android/src/main/java/com/doublesymmetry/trackplayer/service/MusicService.kt
|
|
index afa6b0f..c6f01d5 100644
|
|
--- a/node_modules/react-native-track-player/android/src/main/java/com/doublesymmetry/trackplayer/service/MusicService.kt
|
|
+++ b/node_modules/react-native-track-player/android/src/main/java/com/doublesymmetry/trackplayer/service/MusicService.kt
|
|
@@ -337,0 +338,4 @@ class MusicService : HeadlessJsTaskService() {
|
|
+ fun setPauseAtEndOfItem(enabled: Boolean) {
|
|
+ player.setPauseAtEndOfItem(enabled)
|
|
+ }
|
|
+
|
|
@@ -741,7 +745,7 @@ class MusicService : HeadlessJsTaskService() {
|
|
|
|
@MainThread
|
|
private fun emit(event: String, data: Bundle? = null) {
|
|
- reactNativeHost.reactInstanceManager.currentReactContext
|
|
+ (applicationContext as? com.facebook.react.ReactApplication)?.reactHost?.currentReactContext
|
|
?.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
?.emit(event, data?.let { Arguments.fromBundle(it) })
|
|
}
|
|
@@ -751,7 +755,7 @@ class MusicService : HeadlessJsTaskService() {
|
|
val payload = Arguments.createArray()
|
|
data.forEach { payload.pushMap(Arguments.fromBundle(it)) }
|
|
|
|
- reactNativeHost.reactInstanceManager.currentReactContext
|
|
+ (applicationContext as? com.facebook.react.ReactApplication)?.reactHost?.currentReactContext
|
|
?.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
?.emit(event, payload)
|
|
}
|