summaryrefslogtreecommitdiff
path: root/core/src
diff options
context:
space:
mode:
authorByteHamster <ByteHamster@users.noreply.github.com>2021-03-28 22:46:37 +0200
committerGitHub <noreply@github.com>2021-03-28 22:46:37 +0200
commit7465b747f3630a82ee6375c766dcba015aa78cfc (patch)
tree9744412b09ee9e12f3a3fb002cd343fdbf659376 /core/src
parentdcbe5e6905e8fb2c37bb73f9c692d07ae21111a8 (diff)
parent998535515bae8ec5bcd2bd95bc0cf4f34416dff7 (diff)
downloadAntennaPod-7465b747f3630a82ee6375c766dcba015aa78cfc.zip
Merge pull request #5055 from ByteHamster/spotbugs
Add SpotBugs CI check
Diffstat (limited to 'core/src')
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/backup/OpmlBackupAgent.java2
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/feed/Chapter.java4
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/feed/FeedItem.java4
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/glide/ChapterImageModelLoader.java13
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/glide/FastBlurTransformation.java3
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/download/AntennapodHttpClient.java2
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/download/HttpDownloader.java7
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceMediaPlayer.java2
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/storage/DatabaseExporter.java5
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java2
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/sync/gpoddernet/GpodnetService.java2
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/syndication/HtmlToPlainText.java9
-rw-r--r--core/src/play/java/de/danoeh/antennapod/core/cast/CastManager.java682
-rw-r--r--core/src/play/java/de/danoeh/antennapod/core/cast/CastUtils.java1
-rw-r--r--core/src/play/java/de/danoeh/antennapod/core/cast/MediaInfoCreator.java3
15 files changed, 32 insertions, 709 deletions
diff --git a/core/src/main/java/de/danoeh/antennapod/core/backup/OpmlBackupAgent.java b/core/src/main/java/de/danoeh/antennapod/core/backup/OpmlBackupAgent.java
index c05e2e9f1..6ca84ff87 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/backup/OpmlBackupAgent.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/backup/OpmlBackupAgent.java
@@ -94,7 +94,7 @@ public class OpmlBackupAgent extends BackupAgentHelper {
if (len != -1) {
byte[] oldChecksum = new byte[len];
- inState.read(oldChecksum);
+ IOUtils.read(inState, oldChecksum, 0, len);
Log.d(TAG, "Old checksum: " + new BigInteger(1, oldChecksum).toString(16));
if (Arrays.equals(oldChecksum, newChecksum)) {
diff --git a/core/src/main/java/de/danoeh/antennapod/core/feed/Chapter.java b/core/src/main/java/de/danoeh/antennapod/core/feed/Chapter.java
index 08a531d17..1c13471a5 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/feed/Chapter.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/feed/Chapter.java
@@ -43,7 +43,7 @@ public abstract class Chapter extends FeedComponent {
String imageUrl = cursor.getString(indexImage);
int chapterType = cursor.getInt(indexChapterType);
- Chapter chapter = null;
+ Chapter chapter;
switch (chapterType) {
case SimpleChapter.CHAPTERTYPE_SIMPLECHAPTER:
chapter = new SimpleChapter(start, title, link, imageUrl);
@@ -54,6 +54,8 @@ public abstract class Chapter extends FeedComponent {
case VorbisCommentChapter.CHAPTERTYPE_VORBISCOMMENT_CHAPTER:
chapter = new VorbisCommentChapter(start, title, link, imageUrl);
break;
+ default:
+ throw new IllegalArgumentException("Unknown chapter type");
}
chapter.setId(id);
return chapter;
diff --git a/core/src/main/java/de/danoeh/antennapod/core/feed/FeedItem.java b/core/src/main/java/de/danoeh/antennapod/core/feed/FeedItem.java
index d6926385e..25857dad2 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/feed/FeedItem.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/feed/FeedItem.java
@@ -43,7 +43,7 @@ public class FeedItem extends FeedComponent implements Serializable {
private Date pubDate;
private FeedMedia media;
- private Feed feed;
+ private transient Feed feed;
private long feedId;
private int state;
@@ -65,7 +65,7 @@ public class FeedItem extends FeedComponent implements Serializable {
* The list of chapters of this item. This might be null even if there are chapters of this item
* in the database. The 'hasChapters' attribute should be used to check if this item has any chapters.
* */
- private List<Chapter> chapters;
+ private transient List<Chapter> chapters;
private String imageUrl;
/*
diff --git a/core/src/main/java/de/danoeh/antennapod/core/glide/ChapterImageModelLoader.java b/core/src/main/java/de/danoeh/antennapod/core/glide/ChapterImageModelLoader.java
index 519d625e2..d6d63fed0 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/glide/ChapterImageModelLoader.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/glide/ChapterImageModelLoader.java
@@ -1,7 +1,6 @@
package de.danoeh.antennapod.core.glide;
import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
import com.bumptech.glide.Priority;
import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.load.Options;
@@ -36,7 +35,6 @@ public final class ChapterImageModelLoader implements ModelLoader<EmbeddedChapte
}
}
- @Nullable
@Override
public LoadData<ByteBuffer> buildLoadData(@NonNull EmbeddedChapterImage model,
int width,
@@ -65,9 +63,9 @@ public final class ChapterImageModelLoader implements ModelLoader<EmbeddedChapte
if (image.getMedia().localFileAvailable()) {
File localFile = new File(image.getMedia().getLocalMediaUrl());
stream = new BufferedInputStream(new FileInputStream(localFile));
- stream.skip(image.getPosition());
+ IOUtils.skip(stream, image.getPosition());
byte[] imageContent = new byte[image.getLength()];
- stream.read(imageContent, 0, image.getLength());
+ IOUtils.read(stream, imageContent, 0, image.getLength());
callback.onDataReady(ByteBuffer.wrap(imageContent));
} else {
Request.Builder httpReq = new Request.Builder();
@@ -88,10 +86,13 @@ public final class ChapterImageModelLoader implements ModelLoader<EmbeddedChapte
}
}
- @Override public void cleanup() {
+ @Override
+ public void cleanup() {
// nothing to clean up
}
- @Override public void cancel() {
+
+ @Override
+ public void cancel() {
// cannot cancel
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/glide/FastBlurTransformation.java b/core/src/main/java/de/danoeh/antennapod/core/glide/FastBlurTransformation.java
index 1f8ae5ad9..4de6a7315 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/glide/FastBlurTransformation.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/glide/FastBlurTransformation.java
@@ -8,6 +8,7 @@ import android.util.Log;
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
import com.bumptech.glide.load.resource.bitmap.BitmapTransformation;
+import java.nio.charset.Charset;
import java.security.MessageDigest;
public class FastBlurTransformation extends BitmapTransformation {
@@ -43,7 +44,7 @@ public class FastBlurTransformation extends BitmapTransformation {
@Override
public void updateDiskCacheKey(@NonNull MessageDigest messageDigest) {
- messageDigest.update(TAG.getBytes());
+ messageDigest.update(TAG.getBytes(Charset.defaultCharset()));
}
private static Bitmap fastBlur(Bitmap bitmap, int radius) {
diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/download/AntennapodHttpClient.java b/core/src/main/java/de/danoeh/antennapod/core/service/download/AntennapodHttpClient.java
index c4029d57f..4d1d44908 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/service/download/AntennapodHttpClient.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/service/download/AntennapodHttpClient.java
@@ -120,7 +120,7 @@ public class AntennapodHttpClient {
SocketAddress address = InetSocketAddress.createUnresolved(config.host, port);
Proxy proxy = new Proxy(config.type, address);
builder.proxy(proxy);
- if (!TextUtils.isEmpty(config.username)) {
+ if (!TextUtils.isEmpty(config.username) && config.password != null) {
String credentials = Credentials.basic(config.username, config.password);
builder.interceptors().add(chain -> {
Request request = chain.request().newBuilder()
diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/download/HttpDownloader.java b/core/src/main/java/de/danoeh/antennapod/core/service/download/HttpDownloader.java
index 2d955859f..5050225f7 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/service/download/HttpDownloader.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/service/download/HttpDownloader.java
@@ -188,8 +188,11 @@ public class HttpDownloader extends Downloader {
out = new RandomAccessFile(destination, "rw");
out.seek(request.getSoFar());
} else {
- destination.delete();
- destination.createNewFile();
+ boolean success = destination.delete();
+ success |= destination.createNewFile();
+ if (!success) {
+ throw new IOException("Unable to recreate partially downloaded file");
+ }
out = new RandomAccessFile(destination, "rw");
}
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 1f047ceee..785784497 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
@@ -217,7 +217,7 @@ public abstract class PlaybackServiceMediaPlayer {
* could result in nonsensical results (like a status of PLAYING, but a null playable)
* @return the current player status
*/
- public PlayerStatus getPlayerStatus() {
+ public synchronized PlayerStatus getPlayerStatus() {
return playerStatus;
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/DatabaseExporter.java b/core/src/main/java/de/danoeh/antennapod/core/storage/DatabaseExporter.java
index 271babc6e..a0fac0c74 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/storage/DatabaseExporter.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/storage/DatabaseExporter.java
@@ -91,7 +91,10 @@ public class DatabaseExporter {
db.close();
File currentDB = context.getDatabasePath(PodDBAdapter.DATABASE_NAME);
- currentDB.delete();
+ boolean success = currentDB.delete();
+ if (!success) {
+ throw new IOException("Unable to delete old database");
+ }
FileUtils.moveFile(tempDB, currentDB);
} catch (IOException | SQLiteException e) {
Log.e(TAG, Log.getStackTraceString(e));
diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java b/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java
index 98d5e6310..7ab776856 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java
@@ -331,7 +331,7 @@ public class PodDBAdapter {
PodDBAdapter.context = context.getApplicationContext();
}
- public static PodDBAdapter getInstance() {
+ public static synchronized PodDBAdapter getInstance() {
if (instance == null) {
instance = new PodDBAdapter();
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/sync/gpoddernet/GpodnetService.java b/core/src/main/java/de/danoeh/antennapod/core/sync/gpoddernet/GpodnetService.java
index cecfc0d2c..cd0fc93ea 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/sync/gpoddernet/GpodnetService.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/sync/gpoddernet/GpodnetService.java
@@ -667,11 +667,11 @@ public class GpodnetService implements ISyncService {
while ((count = in.read(buffer)) > 0) {
outputStream.write(buffer, 0, count);
}
+ return outputStream.toString("UTF-8");
} catch (IOException e) {
e.printStackTrace();
throw new GpodnetServiceException(e);
}
- return outputStream.toString();
}
private void checkStatusCode(@NonNull Response response) throws GpodnetServiceException {
diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/syndication/HtmlToPlainText.java b/core/src/main/java/de/danoeh/antennapod/core/util/syndication/HtmlToPlainText.java
index baa467acf..37dee0486 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/util/syndication/HtmlToPlainText.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/util/syndication/HtmlToPlainText.java
@@ -34,8 +34,7 @@ import java.util.regex.Pattern;
public class HtmlToPlainText {
/**
- * Use this method to strip off HTML encoding from given text
- * <p>
+ * Use this method to strip off HTML encoding from given text.
* Replaces bullet points with *, ignores colors/bold/...
*
* @param str String with any encoding
@@ -60,10 +59,8 @@ public class HtmlToPlainText {
* @return <b>True</b> if text contains any HTML tags<br /><b>False</b> is no HTML tag is found
*/
private static boolean isHtml(String str) {
- final String HTML_TAG_PATTERN = "<(\"[^\"]*\"|'[^']*'|[^'\">])*>";
- Pattern htmlValidator = TextUtils.isEmpty(HTML_TAG_PATTERN) ? null : Pattern.compile(HTML_TAG_PATTERN);
-
- return htmlValidator.matcher(str).find();
+ final String htmlTagPattern = "<(\"[^\"]*\"|'[^']*'|[^'\">])*>";
+ return Pattern.compile(htmlTagPattern).matcher(str).find();
}
/**
diff --git a/core/src/play/java/de/danoeh/antennapod/core/cast/CastManager.java b/core/src/play/java/de/danoeh/antennapod/core/cast/CastManager.java
index 48c3bfbfc..dd07b9cd8 100644
--- a/core/src/play/java/de/danoeh/antennapod/core/cast/CastManager.java
+++ b/core/src/play/java/de/danoeh/antennapod/core/cast/CastManager.java
@@ -23,13 +23,11 @@
package de.danoeh.antennapod.core.cast;
import android.content.Context;
-import android.os.Build;
import androidx.annotation.NonNull;
import androidx.core.view.ActionProvider;
import androidx.core.view.MenuItemCompat;
import androidx.mediarouter.media.MediaRouter;
import android.util.Log;
-import android.view.KeyEvent;
import android.view.MenuItem;
import com.google.android.gms.cast.ApplicationMetadata;
@@ -46,7 +44,6 @@ import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import com.google.android.libraries.cast.companionlibrary.cast.BaseCastManager;
import com.google.android.libraries.cast.companionlibrary.cast.CastConfiguration;
-import com.google.android.libraries.cast.companionlibrary.cast.MediaQueue;
import com.google.android.libraries.cast.companionlibrary.cast.exceptions.CastException;
import com.google.android.libraries.cast.companionlibrary.cast.exceptions.NoConnectionException;
import com.google.android.libraries.cast.companionlibrary.cast.exceptions.OnFailedListener;
@@ -58,9 +55,7 @@ import java.io.IOException;
import java.util.List;
import java.util.Locale;
import java.util.Set;
-import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;
-import java.util.concurrent.TimeUnit;
import de.danoeh.antennapod.core.ClientConfig;
import de.danoeh.antennapod.core.R;
@@ -97,32 +92,14 @@ public class CastManager extends BaseCastManager implements OnFailedListener {
public static final String CAST_APP_ID = CastMediaControlIntent.DEFAULT_MEDIA_RECEIVER_APPLICATION_ID;
- public static final double DEFAULT_VOLUME_STEP = 0.05;
- public static final long DEFAULT_LIVE_STREAM_DURATION_MS = TimeUnit.HOURS.toMillis(2);
- private double volumeStep = DEFAULT_VOLUME_STEP;
- private MediaQueue mediaQueue;
private MediaStatus mediaStatus;
-
private static CastManager INSTANCE;
private RemoteMediaPlayer remoteMediaPlayer;
private int state = MediaStatus.PLAYER_STATE_IDLE;
- private int idleReason;
private final Set<CastConsumer> castConsumers = new CopyOnWriteArraySet<>();
- private long liveStreamDuration = DEFAULT_LIVE_STREAM_DURATION_MS;
- private MediaQueueItem preLoadingItem;
public static final int QUEUE_OPERATION_LOAD = 1;
- public static final int QUEUE_OPERATION_INSERT_ITEMS = 2;
- public static final int QUEUE_OPERATION_UPDATE_ITEMS = 3;
- public static final int QUEUE_OPERATION_JUMP = 4;
- public static final int QUEUE_OPERATION_REMOVE_ITEM = 5;
- public static final int QUEUE_OPERATION_REMOVE_ITEMS = 6;
- public static final int QUEUE_OPERATION_REORDER = 7;
- public static final int QUEUE_OPERATION_MOVE = 8;
public static final int QUEUE_OPERATION_APPEND = 9;
- public static final int QUEUE_OPERATION_NEXT = 10;
- public static final int QUEUE_OPERATION_PREV = 11;
- public static final int QUEUE_OPERATION_SET_REPEAT = 12;
private CastManager(Context context, CastConfiguration castConfiguration) {
super(context, castConfiguration);
@@ -176,19 +153,6 @@ public class CastManager extends BaseCastManager implements OnFailedListener {
return remoteMediaPlayer;
}
- /**
- * Determines if the media that is loaded remotely is a live stream or not.
- *
- * @throws TransientNetworkDisconnectionException
- * @throws NoConnectionException
- */
- public final boolean isRemoteStreamLive() throws TransientNetworkDisconnectionException,
- NoConnectionException {
- checkConnectivity();
- MediaInfo info = getRemoteMediaInformation();
- return (info != null) && (info.getStreamType() == MediaInfo.STREAM_TYPE_LIVE);
- }
-
/*
* A simple check to make sure remoteMediaPlayer is not null
*/
@@ -199,25 +163,6 @@ public class CastManager extends BaseCastManager implements OnFailedListener {
}
/**
- * Returns the url for the media that is currently playing on the remote device. If there is no
- * connection, this will return <code>null</code>.
- *
- * @throws NoConnectionException If no connectivity to the device exists
- * @throws TransientNetworkDisconnectionException If framework is still trying to recover from
- * a possibly transient loss of network
- */
- public String getRemoteMediaUrl() throws TransientNetworkDisconnectionException,
- NoConnectionException {
- checkConnectivity();
- if (remoteMediaPlayer != null && remoteMediaPlayer.getMediaInfo() != null) {
- MediaInfo info = remoteMediaPlayer.getMediaInfo();
- remoteMediaPlayer.getMediaStatus().getPlayerState();
- return info.getContentId();
- }
- throw new NoConnectionException();
- }
-
- /**
* Indicates if the remote media is currently playing (or buffering).
*
* @throws NoConnectionException
@@ -256,20 +201,6 @@ public class CastManager extends BaseCastManager implements OnFailedListener {
}
/**
- * Returns the {@link MediaInfo} for the current media
- *
- * @throws NoConnectionException If no connectivity to the device exists
- * @throws TransientNetworkDisconnectionException If framework is still trying to recover from
- * a possibly transient loss of network
- */
- public MediaInfo getRemoteMediaInformation() throws TransientNetworkDisconnectionException,
- NoConnectionException {
- checkConnectivity();
- checkRemoteMediaPlayerAvailable();
- return remoteMediaPlayer.getMediaInfo();
- }
-
- /**
* Gets the remote's system volume. It internally detects what type of volume is used.
*
* @throws NoConnectionException If no connectivity to the device exists
@@ -327,30 +258,6 @@ public class CastManager extends BaseCastManager implements OnFailedListener {
}
/**
- * Returns <code>true</code> if remote device is muted.
- *
- * @throws NoConnectionException
- * @throws TransientNetworkDisconnectionException
- */
- public boolean isMute() throws TransientNetworkDisconnectionException, NoConnectionException {
- return isStreamMute() || isDeviceMute();
- }
-
- /**
- * Mutes or un-mutes the stream volume.
- *
- * @throws CastException
- * @throws NoConnectionException
- * @throws TransientNetworkDisconnectionException
- */
- public void setStreamMute(boolean mute) throws CastException, TransientNetworkDisconnectionException,
- NoConnectionException {
- checkConnectivity();
- checkRemoteMediaPlayerAvailable();
- remoteMediaPlayer.setStreamMute(mApiClient, mute);
- }
-
- /**
* Returns the duration of the media that is loaded, in milliseconds.
*
* @throws NoConnectionException
@@ -364,23 +271,6 @@ public class CastManager extends BaseCastManager implements OnFailedListener {
}
/**
- * Returns the time left (in milliseconds) of the current media. If there is no
- * {@code RemoteMediaPlayer}, it returns -1.
- *
- * @throws TransientNetworkDisconnectionException
- * @throws NoConnectionException
- */
- public long getMediaTimeRemaining()
- throws TransientNetworkDisconnectionException, NoConnectionException {
- checkConnectivity();
- if (remoteMediaPlayer == null) {
- return -1;
- }
- return isRemoteStreamLive() ? liveStreamDuration : remoteMediaPlayer.getStreamDuration()
- - remoteMediaPlayer.getApproximateStreamPosition();
- }
-
- /**
* Returns the current (approximate) position of the current media, in milliseconds.
*
* @throws NoConnectionException
@@ -671,435 +561,6 @@ public class CastManager extends BaseCastManager implements OnFailedListener {
}
/**
- * Inserts a list of new media items into the queue.
- *
- * @param itemsToInsert List of items to insert into the queue, in the order that they should be
- * played. The itemId field of the items should be unassigned or the
- * request will fail with an INVALID_PARAMS error. Must not be {@code null}
- * or empty.
- * @param insertBeforeItemId ID of the item that will be located immediately after the inserted
- * list. If the value is {@link MediaQueueItem#INVALID_ITEM_ID} or
- * invalid, the inserted list will be appended to the end of the
- * queue.
- * @param customData Custom application-specific data to pass along with the request. May be
- * {@code null}.
- * @throws TransientNetworkDisconnectionException
- * @throws NoConnectionException
- * @throws IllegalArgumentException
- */
- public void queueInsertItems(final MediaQueueItem[] itemsToInsert, final int insertBeforeItemId,
- final JSONObject customData)
- throws TransientNetworkDisconnectionException, NoConnectionException {
- Log.d(TAG, "queueInsertItems");
- checkConnectivity();
- if (itemsToInsert == null || itemsToInsert.length == 0) {
- throw new IllegalArgumentException("items cannot be empty or null");
- }
- if (remoteMediaPlayer == null) {
- Log.e(TAG, "Trying to insert into queue with no active media session");
- throw new NoConnectionException();
- }
- remoteMediaPlayer
- .queueInsertItems(mApiClient, itemsToInsert, insertBeforeItemId, customData)
- .setResultCallback(
- result -> {
- for (CastConsumer consumer : castConsumers) {
- consumer.onMediaQueueOperationResult(
- QUEUE_OPERATION_INSERT_ITEMS,
- result.getStatus().getStatusCode());
- }
- });
- }
-
- /**
- * Updates properties of a subset of the existing items in the media queue.
- *
- * @param itemsToUpdate List of queue items to be updated. The items will retain the existing
- * order and will be fully replaced with the ones provided, including the
- * media information. Any other items currently in the queue will remain
- * unchanged. The tracks information can not change once the item is loaded
- * (if the item is the currentItem). If any of the items does not exist it
- * will be ignored.
- * @param customData Custom application-specific data to pass along with the request. May be
- * {@code null}.
- * @throws TransientNetworkDisconnectionException
- * @throws NoConnectionException
- */
- public void queueUpdateItems(final MediaQueueItem[] itemsToUpdate, final JSONObject customData)
- throws TransientNetworkDisconnectionException, NoConnectionException {
- checkConnectivity();
- if (remoteMediaPlayer == null) {
- Log.e(TAG, "Trying to update the queue with no active media session");
- throw new NoConnectionException();
- }
- remoteMediaPlayer
- .queueUpdateItems(mApiClient, itemsToUpdate, customData).setResultCallback(
- result -> {
- Log.d(TAG, "queueUpdateItems() " + result.getStatus() + result.getStatus()
- .isSuccess());
- for (CastConsumer consumer : castConsumers) {
- consumer.onMediaQueueOperationResult(QUEUE_OPERATION_UPDATE_ITEMS,
- result.getStatus().getStatusCode());
- }
- });
- }
-
- /**
- * Plays the item with {@code itemId} in the queue.
- * <p>
- * If {@code itemId} is not found in the queue, this method will report success without sending
- * a request to the receiver.
- *
- * @param itemId The ID of the item to which to jump.
- * @param customData Custom application-specific data to pass along with the request. May be
- * {@code null}.
- * @throws TransientNetworkDisconnectionException
- * @throws NoConnectionException
- * @throws IllegalArgumentException
- */
- public void queueJumpToItem(int itemId, final JSONObject customData)
- throws TransientNetworkDisconnectionException, NoConnectionException,
- IllegalArgumentException {
- checkConnectivity();
- if (itemId == MediaQueueItem.INVALID_ITEM_ID) {
- throw new IllegalArgumentException("itemId is not valid");
- }
- if (remoteMediaPlayer == null) {
- Log.e(TAG, "Trying to jump in a queue with no active media session");
- throw new NoConnectionException();
- }
- remoteMediaPlayer
- .queueJumpToItem(mApiClient, itemId, customData).setResultCallback(
- result -> {
- for (CastConsumer consumer : castConsumers) {
- consumer.onMediaQueueOperationResult(QUEUE_OPERATION_JUMP,
- result.getStatus().getStatusCode());
- }
- });
- }
-
- /**
- * Removes a list of items from the queue. If the remaining queue is empty, the media session
- * will be terminated.
- *
- * @param itemIdsToRemove The list of media item IDs to remove. Must not be {@code null} or
- * empty.
- * @param customData Custom application-specific data to pass along with the request. May be
- * {@code null}.
- * @throws TransientNetworkDisconnectionException
- * @throws NoConnectionException
- * @throws IllegalArgumentException
- */
- public void queueRemoveItems(final int[] itemIdsToRemove, final JSONObject customData)
- throws TransientNetworkDisconnectionException, NoConnectionException,
- IllegalArgumentException {
- Log.d(TAG, "queueRemoveItems");
- checkConnectivity();
- if (itemIdsToRemove == null || itemIdsToRemove.length == 0) {
- throw new IllegalArgumentException("itemIds cannot be empty or null");
- }
- if (remoteMediaPlayer == null) {
- Log.e(TAG, "Trying to remove items from queue with no active media session");
- throw new NoConnectionException();
- }
- remoteMediaPlayer
- .queueRemoveItems(mApiClient, itemIdsToRemove, customData).setResultCallback(
- result -> {
- for (CastConsumer consumer : castConsumers) {
- consumer.onMediaQueueOperationResult(QUEUE_OPERATION_REMOVE_ITEMS,
- result.getStatus().getStatusCode());
- }
- });
- }
-
- /**
- * Removes the item with {@code itemId} from the queue.
- * <p>
- * If {@code itemId} is not found in the queue, this method will silently return without sending
- * a request to the receiver. A {@code itemId} may not be in the queue because it wasn't
- * originally in the queue, or it was removed by another sender.
- *
- * @param itemId The ID of the item to be removed.
- * @param customData Custom application-specific data to pass along with the request. May be
- * {@code null}.
- * @throws TransientNetworkDisconnectionException
- * @throws NoConnectionException
- * @throws IllegalArgumentException
- */
- public void queueRemoveItem(final int itemId, final JSONObject customData)
- throws TransientNetworkDisconnectionException, NoConnectionException,
- IllegalArgumentException {
- Log.d(TAG, "queueRemoveItem");
- checkConnectivity();
- if (itemId == MediaQueueItem.INVALID_ITEM_ID) {
- throw new IllegalArgumentException("itemId is invalid");
- }
- if (remoteMediaPlayer == null) {
- Log.e(TAG, "Trying to remove an item from queue with no active media session");
- throw new NoConnectionException();
- }
- remoteMediaPlayer
- .queueRemoveItem(mApiClient, itemId, customData).setResultCallback(
- result -> {
- for (CastConsumer consumer : castConsumers) {
- consumer.onMediaQueueOperationResult(QUEUE_OPERATION_REMOVE_ITEM,
- result.getStatus().getStatusCode());
- }
- });
- }
-
- /**
- * Reorder a list of media items in the queue.
- *
- * @param itemIdsToReorder The list of media item IDs to reorder, in the new order. Any other
- * items currently in the queue will maintain their existing order. The
- * list will be inserted just before the item specified by
- * {@code insertBeforeItemId}, or at the end of the queue if
- * {@code insertBeforeItemId} is {@link MediaQueueItem#INVALID_ITEM_ID}.
- * <p>
- * For example:
- * <p>
- * If insertBeforeItemId is not specified <br>
- * Existing queue: "A","D","G","H","B","E" <br>
- * itemIds: "D","H","B" <br>
- * New Order: "A","G","E","D","H","B" <br>
- * <p>
- * If insertBeforeItemId is "A" <br>
- * Existing queue: "A","D","G","H","B" <br>
- * itemIds: "D","H","B" <br>
- * New Order: "D","H","B","A","G","E" <br>
- * <p>
- * If insertBeforeItemId is "G" <br>
- * Existing queue: "A","D","G","H","B" <br>
- * itemIds: "D","H","B" <br>
- * New Order: "A","D","H","B","G","E" <br>
- * <p>
- * If any of the items does not exist it will be ignored.
- * Must not be {@code null} or empty.
- * @param insertBeforeItemId ID of the item that will be located immediately after the reordered
- * list. If set to {@link MediaQueueItem#INVALID_ITEM_ID}, the
- * reordered list will be appended at the end of the queue.
- * @param customData Custom application-specific data to pass along with the request. May be
- * {@code null}.
- * @throws TransientNetworkDisconnectionException
- * @throws NoConnectionException
- */
- public void queueReorderItems(final int[] itemIdsToReorder, final int insertBeforeItemId,
- final JSONObject customData)
- throws TransientNetworkDisconnectionException, NoConnectionException,
- IllegalArgumentException {
- Log.d(TAG, "queueReorderItems");
- checkConnectivity();
- if (itemIdsToReorder == null || itemIdsToReorder.length == 0) {
- throw new IllegalArgumentException("itemIdsToReorder cannot be empty or null");
- }
- if (remoteMediaPlayer == null) {
- Log.e(TAG, "Trying to reorder items in a queue with no active media session");
- throw new NoConnectionException();
- }
- remoteMediaPlayer
- .queueReorderItems(mApiClient, itemIdsToReorder, insertBeforeItemId, customData)
- .setResultCallback(
- result -> {
- for (CastConsumer consumer : castConsumers) {
- consumer.onMediaQueueOperationResult(QUEUE_OPERATION_REORDER,
- result.getStatus().getStatusCode());
- }
- });
- }
-
- /**
- * Moves the item with {@code itemId} to a new position in the queue.
- * <p>
- * If {@code itemId} is not found in the queue, either because it wasn't there originally or it
- * was removed by another sender before calling this function, this function will silently
- * return without sending a request to the receiver.
- *
- * @param itemId The ID of the item to be moved.
- * @param newIndex The new index of the item. If the value is negative, an error will be
- * returned. If the value is out of bounds, or becomes out of bounds because the
- * queue was shortened by another sender while this request is in progress, the
- * item will be moved to the end of the queue.
- * @param customData Custom application-specific data to pass along with the request. May be
- * {@code null}.
- * @throws TransientNetworkDisconnectionException
- * @throws NoConnectionException
- */
- public void queueMoveItemToNewIndex(int itemId, int newIndex, final JSONObject customData)
- throws TransientNetworkDisconnectionException, NoConnectionException {
- Log.d(TAG, "queueMoveItemToNewIndex");
- checkConnectivity();
- if (remoteMediaPlayer == null) {
- Log.e(TAG, "Trying to mote item to new index with no active media session");
- throw new NoConnectionException();
- }
- remoteMediaPlayer
- .queueMoveItemToNewIndex(mApiClient, itemId, newIndex, customData)
- .setResultCallback(
- result -> {
- for (CastConsumer consumer : castConsumers) {
- consumer.onMediaQueueOperationResult(QUEUE_OPERATION_MOVE,
- result.getStatus().getStatusCode());
- }
- });
- }
-
- /**
- * Appends a new media item to the end of the queue.
- *
- * @param item The item to append. Must not be {@code null}.
- * @param customData Custom application-specific data to pass along with the request. May be
- * {@code null}.
- * @throws TransientNetworkDisconnectionException
- * @throws NoConnectionException
- */
- public void queueAppendItem(MediaQueueItem item, final JSONObject customData)
- throws TransientNetworkDisconnectionException, NoConnectionException {
- Log.d(TAG, "queueAppendItem");
- checkConnectivity();
- if (remoteMediaPlayer == null) {
- Log.e(TAG, "Trying to append item with no active media session");
- throw new NoConnectionException();
- }
- remoteMediaPlayer
- .queueAppendItem(mApiClient, item, customData)
- .setResultCallback(
- result -> {
- for (CastConsumer consumer : castConsumers) {
- consumer.onMediaQueueOperationResult(QUEUE_OPERATION_APPEND,
- result.getStatus().getStatusCode());
- }
- });
- }
-
- /**
- * Jumps to the next item in the queue.
- *
- * @param customData Custom application-specific data to pass along with the request. May be
- * {@code null}.
- * @throws TransientNetworkDisconnectionException
- * @throws NoConnectionException
- */
- public void queueNext(final JSONObject customData)
- throws TransientNetworkDisconnectionException, NoConnectionException {
- Log.d(TAG, "queueNext");
- checkConnectivity();
- if (remoteMediaPlayer == null) {
- Log.e(TAG, "Trying to update the queue with no active media session");
- throw new NoConnectionException();
- }
- remoteMediaPlayer
- .queueNext(mApiClient, customData).setResultCallback(
- result -> {
- for (CastConsumer consumer : castConsumers) {
- consumer.onMediaQueueOperationResult(QUEUE_OPERATION_NEXT,
- result.getStatus().getStatusCode());
- }
- });
- }
-
- /**
- * Jumps to the previous item in the queue.
- *
- * @param customData Custom application-specific data to pass along with the request. May be
- * {@code null}.
- * @throws TransientNetworkDisconnectionException
- * @throws NoConnectionException
- */
- public void queuePrev(final JSONObject customData)
- throws TransientNetworkDisconnectionException, NoConnectionException {
- Log.d(TAG, "queuePrev");
- checkConnectivity();
- if (remoteMediaPlayer == null) {
- Log.e(TAG, "Trying to update the queue with no active media session");
- throw new NoConnectionException();
- }
- remoteMediaPlayer
- .queuePrev(mApiClient, customData).setResultCallback(
- result -> {
- for (CastConsumer consumer : castConsumers) {
- consumer.onMediaQueueOperationResult(QUEUE_OPERATION_PREV,
- result.getStatus().getStatusCode());
- }
- });
- }
-
- /**
- * Inserts an item in the queue and starts the playback of that newly inserted item. It is
- * assumed that we are inserting before the "current item"
- *
- * @param item The item to be inserted
- * @param insertBeforeItemId ID of the item that will be located immediately after the inserted
- * and is assumed to be the "current item"
- * @param customData Custom application-specific data to pass along with the request. May be
- * {@code null}.
- * @throws TransientNetworkDisconnectionException
- * @throws NoConnectionException
- * @throws IllegalArgumentException
- */
- public void queueInsertBeforeCurrentAndPlay(MediaQueueItem item, int insertBeforeItemId,
- final JSONObject customData)
- throws TransientNetworkDisconnectionException, NoConnectionException {
- Log.d(TAG, "queueInsertBeforeCurrentAndPlay");
- checkConnectivity();
- if (remoteMediaPlayer == null) {
- Log.e(TAG, "Trying to insert into queue with no active media session");
- throw new NoConnectionException();
- }
- if (item == null || insertBeforeItemId == MediaQueueItem.INVALID_ITEM_ID) {
- throw new IllegalArgumentException(
- "item cannot be empty or insertBeforeItemId cannot be invalid");
- }
- remoteMediaPlayer.queueInsertItems(mApiClient, new MediaQueueItem[]{item},
- insertBeforeItemId, customData).setResultCallback(
- result -> {
- if (result.getStatus().isSuccess()) {
-
- try {
- queuePrev(customData);
- } catch (TransientNetworkDisconnectionException |
- NoConnectionException e) {
- Log.e(TAG, "queuePrev() Failed to skip to previous", e);
- }
- }
- for (CastConsumer consumer : castConsumers) {
- consumer.onMediaQueueOperationResult(QUEUE_OPERATION_INSERT_ITEMS,
- result.getStatus().getStatusCode());
- }
- });
- }
-
- /**
- * Sets the repeat mode of the queue.
- *
- * @param repeatMode The repeat playback mode for the queue.
- * @param customData Custom application-specific data to pass along with the request. May be
- * {@code null}.
- * @throws TransientNetworkDisconnectionException
- * @throws NoConnectionException
- */
- public void queueSetRepeatMode(final int repeatMode, final JSONObject customData)
- throws TransientNetworkDisconnectionException, NoConnectionException {
- Log.d(TAG, "queueSetRepeatMode");
- checkConnectivity();
- if (remoteMediaPlayer == null) {
- Log.e(TAG, "Trying to update the queue with no active media session");
- throw new NoConnectionException();
- }
- remoteMediaPlayer
- .queueSetRepeatMode(mApiClient, repeatMode, customData).setResultCallback(
- result -> {
- if (!result.getStatus().isSuccess()) {
- Log.d(TAG, "Failed with status: " + result.getStatus());
- }
- for (CastConsumer consumer : castConsumers) {
- consumer.onMediaQueueOperationResult(QUEUE_OPERATION_SET_REPEAT,
- result.getStatus().getStatusCode());
- }
- });
- }
-
- /**
* Plays the loaded media.
*
* @param position Where to start the playback. Units is milliseconds.
@@ -1294,29 +755,6 @@ public class CastManager extends BaseCastManager implements OnFailedListener {
});
}
- /**
- * Toggles the playback of the media.
- *
- * @throws CastException
- * @throws NoConnectionException
- * @throws TransientNetworkDisconnectionException
- */
- public void togglePlayback() throws CastException, TransientNetworkDisconnectionException,
- NoConnectionException {
- checkConnectivity();
- boolean isPlaying = isRemoteMediaPlaying();
- if (isPlaying) {
- pause();
- } else {
- if (state == MediaStatus.PLAYER_STATE_IDLE
- && idleReason == MediaStatus.IDLE_REASON_FINISHED) {
- loadMedia(getRemoteMediaInformation(), true, 0);
- } else {
- play();
- }
- }
- }
-
private void attachMediaChannel() throws TransientNetworkDisconnectionException,
NoConnectionException {
Log.d(TAG, "attachMediaChannel()");
@@ -1400,22 +838,6 @@ public class CastManager extends BaseCastManager implements OnFailedListener {
}
/**
- * Returns the playback status of the remote device.
- *
- * @return Returns one of the values
- * <ul>
- * <li> <code>MediaStatus.PLAYER_STATE_UNKNOWN</code></li>
- * <li> <code>MediaStatus.PLAYER_STATE_IDLE</code></li>
- * <li> <code>MediaStatus.PLAYER_STATE_PLAYING</code></li>
- * <li> <code>MediaStatus.PLAYER_STATE_PAUSED</code></li>
- * <li> <code>MediaStatus.PLAYER_STATE_BUFFERING</code></li>
- * </ul>
- */
- public int getPlaybackStatus() {
- return state;
- }
-
- /**
* Returns the latest retrieved value for the {@link MediaStatus}. This value is updated
* whenever the onStatusUpdated callback is called.
*/
@@ -1423,24 +845,6 @@ public class CastManager extends BaseCastManager implements OnFailedListener {
return mediaStatus;
}
- /**
- * Returns the Idle reason, defined in <code>MediaStatus.IDLE_*</code>. Note that the returned
- * value is only meaningful if the status is truly <code>MediaStatus.PLAYER_STATE_IDLE
- * </code>
- *
- * <p>Possible values are:
- * <ul>
- * <li>IDLE_REASON_NONE</li>
- * <li>IDLE_REASON_FINISHED</li>
- * <li>IDLE_REASON_CANCELED</li>
- * <li>IDLE_REASON_INTERRUPTED</li>
- * <li>IDLE_REASON_ERROR</li>
- * </ul>
- */
- public int getIdleReason() {
- return idleReason;
- }
-
/*
* This is called by onStatusUpdated() of the RemoteMediaPlayer
*/
@@ -1465,7 +869,7 @@ public class CastManager extends BaseCastManager implements OnFailedListener {
onQueueUpdated(null, null, MediaStatus.REPEAT_MODE_REPEAT_OFF, false);
}
state = mediaStatus.getPlayerState();
- idleReason = mediaStatus.getIdleReason();
+ int idleReason = mediaStatus.getIdleReason();
if (state == MediaStatus.PLAYER_STATE_PLAYING) {
Log.d(TAG, "onRemoteMediaPlayerStatusUpdated(): Player status = playing");
@@ -1503,17 +907,12 @@ public class CastManager extends BaseCastManager implements OnFailedListener {
if (mediaStatus != null) {
item = mediaStatus.getQueueItemById(mediaStatus.getPreloadedItemId());
}
- preLoadingItem = item;
Log.d(TAG, "onRemoteMediaPreloadStatusUpdated() " + item);
for (CastConsumer consumer : castConsumers) {
consumer.onRemoteMediaPreloadStatusUpdated(item);
}
}
- public MediaQueueItem getPreLoadingItem() {
- return preLoadingItem;
- }
-
/*
* This is called by onQueueStatusUpdated() of RemoteMediaPlayer
*/
@@ -1522,13 +921,6 @@ public class CastManager extends BaseCastManager implements OnFailedListener {
Log.d(TAG, "onQueueUpdated() reached");
Log.d(TAG, String.format(Locale.US, "Queue Items size: %d, Item: %s, Repeat Mode: %d, Shuffle: %s",
queueItems == null ? 0 : queueItems.size(), item, repeatMode, shuffle));
- if (queueItems != null) {
- mediaQueue = new MediaQueue(new CopyOnWriteArrayList<>(queueItems), item, shuffle,
- repeatMode);
- } else {
- mediaQueue = new MediaQueue(new CopyOnWriteArrayList<>(), null, false,
- MediaStatus.REPEAT_MODE_REPEAT_OFF);
- }
for (CastConsumer consumer : castConsumers) {
consumer.onMediaQueueUpdated(queueItems, item, repeatMode, shuffle);
}
@@ -1599,7 +991,6 @@ public class CastManager extends BaseCastManager implements OnFailedListener {
super.onDisconnected(stopAppOnExit, clearPersistedConnectionData, setDefaultRoute);
state = MediaStatus.PLAYER_STATE_IDLE;
mediaStatus = null;
- mediaQueue = null;
}
class CastListener extends Cast.Listener {
@@ -1635,77 +1026,6 @@ public class CastManager extends BaseCastManager implements OnFailedListener {
}
/**
- * Clients can call this method to delegate handling of the volume. Clients should override
- * {@code dispatchEvent} and call this method:
- * <pre>
- public boolean dispatchKeyEvent(KeyEvent event) {
- if (mCastManager.onDispatchVolumeKeyEvent(event, VOLUME_DELTA)) {
- return true;
- }
- return super.dispatchKeyEvent(event);
- }
- * </pre>
- * @param event The dispatched event.
- * @param volumeDelta The amount by which volume should be increased or decreased in each step
- * @return <code>true</code> if volume is handled by the library, <code>false</code> otherwise.
- */
- public boolean onDispatchVolumeKeyEvent(KeyEvent event, double volumeDelta) {
- if (isConnected()) {
- boolean isKeyDown = event.getAction() == KeyEvent.ACTION_DOWN;
- switch (event.getKeyCode()) {
- case KeyEvent.KEYCODE_VOLUME_UP:
- return changeVolume(volumeDelta, isKeyDown);
- case KeyEvent.KEYCODE_VOLUME_DOWN:
- return changeVolume(-volumeDelta, isKeyDown);
- }
- }
- return false;
- }
-
- private boolean changeVolume(double volumeIncrement, boolean isKeyDown) {
- if ((Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
- && getPlaybackStatus() == MediaStatus.PLAYER_STATE_PLAYING
- && isFeatureEnabled(CastConfiguration.FEATURE_LOCKSCREEN)) {
- return false;
- }
-
- if (isKeyDown) {
- try {
- adjustDeviceVolume(volumeIncrement);
- } catch (CastException | TransientNetworkDisconnectionException |
- NoConnectionException e) {
- Log.e(TAG, "Failed to change volume", e);
- }
- }
- return true;
- }
-
- /**
- * Sets the volume step, i.e. the fraction by which volume will increase or decrease each time
- * user presses the hard volume buttons on the device.
- *
- * @param volumeStep Should be a double between 0 and 1, inclusive.
- */
- public CastManager setVolumeStep(double volumeStep) {
- if ((volumeStep > 1) || (volumeStep < 0)) {
- throw new IllegalArgumentException("Volume Step should be between 0 and 1, inclusive");
- }
- this.volumeStep = volumeStep;
- return this;
- }
-
- /**
- * Returns the volume step. The default value is {@code DEFAULT_VOLUME_STEP}.
- */
- public double getVolumeStep() {
- return volumeStep;
- }
-
- public final MediaQueue getMediaQueue() {
- return mediaQueue;
- }
-
- /**
* Checks whether the selected Cast Device has the specified audio or video capabilities.
*
* @param capability capability from:
diff --git a/core/src/play/java/de/danoeh/antennapod/core/cast/CastUtils.java b/core/src/play/java/de/danoeh/antennapod/core/cast/CastUtils.java
index 86c85de6b..248f6dc46 100644
--- a/core/src/play/java/de/danoeh/antennapod/core/cast/CastUtils.java
+++ b/core/src/play/java/de/danoeh/antennapod/core/cast/CastUtils.java
@@ -35,7 +35,6 @@ public class CastUtils {
public static final String KEY_FEED_URL = "de.danoeh.antennapod.core.cast.FeedUrl";
public static final String KEY_FEED_WEBSITE = "de.danoeh.antennapod.core.cast.FeedWebsite";
public static final String KEY_EPISODE_NOTES = "de.danoeh.antennapod.core.cast.EpisodeNotes";
- public static final int EPISODE_NOTES_MAX_LENGTH = Integer.MAX_VALUE;
/**
* The field <code>AntennaPod.FormatVersion</code> specifies which version of MediaMetaData
diff --git a/core/src/play/java/de/danoeh/antennapod/core/cast/MediaInfoCreator.java b/core/src/play/java/de/danoeh/antennapod/core/cast/MediaInfoCreator.java
index 91de5418d..a9df49176 100644
--- a/core/src/play/java/de/danoeh/antennapod/core/cast/MediaInfoCreator.java
+++ b/core/src/play/java/de/danoeh/antennapod/core/cast/MediaInfoCreator.java
@@ -39,9 +39,6 @@ public class MediaInfoCreator {
}
String notes = media.getNotes();
if (notes != null) {
- if (notes.length() > CastUtils.EPISODE_NOTES_MAX_LENGTH) {
- notes = notes.substring(0, CastUtils.EPISODE_NOTES_MAX_LENGTH);
- }
metadata.putString(CastUtils.KEY_EPISODE_NOTES, notes);
}
// Default id value