From f8266d0181f09a21649e9636453d62fd3002860e Mon Sep 17 00:00:00 2001 From: Domingos Lopes Date: Thu, 28 Apr 2016 01:52:47 -0400 Subject: [PATCH] give error feedback to the user --- .../PlaybackServiceMediaPlayerTest.java | 26 +++++++++---------- .../activity/MediaplayerActivity.java | 6 ++--- .../activity/MediaplayerInfoActivity.java | 8 ++++-- .../activity/VideoplayerActivity.java | 2 +- .../core/service/playback/LocalPSMP.java | 2 +- .../service/playback/PlaybackService.java | 14 +++++++++- .../playback/PlaybackServiceMediaPlayer.java | 3 ++- .../core/service/playback/RemotePSMP.java | 18 +++++++++++-- .../core/util/playback/MediaPlayerError.java | 2 +- .../util/playback/PlaybackController.java | 15 ++++++----- core/src/main/res/values/strings.xml | 2 ++ 11 files changed, 67 insertions(+), 31 deletions(-) diff --git a/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceMediaPlayerTest.java b/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceMediaPlayerTest.java index b4e6710d2..195dccdda 100644 --- a/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceMediaPlayerTest.java +++ b/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceMediaPlayerTest.java @@ -186,7 +186,7 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase { } @Override - public boolean onMediaPlayerInfo(int code) { + public boolean onMediaPlayerInfo(int code, int resourceId) { return false; } @@ -265,7 +265,7 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase { } @Override - public boolean onMediaPlayerInfo(int code) { + public boolean onMediaPlayerInfo(int code, int resourceId) { return false; } @@ -347,7 +347,7 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase { } @Override - public boolean onMediaPlayerInfo(int code) { + public boolean onMediaPlayerInfo(int code, int resourceId) { return false; } @@ -430,7 +430,7 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase { } @Override - public boolean onMediaPlayerInfo(int code) { + public boolean onMediaPlayerInfo(int code, int resourceId) { return false; } @@ -507,7 +507,7 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase { } @Override - public boolean onMediaPlayerInfo(int code) { + public boolean onMediaPlayerInfo(int code, int resourceId) { return false; } @@ -585,7 +585,7 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase { } @Override - public boolean onMediaPlayerInfo(int code) { + public boolean onMediaPlayerInfo(int code, int resourceId) { return false; } @@ -665,7 +665,7 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase { } @Override - public boolean onMediaPlayerInfo(int code) { + public boolean onMediaPlayerInfo(int code, int resourceId) { return false; } @@ -748,7 +748,7 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase { } @Override - public boolean onMediaPlayerInfo(int code) { + public boolean onMediaPlayerInfo(int code, int resourceId) { return false; } @@ -806,7 +806,7 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase { } @Override - public boolean onMediaPlayerInfo(int code) { return false; } + public boolean onMediaPlayerInfo(int code, int resourceId) { return false; } @Override public boolean onMediaPlayerError(Object inObj, int what, int extra) { @@ -884,7 +884,7 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase { } @Override - public boolean onMediaPlayerInfo(int code) { + public boolean onMediaPlayerInfo(int code, int resourceId) { return false; } @@ -999,7 +999,7 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase { } @Override - public boolean onMediaPlayerInfo(int code) { + public boolean onMediaPlayerInfo(int code, int resourceId) { return false; } @@ -1091,7 +1091,7 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase { } @Override - public boolean onMediaPlayerInfo(int code) { + public boolean onMediaPlayerInfo(int code, int resourceId) { return false; } @@ -1195,7 +1195,7 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase { } @Override - public boolean onMediaPlayerInfo(int code) { + public boolean onMediaPlayerInfo(int code, int resourceId) { return false; } diff --git a/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java index 8c9bc6855..8ee91c7a3 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java @@ -125,8 +125,8 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements } @Override - public void postStatusMsg(int msg) { - MediaplayerActivity.this.postStatusMsg(msg); + public void postStatusMsg(int msg, boolean showToast) { + MediaplayerActivity.this.postStatusMsg(msg, showToast); } @Override @@ -585,7 +585,7 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements */ protected abstract void onAwaitingVideoSurface(); - protected abstract void postStatusMsg(int resId); + protected abstract void postStatusMsg(int resId, boolean showToast); protected abstract void clearStatusMsg(); diff --git a/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerInfoActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerInfoActivity.java index 588aa674d..0e39aa5c3 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerInfoActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerInfoActivity.java @@ -25,6 +25,7 @@ import android.widget.AdapterView; import android.widget.Button; import android.widget.ImageButton; import android.widget.ListView; +import android.widget.Toast; import com.viewpagerindicator.CirclePageIndicator; @@ -185,12 +186,15 @@ public abstract class MediaplayerInfoActivity extends MediaplayerActivity implem } @Override - protected void postStatusMsg(int resId) { + protected void postStatusMsg(int resId, boolean showToast) { if (resId == R.string.player_preparing_msg || resId == R.string.player_seeking_msg || resId == R.string.player_buffering_msg) { // TODO Show progress bar here } + if (showToast) { + Toast.makeText(this, resId, Toast.LENGTH_SHORT).show(); + } } @Override @@ -305,7 +309,7 @@ public abstract class MediaplayerInfoActivity extends MediaplayerActivity implem @Override protected void onBufferStart() { - postStatusMsg(R.string.player_buffering_msg); + postStatusMsg(R.string.player_buffering_msg, false); } @Override diff --git a/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java index cc2cef804..fa3d8e68d 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java @@ -164,7 +164,7 @@ public class VideoplayerActivity extends MediaplayerActivity { } @Override - protected void postStatusMsg(int resId) { + protected void postStatusMsg(int resId, boolean showToast) { if (resId == R.string.player_preparing_msg) { progressIndicator.setVisibility(View.VISIBLE); } else { diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/LocalPSMP.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/LocalPSMP.java index 32bafd580..be80ea112 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/playback/LocalPSMP.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/LocalPSMP.java @@ -848,7 +848,7 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer { (mp, what, extra) -> genericInfoListener(what); private boolean genericInfoListener(int what) { - return callback.onMediaPlayerInfo(what); + return callback.onMediaPlayerInfo(what, 0); } private final MediaPlayer.OnSpeedAdjustmentAvailableChangedListener audioSetSpeedAbilityListener = 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 1fb0b0b06..2e4a486e6 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 @@ -23,6 +23,7 @@ import android.os.IBinder; import android.os.Vibrator; import android.preference.PreferenceManager; import android.support.annotation.NonNull; +import android.support.annotation.StringRes; import android.support.v4.media.MediaMetadataCompat; import android.support.v4.media.session.MediaSessionCompat; import android.support.v4.media.session.PlaybackStateCompat; @@ -170,6 +171,11 @@ public class PlaybackService extends Service { */ public static final int NOTIFICATION_TYPE_SET_SPEED_ABILITY_CHANGED = 9; + /** + * Send a message to the user (with provided String resource id) + */ + public static final int NOTIFICATION_TYPE_SHOW_TOAST = 10; + /** * Returned by getPositionSafe() or getDurationSafe() if the playbackService * is in an invalid state. @@ -641,7 +647,7 @@ public class PlaybackService extends Service { } @Override - public boolean onMediaPlayerInfo(int code) { + public boolean onMediaPlayerInfo(int code, @StringRes int resourceId) { switch (code) { case MediaPlayer.MEDIA_INFO_BUFFERING_START: sendNotificationBroadcast(NOTIFICATION_TYPE_BUFFER_START, 0); @@ -649,6 +655,12 @@ public class PlaybackService extends Service { case MediaPlayer.MEDIA_INFO_BUFFERING_END: sendNotificationBroadcast(NOTIFICATION_TYPE_BUFFER_END, 0); return true; + case RemotePSMP.CAST_ERROR: + sendNotificationBroadcast(NOTIFICATION_TYPE_SHOW_TOAST, resourceId); + return true; + case RemotePSMP.CAST_ERROR_PRIORITY_HIGH: + Toast.makeText(PlaybackService.this, resourceId, Toast.LENGTH_SHORT).show(); + return true; default: return false; } 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/PlaybackServiceMediaPlayer.java index bd870a85d..f3a9c1d03 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/PlaybackServiceMediaPlayer.java @@ -3,6 +3,7 @@ package de.danoeh.antennapod.core.service.playback; import android.content.Context; import android.net.wifi.WifiManager; import android.support.annotation.NonNull; +import android.support.annotation.StringRes; import android.util.Log; import android.util.Pair; import android.view.SurfaceHolder; @@ -323,7 +324,7 @@ public abstract class PlaybackServiceMediaPlayer { void reloadUI(); - boolean onMediaPlayerInfo(int code); + boolean onMediaPlayerInfo(int code, @StringRes int resourceId); boolean onMediaPlayerError(Object inObj, int what, int extra); diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/RemotePSMP.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/RemotePSMP.java index c1ea07f2b..26ab3421e 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/playback/RemotePSMP.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/RemotePSMP.java @@ -17,6 +17,7 @@ import com.google.android.libraries.cast.companionlibrary.cast.exceptions.Transi import java.util.concurrent.atomic.AtomicBoolean; +import de.danoeh.antennapod.core.R; import de.danoeh.antennapod.core.cast.CastConsumer; import de.danoeh.antennapod.core.cast.CastManager; import de.danoeh.antennapod.core.cast.CastUtils; @@ -34,6 +35,10 @@ public class RemotePSMP extends PlaybackServiceMediaPlayer { public static final String TAG = "RemotePSMP"; + public static final int CAST_ERROR = 3001; + + public static final int CAST_ERROR_PRIORITY_HIGH = 3005; + private final CastManager castMgr; private volatile Playable media; @@ -120,13 +125,18 @@ public class RemotePSMP extends PlaybackServiceMediaPlayer { callback.endPlayback(media, true, false, false); } } + + @Override + public void onFailed(int resourceId, int statusCode) { + callback.onMediaPlayerInfo(CAST_ERROR, resourceId); + } }; private void setBuffering(boolean buffering) { if (buffering && isBuffering.compareAndSet(false, true)) { - callback.onMediaPlayerInfo(MediaPlayer.MEDIA_INFO_BUFFERING_START); + callback.onMediaPlayerInfo(MediaPlayer.MEDIA_INFO_BUFFERING_START, 0); } else if (!buffering && isBuffering.compareAndSet(true, false)) { - callback.onMediaPlayerInfo(MediaPlayer.MEDIA_INFO_BUFFERING_END); + callback.onMediaPlayerInfo(MediaPlayer.MEDIA_INFO_BUFFERING_END, 0); } } @@ -218,6 +228,8 @@ public class RemotePSMP extends PlaybackServiceMediaPlayer { case MediaStatus.IDLE_REASON_ERROR: Log.w(TAG, "Got an error status from the Chromecast. Skipping, if possible, to the next episode..."); setPlayerStatus(PlayerStatus.INDETERMINATE, currentMedia); + callback.onMediaPlayerInfo(CAST_ERROR_PRIORITY_HIGH, + R.string.cast_failed_media_error_skipping); endPlaybackCall.endPlayback(currentMedia, startWhenPrepared.get(), true, false); // endPlayback already updates the UI, so no need to trigger it ourselves updateUI = false; @@ -251,6 +263,8 @@ public class RemotePSMP extends PlaybackServiceMediaPlayer { private void playMediaObject(@NonNull final Playable playable, final boolean forceReset, final boolean stream, final boolean startWhenPrepared, final boolean prepareImmediately) { if (!CastUtils.isCastable(playable)) { Log.d(TAG, "media provided is not compatible with cast device"); + callback.onMediaPlayerInfo(CAST_ERROR_PRIORITY_HIGH, R.string.cast_not_castable); + callback.endPlayback(playable, startWhenPrepared, true, false); return; } diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/playback/MediaPlayerError.java b/core/src/main/java/de/danoeh/antennapod/core/util/playback/MediaPlayerError.java index 0650225f0..5ba7f11d6 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/playback/MediaPlayerError.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/playback/MediaPlayerError.java @@ -6,7 +6,7 @@ import de.danoeh.antennapod.core.R; /** Utility class for MediaPlayer errors. */ public class MediaPlayerError { - + /** Get a human-readable string for a specific error code. */ public static String getErrorString(Context context, int code) { int resId; 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 a08c7c398..7870c747e 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 @@ -338,6 +338,9 @@ public abstract class PlaybackController { break; case PlaybackService.NOTIFICATION_TYPE_SET_SPEED_ABILITY_CHANGED: onSetSpeedAbilityChanged(); + break; + case PlaybackService.NOTIFICATION_TYPE_SHOW_TOAST: + postStatusMsg(code, true); } } @@ -416,7 +419,7 @@ public abstract class PlaybackController { Log.d(TAG, "status: " + status.toString()); switch (status) { case ERROR: - postStatusMsg(R.string.player_error_msg); + postStatusMsg(R.string.player_error_msg, false); handleError(MediaPlayer.MEDIA_ERROR_UNKNOWN); break; case PAUSED: @@ -442,7 +445,7 @@ public abstract class PlaybackController { updatePlayButtonAppearance(pauseResource, pauseText); break; case PREPARING: - postStatusMsg(R.string.player_preparing_msg); + postStatusMsg(R.string.player_preparing_msg, false); checkMediaInfoLoaded(); if (playbackService != null) { if (playbackService.isStartWhenPrepared()) { @@ -453,16 +456,16 @@ public abstract class PlaybackController { } break; case STOPPED: - postStatusMsg(R.string.player_stopped_msg); + postStatusMsg(R.string.player_stopped_msg, false); break; case PREPARED: checkMediaInfoLoaded(); - postStatusMsg(R.string.player_ready_msg); + postStatusMsg(R.string.player_ready_msg, false); updatePlayButtonAppearance(playResource, playText); break; case SEEKING: onPositionObserverUpdate(); - postStatusMsg(R.string.player_seeking_msg); + postStatusMsg(R.string.player_seeking_msg, false); break; case INITIALIZED: checkMediaInfoLoaded(); @@ -488,7 +491,7 @@ public abstract class PlaybackController { return null; } - public void postStatusMsg(int msg) {} + public void postStatusMsg(int msg, boolean showToast) {} public void clearStatusMsg() {} diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml index 17d9c5c85..4b0f15df6 100644 --- a/core/src/main/res/values/strings.xml +++ b/core/src/main/res/values/strings.xml @@ -619,6 +619,7 @@ Play on… Disconnect the cast session + Media selected is not compatible with cast device Failed to start the playback of media Failed to stop the playback of media Failed to pause the playback of media @@ -630,4 +631,5 @@ Failed to sync up with the cast device Failed to seek to the new position on the cast device Receiver player has encountered a severe error + Error playing media. Skipping…