[Android] Play queue: Prevent ANR

Geoffrey Métais git at videolan.org
Fri Dec 27 10:57:48 CET 2019


vlc-android | branch: master | Geoffrey Métais <geoffrey.metais at gmail.com> | Thu Dec 26 11:30:11 2019 +0100| [95c9aa0ae981675f4e0859d7ede1b8dc88c3e383] | committer: Geoffrey Métais

Play queue: Prevent ANR

canSwitchToVideo() calls getVideoTracksCount() which can block main
thread.

> https://code.videolan.org/videolan/vlc-android/commit/95c9aa0ae981675f4e0859d7ede1b8dc88c3e383
---

 .../src/org/videolan/vlc/gui/audio/AudioPlayer.kt  |  2 +-
 .../vlc/gui/tv/audioplayer/AudioPlayerActivity.kt  | 32 ++++++++++------------
 .../org/videolan/vlc/viewmodels/PlaylistModel.kt   |  6 ++--
 3 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/vlc-android/src/org/videolan/vlc/gui/audio/AudioPlayer.kt b/vlc-android/src/org/videolan/vlc/gui/audio/AudioPlayer.kt
index 42608cb7a..6109c4fd5 100644
--- a/vlc-android/src/org/videolan/vlc/gui/audio/AudioPlayer.kt
+++ b/vlc-android/src/org/videolan/vlc/gui/audio/AudioPlayer.kt
@@ -355,7 +355,7 @@ class AudioPlayer : Fragment(), PlaylistAdapter.IPlayer, TextWatcher, IAudioPlay
                     it.uri, playlistModel.currentMediaPosition)
             else if (hasMedia()) {
                 it.removeFlags(MediaWrapper.MEDIA_FORCE_AUDIO)
-                playlistModel.switchToVideo()
+                lifecycleScope.launch(start = CoroutineStart.UNDISPATCHED) { playlistModel.switchToVideo() }
             }
         }
     }
diff --git a/vlc-android/src/org/videolan/vlc/gui/tv/audioplayer/AudioPlayerActivity.kt b/vlc-android/src/org/videolan/vlc/gui/tv/audioplayer/AudioPlayerActivity.kt
index 823236c5a..51589e77c 100644
--- a/vlc-android/src/org/videolan/vlc/gui/tv/audioplayer/AudioPlayerActivity.kt
+++ b/vlc-android/src/org/videolan/vlc/gui/tv/audioplayer/AudioPlayerActivity.kt
@@ -38,10 +38,7 @@ import androidx.lifecycle.lifecycleScope
 import androidx.recyclerview.widget.DividerItemDecoration
 import androidx.recyclerview.widget.LinearLayoutManager
 import androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.ObsoleteCoroutinesApi
-import kotlinx.coroutines.withContext
+import kotlinx.coroutines.*
 import org.videolan.medialibrary.interfaces.media.MediaWrapper
 import org.videolan.vlc.R
 import org.videolan.vlc.databinding.TvAudioPlayerBinding
@@ -113,20 +110,21 @@ class AudioPlayerActivity : BaseTvActivity() {
         wasPlaying = state.playing
 
         val mw = model.currentMediaWrapper
-        if (mw != null && !mw.hasFlag(MediaWrapper.MEDIA_FORCE_AUDIO) && model.canSwitchToVideo()) {
-            model.switchToVideo()
-            finish()
-            return
+        lifecycleScope.launch {
+            if (model.switchToVideo()) {
+                finish()
+                return at launch
+            }
+            binding.mediaTitle.text = state.title
+            binding.mediaArtist.text = state.artist
+            binding.buttonShuffle.setImageResource(if (shuffling)
+                R.drawable.ic_shuffle_on
+            else
+                R.drawable.ic_shuffle)
+            if (mw == null || TextUtils.equals(currentCoverArt, mw.artworkMrl)) return at launch
+            currentCoverArt = mw.artworkMrl
+            updateBackground()
         }
-        binding.mediaTitle.text = state.title
-        binding.mediaArtist.text = state.artist
-        binding.buttonShuffle.setImageResource(if (shuffling)
-            R.drawable.ic_shuffle_on
-        else
-            R.drawable.ic_shuffle)
-        if (mw == null || TextUtils.equals(currentCoverArt, mw.artworkMrl)) return
-        currentCoverArt = mw.artworkMrl
-        updateBackground()
     }
 
     private fun updateBackground() = lifecycleScope.launchWhenStarted {
diff --git a/vlc-android/src/org/videolan/vlc/viewmodels/PlaylistModel.kt b/vlc-android/src/org/videolan/vlc/viewmodels/PlaylistModel.kt
index ad870843b..e7411c7a9 100644
--- a/vlc-android/src/org/videolan/vlc/viewmodels/PlaylistModel.kt
+++ b/vlc-android/src/org/videolan/vlc/viewmodels/PlaylistModel.kt
@@ -23,9 +23,11 @@ package org.videolan.vlc.viewmodels
 import androidx.annotation.MainThread
 import androidx.fragment.app.Fragment
 import androidx.lifecycle.*
+import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.ObsoleteCoroutinesApi
 import kotlinx.coroutines.channels.actor
+import kotlinx.coroutines.withContext
 import org.videolan.medialibrary.Tools
 import org.videolan.medialibrary.interfaces.media.MediaWrapper
 import org.videolan.vlc.PlaybackService
@@ -182,7 +184,7 @@ class PlaylistModel : ViewModel(), PlaybackService.Callback by EmptyPBSCallback,
 
     fun load(medialist: List<MediaWrapper>, position: Int) = service?.load(medialist, position)
 
-    fun switchToVideo() : Boolean {
+    suspend fun switchToVideo() : Boolean {
         service?.apply {
             if (PlaylistManager.hasMedia() && !isVideoPlaying && !hasRenderer()) {
                 currentMediaWrapper?.run {
@@ -196,7 +198,7 @@ class PlaylistModel : ViewModel(), PlaybackService.Callback by EmptyPBSCallback,
         return false
     }
 
-    fun canSwitchToVideo() = service?.playlistManager?.player?.canSwitchToVideo() ?: false
+    suspend fun canSwitchToVideo() = withContext(Dispatchers.IO) { service?.playlistManager?.player?.canSwitchToVideo() ?: false }
 
     fun toggleABRepeat() = service?.playlistManager?.toggleABRepeat()
 



More information about the Android mailing list