summaryrefslogtreecommitdiff
path: root/core/src/main/java/de/danoeh
diff options
context:
space:
mode:
authorDomingos Lopes <domingos86lopes@gmail.com>2016-03-19 11:37:37 -0400
committerDomingos Lopes <domingos86lopes+github@gmail.com>2016-04-23 21:39:52 -0400
commitafbae2a7ef8b0466e8e89e82708c2fcb9f77ff35 (patch)
tree65c87fe15ec3c32e59d1c5ae46c75945088e9628 /core/src/main/java/de/danoeh
parent8061d94c1b2dcdc99fc0a3c4554a00f01ca4941f (diff)
downloadAntennaPod-afbae2a7ef8b0466e8e89e82708c2fcb9f77ff35.zip
Create interface for PlaybackServiceMediaPlayer
Diffstat (limited to 'core/src/main/java/de/danoeh')
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/playback/IPlaybackServiceMediaPlayer.java108
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/playback/LocalPSMP.java (renamed from core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceMediaPlayer.java)72
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java20
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java4
4 files changed, 154 insertions, 50 deletions
diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/IPlaybackServiceMediaPlayer.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/IPlaybackServiceMediaPlayer.java
new file mode 100644
index 000000000..c300d48d1
--- /dev/null
+++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/IPlaybackServiceMediaPlayer.java
@@ -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;
+ }
+ }
+}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceMediaPlayer.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/LocalPSMP.java
index d8b334295..1293638ed 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceMediaPlayer.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/LocalPSMP.java
@@ -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) {
diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java
index 6ab9859ac..47f7e8dc8 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java
@@ -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);
diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java b/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java
index 1409ffe09..03f0ab497 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java
@@ -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();