summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/build.gradle4
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/feed/LocalFeedUpdater.java35
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/glide/ApGlideModule.java1
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/glide/GenerativePlaceholderImageModelLoader.java139
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/preferences/PlaybackPreferences.java12
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/download/handler/FeedParserTask.java4
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/playback/LocalPSMP.java1
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java82
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java2
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackServiceStarter.java16
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/widget/WidgetUpdater.java10
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/widget/WidgetUpdaterJobService.java4
-rw-r--r--core/src/main/res/raw/local_feed_default_icon.pngbin1240 -> 0 bytes
-rw-r--r--core/src/test/java/de/danoeh/antennapod/core/feed/LocalFeedUpdaterTest.java28
14 files changed, 205 insertions, 133 deletions
diff --git a/core/build.gradle b/core/build.gradle
index 700487701..af0e2a7a7 100644
--- a/core/build.gradle
+++ b/core/build.gradle
@@ -1,4 +1,6 @@
-apply plugin: "com.android.library"
+plugins {
+ id("com.android.library")
+}
apply from: "../common.gradle"
apply from: "../playFlavor.gradle"
diff --git a/core/src/main/java/de/danoeh/antennapod/core/feed/LocalFeedUpdater.java b/core/src/main/java/de/danoeh/antennapod/core/feed/LocalFeedUpdater.java
index 5d685c24f..e0e1bbaa5 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/feed/LocalFeedUpdater.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/feed/LocalFeedUpdater.java
@@ -1,6 +1,5 @@
package de.danoeh.antennapod.core.feed;
-import android.content.ContentResolver;
import android.content.Context;
import android.media.MediaMetadataRetriever;
import android.net.Uri;
@@ -34,6 +33,7 @@ import de.danoeh.antennapod.model.feed.FeedItem;
import de.danoeh.antennapod.model.feed.FeedMedia;
import de.danoeh.antennapod.model.feed.FeedPreferences;
import de.danoeh.antennapod.model.playback.MediaType;
+import de.danoeh.antennapod.parser.feed.util.MimeTypeUtils;
public class LocalFeedUpdater {
@@ -74,21 +74,8 @@ public class LocalFeedUpdater {
List<DocumentFile> mediaFiles = new ArrayList<>();
Set<String> mediaFileNames = new HashSet<>();
for (DocumentFile file : documentFolder.listFiles()) {
- String mime = file.getType();
- if (mime == null) {
- continue;
- }
-
- MediaType mediaType = MediaType.fromMimeType(mime);
- if (mediaType == MediaType.UNKNOWN) {
- String path = file.getUri().toString();
- int fileExtensionPosition = path.lastIndexOf('.');
- if (fileExtensionPosition >= 0) {
- String extensionWithoutDot = path.substring(fileExtensionPosition + 1);
- mediaType = MediaType.fromFileExtension(extensionWithoutDot);
- }
- }
-
+ String mimeType = MimeTypeUtils.getMimeType(file.getType(), file.getUri().toString());
+ MediaType mediaType = MediaType.fromMimeType(mimeType);
if (mediaType == MediaType.AUDIO || mediaType == MediaType.VIDEO) {
mediaFiles.add(file);
mediaFileNames.add(file.getName());
@@ -116,7 +103,7 @@ public class LocalFeedUpdater {
}
}
- feed.setImageUrl(getImageUrl(context, documentFolder));
+ feed.setImageUrl(getImageUrl(documentFolder));
feed.getPreferences().setAutoDownload(false);
feed.getPreferences().setAutoDeleteAction(FeedPreferences.AutoDeleteAction.NO);
@@ -134,7 +121,7 @@ public class LocalFeedUpdater {
* Returns the image URL for the local feed.
*/
@NonNull
- static String getImageUrl(@NonNull Context context, @NonNull DocumentFile documentFolder) {
+ static String getImageUrl(@NonNull DocumentFile documentFolder) {
// look for special file names
for (String iconLocation : PREFERRED_FEED_IMAGE_FILENAMES) {
DocumentFile image = documentFolder.findFile(iconLocation);
@@ -152,17 +139,7 @@ public class LocalFeedUpdater {
}
// use default icon as fallback
- return getDefaultIconUrl(context);
- }
-
- /**
- * Returns the URL of the default icon for a local feed. The URL refers to an app resource file.
- */
- public static String getDefaultIconUrl(Context context) {
- String resourceEntryName = context.getResources().getResourceEntryName(R.raw.local_feed_default_icon);
- return ContentResolver.SCHEME_ANDROID_RESOURCE + "://"
- + context.getPackageName() + "/raw/"
- + resourceEntryName;
+ return Feed.PREFIX_GENERATIVE_COVER + documentFolder.getUri();
}
private static FeedItem feedContainsFile(Feed feed, String filename) {
diff --git a/core/src/main/java/de/danoeh/antennapod/core/glide/ApGlideModule.java b/core/src/main/java/de/danoeh/antennapod/core/glide/ApGlideModule.java
index 797addcc1..593b683f7 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/glide/ApGlideModule.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/glide/ApGlideModule.java
@@ -42,6 +42,7 @@ public class ApGlideModule extends AppGlideModule {
@Override
public void registerComponents(@NonNull Context context, @NonNull Glide glide, @NonNull Registry registry) {
registry.replace(String.class, InputStream.class, new MetadataRetrieverLoader.Factory(context));
+ registry.append(String.class, InputStream.class, new GenerativePlaceholderImageModelLoader.Factory());
registry.append(String.class, InputStream.class, new ApOkHttpUrlLoader.Factory());
registry.append(String.class, InputStream.class, new NoHttpStringLoader.StreamFactory());
diff --git a/core/src/main/java/de/danoeh/antennapod/core/glide/GenerativePlaceholderImageModelLoader.java b/core/src/main/java/de/danoeh/antennapod/core/glide/GenerativePlaceholderImageModelLoader.java
new file mode 100644
index 000000000..a2263bc28
--- /dev/null
+++ b/core/src/main/java/de/danoeh/antennapod/core/glide/GenerativePlaceholderImageModelLoader.java
@@ -0,0 +1,139 @@
+package de.danoeh.antennapod.core.glide;
+
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.LinearGradient;
+import android.graphics.Paint;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffColorFilter;
+import android.graphics.Shader;
+import androidx.annotation.NonNull;
+import com.bumptech.glide.Priority;
+import com.bumptech.glide.load.DataSource;
+import com.bumptech.glide.load.Options;
+import com.bumptech.glide.load.data.DataFetcher;
+import com.bumptech.glide.load.model.ModelLoader;
+import com.bumptech.glide.load.model.ModelLoaderFactory;
+import com.bumptech.glide.load.model.MultiModelLoaderFactory;
+import com.bumptech.glide.signature.ObjectKey;
+import de.danoeh.antennapod.model.feed.Feed;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.util.Random;
+
+public final class GenerativePlaceholderImageModelLoader implements ModelLoader<String, InputStream> {
+
+ public static class Factory implements ModelLoaderFactory<String, InputStream> {
+ @NonNull
+ @Override
+ public ModelLoader<String, InputStream> build(@NonNull MultiModelLoaderFactory unused) {
+ return new GenerativePlaceholderImageModelLoader();
+ }
+
+ @Override
+ public void teardown() {
+ // Do nothing.
+ }
+ }
+
+ @Override
+ public LoadData<InputStream> buildLoadData(@NonNull String model, int width, int height, @NonNull Options options) {
+ return new LoadData<>(new ObjectKey(model), new EmbeddedImageFetcher(model, width, height));
+ }
+
+ @Override
+ public boolean handles(@NonNull String model) {
+ return model.startsWith(Feed.PREFIX_GENERATIVE_COVER);
+ }
+
+ static class EmbeddedImageFetcher implements DataFetcher<InputStream> {
+ private static final int[] PALETTES = {0xff78909c, 0xffff6f00, 0xff388e3c,
+ 0xff00838f, 0xff7b1fa2, 0xffb71c1c, 0xff2196f3};
+ private final String model;
+ private final int width;
+ private final int height;
+
+ public EmbeddedImageFetcher(String model, int width, int height) {
+ this.model = model;
+ this.width = width;
+ this.height = height;
+ }
+
+ @Override
+ public void loadData(@NonNull Priority priority, @NonNull DataCallback<? super InputStream> callback) {
+ final Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+ final Canvas canvas = new Canvas(bitmap);
+ final Random generator = new Random(model.hashCode());
+ final int lineGridSteps = 4 + generator.nextInt(4);
+ final int slope = width / 4;
+ final float shadowWidth = width * 0.01f;
+ final float lineDistance = ((float) width / (lineGridSteps - 2));
+ final int baseColor = PALETTES[generator.nextInt(PALETTES.length)];
+
+ Paint paint = new Paint();
+ int color = randomShadeOfGrey(generator);
+ paint.setColor(color);
+ paint.setStrokeWidth(lineDistance);
+ paint.setColorFilter(new PorterDuffColorFilter(baseColor, PorterDuff.Mode.MULTIPLY));
+ Paint paintShadow = new Paint();
+ paintShadow.setColor(0xff000000);
+ paintShadow.setStrokeWidth(lineDistance);
+
+ int forcedColorChange = 1 + generator.nextInt(lineGridSteps - 2);
+ for (int i = lineGridSteps - 1; i >= 0; i--) {
+ float linePos = (i - 0.5f) * lineDistance;
+ boolean switchColor = generator.nextFloat() < 0.3f || i == forcedColorChange;
+ if (switchColor) {
+ int newColor = color;
+ while (newColor == color) {
+ newColor = randomShadeOfGrey(generator);
+ }
+ color = newColor;
+ paint.setColor(newColor);
+ canvas.drawLine(linePos + slope + shadowWidth, -slope,
+ linePos - slope + shadowWidth, height + slope, paintShadow);
+ }
+ canvas.drawLine(linePos + slope, -slope,
+ linePos - slope, height + slope, paint);
+ }
+
+ Paint gradientPaint = new Paint();
+ paint.setDither(true);
+ gradientPaint.setShader(new LinearGradient(0, 0, 0, height, 0x00000000, 0x55000000, Shader.TileMode.CLAMP));
+ canvas.drawRect(0, 0, width, height, gradientPaint);
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
+ InputStream is = new ByteArrayInputStream(baos.toByteArray());
+ callback.onDataReady(is);
+ }
+
+ private static int randomShadeOfGrey(Random generator) {
+ return 0xff777777 + 0x222222 * generator.nextInt(5);
+ }
+
+ @Override
+ public void cleanup() {
+ // nothing to clean up
+ }
+
+ @Override
+ public void cancel() {
+ // cannot cancel
+ }
+
+ @NonNull
+ @Override
+ public Class<InputStream> getDataClass() {
+ return InputStream.class;
+ }
+
+ @NonNull
+ @Override
+ public DataSource getDataSource() {
+ return DataSource.LOCAL;
+ }
+ }
+}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/preferences/PlaybackPreferences.java b/core/src/main/java/de/danoeh/antennapod/core/preferences/PlaybackPreferences.java
index f0c61403f..b0321bff6 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/preferences/PlaybackPreferences.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/preferences/PlaybackPreferences.java
@@ -45,11 +45,6 @@ public class PlaybackPreferences implements SharedPreferences.OnSharedPreference
= "de.danoeh.antennapod.preferences.currentlyPlayingMedia";
/**
- * True if last played media was streamed.
- */
- private static final String PREF_CURRENT_EPISODE_IS_STREAM = "de.danoeh.antennapod.preferences.lastIsStream";
-
- /**
* True if last played media was a video.
*/
private static final String PREF_CURRENT_EPISODE_IS_VIDEO = "de.danoeh.antennapod.preferences.lastIsVideo";
@@ -113,10 +108,6 @@ public class PlaybackPreferences implements SharedPreferences.OnSharedPreference
return prefs.getLong(PREF_CURRENTLY_PLAYING_FEEDMEDIA_ID, NO_MEDIA_PLAYING);
}
- public static boolean getCurrentEpisodeIsStream() {
- return prefs.getBoolean(PREF_CURRENT_EPISODE_IS_STREAM, true);
- }
-
public static boolean getCurrentEpisodeIsVideo() {
return prefs.getBoolean(PREF_CURRENT_EPISODE_IS_VIDEO, false);
}
@@ -138,7 +129,7 @@ public class PlaybackPreferences implements SharedPreferences.OnSharedPreference
editor.apply();
}
- public static void writeMediaPlaying(Playable playable, PlayerStatus playerStatus, boolean stream) {
+ public static void writeMediaPlaying(Playable playable, PlayerStatus playerStatus) {
Log.d(TAG, "Writing playback preferences");
SharedPreferences.Editor editor = prefs.edit();
@@ -146,7 +137,6 @@ public class PlaybackPreferences implements SharedPreferences.OnSharedPreference
writeNoMediaPlaying();
} else {
editor.putLong(PREF_CURRENTLY_PLAYING_MEDIA_TYPE, playable.getPlayableType());
- editor.putBoolean(PREF_CURRENT_EPISODE_IS_STREAM, stream);
editor.putBoolean(PREF_CURRENT_EPISODE_IS_VIDEO, playable.getMediaType() == MediaType.VIDEO);
if (playable instanceof FeedMedia) {
FeedMedia feedMedia = (FeedMedia) playable;
diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/download/handler/FeedParserTask.java b/core/src/main/java/de/danoeh/antennapod/core/service/download/handler/FeedParserTask.java
index 21d3452d6..7e3b07880 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/service/download/handler/FeedParserTask.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/service/download/handler/FeedParserTask.java
@@ -1,5 +1,6 @@
package de.danoeh.antennapod.core.service.download.handler;
+import android.text.TextUtils;
import android.util.Log;
import de.danoeh.antennapod.model.feed.Feed;
import de.danoeh.antennapod.model.feed.FeedItem;
@@ -48,6 +49,9 @@ public class FeedParserTask implements Callable<FeedHandlerResult> {
result = feedHandler.parseFeed(feed);
Log.d(TAG, feed.getTitle() + " parsed");
checkFeedData(feed);
+ if (TextUtils.isEmpty(feed.getImageUrl())) {
+ feed.setImageUrl(Feed.PREFIX_GENERATIVE_COVER + feed.getDownload_url());
+ }
} catch (SAXException | IOException | ParserConfigurationException e) {
successful = false;
e.printStackTrace();
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 db6088d8d..1ef06c511 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
@@ -868,7 +868,6 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
pausedBecauseOfTransientAudiofocusLoss = false;
new PlaybackServiceStarter(context, getPlayable())
.startWhenPrepared(true)
- .streamIfLastWasStream()
.callEvenIfRunning(false)
.start();
}
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 76fdc1040..c6cff1bd3 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
@@ -108,7 +108,6 @@ public class PlaybackService extends MediaBrowserServiceCompat {
private static final String TAG = "PlaybackService";
public static final String EXTRA_PLAYABLE = "PlaybackService.PlayableExtra";
- public static final String EXTRA_SHOULD_STREAM = "extra.de.danoeh.antennapod.core.service.shouldStream";
public static final String EXTRA_ALLOW_STREAM_THIS_TIME = "extra.de.danoeh.antennapod.core.service.allowStream";
public static final String EXTRA_ALLOW_STREAM_ALWAYS = "extra.de.danoeh.antennapod.core.service.allowStreamAlways";
public static final String EXTRA_START_WHEN_PREPARED = "extra.de.danoeh.antennapod.core.service.startWhenPrepared";
@@ -522,7 +521,6 @@ public class PlaybackService extends MediaBrowserServiceCompat {
}
} else {
stateManager.validStartCommandWasReceived();
- boolean stream = intent.getBooleanExtra(EXTRA_SHOULD_STREAM, true);
boolean allowStreamThisTime = intent.getBooleanExtra(EXTRA_ALLOW_STREAM_THIS_TIME, false);
boolean allowStreamAlways = intent.getBooleanExtra(EXTRA_ALLOW_STREAM_ALWAYS, false);
boolean startWhenPrepared = intent.getBooleanExtra(EXTRA_START_WHEN_PREPARED, false);
@@ -531,14 +529,6 @@ public class PlaybackService extends MediaBrowserServiceCompat {
if (allowStreamAlways) {
UserPreferences.setAllowMobileStreaming(true);
}
- boolean localFeed = URLUtil.isContentUrl(playable.getStreamUrl());
- if (stream && !NetworkUtils.isStreamingAllowed() && !allowStreamThisTime && !localFeed) {
- displayStreamingNotAllowedNotification(intent);
- PlaybackPreferences.writeNoMediaPlaying();
- stateManager.stopService();
- return Service.START_NOT_STICKY;
- }
-
Observable.fromCallable(
() -> {
if (playable instanceof FeedMedia) {
@@ -550,15 +540,9 @@ public class PlaybackService extends MediaBrowserServiceCompat {
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
- playableLoaded -> {
- if (!playable.getIdentifier().equals(
- PlaybackPreferences.getCurrentlyPlayingFeedMediaId())) {
- PlaybackPreferences.clearCurrentlyPlayingTemporaryPlaybackSpeed();
- }
- mediaPlayer.playMediaObject(playableLoaded, stream, startWhenPrepared,
- prepareImmediately);
- addPlayableToQueue(playableLoaded);
- }, error -> {
+ loadedPlayable -> startPlaying(loadedPlayable, allowStreamThisTime,
+ startWhenPrepared, prepareImmediately),
+ error -> {
Log.d(TAG, "Playable was not found. Stopping service.");
error.printStackTrace();
stateManager.stopService();
@@ -741,32 +725,39 @@ public class PlaybackService extends MediaBrowserServiceCompat {
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
- playable -> {
- boolean localFeed = URLUtil.isContentUrl(playable.getStreamUrl());
- if (PlaybackPreferences.getCurrentEpisodeIsStream()
- && !NetworkUtils.isStreamingAllowed() && !localFeed) {
- displayStreamingNotAllowedNotification(
- new PlaybackServiceStarter(this, playable)
- .prepareImmediately(true)
- .startWhenPrepared(true)
- .shouldStream(true)
- .getIntent());
- PlaybackPreferences.writeNoMediaPlaying();
- stateManager.stopService();
- return;
- }
- mediaPlayer.playMediaObject(playable, PlaybackPreferences.getCurrentEpisodeIsStream(),
- true, true);
- stateManager.validStartCommandWasReceived();
- updateNotificationAndMediaSession(playable);
- addPlayableToQueue(playable);
- }, error -> {
+ playable -> startPlaying(playable, false, true, true),
+ error -> {
Log.d(TAG, "Playable was not loaded from preferences. Stopping service.");
error.printStackTrace();
stateManager.stopService();
});
}
+ private void startPlaying(Playable playable, boolean allowStreamThisTime,
+ boolean startWhenPrepared, boolean prepareImmediately) {
+ boolean localFeed = URLUtil.isContentUrl(playable.getStreamUrl());
+ boolean stream = !playable.localFileAvailable() || localFeed;
+ if (stream && !localFeed && !NetworkUtils.isStreamingAllowed() && !allowStreamThisTime) {
+ displayStreamingNotAllowedNotification(
+ new PlaybackServiceStarter(this, playable)
+ .prepareImmediately(true)
+ .startWhenPrepared(true)
+ .getIntent());
+ PlaybackPreferences.writeNoMediaPlaying();
+ stateManager.stopService();
+ return;
+ }
+
+ if (!playable.getIdentifier().equals(PlaybackPreferences.getCurrentlyPlayingFeedMediaId())) {
+ PlaybackPreferences.clearCurrentlyPlayingTemporaryPlaybackSpeed();
+ }
+
+ mediaPlayer.playMediaObject(playable, stream, startWhenPrepared, prepareImmediately);
+ stateManager.validStartCommandWasReceived();
+ updateNotificationAndMediaSession(playable);
+ addPlayableToQueue(playable);
+ }
+
/**
* Called by a mediaplayer Activity as soon as it has prepared its
* mediaplayer.
@@ -792,7 +783,7 @@ public class PlaybackService extends MediaBrowserServiceCompat {
@Override
public WidgetUpdater.WidgetState requestWidgetState() {
return new WidgetUpdater.WidgetState(getPlayable(), getStatus(),
- getCurrentPosition(), getDuration(), getCurrentPlaybackSpeed(), isCasting());
+ getCurrentPosition(), getDuration(), getCurrentPlaybackSpeed());
}
@Override
@@ -814,7 +805,7 @@ public class PlaybackService extends MediaBrowserServiceCompat {
switch (newInfo.playerStatus) {
case INITIALIZED:
PlaybackPreferences.writeMediaPlaying(mediaPlayer.getPSMPInfo().playable,
- mediaPlayer.getPSMPInfo().playerStatus, mediaPlayer.isStreaming());
+ mediaPlayer.getPSMPInfo().playerStatus);
updateNotificationAndMediaSession(newInfo.playable);
break;
case PREPARED:
@@ -1005,7 +996,7 @@ public class PlaybackService extends MediaBrowserServiceCompat {
if (!UserPreferences.isFollowQueue()) {
Log.d(TAG, "getNextInQueue(), but follow queue is not enabled.");
- PlaybackPreferences.writeMediaPlaying(nextItem.getMedia(), PlayerStatus.STOPPED, false);
+ PlaybackPreferences.writeMediaPlaying(nextItem.getMedia(), PlayerStatus.STOPPED);
updateNotificationAndMediaSession(nextItem.getMedia());
return null;
}
@@ -1016,7 +1007,6 @@ public class PlaybackService extends MediaBrowserServiceCompat {
new PlaybackServiceStarter(this, nextItem.getMedia())
.prepareImmediately(true)
.startWhenPrepared(true)
- .shouldStream(true)
.getIntent());
PlaybackPreferences.writeNoMediaPlaying();
stateManager.stopService();
@@ -1805,8 +1795,7 @@ public class PlaybackService extends MediaBrowserServiceCompat {
Log.d(TAG, "onPlayFromMediaId: mediaId: " + mediaId + " extras: " + extras.toString());
FeedMedia p = DBReader.getFeedMedia(Long.parseLong(mediaId));
if (p != null) {
- mediaPlayer.playMediaObject(p, !p.localFileAvailable(), true, true);
- addPlayableToQueue(p);
+ startPlaying(p, false, true, true);
}
}
@@ -1817,8 +1806,7 @@ public class PlaybackService extends MediaBrowserServiceCompat {
List<FeedItem> results = FeedSearcher.searchFeedItems(getBaseContext(), query, 0);
if (results.size() > 0 && results.get(0).getMedia() != null) {
FeedMedia media = results.get(0).getMedia();
- mediaPlayer.playMediaObject(media, !media.localFileAvailable(), true, true);
- addPlayableToQueue(media);
+ startPlaying(media, false, true, true);
return;
}
onPlay();
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 549171c76..687a0d80a 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
@@ -331,7 +331,6 @@ public abstract class PlaybackController {
if (playbackService == null) {
new PlaybackServiceStarter(activity, media)
.startWhenPrepared(true)
- .streamIfLastWasStream()
.start();
Log.w(TAG, "Play/Pause button was pressed, but playbackservice was null!");
return;
@@ -354,7 +353,6 @@ public abstract class PlaybackController {
default:
new PlaybackServiceStarter(activity, media)
.startWhenPrepared(true)
- .streamIfLastWasStream()
.callEvenIfRunning(true)
.start();
Log.w(TAG, "Play/Pause button was pressed and PlaybackService state was unknown");
diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackServiceStarter.java b/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackServiceStarter.java
index 3efded9ed..7cf6b9adb 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackServiceStarter.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackServiceStarter.java
@@ -5,7 +5,6 @@ import android.content.Intent;
import android.os.Parcelable;
import androidx.core.content.ContextCompat;
-import de.danoeh.antennapod.core.preferences.PlaybackPreferences;
import de.danoeh.antennapod.core.service.playback.PlaybackService;
import de.danoeh.antennapod.model.playback.Playable;
@@ -13,7 +12,6 @@ public class PlaybackServiceStarter {
private final Context context;
private final Playable media;
private boolean startWhenPrepared = false;
- private boolean shouldStream = false;
private boolean shouldStreamThisTime = false;
private boolean callEvenIfRunning = false;
private boolean prepareImmediately = true;
@@ -26,19 +24,6 @@ public class PlaybackServiceStarter {
/**
* Default value: false
*/
- public PlaybackServiceStarter shouldStream(boolean shouldStream) {
- this.shouldStream = shouldStream;
- return this;
- }
-
- public PlaybackServiceStarter streamIfLastWasStream() {
- boolean lastIsStream = PlaybackPreferences.getCurrentEpisodeIsStream();
- return shouldStream(lastIsStream);
- }
-
- /**
- * Default value: false
- */
public PlaybackServiceStarter startWhenPrepared(boolean startWhenPrepared) {
this.startWhenPrepared = startWhenPrepared;
return this;
@@ -69,7 +54,6 @@ public class PlaybackServiceStarter {
Intent launchIntent = new Intent(context, PlaybackService.class);
launchIntent.putExtra(PlaybackService.EXTRA_PLAYABLE, (Parcelable) media);
launchIntent.putExtra(PlaybackService.EXTRA_START_WHEN_PREPARED, startWhenPrepared);
- launchIntent.putExtra(PlaybackService.EXTRA_SHOULD_STREAM, shouldStream);
launchIntent.putExtra(PlaybackService.EXTRA_PREPARE_IMMEDIATELY, prepareImmediately);
launchIntent.putExtra(PlaybackService.EXTRA_ALLOW_STREAM_THIS_TIME, shouldStreamThisTime);
diff --git a/core/src/main/java/de/danoeh/antennapod/core/widget/WidgetUpdater.java b/core/src/main/java/de/danoeh/antennapod/core/widget/WidgetUpdater.java
index 2762fb9fe..1253c747b 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/widget/WidgetUpdater.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/widget/WidgetUpdater.java
@@ -45,20 +45,17 @@ public abstract class WidgetUpdater {
final int position;
final int duration;
final float playbackSpeed;
- final boolean isCasting;
- public WidgetState(Playable media, PlayerStatus status, int position, int duration,
- float playbackSpeed, boolean isCasting) {
+ public WidgetState(Playable media, PlayerStatus status, int position, int duration, float playbackSpeed) {
this.media = media;
this.status = status;
this.position = position;
this.duration = duration;
this.playbackSpeed = playbackSpeed;
- this.isCasting = isCasting;
}
public WidgetState(PlayerStatus status) {
- this(null, status, Playable.INVALID_TIME, Playable.INVALID_TIME, 1.0f, false);
+ this(null, status, Playable.INVALID_TIME, Playable.INVALID_TIME, 1.0f);
}
}
@@ -71,8 +68,7 @@ public abstract class WidgetUpdater {
}
PendingIntent startMediaPlayer;
- if (widgetState.media != null && widgetState.media.getMediaType() == MediaType.VIDEO
- && !widgetState.isCasting) {
+ if (widgetState.media != null && widgetState.media.getMediaType() == MediaType.VIDEO) {
startMediaPlayer = new VideoPlayerActivityStarter(context).getPendingIntent();
} else {
startMediaPlayer = new MainActivityStarter(context).withOpenPlayer().getPendingIntent();
diff --git a/core/src/main/java/de/danoeh/antennapod/core/widget/WidgetUpdaterJobService.java b/core/src/main/java/de/danoeh/antennapod/core/widget/WidgetUpdaterJobService.java
index 325c508c5..598544a0c 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/widget/WidgetUpdaterJobService.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/widget/WidgetUpdaterJobService.java
@@ -5,7 +5,6 @@ import android.content.Intent;
import androidx.annotation.NonNull;
import androidx.core.app.SafeJobIntentService;
import de.danoeh.antennapod.core.feed.util.PlaybackSpeedUtils;
-import de.danoeh.antennapod.core.preferences.PlaybackPreferences;
import de.danoeh.antennapod.model.playback.Playable;
import de.danoeh.antennapod.core.util.playback.PlayableUtils;
import de.danoeh.antennapod.playback.base.PlayerStatus;
@@ -26,8 +25,7 @@ public class WidgetUpdaterJobService extends SafeJobIntentService {
Playable media = PlayableUtils.createInstanceFromPreferences(getApplicationContext());
if (media != null) {
WidgetUpdater.updateWidget(this, new WidgetUpdater.WidgetState(media, PlayerStatus.STOPPED,
- media.getPosition(), media.getDuration(), PlaybackSpeedUtils.getCurrentPlaybackSpeed(media),
- PlaybackPreferences.getCurrentEpisodeIsStream()));
+ media.getPosition(), media.getDuration(), PlaybackSpeedUtils.getCurrentPlaybackSpeed(media)));
} else {
WidgetUpdater.updateWidget(this, new WidgetUpdater.WidgetState(PlayerStatus.STOPPED));
}
diff --git a/core/src/main/res/raw/local_feed_default_icon.png b/core/src/main/res/raw/local_feed_default_icon.png
deleted file mode 100644
index c1b24a729..000000000
--- a/core/src/main/res/raw/local_feed_default_icon.png
+++ /dev/null
Binary files differ
diff --git a/core/src/test/java/de/danoeh/antennapod/core/feed/LocalFeedUpdaterTest.java b/core/src/test/java/de/danoeh/antennapod/core/feed/LocalFeedUpdaterTest.java
index eb56a1876..37d525670 100644
--- a/core/src/test/java/de/danoeh/antennapod/core/feed/LocalFeedUpdaterTest.java
+++ b/core/src/test/java/de/danoeh/antennapod/core/feed/LocalFeedUpdaterTest.java
@@ -31,7 +31,6 @@ import java.util.List;
import de.danoeh.antennapod.core.ApplicationCallbacks;
import de.danoeh.antennapod.core.ClientConfig;
-import de.danoeh.antennapod.core.R;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBWriter;
@@ -41,6 +40,7 @@ import static org.hamcrest.CoreMatchers.endsWith;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.empty;
+import static org.hamcrest.Matchers.startsWith;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.mock;
@@ -158,8 +158,7 @@ public class LocalFeedUpdaterTest {
callUpdateFeed(LOCAL_FEED_DIR1);
Feed feedAfter = verifySingleFeedInDatabase();
- String resourceEntryName = context.getResources().getResourceEntryName(R.raw.local_feed_default_icon);
- assertThat(feedAfter.getImageUrl(), endsWith(resourceEntryName));
+ assertThat(feedAfter.getImageUrl(), startsWith(Feed.PREFIX_GENERATIVE_COVER));
}
/**
@@ -191,17 +190,15 @@ public class LocalFeedUpdaterTest {
@Test
public void testGetImageUrl_EmptyFolder() {
DocumentFile documentFolder = mockDocumentFolder();
- String imageUrl = LocalFeedUpdater.getImageUrl(context, documentFolder);
- String defaultImageName = context.getResources().getResourceEntryName(R.raw.local_feed_default_icon);
- assertThat(imageUrl, endsWith(defaultImageName));
+ String imageUrl = LocalFeedUpdater.getImageUrl(documentFolder);
+ assertThat(imageUrl, startsWith(Feed.PREFIX_GENERATIVE_COVER));
}
@Test
public void testGetImageUrl_NoImageButAudioFiles() {
DocumentFile documentFolder = mockDocumentFolder(mockDocumentFile("audio.mp3", "audio/mp3"));
- String imageUrl = LocalFeedUpdater.getImageUrl(context, documentFolder);
- String defaultImageName = context.getResources().getResourceEntryName(R.raw.local_feed_default_icon);
- assertThat(imageUrl, endsWith(defaultImageName));
+ String imageUrl = LocalFeedUpdater.getImageUrl(documentFolder);
+ assertThat(imageUrl, startsWith(Feed.PREFIX_GENERATIVE_COVER));
}
@Test
@@ -209,7 +206,7 @@ public class LocalFeedUpdaterTest {
for (String filename : LocalFeedUpdater.PREFERRED_FEED_IMAGE_FILENAMES) {
DocumentFile documentFolder = mockDocumentFolder(mockDocumentFile("audio.mp3", "audio/mp3"),
mockDocumentFile(filename, "image/jpeg")); // image MIME type doesn't matter
- String imageUrl = LocalFeedUpdater.getImageUrl(context, documentFolder);
+ String imageUrl = LocalFeedUpdater.getImageUrl(documentFolder);
assertThat(imageUrl, endsWith(filename));
}
}
@@ -218,7 +215,7 @@ public class LocalFeedUpdaterTest {
public void testGetImageUrl_OtherImageFilenameJpg() {
DocumentFile documentFolder = mockDocumentFolder(mockDocumentFile("audio.mp3", "audio/mp3"),
mockDocumentFile("my-image.jpg", "image/jpeg"));
- String imageUrl = LocalFeedUpdater.getImageUrl(context, documentFolder);
+ String imageUrl = LocalFeedUpdater.getImageUrl(documentFolder);
assertThat(imageUrl, endsWith("my-image.jpg"));
}
@@ -226,7 +223,7 @@ public class LocalFeedUpdaterTest {
public void testGetImageUrl_OtherImageFilenameJpeg() {
DocumentFile documentFolder = mockDocumentFolder(mockDocumentFile("audio.mp3", "audio/mp3"),
mockDocumentFile("my-image.jpeg", "image/jpeg"));
- String imageUrl = LocalFeedUpdater.getImageUrl(context, documentFolder);
+ String imageUrl = LocalFeedUpdater.getImageUrl(documentFolder);
assertThat(imageUrl, endsWith("my-image.jpeg"));
}
@@ -234,7 +231,7 @@ public class LocalFeedUpdaterTest {
public void testGetImageUrl_OtherImageFilenamePng() {
DocumentFile documentFolder = mockDocumentFolder(mockDocumentFile("audio.mp3", "audio/mp3"),
mockDocumentFile("my-image.png", "image/png"));
- String imageUrl = LocalFeedUpdater.getImageUrl(context, documentFolder);
+ String imageUrl = LocalFeedUpdater.getImageUrl(documentFolder);
assertThat(imageUrl, endsWith("my-image.png"));
}
@@ -242,9 +239,8 @@ public class LocalFeedUpdaterTest {
public void testGetImageUrl_OtherImageFilenameUnsupportedMimeType() {
DocumentFile documentFolder = mockDocumentFolder(mockDocumentFile("audio.mp3", "audio/mp3"),
mockDocumentFile("my-image.svg", "image/svg+xml"));
- String imageUrl = LocalFeedUpdater.getImageUrl(context, documentFolder);
- String defaultImageName = context.getResources().getResourceEntryName(R.raw.local_feed_default_icon);
- assertThat(imageUrl, endsWith(defaultImageName));
+ String imageUrl = LocalFeedUpdater.getImageUrl(documentFolder);
+ assertThat(imageUrl, startsWith(Feed.PREFIX_GENERATIVE_COVER));
}
/**