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

Replace updateProgress callback by LiveData

parent 8ca0fec2
......@@ -3,7 +3,7 @@
<data>
<variable
name="progress"
type="org.videolan.vlc.gui.tv.audioplayer.AudioPlayerActivity.Progress" />
type="android.arch.lifecycle.LiveData&lt;org.videolan.vlc.viewmodels.PlaybackProgress>" />
</data>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
......@@ -66,7 +66,7 @@
app:layout_constraintTop_toTopOf="@+id/media_progress"
app:layout_constraintRight_toLeftOf="@+id/media_progress"
app:layout_constraintBottom_toBottomOf="@+id/media_progress"
android:text="@{progress.strTime}"
android:text="@{progress.timeText}"
tools:text="0:30" />
<ProgressBar
......@@ -79,8 +79,8 @@
app:layout_constraintTop_toBottomOf="@+id/media_artist"
app:layout_constraintRight_toLeftOf="@+id/media_length"
app:layout_constraintBottom_toTopOf="@+id/button_play"
android:progress="@{progress.time}"
android:max="@{progress.length}"
android:progress="@{(int)progress.time}"
android:max="@{(int)progress.length}"
android:focusable="true"
android:indeterminate="false"
android:nextFocusDown="@+id/button_play"
......@@ -96,7 +96,7 @@
app:layout_constraintTop_toTopOf="@+id/media_progress"
app:layout_constraintRight_toRightOf="@+id/album_cover"
app:layout_constraintBottom_toBottomOf="@+id/media_progress"
android:text="@{progress.strLength}"
android:text="@{progress.lengthText}"
tools:text="3:52" />
<ImageView
......
......@@ -181,12 +181,8 @@ class PlaybackService : MediaBrowserServiceCompat() {
showNotification()
if (wakeLock.isHeld) wakeLock.release()
}
MediaPlayer.Event.EndReached -> executeUpdateProgress()
MediaPlayer.Event.EncounteredError -> executeUpdate()
MediaPlayer.Event.PositionChanged -> {
updateWidgetPosition(event.positionChanged)
handler.sendEmptyMessage(PUBLISH_PROGRESS)
}
MediaPlayer.Event.PositionChanged -> if (widget != 0) updateWidgetPosition(event.positionChanged)
MediaPlayer.Event.ESAdded -> if (event.esChangedType == Media.Track.Type.Video && (playlistManager.videoBackground || !playlistManager.switchToVideo())) {
/* CbAction notification content intent: resume video or resume audio activity */
updateMetadata()
......@@ -438,7 +434,6 @@ class PlaybackService : MediaBrowserServiceCompat() {
interface Callback {
fun update()
fun updateProgress()
fun onMediaEvent(event: Media.Event)
fun onMediaPlayerEvent(event: MediaPlayer.Event)
}
......@@ -602,11 +597,6 @@ class PlaybackService : MediaBrowserServiceCompat() {
updateWidget()
updateMetadata()
broadcastMetadata()
executeUpdateProgress()
}
private fun executeUpdateProgress() : Unit {
cbActor.offer(CbProgress)
}
private class PlaybackServiceHandler(owner: PlaybackService) : WeakHandler<PlaybackService>(owner) {
......@@ -622,13 +612,6 @@ class PlaybackService : MediaBrowserServiceCompat() {
Toast.makeText(VLCApplication.getAppContext(), text, duration).show()
}
END_MEDIASESSION -> if (service::mediaSession.isInitialized) service.mediaSession.isActive = false
PUBLISH_PROGRESS -> {
val time = System.currentTimeMillis()
if (time - lastPublicationDate > 1000L) {
service.executeUpdateProgress()
lastPublicationDate = time
}
}
}
}
}
......@@ -706,7 +689,6 @@ class PlaybackService : MediaBrowserServiceCompat() {
fun onNewPlayback(mw: MediaWrapper) {
mediaSession.setSessionActivity(sessionPendingIntent)
executeUpdateProgress()
}
fun onPlaylistLoaded() {
......@@ -838,7 +820,6 @@ class PlaybackService : MediaBrowserServiceCompat() {
}
private fun notifyTrackChanged() {
executeUpdateProgress()
updateMetadata()
updateWidget()
broadcastMetadata()
......@@ -850,15 +831,10 @@ class PlaybackService : MediaBrowserServiceCompat() {
}
@MainThread
operator fun next() {
playlistManager.next()
executeUpdateProgress()
}
fun next() = playlistManager.next()
@MainThread
fun previous(force: Boolean) {
playlistManager.previous(force)
}
fun previous(force: Boolean) = playlistManager.previous(force)
@MainThread
fun shuffle() {
......@@ -1310,15 +1286,11 @@ class PlaybackService : MediaBrowserServiceCompat() {
private val cbActor by lazy {
actor<CbAction>(UI, capacity = Channel.UNLIMITED) {
for (update in channel) when (update) {
CbProgress -> for (callback in callbacks) callback.updateProgress()
CbUpdate -> for (callback in callbacks) callback.update()
is CbMediaEvent -> for (callback in callbacks) callback.onMediaEvent(update.event)
is CbMediaPlayerEvent -> for (callback in callbacks) callback.onMediaPlayerEvent(update.event)
is CbRemove -> callbacks.remove(update.cb)
is CbAdd -> {
callbacks.add(update.cb)
if (playlistManager.hasCurrentMedia()) executeUpdateProgress()
}
is CbAdd -> callbacks.add(update.cb)
ShowNotification -> showNotificationInternal()
is HideNotification -> hideNotificationInternal(update.remove)
UpdateMeta -> updateMetadataInternal()
......@@ -1332,7 +1304,6 @@ class PlaybackService : MediaBrowserServiceCompat() {
private const val SHOW_TOAST = 1
private const val END_MEDIASESSION = 2
private const val PUBLISH_PROGRESS = 3
internal const val DELAY_DOUBLE_CLICK = 800L
internal const val DELAY_LONG_CLICK = 1000L
......@@ -1355,7 +1326,6 @@ class PlaybackService : MediaBrowserServiceCompat() {
// Actor actions sealed classes
private sealed class CbAction
private object CbProgress : CbAction()
private object CbUpdate : CbAction()
private data class CbMediaEvent(val event : Media.Event) : CbAction()
private data class CbMediaPlayerEvent(val event : MediaPlayer.Event) : CbAction()
......
......@@ -21,10 +21,9 @@
package org.videolan.vlc.gui.tv.audioplayer;
import android.annotation.TargetApi;
import android.arch.lifecycle.ViewModelProviders;
import android.content.SharedPreferences;
import android.databinding.DataBindingUtil;
import android.databinding.ObservableField;
import android.databinding.ObservableInt;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
......@@ -40,7 +39,6 @@ import android.view.View;
import org.videolan.libvlc.Media;
import org.videolan.libvlc.MediaPlayer;
import org.videolan.medialibrary.Tools;
import org.videolan.medialibrary.media.MediaWrapper;
import org.videolan.vlc.PlaybackService;
import org.videolan.vlc.R;
......@@ -53,6 +51,7 @@ import org.videolan.vlc.gui.tv.browser.BaseTvActivity;
import org.videolan.vlc.util.AndroidDevices;
import org.videolan.vlc.util.Constants;
import org.videolan.vlc.util.WorkersKt;
import org.videolan.vlc.viewmodels.PlaylistModel;
import java.util.ArrayList;
import java.util.Collections;
......@@ -76,11 +75,11 @@ public class AudioPlayerActivity extends BaseTvActivity implements PlaybackServi
private int mCurrentlyPlaying;
private boolean mShuffling = false;
private String mCurrentCoverArt;
private PlaylistModel model;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mBinding = DataBindingUtil.setContentView(this, R.layout.tv_audio_player);
mBinding.setProgress(new Progress());
mMediaList = getIntent().getParcelableArrayListExtra(MEDIA_LIST);
if (mMediaList == null) mMediaList = new ArrayList<>();
......@@ -89,6 +88,7 @@ public class AudioPlayerActivity extends BaseTvActivity implements PlaybackServi
mBinding.playlist.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
mAdapter = new PlaylistAdapter(this, mMediaList);
mBinding.playlist.setAdapter(mAdapter);
mBinding.setLifecycleOwner(this);
}
@Override
......@@ -113,7 +113,15 @@ public class AudioPlayerActivity extends BaseTvActivity implements PlaybackServi
update();
mAdapter.updateList(mMediaList);
}
model = ViewModelProviders.of(this, new PlaylistModel.Factory(service)).get(PlaylistModel.class);
model.setup();
mBinding.setProgress(model.getProgress());
}
@Override
public void onDisconnected() {
mBinding.setProgress(null);
super.onDisconnected();
}
@Override
......@@ -140,7 +148,6 @@ public class AudioPlayerActivity extends BaseTvActivity implements PlaybackServi
}
mBinding.mediaTitle.setText(mService.getTitle());
mBinding.mediaArtist.setText(mService.getArtist());
mBinding.getProgress().update(mService.getTime(), mService.getLength());
mCurrentlyPlaying = mService.getCurrentMediaPosition();
mAdapter.setSelection(mCurrentlyPlaying);
final MediaWrapper mw = mService.getCurrentMediaWrapper();
......@@ -173,11 +180,6 @@ public class AudioPlayerActivity extends BaseTvActivity implements PlaybackServi
});
}
@Override
public void updateProgress() {
if (mService != null) mBinding.getProgress().updateTime(mService.getTime());
}
@Override
public void onMediaEvent(Media.Event event) {}
......@@ -327,22 +329,4 @@ public class AudioPlayerActivity extends BaseTvActivity implements PlaybackServi
if (mService.isPlaying()) mService.pause();
else if (mService.hasMedia()) mService.play();
}
public class Progress {
public ObservableInt time = new ObservableInt(0);
public ObservableInt length = new ObservableInt(0);
public ObservableField<String> strTime = new ObservableField<>("");
public ObservableField<String> strLength = new ObservableField<>("");
void updateTime(long time) {
strTime.set(Tools.millisToString(time));
this.time.set((int) time);
}
void update(long time, long length) {
updateTime(time);
this.length.set((int) length);
strLength.set(Tools.millisToString(length));
}
}
}
......@@ -203,9 +203,6 @@ public class PopupManager implements PlaybackService.Callback, GestureDetector.O
@Override
public void update() {}
@Override
public void updateProgress() {}
@Override
public void onMediaEvent(Media.Event event) {}
......
......@@ -1493,9 +1493,6 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVLCVout.C
mPlaylistAdapter.update(mService.getMedias());
}
@Override
public void updateProgress() {}
@Override
public void onMediaEvent(Media.Event event) {
switch (event.type) {
......
package org.videolan.vlc.media
import android.arch.lifecycle.MutableLiveData
import android.net.Uri
import android.support.annotation.MainThread
import android.support.v4.media.session.PlaybackStateCompat
......@@ -21,6 +22,7 @@ class PlayerController : IVLCVout.Callback, MediaPlayer.EventListener {
// private val exceptionHandler by lazy(LazyThreadSafetyMode.NONE) { CoroutineExceptionHandler { _, _ -> onPlayerError() } }
private val playerContext by lazy(LazyThreadSafetyMode.NONE) { newSingleThreadContext("vlc-player") }
private val settings by lazy(LazyThreadSafetyMode.NONE) { VLCApplication.getSettings() }
val currentTime by lazy(LazyThreadSafetyMode.NONE) { MutableLiveData<Long>() }
private var mediaplayer = newMediaPlayer()
var switchToVideo = false
......@@ -32,7 +34,6 @@ class PlayerController : IVLCVout.Callback, MediaPlayer.EventListener {
private set
@Volatile var hasRenderer = false
private set
@Volatile private var currentTime = 0L
@Volatile var length = 0L
private set
......@@ -69,7 +70,8 @@ class PlayerController : IVLCVout.Callback, MediaPlayer.EventListener {
mediaplayerEventListener = listener
seekable = true
pausable = true
currentTime = 0L
currentTime.value = 0L
lastTime = 0L
length = media.duration
mediaplayer.setEventListener(null)
mediaplayer.media = media.apply { if (hasRenderer) parse() }
......@@ -208,7 +210,7 @@ class PlayerController : IVLCVout.Callback, MediaPlayer.EventListener {
switchToVideo = false
}
fun getTime() = currentTime
fun getTime() = currentTime.value ?: 0L
fun setRate(rate: Float, save: Boolean) {
mediaplayer.rate = rate
......@@ -270,6 +272,7 @@ class PlayerController : IVLCVout.Callback, MediaPlayer.EventListener {
}
}
private var lastTime = 0L
override fun onEvent(event: MediaPlayer.Event?) {
if (event === null) return
when(event.type) {
......@@ -278,15 +281,22 @@ class PlayerController : IVLCVout.Callback, MediaPlayer.EventListener {
MediaPlayer.Event.EncounteredError -> setPlaybackStopped()
MediaPlayer.Event.PausableChanged -> pausable = event.pausable
MediaPlayer.Event.SeekableChanged -> seekable = event.seekable
MediaPlayer.Event.TimeChanged -> currentTime = event.timeChanged
MediaPlayer.Event.LengthChanged -> length = event.lengthChanged
MediaPlayer.Event.TimeChanged -> {
val time = event.timeChanged
if (time - lastTime > 950L) {
currentTime.value = time
lastTime = time
}
}
}
mediaplayerEventListener?.onEvent(event)
}
private fun setPlaybackStopped() {
playbackState = PlaybackStateCompat.STATE_STOPPED
currentTime = 0L
currentTime.value = 0L
lastTime = 0L
length = 0L
}
......
......@@ -149,7 +149,6 @@ object EmptyMLCallbacks : MediaAddedCb, MediaUpdatedCb, Medialibrary.ArtistsAdde
object EmptyPBSCallback : PlaybackService.Callback {
override fun update() {}
override fun updateProgress() {}
override fun onMediaEvent(event: Media.Event) {}
override fun onMediaPlayerEvent(event: MediaPlayer.Event) {}
}
......
package org.videolan.vlc.viewmodels
import android.arch.lifecycle.MutableLiveData
import android.arch.lifecycle.MediatorLiveData
import android.arch.lifecycle.ViewModel
import android.arch.lifecycle.ViewModelProvider
import android.arch.lifecycle.ViewModelProviders
......@@ -18,7 +18,13 @@ import org.videolan.vlc.util.PlaylistFilterDelegate
class PlaylistModel(private val service: PlaybackService) : ViewModel(), PlaybackService.Callback by EmptyPBSCallback {
val dataset = LiveDataset<MediaWrapper>()
val progress = MutableLiveData<PlaybackProgress>()
val progress by lazy(LazyThreadSafetyMode.NONE) {
MediatorLiveData<PlaybackProgress>().apply {
addSource(service.playlistManager.player.currentTime, {
value = PlaybackProgress(it ?: 0L, service.length)
})
}
}
private val filter by lazy(LazyThreadSafetyMode.NONE) { PlaylistFilterDelegate(dataset) }
......@@ -31,10 +37,6 @@ class PlaylistModel(private val service: PlaybackService) : ViewModel(), Playbac
dataset.value = service.medias.toMutableList()
}
override fun updateProgress() {
progress.value = PlaybackProgress(service.time, service.length)
}
fun filter(query: CharSequence?) = launch(UI, CoroutineStart.UNDISPATCHED) { filter.filter(query) }
public override fun onCleared() {
......@@ -60,4 +62,8 @@ class PlaylistModel(private val service: PlaybackService) : ViewModel(), Playbac
}
}
data class PlaybackProgress(val time: Long, val length: Long, val timeText : String = Tools.millisToString(time), val lengthText : String = Tools.millisToString(length))
\ No newline at end of file
data class PlaybackProgress(
val time: Long,
val length: Long,
val timeText : String = Tools.millisToString(time),
val lengthText : String = Tools.millisToString(length))
\ 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