Commit 4f1afc90 authored by Geoffrey Métais's avatar Geoffrey Métais
Browse files

PlaybackService: Extract ML receiver

parent 7722f66e
......@@ -14,10 +14,10 @@ import org.videolan.medialibrary.media.MediaLibraryItem
import org.videolan.medialibrary.media.MediaWrapper
import org.videolan.vlc.extensions.ExtensionsManager
import org.videolan.vlc.media.BrowserProvider
import org.videolan.vlc.media.MediaUtils
import org.videolan.vlc.util.AndroidDevices
import org.videolan.vlc.util.Constants
import org.videolan.vlc.util.VoiceSearchParams
import org.videolan.vlc.util.registerMedialibrary
internal class MediaSessionCallback(private val playbackService: PlaybackService) : MediaSessionCompat.Callback() {
private var mHeadsetDownTime = 0L
......@@ -35,7 +35,7 @@ internal class MediaSessionCallback(private val playbackService: PlaybackService
KeyEvent.ACTION_DOWN -> {
if (event.repeatCount <= 0) mHeadsetDownTime = time
if (!playbackService.hasMedia()) {
MediaUtils.loadlastPlaylistNoUi(playbackService, Constants.PLAYLIST_TYPE_AUDIO)
PlaybackService.loadLastAudio(playbackService)
return true
}
}
......@@ -77,7 +77,7 @@ internal class MediaSessionCallback(private val playbackService: PlaybackService
override fun onPlay() {
if (playbackService.hasMedia()) playbackService.play()
else MediaUtils.loadlastPlaylistNoUi(playbackService, Constants.PLAYLIST_TYPE_AUDIO)
else PlaybackService.loadLastAudio(playbackService)
}
override fun onCustomAction(action: String?, extras: Bundle?) {
......@@ -106,9 +106,7 @@ internal class MediaSessionCallback(private val playbackService: PlaybackService
}
override fun onPlayFromUri(uri: Uri?, extras: Bundle?) {
playbackService.loadUri(uri)
}
override fun onPlayFromUri(uri: Uri?, extras: Bundle?) = playbackService.loadUri(uri)
override fun onPlayFromSearch(query: String?, extras: Bundle?) {
if (!playbackService.medialibrary.isInitiated || playbackService.libraryReceiver != null) {
......@@ -145,35 +143,19 @@ internal class MediaSessionCallback(private val playbackService: PlaybackService
}
}
override fun onPause() {
playbackService.pause()
}
override fun onPause() = playbackService.pause()
override fun onStop() {
playbackService.stop()
}
override fun onStop() = playbackService.stop()
override fun onSkipToNext() {
playbackService.next()
}
override fun onSkipToNext() = playbackService.next()
override fun onSkipToPrevious() {
playbackService.previous(false)
}
override fun onSkipToPrevious() = playbackService.previous(false)
override fun onSeekTo(pos: Long) {
playbackService.seek(pos)
}
override fun onSeekTo(pos: Long) = playbackService.seek(pos)
override fun onFastForward() {
playbackService.seek(Math.min(playbackService.length, playbackService.time + 5000))
}
override fun onFastForward() = playbackService.seek(Math.min(playbackService.length, playbackService.time + 5000))
override fun onRewind() {
playbackService.seek(Math.max(0, playbackService.time - 5000))
}
override fun onRewind() = playbackService.seek(Math.max(0, playbackService.time - 5000))
override fun onSkipToQueueItem(id: Long) {
playbackService.playIndex(id.toInt())
}
override fun onSkipToQueueItem(id: Long) = playbackService.playIndex(id.toInt())
}
\ No newline at end of file
......@@ -32,7 +32,6 @@ import android.preference.PreferenceManager
import android.support.annotation.MainThread
import android.support.v4.app.NotificationManagerCompat
import android.support.v4.app.ServiceCompat
import android.support.v4.content.LocalBroadcastManager
import android.support.v4.media.MediaBrowserCompat
import android.support.v4.media.MediaBrowserServiceCompat
import android.support.v4.media.MediaDescriptionCompat
......@@ -95,7 +94,7 @@ class PlaybackService : MediaBrowserServiceCompat() {
private var widgetPositionTimestamp = System.currentTimeMillis()
private var popupManager: PopupManager? = null
internal var libraryReceiver: MedialibraryReceiver? = null
internal var libraryReceiver: PBSMedialibraryReceiver? = null
private val receiver = object : BroadcastReceiver() {
private var wasPlaying = false
......@@ -192,7 +191,7 @@ class PlaybackService : MediaBrowserServiceCompat() {
/* CbAction notification content intent: resume video or resume audio activity */
updateMetadata()
}
MediaPlayer.Event.MediaChanged -> Log.d(TAG, "onEvent: MediaChanged")
MediaPlayer.Event.MediaChanged -> if (BuildConfig.DEBUG) Log.d(TAG, "onEvent: MediaChanged")
}
cbActor.offer(CbMediaPlayerEvent(event))
}
......@@ -492,17 +491,6 @@ class PlaybackService : MediaBrowserServiceCompat() {
keyguardManager = getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
}
internal fun registerMedialibrary(action: Runnable?) {
if (!Permissions.canReadStorage(this)) return
val lbm = LocalBroadcastManager.getInstance(this)
if (libraryReceiver == null) {
libraryReceiver = MedialibraryReceiver()
lbm.registerReceiver(libraryReceiver!!, IntentFilter(VLCApplication.ACTION_MEDIALIBRARY_READY))
Util.startService(this@PlaybackService, Intent(Constants.ACTION_INIT, null, this, MediaParsingService::class.java))
}
if (action != null) libraryReceiver!!.addAction(action)
}
private fun updateHasWidget() {
val manager = AppWidgetManager.getInstance(this)
widget = when {
......@@ -518,11 +506,9 @@ class PlaybackService : MediaBrowserServiceCompat() {
Intent.ACTION_MEDIA_BUTTON -> {
if (AndroidDevices.hasTsp || AndroidDevices.hasPlayServices) MediaButtonReceiver.handleIntent(mediaSession, intent)
}
Constants.ACTION_REMOTE_PLAYPAUSE -> {
if (playlistManager.hasCurrentMedia()) return Service.START_NOT_STICKY
else loadLastAudioPlaylist()
}
Constants.ACTION_REMOTE_PLAY -> {
Constants.ACTION_REMOTE_PLAYPAUSE,
Constants.ACTION_REMOTE_PLAY,
Constants.ACTION_REMOTE_LAST_PLAYLIST -> {
if (playlistManager.hasCurrentMedia()) play()
else loadLastAudioPlaylist()
}
......@@ -946,14 +932,11 @@ class PlaybackService : MediaBrowserServiceCompat() {
private fun loadLastAudioPlaylist() {
if (AndroidDevices.isAndroidTv) return
if (medialibrary.isInitiated && libraryReceiver == null)
if (!playlistManager.loadLastPlaylist(Constants.PLAYLIST_TYPE_AUDIO)) stopSelf()
else
registerMedialibrary(Runnable { if (!playlistManager.loadLastPlaylist(Constants.PLAYLIST_TYPE_AUDIO)) stopSelf() })
runOnceReady(Runnable { if (!playlistManager.loadLastPlaylist()) stopSelf() })
}
fun loadLastPlaylist(type: Int) {
playlistManager.loadLastPlaylist(type)
runOnceReady(Runnable { playlistManager.loadLastPlaylist(type) })
}
fun showToast(text: String, duration: Int) {
......@@ -1282,7 +1265,7 @@ class PlaybackService : MediaBrowserServiceCompat() {
companion object {
const val TAG = "PlaybackService.Client"
private fun getServiceIntent(context: Context): Intent {
fun getServiceIntent(context: Context): Intent {
return Intent(context, PlaybackService::class.java)
}
......@@ -1324,16 +1307,6 @@ class PlaybackService : MediaBrowserServiceCompat() {
}
}
private val pendingActions by lazy(LazyThreadSafetyMode.NONE) { LinkedList<Runnable>() }
internal inner class MedialibraryReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
libraryReceiver = null
LocalBroadcastManager.getInstance(this@PlaybackService).unregisterReceiver(this)
cbActor.offer(MLActionsExecute)
}
fun addAction(r: Runnable) = cbActor.offer(MLActionAdd(r))
}
private val cbActor by lazy {
actor<CbAction>(UI, capacity = Channel.UNLIMITED) {
......@@ -1347,8 +1320,6 @@ class PlaybackService : MediaBrowserServiceCompat() {
callbacks.add(update.cb)
if (playlistManager.hasCurrentMedia()) executeUpdateProgress()
}
is MLActionAdd -> pendingActions.add(update.runnable)
MLActionsExecute -> for (r in pendingActions) r.run()
ShowNotification -> showNotificationInternal()
is HideNotification -> hideNotificationInternal(update.remove)
UpdateMeta -> updateMetadataInternal()
......@@ -1371,6 +1342,12 @@ class PlaybackService : MediaBrowserServiceCompat() {
return binder.service
}
fun loadLastAudio(context: Context) {
val i = PlaybackService.Client.getServiceIntent(context)
i.action = Constants.ACTION_REMOTE_LAST_PLAYLIST
Util.startService(context, i)
}
private const val PLAYBACK_BASE_ACTIONS = (PlaybackStateCompat.ACTION_PLAY_FROM_SEARCH
or PlaybackStateCompat.ACTION_PLAY_FROM_MEDIA_ID or PlaybackStateCompat.ACTION_PLAY_FROM_URI
or PlaybackStateCompat.ACTION_PLAY_PAUSE)
......@@ -1385,8 +1362,6 @@ private data class CbMediaEvent(val event : Media.Event) : CbAction()
private data class CbMediaPlayerEvent(val event : MediaPlayer.Event) : CbAction()
private data class CbAdd(val cb : PlaybackService.Callback) : CbAction()
private data class CbRemove(val cb : PlaybackService.Callback) : CbAction()
private data class MLActionAdd(val runnable: Runnable) : CbAction()
private object MLActionsExecute : CbAction()
private object ShowNotification : CbAction()
private data class HideNotification(val remove: Boolean) : CbAction()
private object UpdateMeta : CbAction()
\ No newline at end of file
......@@ -53,17 +53,6 @@ public class MediaUtils {
});
}
public static void loadlastPlaylistNoUi(final Context context, final int type){
if (context == null) return;
new BaseCallBack(context) {
@Override
public void onConnected(PlaybackService service) {
service.loadLastPlaylist(type);
mClient.disconnect();
}
};
}
public static void getSubs(Activity activity, MediaWrapper media, SubtitlesDownloader.Callback cb) {
final List<MediaWrapper> mediaList = new ArrayList<>();
mediaList.add(media);
......
......@@ -10,8 +10,11 @@ import android.support.v7.preference.PreferenceManager
import android.text.TextUtils
import android.util.Log
import android.widget.Toast
import kotlinx.coroutines.experimental.*
import kotlinx.coroutines.experimental.CommonPool
import kotlinx.coroutines.experimental.CoroutineStart
import kotlinx.coroutines.experimental.android.UI
import kotlinx.coroutines.experimental.launch
import kotlinx.coroutines.experimental.withContext
import org.videolan.libvlc.Media
import org.videolan.libvlc.MediaPlayer
import org.videolan.libvlc.RendererItem
......@@ -20,7 +23,6 @@ import org.videolan.medialibrary.media.MediaWrapper
import org.videolan.vlc.BuildConfig
import org.videolan.vlc.PlaybackService
import org.videolan.vlc.R
import org.videolan.vlc.R.string.audio
import org.videolan.vlc.VLCApplication
import org.videolan.vlc.gui.preferences.PreferencesActivity
import org.videolan.vlc.gui.preferences.PreferencesFragment
......@@ -119,7 +121,7 @@ class PlaylistManager(val service: PlaybackService) : MediaWrapperList.EventList
@Volatile
private var loadingLastPlaylist = false
fun loadLastPlaylist(type: Int) : Boolean {
fun loadLastPlaylist(type: Int = Constants.PLAYLIST_TYPE_AUDIO) : Boolean {
if (loadingLastPlaylist) return true
loadingLastPlaylist = true
val audio = type == Constants.PLAYLIST_TYPE_AUDIO
......
/*****************************************************************************
* PBSMedialibraryReceiver.kt
*****************************************************************************
* Copyright © 2018 VLC authors and VideoLAN
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
package org.videolan.vlc.util
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.support.v4.content.LocalBroadcastManager
import org.videolan.vlc.MediaParsingService
import org.videolan.vlc.PlaybackService
import org.videolan.vlc.VLCApplication
import java.util.*
internal class PBSMedialibraryReceiver(private val service: PlaybackService) : BroadcastReceiver() {
private val pendingActions by lazy(LazyThreadSafetyMode.NONE) { LinkedList<Runnable>() }
init {
LocalBroadcastManager.getInstance(service).registerReceiver(this, IntentFilter(VLCApplication.ACTION_MEDIALIBRARY_READY))
}
override fun onReceive(context: Context, intent: Intent) {
service.libraryReceiver = null
LocalBroadcastManager.getInstance(service).unregisterReceiver(this)
for (r in pendingActions) r.run()
}
fun addAction(r: Runnable) = pendingActions.add(r)
}
internal fun PlaybackService.registerMedialibrary(action: Runnable?) {
if (!Permissions.canReadStorage(this)) return
if (libraryReceiver == null) {
libraryReceiver = PBSMedialibraryReceiver(this)
Util.startService(this, Intent(Constants.ACTION_INIT, null, this, MediaParsingService::class.java))
}
if (action != null) libraryReceiver?.addAction(action)
}
internal fun PlaybackService.runOnceReady(action: Runnable) {
when {
medialibrary.isInitiated -> action.run()
libraryReceiver == null -> registerMedialibrary(action)
else -> libraryReceiver?.addAction(action)
}
}
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment