doublesymmetry / react-native-track-player

A fully fledged audio module created for music apps. Provides audio playback, external media controls, background mode and more!
https://rntp.dev/
Apache License 2.0
3.18k stars 981 forks source link

Android crash on queue remove function for TV Box #2187

Closed codehesionza closed 8 months ago

codehesionza commented 8 months ago

Describe the Bug Android TV Box running android 7.1.2 I'm using this package for a TV application using React Native TvOS. I tried removing an element from the queue and the app crashes on the android side.

I dont have any java or kotlin experience so not sure what else to do. I suspect the sort function is not available on android 7.1.2.

Any ideas?

Android Code causing the problem:

fun remove(indexes: List<Int>) {
    val sorted = indexes.toList()
    // Sort the indexes in descending order so we can safely remove them one by one
    // without having the next index possibly newly pointing to another item than intended:
    Collections.sort(sorted, Collections.reverseOrder());
    sorted.forEach {
        remove(it)
    }
}

Crash:

FATAL EXCEPTION: main
Process: com.mytvapp, PID: 6889
java.lang.UnsupportedOperationException
at java.util.AbstractList.set(AbstractList.java:132)
at java.util.AbstractList$ListItr.set(AbstractList.java:426)
at java.util.Collections.sort(Collections.java:247)
at com.doublesymmetry.kotlinaudio.players.QueuedAudioPlayer.remove(QueuedAudioPlayer.kt:154)
at com.doublesymmetry.trackplayer.service.MusicService.remove(MusicService.kt:318)
at com.doublesymmetry.trackplayer.module.MusicModule$remove$1.invokeSuspend(MusicModule.kt:328)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at android.os.Handler.handleCallback(Handler.java:755)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6121)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:912)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:802)
Suppressed: kotlinx.coroutines.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@299f479, Dispatchers.Main]

Environment Info:

System:
    OS: macOS 13.1
    CPU: (8) arm64 Apple M1 Pro
    Memory: 58.94 MB / 16.00 GB
    Shell: 5.8.1 - /bin/zsh
  Binaries:
    Node: 20.1.0 - ~/.nvm/versions/node/v20.1.0/bin/node
    Yarn: 1.22.19 - ~/.nvm/versions/node/v20.1.0/bin/yarn
    npm: 9.6.4 - ~/.nvm/versions/node/v20.1.0/bin/npm
    Watchman: 2023.09.04.00 - /opt/homebrew/bin/watchman
  Managers:
    CocoaPods: 1.12.1 - /Users/keatonroux/.rvm/gems/ruby-3.0.0/bin/pod
  SDKs:
    iOS SDK:
      Platforms: DriverKit 22.4, iOS 16.4, macOS 13.3, tvOS 16.4, watchOS 9.4
    Android SDK: Not Found
  IDEs:
    Android Studio: 2022.3 AI-223.8836.35.2231.10406996
    Xcode: 14.3.1/14E300c - /usr/bin/xcodebuild
  Languages:
    Java: 11.0.17 - /usr/bin/javac
  npmPackages:
    @react-native-community/cli: Not Found
    react: 18.2.0 => 18.2.0
    react-native: Not Found
    react-native-macos: Not Found
    react-native-tvos:  0.71.12-0
  npmGlobalPackages:
    *react-native*: Not Found
codehesionza commented 8 months ago

I managed to fix it by modifying the Bridge code.

I see all remove types are being handled by 1 function and then uses the array remove from kotlinplayer. So I changed the following

musicService.remove(indexes)

to

for (index in indexes) {
    musicService.remove(index)
}

and did this:

@MainThread
fun remove(index: Int) {
    player.remove(index)
}
dcvz commented 8 months ago

Thanks for reporting! I'll take a look later today

kaanoner3 commented 8 months ago

I have the same issue, and it is happening for Android versions below 8

dcvz commented 8 months ago

My guess is that Android < 8 did not have the ability to sort the way we're doing it This is the crashing line:

Collections.sort(sorted, Collections.reverseOrder());
dcvz commented 8 months ago

Potential fix here: https://github.com/doublesymmetry/KotlinAudio/pull/100- haven't had a chance to test it on Android < 8 yet

kaanoner3 commented 8 months ago

I can confirm that this resolved the issue for me. Thank you @dcvz!