Create interface for PlaybackServiceMediaPlayer
This commit is contained in:
parent
8061d94c1b
commit
afbae2a7ef
|
@ -20,14 +20,15 @@ import de.danoeh.antennapod.core.feed.Feed;
|
|||
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||
import de.danoeh.antennapod.core.feed.FeedMedia;
|
||||
import de.danoeh.antennapod.core.feed.FeedPreferences;
|
||||
import de.danoeh.antennapod.core.service.playback.PlaybackServiceMediaPlayer;
|
||||
import de.danoeh.antennapod.core.service.playback.IPlaybackServiceMediaPlayer;
|
||||
import de.danoeh.antennapod.core.service.playback.LocalPSMP;
|
||||
import de.danoeh.antennapod.core.service.playback.PlayerStatus;
|
||||
import de.danoeh.antennapod.core.storage.PodDBAdapter;
|
||||
import de.danoeh.antennapod.core.util.playback.Playable;
|
||||
import de.test.antennapod.util.service.download.HTTPBin;
|
||||
|
||||
/**
|
||||
* Test class for PlaybackServiceMediaPlayer
|
||||
* Test class for LocalPSMP
|
||||
*/
|
||||
public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase {
|
||||
private static final String TAG = "PlaybackServiceMediaPlayerTest";
|
||||
|
@ -85,7 +86,7 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase {
|
|||
assertEquals(0, httpServer.serveFile(dest));
|
||||
}
|
||||
|
||||
private void checkPSMPInfo(PlaybackServiceMediaPlayer.PSMPInfo info) {
|
||||
private void checkPSMPInfo(LocalPSMP.PSMPInfo info) {
|
||||
try {
|
||||
switch (info.playerStatus) {
|
||||
case PLAYING:
|
||||
|
@ -111,7 +112,7 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase {
|
|||
|
||||
public void testInit() {
|
||||
final Context c = getInstrumentation().getTargetContext();
|
||||
PlaybackServiceMediaPlayer psmp = new PlaybackServiceMediaPlayer(c, defaultCallback);
|
||||
IPlaybackServiceMediaPlayer psmp = new LocalPSMP(c, defaultCallback);
|
||||
psmp.shutdown();
|
||||
}
|
||||
|
||||
|
@ -137,9 +138,9 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase {
|
|||
public void testPlayMediaObjectStreamNoStartNoPrepare() throws InterruptedException {
|
||||
final Context c = getInstrumentation().getTargetContext();
|
||||
final CountDownLatch countDownLatch = new CountDownLatch(2);
|
||||
PlaybackServiceMediaPlayer.PSMPCallback callback = new PlaybackServiceMediaPlayer.PSMPCallback() {
|
||||
IPlaybackServiceMediaPlayer.PSMPCallback callback = new IPlaybackServiceMediaPlayer.PSMPCallback() {
|
||||
@Override
|
||||
public void statusChanged(PlaybackServiceMediaPlayer.PSMPInfo newInfo) {
|
||||
public void statusChanged(LocalPSMP.PSMPInfo newInfo) {
|
||||
try {
|
||||
checkPSMPInfo(newInfo);
|
||||
if (newInfo.playerStatus == PlayerStatus.ERROR)
|
||||
|
@ -200,7 +201,7 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase {
|
|||
}
|
||||
|
||||
};
|
||||
PlaybackServiceMediaPlayer psmp = new PlaybackServiceMediaPlayer(c, callback);
|
||||
IPlaybackServiceMediaPlayer psmp = new LocalPSMP(c, callback);
|
||||
Playable p = writeTestPlayable(PLAYABLE_FILE_URL, null);
|
||||
psmp.playMediaObject(p, true, false, false);
|
||||
boolean res = countDownLatch.await(LATCH_TIMEOUT_SECONDS, TimeUnit.SECONDS);
|
||||
|
@ -216,9 +217,9 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase {
|
|||
public void testPlayMediaObjectStreamStartNoPrepare() throws InterruptedException {
|
||||
final Context c = getInstrumentation().getTargetContext();
|
||||
final CountDownLatch countDownLatch = new CountDownLatch(2);
|
||||
PlaybackServiceMediaPlayer.PSMPCallback callback = new PlaybackServiceMediaPlayer.PSMPCallback() {
|
||||
IPlaybackServiceMediaPlayer.PSMPCallback callback = new IPlaybackServiceMediaPlayer.PSMPCallback() {
|
||||
@Override
|
||||
public void statusChanged(PlaybackServiceMediaPlayer.PSMPInfo newInfo) {
|
||||
public void statusChanged(LocalPSMP.PSMPInfo newInfo) {
|
||||
try {
|
||||
checkPSMPInfo(newInfo);
|
||||
if (newInfo.playerStatus == PlayerStatus.ERROR)
|
||||
|
@ -278,7 +279,7 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase {
|
|||
return false;
|
||||
}
|
||||
};
|
||||
PlaybackServiceMediaPlayer psmp = new PlaybackServiceMediaPlayer(c, callback);
|
||||
IPlaybackServiceMediaPlayer psmp = new LocalPSMP(c, callback);
|
||||
Playable p = writeTestPlayable(PLAYABLE_FILE_URL, null);
|
||||
psmp.playMediaObject(p, true, true, false);
|
||||
|
||||
|
@ -295,9 +296,9 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase {
|
|||
public void testPlayMediaObjectStreamNoStartPrepare() throws InterruptedException {
|
||||
final Context c = getInstrumentation().getTargetContext();
|
||||
final CountDownLatch countDownLatch = new CountDownLatch(4);
|
||||
PlaybackServiceMediaPlayer.PSMPCallback callback = new PlaybackServiceMediaPlayer.PSMPCallback() {
|
||||
IPlaybackServiceMediaPlayer.PSMPCallback callback = new IPlaybackServiceMediaPlayer.PSMPCallback() {
|
||||
@Override
|
||||
public void statusChanged(PlaybackServiceMediaPlayer.PSMPInfo newInfo) {
|
||||
public void statusChanged(LocalPSMP.PSMPInfo newInfo) {
|
||||
try {
|
||||
checkPSMPInfo(newInfo);
|
||||
if (newInfo.playerStatus == PlayerStatus.ERROR)
|
||||
|
@ -360,7 +361,7 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase {
|
|||
return false;
|
||||
}
|
||||
};
|
||||
PlaybackServiceMediaPlayer psmp = new PlaybackServiceMediaPlayer(c, callback);
|
||||
IPlaybackServiceMediaPlayer psmp = new LocalPSMP(c, callback);
|
||||
Playable p = writeTestPlayable(PLAYABLE_FILE_URL, null);
|
||||
psmp.playMediaObject(p, true, false, true);
|
||||
boolean res = countDownLatch.await(LATCH_TIMEOUT_SECONDS, TimeUnit.SECONDS);
|
||||
|
@ -375,9 +376,9 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase {
|
|||
public void testPlayMediaObjectStreamStartPrepare() throws InterruptedException {
|
||||
final Context c = getInstrumentation().getTargetContext();
|
||||
final CountDownLatch countDownLatch = new CountDownLatch(5);
|
||||
PlaybackServiceMediaPlayer.PSMPCallback callback = new PlaybackServiceMediaPlayer.PSMPCallback() {
|
||||
IPlaybackServiceMediaPlayer.PSMPCallback callback = new IPlaybackServiceMediaPlayer.PSMPCallback() {
|
||||
@Override
|
||||
public void statusChanged(PlaybackServiceMediaPlayer.PSMPInfo newInfo) {
|
||||
public void statusChanged(LocalPSMP.PSMPInfo newInfo) {
|
||||
try {
|
||||
checkPSMPInfo(newInfo);
|
||||
if (newInfo.playerStatus == PlayerStatus.ERROR)
|
||||
|
@ -444,7 +445,7 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase {
|
|||
}
|
||||
|
||||
};
|
||||
PlaybackServiceMediaPlayer psmp = new PlaybackServiceMediaPlayer(c, callback);
|
||||
IPlaybackServiceMediaPlayer psmp = new LocalPSMP(c, callback);
|
||||
Playable p = writeTestPlayable(PLAYABLE_FILE_URL, null);
|
||||
psmp.playMediaObject(p, true, true, true);
|
||||
boolean res = countDownLatch.await(LATCH_TIMEOUT_SECONDS, TimeUnit.SECONDS);
|
||||
|
@ -458,9 +459,9 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase {
|
|||
public void testPlayMediaObjectLocalNoStartNoPrepare() throws InterruptedException {
|
||||
final Context c = getInstrumentation().getTargetContext();
|
||||
final CountDownLatch countDownLatch = new CountDownLatch(2);
|
||||
PlaybackServiceMediaPlayer.PSMPCallback callback = new PlaybackServiceMediaPlayer.PSMPCallback() {
|
||||
IPlaybackServiceMediaPlayer.PSMPCallback callback = new IPlaybackServiceMediaPlayer.PSMPCallback() {
|
||||
@Override
|
||||
public void statusChanged(PlaybackServiceMediaPlayer.PSMPInfo newInfo) {
|
||||
public void statusChanged(LocalPSMP.PSMPInfo newInfo) {
|
||||
try {
|
||||
checkPSMPInfo(newInfo);
|
||||
if (newInfo.playerStatus == PlayerStatus.ERROR)
|
||||
|
@ -521,7 +522,7 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase {
|
|||
}
|
||||
|
||||
};
|
||||
PlaybackServiceMediaPlayer psmp = new PlaybackServiceMediaPlayer(c, callback);
|
||||
IPlaybackServiceMediaPlayer psmp = new LocalPSMP(c, callback);
|
||||
Playable p = writeTestPlayable(PLAYABLE_FILE_URL, PLAYABLE_LOCAL_URL);
|
||||
psmp.playMediaObject(p, false, false, false);
|
||||
boolean res = countDownLatch.await(LATCH_TIMEOUT_SECONDS, TimeUnit.SECONDS);
|
||||
|
@ -536,9 +537,9 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase {
|
|||
public void testPlayMediaObjectLocalStartNoPrepare() throws InterruptedException {
|
||||
final Context c = getInstrumentation().getTargetContext();
|
||||
final CountDownLatch countDownLatch = new CountDownLatch(2);
|
||||
PlaybackServiceMediaPlayer.PSMPCallback callback = new PlaybackServiceMediaPlayer.PSMPCallback() {
|
||||
IPlaybackServiceMediaPlayer.PSMPCallback callback = new IPlaybackServiceMediaPlayer.PSMPCallback() {
|
||||
@Override
|
||||
public void statusChanged(PlaybackServiceMediaPlayer.PSMPInfo newInfo) {
|
||||
public void statusChanged(LocalPSMP.PSMPInfo newInfo) {
|
||||
try {
|
||||
checkPSMPInfo(newInfo);
|
||||
if (newInfo.playerStatus == PlayerStatus.ERROR)
|
||||
|
@ -598,7 +599,7 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase {
|
|||
return false;
|
||||
}
|
||||
};
|
||||
PlaybackServiceMediaPlayer psmp = new PlaybackServiceMediaPlayer(c, callback);
|
||||
IPlaybackServiceMediaPlayer psmp = new LocalPSMP(c, callback);
|
||||
Playable p = writeTestPlayable(PLAYABLE_FILE_URL, PLAYABLE_LOCAL_URL);
|
||||
psmp.playMediaObject(p, false, true, false);
|
||||
boolean res = countDownLatch.await(LATCH_TIMEOUT_SECONDS, TimeUnit.SECONDS);
|
||||
|
@ -613,9 +614,9 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase {
|
|||
public void testPlayMediaObjectLocalNoStartPrepare() throws InterruptedException {
|
||||
final Context c = getInstrumentation().getTargetContext();
|
||||
final CountDownLatch countDownLatch = new CountDownLatch(4);
|
||||
PlaybackServiceMediaPlayer.PSMPCallback callback = new PlaybackServiceMediaPlayer.PSMPCallback() {
|
||||
IPlaybackServiceMediaPlayer.PSMPCallback callback = new IPlaybackServiceMediaPlayer.PSMPCallback() {
|
||||
@Override
|
||||
public void statusChanged(PlaybackServiceMediaPlayer.PSMPInfo newInfo) {
|
||||
public void statusChanged(LocalPSMP.PSMPInfo newInfo) {
|
||||
try {
|
||||
checkPSMPInfo(newInfo);
|
||||
if (newInfo.playerStatus == PlayerStatus.ERROR)
|
||||
|
@ -678,7 +679,7 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase {
|
|||
return false;
|
||||
}
|
||||
};
|
||||
PlaybackServiceMediaPlayer psmp = new PlaybackServiceMediaPlayer(c, callback);
|
||||
IPlaybackServiceMediaPlayer psmp = new LocalPSMP(c, callback);
|
||||
Playable p = writeTestPlayable(PLAYABLE_FILE_URL, PLAYABLE_LOCAL_URL);
|
||||
psmp.playMediaObject(p, false, false, true);
|
||||
boolean res = countDownLatch.await(LATCH_TIMEOUT_SECONDS, TimeUnit.SECONDS);
|
||||
|
@ -692,9 +693,9 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase {
|
|||
public void testPlayMediaObjectLocalStartPrepare() throws InterruptedException {
|
||||
final Context c = getInstrumentation().getTargetContext();
|
||||
final CountDownLatch countDownLatch = new CountDownLatch(5);
|
||||
PlaybackServiceMediaPlayer.PSMPCallback callback = new PlaybackServiceMediaPlayer.PSMPCallback() {
|
||||
IPlaybackServiceMediaPlayer.PSMPCallback callback = new IPlaybackServiceMediaPlayer.PSMPCallback() {
|
||||
@Override
|
||||
public void statusChanged(PlaybackServiceMediaPlayer.PSMPInfo newInfo) {
|
||||
public void statusChanged(LocalPSMP.PSMPInfo newInfo) {
|
||||
try {
|
||||
checkPSMPInfo(newInfo);
|
||||
if (newInfo.playerStatus == PlayerStatus.ERROR)
|
||||
|
@ -761,7 +762,7 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase {
|
|||
return false;
|
||||
}
|
||||
};
|
||||
PlaybackServiceMediaPlayer psmp = new PlaybackServiceMediaPlayer(c, callback);
|
||||
IPlaybackServiceMediaPlayer psmp = new LocalPSMP(c, callback);
|
||||
Playable p = writeTestPlayable(PLAYABLE_FILE_URL, PLAYABLE_LOCAL_URL);
|
||||
psmp.playMediaObject(p, false, true, true);
|
||||
boolean res = countDownLatch.await(LATCH_TIMEOUT_SECONDS, TimeUnit.SECONDS);
|
||||
|
@ -773,9 +774,9 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase {
|
|||
}
|
||||
|
||||
|
||||
private final PlaybackServiceMediaPlayer.PSMPCallback defaultCallback = new PlaybackServiceMediaPlayer.PSMPCallback() {
|
||||
private final IPlaybackServiceMediaPlayer.PSMPCallback defaultCallback = new IPlaybackServiceMediaPlayer.PSMPCallback() {
|
||||
@Override
|
||||
public void statusChanged(PlaybackServiceMediaPlayer.PSMPInfo newInfo) {
|
||||
public void statusChanged(LocalPSMP.PSMPInfo newInfo) {
|
||||
checkPSMPInfo(newInfo);
|
||||
}
|
||||
|
||||
|
@ -823,9 +824,9 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase {
|
|||
final int latchCount = (stream && reinit) ? 2 : 1;
|
||||
final CountDownLatch countDownLatch = new CountDownLatch(latchCount);
|
||||
|
||||
PlaybackServiceMediaPlayer.PSMPCallback callback = new PlaybackServiceMediaPlayer.PSMPCallback() {
|
||||
IPlaybackServiceMediaPlayer.PSMPCallback callback = new IPlaybackServiceMediaPlayer.PSMPCallback() {
|
||||
@Override
|
||||
public void statusChanged(PlaybackServiceMediaPlayer.PSMPInfo newInfo) {
|
||||
public void statusChanged(LocalPSMP.PSMPInfo newInfo) {
|
||||
checkPSMPInfo(newInfo);
|
||||
if (newInfo.playerStatus == PlayerStatus.ERROR) {
|
||||
if (assertionError == null)
|
||||
|
@ -899,7 +900,7 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase {
|
|||
return false;
|
||||
}
|
||||
};
|
||||
PlaybackServiceMediaPlayer psmp = new PlaybackServiceMediaPlayer(c, callback);
|
||||
IPlaybackServiceMediaPlayer psmp = new LocalPSMP(c, callback);
|
||||
Playable p = writeTestPlayable(PLAYABLE_FILE_URL, PLAYABLE_LOCAL_URL);
|
||||
if (initialState == PlayerStatus.PLAYING) {
|
||||
psmp.playMediaObject(p, stream, true, true);
|
||||
|
@ -954,9 +955,9 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase {
|
|||
(initialState == PlayerStatus.PREPARED) ? 1 : 0;
|
||||
final CountDownLatch countDownLatch = new CountDownLatch(latchCount);
|
||||
|
||||
PlaybackServiceMediaPlayer.PSMPCallback callback = new PlaybackServiceMediaPlayer.PSMPCallback() {
|
||||
IPlaybackServiceMediaPlayer.PSMPCallback callback = new IPlaybackServiceMediaPlayer.PSMPCallback() {
|
||||
@Override
|
||||
public void statusChanged(PlaybackServiceMediaPlayer.PSMPInfo newInfo) {
|
||||
public void statusChanged(LocalPSMP.PSMPInfo newInfo) {
|
||||
checkPSMPInfo(newInfo);
|
||||
if (newInfo.playerStatus == PlayerStatus.ERROR) {
|
||||
if (assertionError == null)
|
||||
|
@ -1015,7 +1016,7 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase {
|
|||
return false;
|
||||
}
|
||||
};
|
||||
PlaybackServiceMediaPlayer psmp = new PlaybackServiceMediaPlayer(c, callback);
|
||||
IPlaybackServiceMediaPlayer psmp = new LocalPSMP(c, callback);
|
||||
if (initialState == PlayerStatus.PREPARED || initialState == PlayerStatus.PLAYING || initialState == PlayerStatus.PAUSED) {
|
||||
boolean startWhenPrepared = (initialState != PlayerStatus.PREPARED);
|
||||
psmp.playMediaObject(writeTestPlayable(PLAYABLE_FILE_URL, PLAYABLE_LOCAL_URL), false, startWhenPrepared, true);
|
||||
|
@ -1047,9 +1048,9 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase {
|
|||
final Context c = getInstrumentation().getTargetContext();
|
||||
final int latchCount = 1;
|
||||
final CountDownLatch countDownLatch = new CountDownLatch(latchCount);
|
||||
PlaybackServiceMediaPlayer.PSMPCallback callback = new PlaybackServiceMediaPlayer.PSMPCallback() {
|
||||
IPlaybackServiceMediaPlayer.PSMPCallback callback = new IPlaybackServiceMediaPlayer.PSMPCallback() {
|
||||
@Override
|
||||
public void statusChanged(PlaybackServiceMediaPlayer.PSMPInfo newInfo) {
|
||||
public void statusChanged(LocalPSMP.PSMPInfo newInfo) {
|
||||
checkPSMPInfo(newInfo);
|
||||
if (newInfo.playerStatus == PlayerStatus.ERROR) {
|
||||
if (assertionError == null)
|
||||
|
@ -1106,7 +1107,7 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase {
|
|||
return false;
|
||||
}
|
||||
};
|
||||
PlaybackServiceMediaPlayer psmp = new PlaybackServiceMediaPlayer(c, callback);
|
||||
IPlaybackServiceMediaPlayer psmp = new LocalPSMP(c, callback);
|
||||
Playable p = writeTestPlayable(PLAYABLE_FILE_URL, PLAYABLE_LOCAL_URL);
|
||||
if (initialState == PlayerStatus.INITIALIZED
|
||||
|| initialState == PlayerStatus.PLAYING
|
||||
|
@ -1152,9 +1153,9 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase {
|
|||
final Context c = getInstrumentation().getTargetContext();
|
||||
final int latchCount = 2;
|
||||
final CountDownLatch countDownLatch = new CountDownLatch(latchCount);
|
||||
PlaybackServiceMediaPlayer.PSMPCallback callback = new PlaybackServiceMediaPlayer.PSMPCallback() {
|
||||
IPlaybackServiceMediaPlayer.PSMPCallback callback = new IPlaybackServiceMediaPlayer.PSMPCallback() {
|
||||
@Override
|
||||
public void statusChanged(PlaybackServiceMediaPlayer.PSMPInfo newInfo) {
|
||||
public void statusChanged(LocalPSMP.PSMPInfo newInfo) {
|
||||
checkPSMPInfo(newInfo);
|
||||
if (newInfo.playerStatus == PlayerStatus.ERROR) {
|
||||
if (assertionError == null)
|
||||
|
@ -1210,7 +1211,7 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase {
|
|||
return false;
|
||||
}
|
||||
};
|
||||
PlaybackServiceMediaPlayer psmp = new PlaybackServiceMediaPlayer(c, callback);
|
||||
IPlaybackServiceMediaPlayer psmp = new LocalPSMP(c, callback);
|
||||
Playable p = writeTestPlayable(PLAYABLE_FILE_URL, PLAYABLE_LOCAL_URL);
|
||||
boolean prepareImmediately = initialState != PlayerStatus.INITIALIZED;
|
||||
boolean startImmediately = initialState != PlayerStatus.PREPARED;
|
||||
|
|
|
@ -0,0 +1,108 @@
|
|||
package de.danoeh.antennapod.core.service.playback;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.media.session.MediaSessionCompat;
|
||||
import android.util.Pair;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.SurfaceHolder;
|
||||
|
||||
import de.danoeh.antennapod.core.feed.Chapter;
|
||||
import de.danoeh.antennapod.core.feed.MediaType;
|
||||
import de.danoeh.antennapod.core.util.playback.Playable;
|
||||
|
||||
/**
|
||||
* Interface that allows for different implementations of the PlaybackServiceMediaPlayer for local
|
||||
* and remote (cast devices) playback.
|
||||
*/
|
||||
public interface IPlaybackServiceMediaPlayer {
|
||||
void playMediaObject(@NonNull Playable playable, boolean stream, boolean startWhenPrepared, boolean prepareImmediately);
|
||||
|
||||
void resume();
|
||||
|
||||
void pause(boolean abandonFocus, boolean reinit);
|
||||
|
||||
void prepare();
|
||||
|
||||
void reinit();
|
||||
|
||||
void seekTo(int t);
|
||||
|
||||
void seekDelta(int d);
|
||||
|
||||
void seekToChapter(@NonNull Chapter c);
|
||||
|
||||
int getDuration();
|
||||
|
||||
int getPosition();
|
||||
|
||||
boolean isStartWhenPrepared();
|
||||
|
||||
void setStartWhenPrepared(boolean startWhenPrepared);
|
||||
|
||||
boolean canSetSpeed();
|
||||
|
||||
void setSpeed(float speed);
|
||||
|
||||
float getPlaybackSpeed();
|
||||
|
||||
void setVolume(float volumeLeft, float volumeRight);
|
||||
|
||||
boolean canDownmix();
|
||||
|
||||
void setDownmix(boolean enable);
|
||||
|
||||
MediaType getCurrentMediaType();
|
||||
|
||||
boolean isStreaming();
|
||||
|
||||
void shutdown();
|
||||
|
||||
void setVideoSurface(SurfaceHolder surface);
|
||||
|
||||
void resetVideoSurface();
|
||||
|
||||
Pair<Integer, Integer> getVideoSize();
|
||||
|
||||
PSMPInfo getPSMPInfo();
|
||||
|
||||
PlayerStatus getPlayerStatus();
|
||||
|
||||
Playable getPlayable();
|
||||
|
||||
void endPlayback(boolean wasSkipped);
|
||||
|
||||
void stop();
|
||||
|
||||
interface PSMPCallback {
|
||||
void statusChanged(PSMPInfo newInfo);
|
||||
|
||||
void shouldStop();
|
||||
|
||||
void playbackSpeedChanged(float s);
|
||||
|
||||
void setSpeedAbilityChanged();
|
||||
|
||||
void onBufferingUpdate(int percent);
|
||||
|
||||
void updateMediaSessionMetadata(Playable p);
|
||||
|
||||
boolean onMediaPlayerInfo(int code);
|
||||
|
||||
boolean onMediaPlayerError(Object inObj, int what, int extra);
|
||||
|
||||
boolean endPlayback(boolean playNextEpisode, boolean wasSkipped);
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds information about a PSMP object.
|
||||
*/
|
||||
class PSMPInfo {
|
||||
public PlayerStatus playerStatus;
|
||||
public Playable playable;
|
||||
|
||||
public PSMPInfo(PlayerStatus playerStatus, Playable playable) {
|
||||
this.playerStatus = playerStatus;
|
||||
this.playable = playable;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -36,7 +36,7 @@ import de.danoeh.antennapod.core.util.playback.VideoPlayer;
|
|||
/**
|
||||
* Manages the MediaPlayer object of the PlaybackService.
|
||||
*/
|
||||
public class PlaybackServiceMediaPlayer {
|
||||
public class LocalPSMP implements IPlaybackServiceMediaPlayer {
|
||||
public static final String TAG = "PlaybackSvcMediaPlayer";
|
||||
|
||||
/**
|
||||
|
@ -74,8 +74,8 @@ public class PlaybackServiceMediaPlayer {
|
|||
*/
|
||||
private WifiManager.WifiLock wifiLock;
|
||||
|
||||
public PlaybackServiceMediaPlayer(@NonNull Context context,
|
||||
@NonNull PSMPCallback callback) {
|
||||
public LocalPSMP(@NonNull Context context,
|
||||
@NonNull PSMPCallback callback) {
|
||||
this.context = context;
|
||||
this.callback = callback;
|
||||
this.audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
|
||||
|
@ -124,6 +124,7 @@ public class PlaybackServiceMediaPlayer {
|
|||
* for playback immediately (see 'prepareImmediately' parameter for more details)
|
||||
* @param prepareImmediately Set to true if the method should also prepare the episode for playback.
|
||||
*/
|
||||
@Override
|
||||
public void playMediaObject(@NonNull final Playable playable, final boolean stream, final boolean startWhenPrepared, final boolean prepareImmediately) {
|
||||
Log.d(TAG, "playMediaObject(...)");
|
||||
executor.submit(() -> {
|
||||
|
@ -194,7 +195,7 @@ public class PlaybackServiceMediaPlayer {
|
|||
this.mediaType = media.getMediaType();
|
||||
this.videoSize = null;
|
||||
createMediaPlayer();
|
||||
PlaybackServiceMediaPlayer.this.startWhenPrepared.set(startWhenPrepared);
|
||||
LocalPSMP.this.startWhenPrepared.set(startWhenPrepared);
|
||||
setPlayerStatus(PlayerStatus.INITIALIZING, media);
|
||||
try {
|
||||
media.loadMetadata();
|
||||
|
@ -224,6 +225,7 @@ public class PlaybackServiceMediaPlayer {
|
|||
* <p/>
|
||||
* This method is executed on an internal executor service.
|
||||
*/
|
||||
@Override
|
||||
public void resume() {
|
||||
executor.submit(() -> {
|
||||
playerLock.lock();
|
||||
|
@ -280,6 +282,7 @@ public class PlaybackServiceMediaPlayer {
|
|||
* @param reinit is true if service should reinit after pausing if the media
|
||||
* file is being streamed
|
||||
*/
|
||||
@Override
|
||||
public void pause(final boolean abandonFocus, final boolean reinit) {
|
||||
executor.submit(() -> {
|
||||
playerLock.lock();
|
||||
|
@ -310,6 +313,7 @@ public class PlaybackServiceMediaPlayer {
|
|||
* <p/>
|
||||
* This method is executed on an internal executor service.
|
||||
*/
|
||||
@Override
|
||||
public void prepare() {
|
||||
executor.submit(() -> {
|
||||
playerLock.lock();
|
||||
|
@ -370,6 +374,7 @@ public class PlaybackServiceMediaPlayer {
|
|||
* <p/>
|
||||
* This method is executed on an internal executor service.
|
||||
*/
|
||||
@Override
|
||||
public void reinit() {
|
||||
executor.submit(() -> {
|
||||
playerLock.lock();
|
||||
|
@ -434,6 +439,7 @@ public class PlaybackServiceMediaPlayer {
|
|||
* <p/>
|
||||
* This method is executed on an internal executor service.
|
||||
*/
|
||||
@Override
|
||||
public void seekTo(final int t) {
|
||||
executor.submit(() -> seekToSync(t));
|
||||
}
|
||||
|
@ -443,6 +449,7 @@ public class PlaybackServiceMediaPlayer {
|
|||
*
|
||||
* @param d offset from current position (positive or negative)
|
||||
*/
|
||||
@Override
|
||||
public void seekDelta(final int d) {
|
||||
executor.submit(() -> {
|
||||
playerLock.lock();
|
||||
|
@ -460,6 +467,7 @@ public class PlaybackServiceMediaPlayer {
|
|||
/**
|
||||
* Seek to the start of the specified chapter.
|
||||
*/
|
||||
@Override
|
||||
public void seekToChapter(@NonNull Chapter c) {
|
||||
seekTo((int) c.getStart());
|
||||
}
|
||||
|
@ -467,6 +475,7 @@ public class PlaybackServiceMediaPlayer {
|
|||
/**
|
||||
* Returns the duration of the current media object or INVALID_TIME if the duration could not be retrieved.
|
||||
*/
|
||||
@Override
|
||||
public int getDuration() {
|
||||
if (!playerLock.tryLock()) {
|
||||
return INVALID_TIME;
|
||||
|
@ -488,6 +497,7 @@ public class PlaybackServiceMediaPlayer {
|
|||
/**
|
||||
* Returns the position of the current media object or INVALID_TIME if the position could not be retrieved.
|
||||
*/
|
||||
@Override
|
||||
public int getPosition() {
|
||||
try {
|
||||
if (!playerLock.tryLock(50, TimeUnit.MILLISECONDS)) {
|
||||
|
@ -513,10 +523,12 @@ public class PlaybackServiceMediaPlayer {
|
|||
return retVal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStartWhenPrepared() {
|
||||
return startWhenPrepared.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStartWhenPrepared(boolean startWhenPrepared) {
|
||||
this.startWhenPrepared.set(startWhenPrepared);
|
||||
}
|
||||
|
@ -524,6 +536,7 @@ public class PlaybackServiceMediaPlayer {
|
|||
/**
|
||||
* Returns true if the playback speed can be adjusted.
|
||||
*/
|
||||
@Override
|
||||
public boolean canSetSpeed() {
|
||||
boolean retVal = false;
|
||||
if (mediaPlayer != null && media != null && media.getMediaType() == MediaType.AUDIO) {
|
||||
|
@ -552,6 +565,7 @@ public class PlaybackServiceMediaPlayer {
|
|||
* Sets the playback speed.
|
||||
* This method is executed on an internal executor service.
|
||||
*/
|
||||
@Override
|
||||
public void setSpeed(final float speed) {
|
||||
executor.submit(() -> setSpeedSync(speed));
|
||||
}
|
||||
|
@ -559,6 +573,7 @@ public class PlaybackServiceMediaPlayer {
|
|||
/**
|
||||
* Returns the current playback speed. If the playback speed could not be retrieved, 1 is returned.
|
||||
*/
|
||||
@Override
|
||||
public float getPlaybackSpeed() {
|
||||
if (!playerLock.tryLock()) {
|
||||
return 1;
|
||||
|
@ -578,6 +593,7 @@ public class PlaybackServiceMediaPlayer {
|
|||
* Sets the playback volume.
|
||||
* This method is executed on an internal executor service.
|
||||
*/
|
||||
@Override
|
||||
public void setVolume(final float volumeLeft, float volumeRight) {
|
||||
executor.submit(() -> setVolumeSync(volumeLeft, volumeRight));
|
||||
}
|
||||
|
@ -598,6 +614,7 @@ public class PlaybackServiceMediaPlayer {
|
|||
/**
|
||||
* Returns true if the mediaplayer can mix stereo down to mono
|
||||
*/
|
||||
@Override
|
||||
public boolean canDownmix() {
|
||||
boolean retVal = false;
|
||||
if (mediaPlayer != null && media != null && media.getMediaType() == MediaType.AUDIO) {
|
||||
|
@ -606,6 +623,7 @@ public class PlaybackServiceMediaPlayer {
|
|||
return retVal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDownmix(boolean enable) {
|
||||
playerLock.lock();
|
||||
if (media != null && media.getMediaType() == MediaType.AUDIO) {
|
||||
|
@ -615,10 +633,12 @@ public class PlaybackServiceMediaPlayer {
|
|||
playerLock.unlock();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MediaType getCurrentMediaType() {
|
||||
return mediaType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStreaming() {
|
||||
return stream;
|
||||
}
|
||||
|
@ -627,6 +647,7 @@ public class PlaybackServiceMediaPlayer {
|
|||
/**
|
||||
* Releases internally used resources. This method should only be called when the object is not used anymore.
|
||||
*/
|
||||
@Override
|
||||
public void shutdown() {
|
||||
executor.shutdown();
|
||||
if (mediaPlayer != null) {
|
||||
|
@ -635,6 +656,7 @@ public class PlaybackServiceMediaPlayer {
|
|||
releaseWifiLockIfNecessary();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVideoSurface(final SurfaceHolder surface) {
|
||||
executor.submit(() -> {
|
||||
playerLock.lock();
|
||||
|
@ -645,6 +667,7 @@ public class PlaybackServiceMediaPlayer {
|
|||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetVideoSurface() {
|
||||
executor.submit(() -> {
|
||||
playerLock.lock();
|
||||
|
@ -662,6 +685,7 @@ public class PlaybackServiceMediaPlayer {
|
|||
* return an invalid non-null value if the getVideoWidth() and getVideoHeight() methods of the media player return
|
||||
* invalid values.
|
||||
*/
|
||||
@Override
|
||||
public Pair<Integer, Integer> getVideoSize() {
|
||||
if (!playerLock.tryLock()) {
|
||||
// use cached value if lock can't be aquired
|
||||
|
@ -684,6 +708,7 @@ public class PlaybackServiceMediaPlayer {
|
|||
*
|
||||
* @return The PSMPInfo object.
|
||||
*/
|
||||
@Override
|
||||
public synchronized PSMPInfo getPSMPInfo() {
|
||||
return new PSMPInfo(playerStatus, media);
|
||||
}
|
||||
|
@ -694,6 +719,7 @@ public class PlaybackServiceMediaPlayer {
|
|||
* could result in nonsensical results (like a status of PLAYING, but a null playable)
|
||||
* @return the current player status
|
||||
*/
|
||||
@Override
|
||||
public PlayerStatus getPlayerStatus() {
|
||||
return playerStatus;
|
||||
}
|
||||
|
@ -704,6 +730,7 @@ public class PlaybackServiceMediaPlayer {
|
|||
* could result in nonsensical results (like a status of PLAYING, but a null playable)
|
||||
* @return the current media. May be null
|
||||
*/
|
||||
@Override
|
||||
public Playable getPlayable() {
|
||||
return media;
|
||||
}
|
||||
|
@ -799,6 +826,7 @@ public class PlaybackServiceMediaPlayer {
|
|||
};
|
||||
|
||||
|
||||
@Override
|
||||
public void endPlayback(final boolean wasSkipped) {
|
||||
executor.submit(() -> {
|
||||
playerLock.lock();
|
||||
|
@ -821,11 +849,12 @@ public class PlaybackServiceMediaPlayer {
|
|||
}
|
||||
|
||||
/**
|
||||
* Moves the PlaybackServiceMediaPlayer into STOPPED state. This call is only valid if the player is currently in
|
||||
* Moves the LocalPSMP into STOPPED state. This call is only valid if the player is currently in
|
||||
* INDETERMINATE state, for example after a call to endPlayback.
|
||||
* This method will only take care of changing the PlayerStatus of this object! Other tasks like
|
||||
* abandoning audio focus have to be done with other methods.
|
||||
*/
|
||||
@Override
|
||||
public void stop() {
|
||||
executor.submit(() -> {
|
||||
playerLock.lock();
|
||||
|
@ -858,39 +887,6 @@ public class PlaybackServiceMediaPlayer {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds information about a PSMP object.
|
||||
*/
|
||||
public class PSMPInfo {
|
||||
public PlayerStatus playerStatus;
|
||||
public Playable playable;
|
||||
|
||||
public PSMPInfo(PlayerStatus playerStatus, Playable playable) {
|
||||
this.playerStatus = playerStatus;
|
||||
this.playable = playable;
|
||||
}
|
||||
}
|
||||
|
||||
public interface PSMPCallback {
|
||||
void statusChanged(PSMPInfo newInfo);
|
||||
|
||||
void shouldStop();
|
||||
|
||||
void playbackSpeedChanged(float s);
|
||||
|
||||
void setSpeedAbilityChanged();
|
||||
|
||||
void onBufferingUpdate(int percent);
|
||||
|
||||
void updateMediaSessionMetadata(Playable p);
|
||||
|
||||
boolean onMediaPlayerInfo(int code);
|
||||
|
||||
boolean onMediaPlayerError(Object inObj, int what, int extra);
|
||||
|
||||
boolean endPlayback(boolean playNextEpisode, boolean wasSkipped);
|
||||
}
|
||||
|
||||
private IPlayer setMediaPlayerListeners(IPlayer mp) {
|
||||
if (mp != null && media != null) {
|
||||
if (media.getMediaType() == MediaType.AUDIO) {
|
|
@ -174,7 +174,7 @@ public class PlaybackService extends Service implements SharedPreferences.OnShar
|
|||
|
||||
private static final int NOTIFICATION_ID = 1;
|
||||
|
||||
private PlaybackServiceMediaPlayer mediaPlayer;
|
||||
private IPlaybackServiceMediaPlayer mediaPlayer;
|
||||
private PlaybackServiceTaskManager taskManager;
|
||||
/**
|
||||
* Only used for Lollipop notifications.
|
||||
|
@ -248,7 +248,7 @@ public class PlaybackService extends Service implements SharedPreferences.OnShar
|
|||
registerReceiver(pauseResumeCurrentEpisodeReceiver, new IntentFilter(
|
||||
ACTION_RESUME_PLAY_CURRENT_EPISODE));
|
||||
taskManager = new PlaybackServiceTaskManager(this, taskManagerCallback);
|
||||
mediaPlayer = new PlaybackServiceMediaPlayer(this, mediaPlayerCallback);
|
||||
mediaPlayer = new LocalPSMP(this, mediaPlayerCallback);
|
||||
|
||||
ComponentName eventReceiver = new ComponentName(getApplicationContext(),
|
||||
MediaButtonReceiver.class);
|
||||
|
@ -353,7 +353,7 @@ public class PlaybackService extends Service implements SharedPreferences.OnShar
|
|||
*/
|
||||
private void handleKeycode(int keycode, int source) {
|
||||
Log.d(TAG, "Handling keycode: " + keycode);
|
||||
final PlaybackServiceMediaPlayer.PSMPInfo info = mediaPlayer.getPSMPInfo();
|
||||
final IPlaybackServiceMediaPlayer.PSMPInfo info = mediaPlayer.getPSMPInfo();
|
||||
final PlayerStatus status = info.playerStatus;
|
||||
switch (keycode) {
|
||||
case KeyEvent.KEYCODE_HEADSETHOOK:
|
||||
|
@ -491,9 +491,9 @@ public class PlaybackService extends Service implements SharedPreferences.OnShar
|
|||
}
|
||||
};
|
||||
|
||||
private final PlaybackServiceMediaPlayer.PSMPCallback mediaPlayerCallback = new PlaybackServiceMediaPlayer.PSMPCallback() {
|
||||
private final IPlaybackServiceMediaPlayer.PSMPCallback mediaPlayerCallback = new IPlaybackServiceMediaPlayer.PSMPCallback() {
|
||||
@Override
|
||||
public void statusChanged(PlaybackServiceMediaPlayer.PSMPInfo newInfo) {
|
||||
public void statusChanged(IPlaybackServiceMediaPlayer.PSMPInfo newInfo) {
|
||||
currentMediaType = mediaPlayer.getCurrentMediaType();
|
||||
updateMediaSession(newInfo.playerStatus);
|
||||
switch (newInfo.playerStatus) {
|
||||
|
@ -779,7 +779,7 @@ public class PlaybackService extends Service implements SharedPreferences.OnShar
|
|||
|
||||
SharedPreferences.Editor editor = PreferenceManager
|
||||
.getDefaultSharedPreferences(getApplicationContext()).edit();
|
||||
PlaybackServiceMediaPlayer.PSMPInfo info = mediaPlayer.getPSMPInfo();
|
||||
IPlaybackServiceMediaPlayer.PSMPInfo info = mediaPlayer.getPSMPInfo();
|
||||
MediaType mediaType = mediaPlayer.getCurrentMediaType();
|
||||
boolean stream = mediaPlayer.isStreaming();
|
||||
int playerStatus = getCurrentPlayerStatusAsInt(info.playerStatus);
|
||||
|
@ -940,7 +940,7 @@ public class PlaybackService extends Service implements SharedPreferences.OnShar
|
|||
/**
|
||||
* Prepares notification and starts the service in the foreground.
|
||||
*/
|
||||
private void setupNotification(final PlaybackServiceMediaPlayer.PSMPInfo info) {
|
||||
private void setupNotification(final IPlaybackServiceMediaPlayer.PSMPInfo info) {
|
||||
final PendingIntent pIntent = PendingIntent.getActivity(this, 0,
|
||||
PlaybackService.getPlayerActivityIntent(this),
|
||||
PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
|
@ -1144,7 +1144,7 @@ public class PlaybackService extends Service implements SharedPreferences.OnShar
|
|||
return taskManager.getSleepTimerTimeLeft();
|
||||
}
|
||||
|
||||
private void bluetoothNotifyChange(PlaybackServiceMediaPlayer.PSMPInfo info, String whatChanged) {
|
||||
private void bluetoothNotifyChange(IPlaybackServiceMediaPlayer.PSMPInfo info, String whatChanged) {
|
||||
boolean isPlaying = false;
|
||||
|
||||
if (info.playerStatus == PlayerStatus.PLAYING) {
|
||||
|
@ -1319,7 +1319,7 @@ public class PlaybackService extends Service implements SharedPreferences.OnShar
|
|||
mediaPlayer.reinit();
|
||||
}
|
||||
|
||||
public PlaybackServiceMediaPlayer.PSMPInfo getPSMPInfo() {
|
||||
public IPlaybackServiceMediaPlayer.PSMPInfo getPSMPInfo() {
|
||||
return mediaPlayer.getPSMPInfo();
|
||||
}
|
||||
|
||||
|
@ -1391,7 +1391,7 @@ public class PlaybackService extends Service implements SharedPreferences.OnShar
|
|||
}
|
||||
|
||||
/**
|
||||
* @see de.danoeh.antennapod.core.service.playback.PlaybackServiceMediaPlayer#seekToChapter(de.danoeh.antennapod.core.feed.Chapter)
|
||||
* @see LocalPSMP#seekToChapter(de.danoeh.antennapod.core.feed.Chapter)
|
||||
*/
|
||||
public void seekToChapter(Chapter c) {
|
||||
mediaPlayer.seekToChapter(c);
|
||||
|
|
|
@ -34,8 +34,8 @@ import de.danoeh.antennapod.core.feed.FeedMedia;
|
|||
import de.danoeh.antennapod.core.feed.MediaType;
|
||||
import de.danoeh.antennapod.core.preferences.PlaybackPreferences;
|
||||
import de.danoeh.antennapod.core.preferences.UserPreferences;
|
||||
import de.danoeh.antennapod.core.service.playback.LocalPSMP;
|
||||
import de.danoeh.antennapod.core.service.playback.PlaybackService;
|
||||
import de.danoeh.antennapod.core.service.playback.PlaybackServiceMediaPlayer;
|
||||
import de.danoeh.antennapod.core.service.playback.PlayerStatus;
|
||||
import de.danoeh.antennapod.core.storage.DBTasks;
|
||||
import de.danoeh.antennapod.core.util.Converter;
|
||||
|
@ -281,7 +281,7 @@ public abstract class PlaybackController {
|
|||
public void onReceive(Context context, Intent intent) {
|
||||
Log.d(TAG, "Received statusUpdate Intent.");
|
||||
if (isConnectedToPlaybackService()) {
|
||||
PlaybackServiceMediaPlayer.PSMPInfo info = playbackService.getPSMPInfo();
|
||||
LocalPSMP.PSMPInfo info = playbackService.getPSMPInfo();
|
||||
status = info.playerStatus;
|
||||
media = info.playable;
|
||||
handleStatus();
|
||||
|
|
Loading…
Reference in New Issue