summaryrefslogtreecommitdiff
path: root/core/src/main/java
diff options
context:
space:
mode:
authorMartin Fietz <marf@hadiko-99-4.hadiko.uni-karlsruhe.de>2015-04-05 19:48:57 +0200
committerMartin Fietz <marf@hadiko-99-4.hadiko.uni-karlsruhe.de>2015-04-05 22:12:29 +0200
commitfbf1d8373c4e6bd38a73af7e8ff0abe932da0ad8 (patch)
treec01e2db0db4a595c89713a41a55e3d9531ac9354 /core/src/main/java
parent3d19b939b125d36d3ac0ef3e828eabf403aa03d6 (diff)
downloadAntennaPod-fbf1d8373c4e6bd38a73af7e8ff0abe932da0ad8.zip
Minor changes: Log, import order, small refactorings
Diffstat (limited to 'core/src/main/java')
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/feed/EventDistributor.java14
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/feed/FeedItem.java8
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java100
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceTaskManager.java15
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/storage/APCleanupAlgorithm.java4
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/storage/DBReader.java31
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/storage/DBTasks.java6
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/storage/DBWriter.java70
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/LongList.java241
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/QueueAccess.java21
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java36
11 files changed, 371 insertions, 175 deletions
diff --git a/core/src/main/java/de/danoeh/antennapod/core/feed/EventDistributor.java b/core/src/main/java/de/danoeh/antennapod/core/feed/EventDistributor.java
index 5a2cfa40e..6655a7522 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/feed/EventDistributor.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/feed/EventDistributor.java
@@ -5,8 +5,6 @@ import android.util.Log;
import org.apache.commons.lang3.Validate;
-import de.danoeh.antennapod.core.BuildConfig;
-
import java.util.AbstractQueue;
import java.util.Observable;
import java.util.Observer;
@@ -71,23 +69,17 @@ public class EventDistributor extends Observable {
private void processEventQueue() {
Integer result = 0;
- if (BuildConfig.DEBUG)
- Log.d(TAG,
- "Processing event queue. Number of events: "
- + events.size());
+ Log.d(TAG, "Processing event queue. Number of events: " + events.size());
for (Integer current = events.poll(); current != null; current = events
.poll()) {
result |= current;
}
if (result != 0) {
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Notifying observers. Data: " + result);
+ Log.d(TAG, "Notifying observers. Data: " + result);
setChanged();
notifyObservers(result);
} else {
- if (BuildConfig.DEBUG)
- Log.d(TAG,
- "Event queue didn't contain any new events. Observers will not be notified.");
+ Log.d(TAG, "Event queue didn't contain any new events. Observers will not be notified.");
}
}
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 5a4d869e7..4fd7a184c 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
@@ -2,6 +2,9 @@ package de.danoeh.antennapod.core.feed;
import android.net.Uri;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
import java.util.Date;
import java.util.List;
import java.util.concurrent.Callable;
@@ -384,4 +387,9 @@ public class FeedItem extends FeedComponent implements ShownotesProvider, Flattr
public boolean hasChapters() {
return hasChapters;
}
+
+ @Override
+ public String toString() {
+ return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
+ }
}
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 c1563a0fa..43c345fec 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
@@ -36,7 +36,6 @@ import org.apache.commons.lang3.StringUtils;
import java.io.IOException;
import java.util.List;
-import de.danoeh.antennapod.core.BuildConfig;
import de.danoeh.antennapod.core.ClientConfig;
import de.danoeh.antennapod.core.R;
import de.danoeh.antennapod.core.feed.Chapter;
@@ -184,8 +183,7 @@ public class PlaybackService extends Service {
@Override
public boolean onUnbind(Intent intent) {
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Received onUnbind event");
+ Log.d(TAG, "Received onUnbind event");
return super.onUnbind(intent);
}
@@ -219,8 +217,7 @@ public class PlaybackService extends Service {
@Override
public void onCreate() {
super.onCreate();
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Service created.");
+ Log.d(TAG, "Service created.");
isRunning = true;
registerReceiver(headsetDisconnected, new IntentFilter(
@@ -247,8 +244,7 @@ public class PlaybackService extends Service {
@Override
public void onDestroy() {
super.onDestroy();
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Service is about to be destroyed");
+ Log.d(TAG, "Service is about to be destroyed");
isRunning = false;
started = false;
currentMediaType = MediaType.UNKNOWN;
@@ -264,8 +260,7 @@ public class PlaybackService extends Service {
@Override
public IBinder onBind(Intent intent) {
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Received onBind event");
+ Log.d(TAG, "Received onBind event");
return mBinder;
}
@@ -273,8 +268,7 @@ public class PlaybackService extends Service {
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
- if (BuildConfig.DEBUG)
- Log.d(TAG, "OnStartCommand called");
+ Log.d(TAG, "OnStartCommand called");
final int keycode = intent.getIntExtra(MediaButtonReceiver.EXTRA_KEYCODE, -1);
final Playable playable = intent.getParcelableExtra(EXTRA_PLAYABLE);
if (keycode == -1 && playable == null) {
@@ -283,14 +277,12 @@ public class PlaybackService extends Service {
}
if ((flags & Service.START_FLAG_REDELIVERY) != 0) {
- if (BuildConfig.DEBUG)
- Log.d(TAG, "onStartCommand is a redelivered intent, calling stopForeground now.");
+ Log.d(TAG, "onStartCommand is a redelivered intent, calling stopForeground now.");
stopForeground(true);
} else {
if (keycode != -1) {
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Received media button event");
+ Log.d(TAG, "Received media button event");
handleKeycode(keycode);
} else {
started = true;
@@ -310,8 +302,7 @@ public class PlaybackService extends Service {
* Handles media button events
*/
private void handleKeycode(int keycode) {
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Handling keycode: " + keycode);
+ Log.d(TAG, "Handling keycode: " + keycode);
final PlaybackServiceMediaPlayer.PSMPInfo info = mediaPlayer.getPSMPInfo();
final PlayerStatus status = info.playerStatus;
switch (keycode) {
@@ -381,8 +372,7 @@ public class PlaybackService extends Service {
* mediaplayer.
*/
public void setVideoSurface(SurfaceHolder sh) {
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Setting display");
+ Log.d(TAG, "Setting display");
mediaPlayer.setVideoSurface(sh);
}
@@ -465,22 +455,6 @@ public class PlaybackService extends Service {
.build();
GpodnetPreferences.enqueueEpisodeAction(action);
}
-
- // if episode is near end [outro playing]:
- // mark as read, remove from queue, add to playlist history
- // auto delete: see {@link de.danoeh.antennapod.activity.MediaPlayerActivity#onStop()}
- if (playable instanceof FeedMedia) {
- FeedMedia media = (FeedMedia) playable;
- if(media.hasAlmostEnded()) {
- FeedItem item = media.getItem();
- Log.d(TAG, "smart mark as read");
- DBWriter.markItemRead(PlaybackService.this, item, true, false);
- DBWriter.removeQueueItem(PlaybackService.this, item.getId(), false);
- DBWriter.addItemToPlaybackHistory(PlaybackService.this, media);
- // episode should already be flattered, no action required
- }
- }
-
break;
case STOPPED:
@@ -489,10 +463,8 @@ public class PlaybackService extends Service {
break;
case PLAYING:
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Audiofocus successfully requested");
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Resuming/Starting playback");
+ Log.d(TAG, "Audiofocus successfully requested");
+ Log.d(TAG, "Resuming/Starting playback");
taskManager.startPositionSaver();
taskManager.startWidgetUpdater();
@@ -574,8 +546,7 @@ public class PlaybackService extends Service {
};
private void endPlayback(boolean playNextEpisode) {
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Playback ended");
+ Log.d(TAG, "Playback ended");
final Playable playable = mediaPlayer.getPSMPInfo().playable;
if (playable == null) {
@@ -602,7 +573,7 @@ public class PlaybackService extends Service {
// isInQueue remains false
}
if (isInQueue) {
- DBWriter.removeQueueItem(PlaybackService.this, item.getId(), true);
+ DBWriter.removeQueueItem(PlaybackService.this, item, true);
}
DBWriter.addItemToPlaybackHistory(PlaybackService.this, media);
@@ -643,8 +614,7 @@ public class PlaybackService extends Service {
UserPreferences.isFollowQueue();
if (loadNextItem) {
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Loading next item in queue");
+ Log.d(TAG, "Loading next item in queue");
nextMedia = nextItem.getMedia();
}
final boolean prepareImmediately;
@@ -770,8 +740,7 @@ public class PlaybackService extends Service {
}
private void writePlayerStatusPlaybackPreferences() {
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Writing player status playback preferences");
+ Log.d(TAG, "Writing player status playback preferences");
SharedPreferences.Editor editor = PreferenceManager
.getDefaultSharedPreferences(getApplicationContext()).edit();
@@ -820,8 +789,7 @@ public class PlaybackService extends Service {
@Override
protected Void doInBackground(Void... params) {
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Starting background work");
+ Log.d(TAG, "Starting background work");
if (android.os.Build.VERSION.SDK_INT >= 11) {
if (info.playable != null) {
try {
@@ -931,8 +899,7 @@ public class PlaybackService extends Service {
notification = notificationBuilder.build();
}
startForeground(NOTIFICATION_ID, notification);
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Notification set up");
+ Log.d(TAG, "Notification set up");
}
}
@@ -958,8 +925,7 @@ public class PlaybackService extends Service {
float playbackSpeed = getCurrentPlaybackSpeed();
final Playable playable = mediaPlayer.getPSMPInfo().playable;
if (position != INVALID_TIME && duration != INVALID_TIME && playable != null) {
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Saving current position to " + position);
+ Log.d(TAG, "Saving current position to " + position);
if (updatePlayedDuration && playable instanceof FeedMedia) {
FeedMedia media = (FeedMedia) playable;
FeedItem item = media.getItem();
@@ -968,8 +934,7 @@ public class PlaybackService extends Service {
if (isAutoFlattrable(media) &&
(media.getPlayedDuration() > UserPreferences.getAutoFlattrPlayedDurationThreshold() * duration)) {
- if (BuildConfig.DEBUG)
- Log.d(TAG, "saveCurrentPosition: performing auto flattr since played duration " + Integer.toString(media.getPlayedDuration())
+ Log.d(TAG, "saveCurrentPosition: performing auto flattr since played duration " + Integer.toString(media.getPlayedDuration())
+ " is " + UserPreferences.getAutoFlattrPlayedDurationThreshold() * 100 + "% of file duration " + Integer.toString(duration));
DBTasks.flattrItemIfLoggedIn(this, item);
}
@@ -1062,8 +1027,7 @@ public class PlaybackService extends Service {
editor.apply();
}
- if (BuildConfig.DEBUG)
- Log.d(TAG, "RemoteControlClient state was refreshed");
+ Log.d(TAG, "RemoteControlClient state was refreshed");
}
}
}
@@ -1106,15 +1070,12 @@ public class PlaybackService extends Service {
if (StringUtils.equals(intent.getAction(), Intent.ACTION_HEADSET_PLUG)) {
int state = intent.getIntExtra("state", -1);
if (state != -1) {
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Headset plug event. State is " + state);
+ Log.d(TAG, "Headset plug event. State is " + state);
if (state == UNPLUGGED) {
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Headset was unplugged during playback.");
+ Log.d(TAG, "Headset was unplugged during playback.");
pauseIfPauseOnDisconnect();
} else if (state == PLUGGED) {
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Headset was plugged in during playback.");
+ Log.d(TAG, "Headset was plugged in during playback.");
unpauseIfPauseOnDisconnect();
}
} else {
@@ -1131,8 +1092,7 @@ public class PlaybackService extends Service {
int state = intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, -1);
int prevState = intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_PREVIOUS_STATE, -1);
if (state == AudioManager.SCO_AUDIO_STATE_CONNECTED) {
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Received bluetooth connection intent");
+ Log.d(TAG, "Received bluetooth connection intent");
unpauseIfPauseOnDisconnect();
}
}
@@ -1144,8 +1104,7 @@ public class PlaybackService extends Service {
@Override
public void onReceive(Context context, Intent intent) {
// sound is about to change, eg. bluetooth -> speaker
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Pausing playback because audio is becoming noisy");
+ Log.d(TAG, "Pausing playback because audio is becoming noisy");
pauseIfPauseOnDisconnect();
}
// android.media.AUDIO_BECOMING_NOISY
@@ -1191,8 +1150,7 @@ public class PlaybackService extends Service {
@Override
public void onReceive(Context context, Intent intent) {
if (StringUtils.equals(intent.getAction(), ACTION_SKIP_CURRENT_EPISODE)) {
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Received SKIP_CURRENT_EPISODE intent");
+ Log.d(TAG, "Received SKIP_CURRENT_EPISODE intent");
mediaPlayer.endPlayback();
}
}
@@ -1202,8 +1160,7 @@ public class PlaybackService extends Service {
@Override
public void onReceive(Context context, Intent intent) {
if (StringUtils.equals(intent.getAction(), ACTION_RESUME_PLAY_CURRENT_EPISODE)) {
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Received RESUME_PLAY_CURRENT_EPISODE intent");
+ Log.d(TAG, "Received RESUME_PLAY_CURRENT_EPISODE intent");
mediaPlayer.resume();
}
}
@@ -1213,8 +1170,7 @@ public class PlaybackService extends Service {
@Override
public void onReceive(Context context, Intent intent) {
if (StringUtils.equals(intent.getAction(), ACTION_PAUSE_PLAY_CURRENT_EPISODE)) {
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Received PAUSE_PLAY_CURRENT_EPISODE intent");
+ Log.d(TAG, "Received PAUSE_PLAY_CURRENT_EPISODE intent");
mediaPlayer.pause(false, false);
}
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceTaskManager.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceTaskManager.java
index 1865afa6f..3e414a8b7 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceTaskManager.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceTaskManager.java
@@ -5,14 +5,21 @@ import android.util.Log;
import org.apache.commons.lang3.Validate;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TimeUnit;
+
import de.danoeh.antennapod.core.BuildConfig;
-import de.danoeh.antennapod.core.feed.EventDistributor;
import de.danoeh.antennapod.core.feed.FeedItem;
+import de.danoeh.antennapod.core.feed.QueueEvent;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.util.playback.Playable;
-
-import java.util.List;
-import java.util.concurrent.*;
+import de.greenrobot.event.EventBus;
/**
* Manages the background tasks of PlaybackSerivce, i.e.
diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/APCleanupAlgorithm.java b/core/src/main/java/de/danoeh/antennapod/core/storage/APCleanupAlgorithm.java
index 0164e914b..de6c02de7 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/storage/APCleanupAlgorithm.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/storage/APCleanupAlgorithm.java
@@ -12,7 +12,7 @@ import java.util.concurrent.ExecutionException;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.preferences.UserPreferences;
-import de.danoeh.antennapod.core.util.QueueAccess;
+import de.danoeh.antennapod.core.util.LongList;
/**
* Implementation of the EpisodeCleanupAlgorithm interface used by AntennaPod.
@@ -24,7 +24,7 @@ public class APCleanupAlgorithm implements EpisodeCleanupAlgorithm<Integer> {
public int performCleanup(Context context, Integer episodeNumber) {
List<FeedItem> candidates = new ArrayList<FeedItem>();
List<FeedItem> downloadedItems = DBReader.getDownloadedItems(context);
- QueueAccess queue = QueueAccess.IDListAccess(DBReader.getQueueIDList(context));
+ LongList queue = DBReader.getQueueIDList(context);
List<FeedItem> delete;
for (FeedItem item : downloadedItems) {
if (item.hasMedia() && item.getMedia().isDownloaded()
diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/DBReader.java b/core/src/main/java/de/danoeh/antennapod/core/storage/DBReader.java
index e10fffc18..a7c98c7c6 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/storage/DBReader.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/storage/DBReader.java
@@ -21,6 +21,7 @@ import de.danoeh.antennapod.core.feed.SimpleChapter;
import de.danoeh.antennapod.core.feed.VorbisCommentChapter;
import de.danoeh.antennapod.core.service.download.DownloadStatus;
import de.danoeh.antennapod.core.util.DownloadError;
+import de.danoeh.antennapod.core.util.LongList;
import de.danoeh.antennapod.core.util.comparator.DownloadStatusComparator;
import de.danoeh.antennapod.core.util.comparator.FeedItemPubdateComparator;
import de.danoeh.antennapod.core.util.comparator.PlaybackCompletionDateComparator;
@@ -338,8 +339,7 @@ public final class DBReader {
}
static List<FeedItem> getQueue(Context context, PodDBAdapter adapter) {
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Extracting queue");
+ Log.d(TAG, "getQueue()");
Cursor itemlistCursor = adapter.getQueueCursor();
List<FeedItem> items = extractItemlistFromCursor(adapter,
@@ -358,21 +358,21 @@ public final class DBReader {
* @return A list of IDs sorted by the same order as the queue. The caller can wrap the returned
* list in a {@link de.danoeh.antennapod.core.util.QueueAccess} object for easier access to the queue's properties.
*/
- public static List<Long> getQueueIDList(Context context) {
+ public static LongList getQueueIDList(Context context) {
PodDBAdapter adapter = new PodDBAdapter(context);
adapter.open();
- List<Long> result = getQueueIDList(adapter);
+ LongList result = getQueueIDList(adapter);
adapter.close();
return result;
}
- static List<Long> getQueueIDList(PodDBAdapter adapter) {
+ static LongList getQueueIDList(PodDBAdapter adapter) {
adapter.open();
Cursor queueCursor = adapter.getQueueIDCursor();
- List<Long> queueIds = new ArrayList<Long>(queueCursor.getCount());
+ LongList queueIds = new LongList(queueCursor.getCount());
if (queueCursor.moveToFirst()) {
do {
queueIds.add(queueCursor.getLong(0));
@@ -383,6 +383,22 @@ public final class DBReader {
/**
+ * Return the size of the queue.
+ *
+ * @param context A context that is used for opening a database connection.
+ * @return Size of the queue.
+ */
+ public static int getQueueSize(Context context) {
+ Log.d(TAG, "getQueueSize()");
+
+ PodDBAdapter adapter = new PodDBAdapter(context);
+ adapter.open();
+ int size = adapter.getQueueSize();
+ adapter.close();
+ return size;
+ }
+
+ /**
* Loads a list of the FeedItems in the queue. If the FeedItems of the queue are not used directly, consider using
* {@link #getQueueIDList(android.content.Context)} instead.
*
@@ -391,8 +407,7 @@ public final class DBReader {
* list in a {@link de.danoeh.antennapod.core.util.QueueAccess} object for easier access to the queue's properties.
*/
public static List<FeedItem> getQueue(Context context) {
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Extracting queue");
+ Log.d(TAG, "getQueue()");
PodDBAdapter adapter = new PodDBAdapter(context);
adapter.open();
diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/DBTasks.java b/core/src/main/java/de/danoeh/antennapod/core/storage/DBTasks.java
index e0e370b0d..9fa17bf72 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/storage/DBTasks.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/storage/DBTasks.java
@@ -34,7 +34,7 @@ import de.danoeh.antennapod.core.service.GpodnetSyncService;
import de.danoeh.antennapod.core.service.download.DownloadStatus;
import de.danoeh.antennapod.core.service.playback.PlaybackService;
import de.danoeh.antennapod.core.util.DownloadError;
-import de.danoeh.antennapod.core.util.QueueAccess;
+import de.danoeh.antennapod.core.util.LongList;
import de.danoeh.antennapod.core.util.comparator.FeedItemPubdateComparator;
import de.danoeh.antennapod.core.util.exception.MediaFileNotFoundException;
import de.danoeh.antennapod.core.util.flattr.FlattrUtils;
@@ -524,8 +524,8 @@ public final class DBTasks {
* @param feedItemId ID of the FeedItem
*/
public static boolean isInQueue(Context context, final long feedItemId) {
- List<Long> queue = DBReader.getQueueIDList(context);
- return QueueAccess.IDListAccess(queue).contains(feedItemId);
+ LongList queue = DBReader.getQueueIDList(context);
+ return queue.contains(feedItemId);
}
private static Feed searchFeedByIdentifyingValueOrID(Context context, PodDBAdapter adapter,
diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/DBWriter.java b/core/src/main/java/de/danoeh/antennapod/core/storage/DBWriter.java
index 53fe5149b..63c52b488 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/storage/DBWriter.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/storage/DBWriter.java
@@ -33,17 +33,19 @@ import de.danoeh.antennapod.core.feed.FeedImage;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
import de.danoeh.antennapod.core.feed.FeedPreferences;
+import de.danoeh.antennapod.core.feed.QueueEvent;
import de.danoeh.antennapod.core.gpoddernet.model.GpodnetEpisodeAction;
-import de.danoeh.antennapod.core.gpoddernet.model.GpodnetEpisodeAction.Action;
import de.danoeh.antennapod.core.preferences.GpodnetPreferences;
import de.danoeh.antennapod.core.preferences.PlaybackPreferences;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.service.download.DownloadStatus;
import de.danoeh.antennapod.core.service.playback.PlaybackService;
+import de.danoeh.antennapod.core.util.LongList;
import de.danoeh.antennapod.core.util.QueueAccess;
import de.danoeh.antennapod.core.util.flattr.FlattrStatus;
import de.danoeh.antennapod.core.util.flattr.FlattrThing;
import de.danoeh.antennapod.core.util.flattr.SimpleFlattrThing;
+import de.greenrobot.event.EventBus;
/**
* Provides methods for writing data to AntennaPod's database.
@@ -126,16 +128,15 @@ public class DBWriter {
// Gpodder: queue delete action for synchronization
if(GpodnetPreferences.loggedIn()) {
FeedItem item = media.getItem();
- GpodnetEpisodeAction action = new GpodnetEpisodeAction.Builder(item, Action.DELETE)
+ GpodnetEpisodeAction action = new GpodnetEpisodeAction.Builder(item, GpodnetEpisodeAction.Action.DELETE)
.currentDeviceId()
.currentTimestamp()
.build();
GpodnetPreferences.enqueueEpisodeAction(action);
}
}
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Deleting File. Result: " + result);
- EventDistributor.getInstance().sendQueueUpdateBroadcast();
+ Log.d(TAG, "Deleting File. Result: " + result);
+ EventBus.getDefault().post(new QueueEvent(QueueEvent.Action.DELETED_MEDIA, media.getItem()));
EventDistributor.getInstance().sendUnreadItemsUpdateBroadcast();
}
}
@@ -370,8 +371,7 @@ public class DBWriter {
}
if (queueModified) {
adapter.setQueue(queue);
- EventDistributor.getInstance()
- .sendQueueUpdateBroadcast();
+ EventBus.getDefault().post(new QueueEvent(QueueEvent.Action.ADDED, item, index));
}
if (unreadItemsModified && item != null) {
adapter.setSingleFeedItem(item);
@@ -439,8 +439,7 @@ public class DBWriter {
}
if (queueModified) {
adapter.setQueue(queue);
- EventDistributor.getInstance()
- .sendQueueUpdateBroadcast();
+ EventBus.getDefault().post(new QueueEvent(QueueEvent.Action.ADDED_ITEMS, queue));
}
if (unreadItemsModified) {
adapter.setFeedItemlist(itemsToSave);
@@ -471,7 +470,7 @@ public class DBWriter {
adapter.clearQueue();
adapter.close();
- EventDistributor.getInstance().sendQueueUpdateBroadcast();
+ EventBus.getDefault().post(new QueueEvent(QueueEvent.Action.CLEARED));
}
});
}
@@ -480,11 +479,11 @@ public class DBWriter {
* Removes a FeedItem object from the queue.
*
* @param context A context that is used for opening a database connection.
- * @param itemId ID of the FeedItem that should be removed.
+ * @param item FeedItem that should be removed.
* @param performAutoDownload true if an auto-download process should be started after the operation.
*/
public static Future<?> removeQueueItem(final Context context,
- final long itemId, final boolean performAutoDownload) {
+ final FeedItem item, final boolean performAutoDownload) {
return dbExec.submit(new Runnable() {
@Override
@@ -498,16 +497,14 @@ public class DBWriter {
if (queue != null) {
boolean queueModified = false;
QueueAccess queueAccess = QueueAccess.ItemListAccess(queue);
- if (queueAccess.contains(itemId)) {
- item = DBReader.getFeedItem(context, itemId);
+ if (queueAccess.contains(item.getId())) {
if (item != null) {
- queueModified = queueAccess.remove(itemId);
+ queueModified = queueAccess.remove(item.getId());
}
}
if (queueModified) {
adapter.setQueue(queue);
- EventDistributor.getInstance()
- .sendQueueUpdateBroadcast();
+ EventBus.getDefault().post(new QueueEvent(QueueEvent.Action.REMOVED, item));
} else {
Log.w(TAG, "Queue was not modified by call to removeQueueItem");
}
@@ -535,16 +532,13 @@ public class DBWriter {
return dbExec.submit(new Runnable() {
@Override
public void run() {
- List<Long> queueIdList = DBReader.getQueueIDList(context);
- int currentLocation = 0;
- for (long id : queueIdList) {
- if (id == itemId) {
- moveQueueItemHelper(context, currentLocation, 0, broadcastUpdate);
- return;
- }
- currentLocation++;
+ LongList queueIdList = DBReader.getQueueIDList(context);
+ int index = queueIdList.indexOf(itemId);
+ if (index >=0) {
+ moveQueueItemHelper(context, index, 0, broadcastUpdate);
+ } else {
+ Log.e(TAG, "moveQueueItemToTop: item not found");
}
- Log.e(TAG, "moveQueueItemToTop: item not found");
}
});
}
@@ -562,17 +556,14 @@ public class DBWriter {
return dbExec.submit(new Runnable() {
@Override
public void run() {
- List<Long> queueIdList = DBReader.getQueueIDList(context);
- int currentLocation = 0;
- for (long id : queueIdList) {
- if (id == itemId) {
- moveQueueItemHelper(context, currentLocation, queueIdList.size() - 1,
- broadcastUpdate);
- return;
- }
- currentLocation++;
+ LongList queueIdList = DBReader.getQueueIDList(context);
+ int index = queueIdList.indexOf(itemId);
+ if(index >= 0) {
+ moveQueueItemHelper(context, index, queueIdList.size() - 1,
+ broadcastUpdate);
+ } else {
+ Log.e(TAG, "moveQueueItemToBottom: item not found");
}
- Log.e(TAG, "moveQueueItemToBottom: item not found");
}
});
}
@@ -626,8 +617,8 @@ public class DBWriter {
adapter.setQueue(queue);
if (broadcastUpdate) {
- EventDistributor.getInstance()
- .sendQueueUpdateBroadcast();
+ EventBus.getDefault().post(new QueueEvent(QueueEvent.Action.REMOVED, item));
+ EventBus.getDefault().post(new QueueEvent(QueueEvent.Action.ADDED, item, to));
}
}
@@ -1036,8 +1027,7 @@ public class DBWriter {
Collections.sort(queue, comparator);
adapter.setQueue(queue);
if (broadcastUpdate) {
- EventDistributor.getInstance()
- .sendQueueUpdateBroadcast();
+ EventBus.getDefault().post(new QueueEvent(QueueEvent.Action.SORTED));
}
} else {
Log.e(TAG, "sortQueue: Could not load queue");
diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/LongList.java b/core/src/main/java/de/danoeh/antennapod/core/util/LongList.java
new file mode 100644
index 000000000..f5d0cab0c
--- /dev/null
+++ b/core/src/main/java/de/danoeh/antennapod/core/util/LongList.java
@@ -0,0 +1,241 @@
+package de.danoeh.antennapod.core.util;
+
+import java.util.Arrays;
+
+/**
+ * Fast and memory efficient long list
+ */
+public final class LongList {
+
+ private long[] values;
+ private int size;
+
+ /**
+ * Constructs an empty instance with a default initial capacity.
+ */
+ public LongList() {
+ this(4);
+ }
+
+ /**
+ * Constructs an empty instance.
+ *
+ * @param initialCapacity {@code >= 0;} initial capacity of the list
+ */
+ public LongList(int initialCapacity) {
+ if(initialCapacity < 0) {
+ throw new IllegalArgumentException("initial capacity must be 0 or higher");
+ }
+ values = new long[initialCapacity];
+ size = 0;
+ }
+
+ @Override
+ public int hashCode() {
+ Arrays.hashCode(values);
+ int hashCode = 1;
+ for (int i = 0; i < size; i++) {
+ long value = values[i];
+ hashCode = 31 * hashCode + (int)(value ^ (value >>> 32));
+ }
+ return hashCode;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+ if (! (other instanceof LongList)) {
+ return false;
+ }
+ LongList otherList = (LongList) other;
+ if (size != otherList.size) {
+ return false;
+ }
+ for (int i = 0; i < size; i++) {
+ if (values[i] != otherList.values[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ StringBuffer sb = new StringBuffer(size * 5 + 10);
+ sb.append("LongList{");
+ for (int i = 0; i < size; i++) {
+ if (i != 0) {
+ sb.append(", ");
+ }
+ sb.append(values[i]);
+ }
+ sb.append("}");
+ return sb.toString();
+ }
+
+ /**
+ * Gets the number of elements in this list.
+ */
+ public int size() {
+ return size;
+ }
+
+ /**
+ * Gets the indicated value.
+ *
+ * @param n {@code >= 0, < size();} which element
+ * @return the indicated element's value
+ */
+ public long get(int n) {
+ if (n >= size) {
+ throw new IndexOutOfBoundsException("n >= size()");
+ } else if(n < 0) {
+ throw new IndexOutOfBoundsException("n < 0");
+ }
+ return values[n];
+ }
+
+ /**
+ * Sets the value at the given index.
+ *
+ * @param index the index at which to put the specified object.
+ * @param value the object to add.
+ * @return the previous element at the index.
+ */
+ public long set(int index, long value) {
+ if (index >= size) {
+ throw new IndexOutOfBoundsException("n >= size()");
+ } else if(index < 0) {
+ throw new IndexOutOfBoundsException("n < 0");
+ }
+ long result = values[index];
+ values[index] = value;
+ return result;
+ }
+
+ /**
+ * Adds an element to the end of the list. This will increase the
+ * list's capacity if necessary.
+ *
+ * @param value the value to add
+ */
+ public void add(long value) {
+ growIfNeeded();
+ values[size++] = value;
+ }
+
+ /**
+ * Inserts element into specified index, moving elements at and above
+ * that index up one. May not be used to insert at an index beyond the
+ * current size (that is, insertion as a last element is legal but
+ * no further).
+ *
+ * @param n {@code >= 0, <=size();} index of where to insert
+ * @param value value to insert
+ */
+ public void insert(int n, int value) {
+ if (n > size) {
+ throw new IndexOutOfBoundsException("n > size()");
+ } else if(n < 0) {
+ throw new IndexOutOfBoundsException("n < 0");
+ }
+
+ growIfNeeded();
+
+ System.arraycopy (values, n, values, n+1, size - n);
+ values[n] = value;
+ size++;
+ }
+
+ /**
+ * Removes value from this list.
+ *
+ * @param value value to remove
+ * return {@code true} if the value was removed, {@code false} otherwise
+ */
+ public boolean remove(long value) {
+ for (int i = 0; i < size; i++) {
+ if (values[i] == value) {
+ size--;
+ System.arraycopy(values, i+1, values, i, size-i);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Removes an element at a given index, shifting elements at greater
+ * indicies down one.
+ *
+ * @param index index of element to remove
+ */
+ public void removeIndex(int index) {
+ if (index >= size) {
+ throw new IndexOutOfBoundsException("n >= size()");
+ } else if(index < 0) {
+ throw new IndexOutOfBoundsException("n < 0");
+ }
+ size--;
+ System.arraycopy (values, index + 1, values, index, size - index);
+ }
+
+ /**
+ * Increases size of array if needed
+ */
+ private void growIfNeeded() {
+ if (size == values.length) {
+ // Resize.
+ long[] newArray = new long[size * 3 / 2 + 10];
+ System.arraycopy(values, 0, newArray, 0, size);
+ values = newArray;
+ }
+ }
+
+ /**
+ * Returns the index of the given value, or -1 if the value does not
+ * appear in the list.
+ *
+ * @param value value to find
+ * @return index of value or -1
+ */
+ public int indexOf(long value) {
+ for (int i = 0; i < size; i++) {
+ if (values[i] == value) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Removes all values from this list.
+ */
+ public void clear() {
+ values = new long[4];
+ size = 0;
+ }
+
+
+ /**
+ * Returns true if the given value is contained in the list
+ *
+ * @param value value to look for
+ * @return {@code true} if this list contains {@code value}, {@code false} otherwise
+ */
+ public boolean contains(long value) {
+ return indexOf(value) >= 0;
+ }
+
+ /**
+ * Returns an array with a copy of this list's values
+ *
+ * @return array with a copy of this list's values
+ */
+ public long[] toArray() {
+ return Arrays.copyOf(values, size);
+
+ }
+}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/QueueAccess.java b/core/src/main/java/de/danoeh/antennapod/core/util/QueueAccess.java
index 8e40ae184..7377b202d 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/util/QueueAccess.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/util/QueueAccess.java
@@ -1,10 +1,10 @@
package de.danoeh.antennapod.core.util;
-import de.danoeh.antennapod.core.feed.FeedItem;
-
import java.util.Iterator;
import java.util.List;
+import de.danoeh.antennapod.core.feed.FeedItem;
+
/**
* Provides methods for accessing the queue. It is possible to load only a part of the information about the queue that
* is stored in the database (e.g. sometimes the user just has to test if a specific item is contained in the List.
@@ -25,23 +25,6 @@ public abstract class QueueAccess {
public abstract boolean remove(long id);
private QueueAccess() {
-
- }
-
- public static QueueAccess IDListAccess(final List<Long> ids) {
- return new QueueAccess() {
- @Override
- public boolean contains(long id) {
- return (ids != null) && ids.contains(id);
- }
-
- @Override
- public boolean remove(long id) {
- return ids.remove(id);
- }
-
-
- };
}
public static QueueAccess ItemListAccess(final List<FeedItem> items) {
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 26dd2ec4c..17c752bb6 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
@@ -1,7 +1,13 @@
package de.danoeh.antennapod.core.util.playback;
import android.app.Activity;
-import android.content.*;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.ServiceConnection;
+import android.content.SharedPreferences;
import android.content.res.TypedArray;
import android.media.MediaPlayer;
import android.os.AsyncTask;
@@ -19,6 +25,13 @@ import android.widget.TextView;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
+import java.util.concurrent.RejectedExecutionHandler;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
import de.danoeh.antennapod.core.BuildConfig;
import de.danoeh.antennapod.core.R;
import de.danoeh.antennapod.core.feed.Chapter;
@@ -33,8 +46,6 @@ import de.danoeh.antennapod.core.storage.DBTasks;
import de.danoeh.antennapod.core.util.Converter;
import de.danoeh.antennapod.core.util.playback.Playable.PlayableUtils;
-import java.util.concurrent.*;
-
/**
* Communicates with the playback service. GUI classes should use this class to
* control playback instead of communicating with the PlaybackService directly.
@@ -118,8 +129,7 @@ public abstract class PlaybackController {
* example in the activity's onStop() method.
*/
public void release() {
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Releasing PlaybackController");
+ Log.d(TAG, "Releasing PlaybackController");
try {
activity.unregisterReceiver(statusUpdate);
@@ -177,7 +187,7 @@ public abstract class PlaybackController {
boolean bound = false;
if (!PlaybackService.started) {
if (serviceIntent != null) {
- if (BuildConfig.DEBUG) Log.d(TAG, "Calling start service");
+ Log.d(TAG, "Calling start service");
activity.startService(serviceIntent);
bound = activity.bindService(serviceIntent, mConnection, 0);
} else {
@@ -186,14 +196,11 @@ public abstract class PlaybackController {
handleStatus();
}
} else {
- if (BuildConfig.DEBUG)
- Log.d(TAG,
- "PlaybackService is running, trying to connect without start command.");
+ Log.d(TAG, "PlaybackService is running, trying to connect without start command.");
bound = activity.bindService(new Intent(activity,
PlaybackService.class), mConnection, 0);
}
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Result for service binding: " + bound);
+ Log.d(TAG, "Result for service binding: " + bound);
}
};
intentLoader.execute();
@@ -272,8 +279,7 @@ public abstract class PlaybackController {
.getService();
if (!released) {
queryService();
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Connection to Service established");
+ Log.d(TAG, "Connection to Service established");
} else {
Log.i(TAG, "Connection to playback service has been established, but controller has already been released");
}
@@ -282,9 +288,7 @@ public abstract class PlaybackController {
@Override
public void onServiceDisconnected(ComponentName name) {
playbackService = null;
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Disconnected from Service");
-
+ Log.d(TAG, "Disconnected from Service");
}
};