Refactor database access

This commit is contained in:
Martin Fietz 2015-09-09 14:05:58 +02:00
parent 2c3f7921d2
commit 75dfc89a44
65 changed files with 1509 additions and 1698 deletions

View File

@ -2,6 +2,7 @@ package de.test.antennapod;
import android.test.InstrumentationTestRunner; import android.test.InstrumentationTestRunner;
import android.test.suitebuilder.TestSuiteBuilder; import android.test.suitebuilder.TestSuiteBuilder;
import junit.framework.TestSuite; import junit.framework.TestSuite;
public class AntennaPodTestRunner extends InstrumentationTestRunner { public class AntennaPodTestRunner extends InstrumentationTestRunner {
@ -13,4 +14,5 @@ public class AntennaPodTestRunner extends InstrumentationTestRunner {
.excludePackages("de.test.antennapod.gpodnet") .excludePackages("de.test.antennapod.gpodnet")
.build(); .build();
} }
} }

View File

@ -1,7 +1,6 @@
package de.test.antennapod.service.playback; package de.test.antennapod.service.playback;
import android.content.Context; import android.content.Context;
import android.media.RemoteControlClient;
import android.test.InstrumentationTestCase; import android.test.InstrumentationTestCase;
import junit.framework.AssertionFailedError; import junit.framework.AssertionFailedError;
@ -45,7 +44,7 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase {
@Override @Override
protected void tearDown() throws Exception { protected void tearDown() throws Exception {
super.tearDown(); super.tearDown();
PodDBAdapter.deleteDatabase(getInstrumentation().getTargetContext()); PodDBAdapter.deleteDatabase();
httpServer.stop(); httpServer.stop();
} }
@ -54,16 +53,16 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase {
super.setUp(); super.setUp();
assertionError = null; assertionError = null;
final Context context = getInstrumentation().getTargetContext(); // create new database
context.deleteDatabase(PodDBAdapter.DATABASE_NAME); PodDBAdapter.deleteDatabase();
// make sure database is created PodDBAdapter adapter = PodDBAdapter.getInstance();
PodDBAdapter adapter = new PodDBAdapter(context);
adapter.open(); adapter.open();
adapter.close(); adapter.close();
httpServer = new HTTPBin(); httpServer = new HTTPBin();
httpServer.start(); httpServer.start();
final Context context = getInstrumentation().getTargetContext();
File cacheDir = context.getExternalFilesDir("testFiles"); File cacheDir = context.getExternalFilesDir("testFiles");
if (cacheDir == null) if (cacheDir == null)
cacheDir = context.getExternalFilesDir("testFiles"); cacheDir = context.getExternalFilesDir("testFiles");
@ -119,12 +118,12 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase {
Feed f = new Feed(0, new Date(), "f", "l", "d", null, null, null, null, "i", null, null, "l", false); Feed f = new Feed(0, new Date(), "f", "l", "d", null, null, null, null, "i", null, null, "l", false);
FeedPreferences prefs = new FeedPreferences(f.getId(), false, FeedPreferences.AutoDeleteAction.NO, null, null); FeedPreferences prefs = new FeedPreferences(f.getId(), false, FeedPreferences.AutoDeleteAction.NO, null, null);
f.setPreferences(prefs); f.setPreferences(prefs);
f.setItems(new ArrayList<FeedItem>()); f.setItems(new ArrayList<>());
FeedItem i = new FeedItem(0, "t", "i", "l", new Date(), FeedItem.UNPLAYED, f); FeedItem i = new FeedItem(0, "t", "i", "l", new Date(), FeedItem.UNPLAYED, f);
f.getItems().add(i); f.getItems().add(i);
FeedMedia media = new FeedMedia(0, i, 0, 0, 0, "audio/wav", fileUrl, downloadUrl, fileUrl != null, null, 0); FeedMedia media = new FeedMedia(0, i, 0, 0, 0, "audio/wav", fileUrl, downloadUrl, fileUrl != null, null, 0);
i.setMedia(media); i.setMedia(media);
PodDBAdapter adapter = new PodDBAdapter(c); PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
adapter.setCompleteFeed(f); adapter.setCompleteFeed(f);
assertTrue(media.getId() != 0); assertTrue(media.getId() != 0);

View File

@ -26,16 +26,16 @@ public class PlaybackServiceTaskManagerTest extends InstrumentationTestCase {
@Override @Override
protected void tearDown() throws Exception { protected void tearDown() throws Exception {
super.tearDown(); super.tearDown();
assertTrue(PodDBAdapter.deleteDatabase(getInstrumentation().getTargetContext())); PodDBAdapter.deleteDatabase();
} }
@Override @Override
protected void setUp() throws Exception { protected void setUp() throws Exception {
super.setUp(); super.setUp();
final Context context = getInstrumentation().getTargetContext();
context.deleteDatabase(PodDBAdapter.DATABASE_NAME); // create new database
// make sure database is created PodDBAdapter.deleteDatabase();
PodDBAdapter adapter = new PodDBAdapter(context); PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
adapter.close(); adapter.close();
} }
@ -49,11 +49,11 @@ public class PlaybackServiceTaskManagerTest extends InstrumentationTestCase {
final Context c = getInstrumentation().getTargetContext(); final Context c = getInstrumentation().getTargetContext();
final int NUM_ITEMS = 10; final int NUM_ITEMS = 10;
Feed f = new Feed(0, new Date(), "title", "link", "d", null, null, null, null, "id", null, "null", "url", false); Feed f = new Feed(0, new Date(), "title", "link", "d", null, null, null, null, "id", null, "null", "url", false);
f.setItems(new ArrayList<FeedItem>()); f.setItems(new ArrayList<>());
for (int i = 0; i < NUM_ITEMS; i++) { for (int i = 0; i < NUM_ITEMS; i++) {
f.getItems().add(new FeedItem(0, pref + i, pref + i, "link", new Date(), FeedItem.PLAYED, f)); f.getItems().add(new FeedItem(0, pref + i, pref + i, "link", new Date(), FeedItem.PLAYED, f));
} }
PodDBAdapter adapter = new PodDBAdapter(c); PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
adapter.setCompleteFeed(f); adapter.setCompleteFeed(f);
adapter.setQueue(f.getItems()); adapter.setQueue(f.getItems());

View File

@ -15,7 +15,6 @@ import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.FeedItemStatistics; import de.danoeh.antennapod.core.storage.FeedItemStatistics;
import de.danoeh.antennapod.core.storage.PodDBAdapter; import de.danoeh.antennapod.core.storage.PodDBAdapter;
import de.danoeh.antennapod.core.util.LongList; import de.danoeh.antennapod.core.util.LongList;
import de.danoeh.antennapod.core.util.flattr.FlattrStatus;
import static de.test.antennapod.storage.DBTestUtils.saveFeedlist; import static de.test.antennapod.storage.DBTestUtils.saveFeedlist;
@ -27,25 +26,23 @@ public class DBReaderTest extends InstrumentationTestCase {
@Override @Override
protected void tearDown() throws Exception { protected void tearDown() throws Exception {
super.tearDown(); super.tearDown();
final Context context = getInstrumentation().getTargetContext(); assertTrue(PodDBAdapter.deleteDatabase());
assertTrue(PodDBAdapter.deleteDatabase(context));
} }
@Override @Override
protected void setUp() throws Exception { protected void setUp() throws Exception {
super.setUp(); super.setUp();
final Context context = getInstrumentation().getTargetContext();
context.deleteDatabase(PodDBAdapter.DATABASE_NAME); // create new database
// make sure database is created PodDBAdapter.deleteDatabase();
PodDBAdapter adapter = new PodDBAdapter(context); PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
adapter.close(); adapter.close();
} }
public void testGetFeedList() { public void testGetFeedList() {
final Context context = getInstrumentation().getTargetContext(); List<Feed> feeds = saveFeedlist(10, 0, false);
List<Feed> feeds = saveFeedlist(context, 10, 0, false); List<Feed> savedFeeds = DBReader.getFeedList();
List<Feed> savedFeeds = DBReader.getFeedList(context);
assertNotNull(savedFeeds); assertNotNull(savedFeeds);
assertEquals(feeds.size(), savedFeeds.size()); assertEquals(feeds.size(), savedFeeds.size());
for (int i = 0; i < feeds.size(); i++) { for (int i = 0; i < feeds.size(); i++) {
@ -54,8 +51,7 @@ public class DBReaderTest extends InstrumentationTestCase {
} }
public void testGetFeedListSortOrder() { public void testGetFeedListSortOrder() {
final Context context = getInstrumentation().getTargetContext(); PodDBAdapter adapter = PodDBAdapter.getInstance();
PodDBAdapter adapter = new PodDBAdapter(context);
adapter.open(); adapter.open();
Feed feed1 = new Feed(0, new Date(), "A", "link", "d", null, null, null, "rss", "A", null, "", "", true); Feed feed1 = new Feed(0, new Date(), "A", "link", "d", null, null, null, "rss", "A", null, "", "", true);
@ -73,7 +69,7 @@ public class DBReaderTest extends InstrumentationTestCase {
adapter.close(); adapter.close();
List<Feed> saved = DBReader.getFeedList(context); List<Feed> saved = DBReader.getFeedList();
assertNotNull(saved); assertNotNull(saved);
assertEquals("Wrong size: ", 4, saved.size()); assertEquals("Wrong size: ", 4, saved.size());
@ -84,9 +80,8 @@ public class DBReaderTest extends InstrumentationTestCase {
} }
public void testFeedListDownloadUrls() { public void testFeedListDownloadUrls() {
final Context context = getInstrumentation().getTargetContext(); List<Feed> feeds = saveFeedlist(10, 0, false);
List<Feed> feeds = saveFeedlist(context, 10, 0, false); List<String> urls = DBReader.getFeedListDownloadUrls();
List<String> urls = DBReader.getFeedListDownloadUrls(context);
assertNotNull(urls); assertNotNull(urls);
assertTrue(urls.size() == feeds.size()); assertTrue(urls.size() == feeds.size());
for (int i = 0; i < urls.size(); i++) { for (int i = 0; i < urls.size(); i++) {
@ -98,8 +93,8 @@ public class DBReaderTest extends InstrumentationTestCase {
final Context context = getInstrumentation().getTargetContext(); final Context context = getInstrumentation().getTargetContext();
final int numFeeds = 10; final int numFeeds = 10;
final int numItems = 1; final int numItems = 1;
List<Feed> feeds = saveFeedlist(context, numFeeds, numItems, false); List<Feed> feeds = saveFeedlist(numFeeds, numItems, false);
List<FeedItem> items = new ArrayList<FeedItem>(); List<FeedItem> items = new ArrayList<>();
for (Feed f : feeds) { for (Feed f : feeds) {
for (FeedItem item : f.getItems()) { for (FeedItem item : f.getItems()) {
item.setFeed(null); item.setFeed(null);
@ -107,7 +102,7 @@ public class DBReaderTest extends InstrumentationTestCase {
items.add(item); items.add(item);
} }
} }
DBReader.loadFeedDataOfFeedItemlist(context, items); DBReader.loadFeedDataOfFeedItemlist(items);
for (int i = 0; i < numFeeds; i++) { for (int i = 0; i < numFeeds; i++) {
for (int j = 0; j < numItems; j++) { for (int j = 0; j < numItems; j++) {
FeedItem item = feeds.get(i).getItems().get(j); FeedItem item = feeds.get(i).getItems().get(j);
@ -119,13 +114,12 @@ public class DBReaderTest extends InstrumentationTestCase {
} }
public void testGetFeedItemList() { public void testGetFeedItemList() {
final Context context = getInstrumentation().getTargetContext();
final int numFeeds = 1; final int numFeeds = 1;
final int numItems = 10; final int numItems = 10;
Feed feed = saveFeedlist(context, numFeeds, numItems, false).get(0); Feed feed = saveFeedlist(numFeeds, numItems, false).get(0);
List<FeedItem> items = feed.getItems(); List<FeedItem> items = feed.getItems();
feed.setItems(null); feed.setItems(null);
List<FeedItem> savedItems = DBReader.getFeedItemList(context, feed); List<FeedItem> savedItems = DBReader.getFeedItemList(feed);
assertNotNull(savedItems); assertNotNull(savedItems);
assertTrue(savedItems.size() == items.size()); assertTrue(savedItems.size() == items.size());
for (int i = 0; i < savedItems.size(); i++) { for (int i = 0; i < savedItems.size(); i++) {
@ -137,22 +131,21 @@ public class DBReaderTest extends InstrumentationTestCase {
if (numItems <= 0) { if (numItems <= 0) {
throw new IllegalArgumentException("numItems<=0"); throw new IllegalArgumentException("numItems<=0");
} }
final Context context = getInstrumentation().getTargetContext(); List<Feed> feeds = saveFeedlist(numItems, numItems, false);
List<Feed> feeds = saveFeedlist(context, numItems, numItems, false); List<FeedItem> allItems = new ArrayList<>();
List<FeedItem> allItems = new ArrayList<FeedItem>();
for (Feed f : feeds) { for (Feed f : feeds) {
allItems.addAll(f.getItems()); allItems.addAll(f.getItems());
} }
// take random items from every feed // take random items from every feed
Random random = new Random(); Random random = new Random();
List<FeedItem> queue = new ArrayList<FeedItem>(); List<FeedItem> queue = new ArrayList<>();
while (queue.size() < numItems) { while (queue.size() < numItems) {
int index = random.nextInt(numItems); int index = random.nextInt(numItems);
if (!queue.contains(allItems.get(index))) { if (!queue.contains(allItems.get(index))) {
queue.add(allItems.get(index)); queue.add(allItems.get(index));
} }
} }
PodDBAdapter adapter = new PodDBAdapter(context); PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
adapter.setQueue(queue); adapter.setQueue(queue);
adapter.close(); adapter.close();
@ -160,10 +153,9 @@ public class DBReaderTest extends InstrumentationTestCase {
} }
public void testGetQueueIDList() { public void testGetQueueIDList() {
final Context context = getInstrumentation().getTargetContext();
final int numItems = 10; final int numItems = 10;
List<FeedItem> queue = saveQueue(numItems); List<FeedItem> queue = saveQueue(numItems);
LongList ids = DBReader.getQueueIDList(context); LongList ids = DBReader.getQueueIDList();
assertNotNull(ids); assertNotNull(ids);
assertTrue(queue.size() == ids.size()); assertTrue(queue.size() == ids.size());
for (int i = 0; i < queue.size(); i++) { for (int i = 0; i < queue.size(); i++) {
@ -173,10 +165,9 @@ public class DBReaderTest extends InstrumentationTestCase {
} }
public void testGetQueue() { public void testGetQueue() {
final Context context = getInstrumentation().getTargetContext();
final int numItems = 10; final int numItems = 10;
List<FeedItem> queue = saveQueue(numItems); List<FeedItem> queue = saveQueue(numItems);
List<FeedItem> savedQueue = DBReader.getQueue(context); List<FeedItem> savedQueue = DBReader.getQueue();
assertNotNull(savedQueue); assertNotNull(savedQueue);
assertTrue(queue.size() == savedQueue.size()); assertTrue(queue.size() == savedQueue.size());
for (int i = 0; i < queue.size(); i++) { for (int i = 0; i < queue.size(); i++) {
@ -189,13 +180,12 @@ public class DBReaderTest extends InstrumentationTestCase {
if (numItems <= 0) { if (numItems <= 0) {
throw new IllegalArgumentException("numItems<=0"); throw new IllegalArgumentException("numItems<=0");
} }
final Context context = getInstrumentation().getTargetContext(); List<Feed> feeds = saveFeedlist(numItems, numItems, true);
List<Feed> feeds = saveFeedlist(context, numItems, numItems, true); List<FeedItem> items = new ArrayList<>();
List<FeedItem> items = new ArrayList<FeedItem>();
for (Feed f : feeds) { for (Feed f : feeds) {
items.addAll(f.getItems()); items.addAll(f.getItems());
} }
List<FeedItem> downloaded = new ArrayList<FeedItem>(); List<FeedItem> downloaded = new ArrayList<>();
Random random = new Random(); Random random = new Random();
while (downloaded.size() < numItems) { while (downloaded.size() < numItems) {
@ -207,7 +197,7 @@ public class DBReaderTest extends InstrumentationTestCase {
downloaded.add(item); downloaded.add(item);
} }
} }
PodDBAdapter adapter = new PodDBAdapter(context); PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
adapter.setFeedItemlist(downloaded); adapter.setFeedItemlist(downloaded);
adapter.close(); adapter.close();
@ -215,10 +205,9 @@ public class DBReaderTest extends InstrumentationTestCase {
} }
public void testGetDownloadedItems() { public void testGetDownloadedItems() {
final Context context = getInstrumentation().getTargetContext();
final int numItems = 10; final int numItems = 10;
List<FeedItem> downloaded = saveDownloadedItems(numItems); List<FeedItem> downloaded = saveDownloadedItems(numItems);
List<FeedItem> downloaded_saved = DBReader.getDownloadedItems(context); List<FeedItem> downloaded_saved = DBReader.getDownloadedItems();
assertNotNull(downloaded_saved); assertNotNull(downloaded_saved);
assertTrue(downloaded_saved.size() == downloaded.size()); assertTrue(downloaded_saved.size() == downloaded.size());
for (FeedItem item : downloaded_saved) { for (FeedItem item : downloaded_saved) {
@ -232,13 +221,12 @@ public class DBReaderTest extends InstrumentationTestCase {
if (numItems <= 0) { if (numItems <= 0) {
throw new IllegalArgumentException("numItems<=0"); throw new IllegalArgumentException("numItems<=0");
} }
final Context context = getInstrumentation().getTargetContext(); List<Feed> feeds = saveFeedlist(numItems, numItems, true);
List<Feed> feeds = saveFeedlist(context, numItems, numItems, true); List<FeedItem> items = new ArrayList<>();
List<FeedItem> items = new ArrayList<FeedItem>();
for (Feed f : feeds) { for (Feed f : feeds) {
items.addAll(f.getItems()); items.addAll(f.getItems());
} }
List<FeedItem> unread = new ArrayList<FeedItem>(); List<FeedItem> unread = new ArrayList<>();
Random random = new Random(); Random random = new Random();
while (unread.size() < numItems) { while (unread.size() < numItems) {
@ -249,7 +237,7 @@ public class DBReaderTest extends InstrumentationTestCase {
unread.add(item); unread.add(item);
} }
} }
PodDBAdapter adapter = new PodDBAdapter(context); PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
adapter.setFeedItemlist(unread); adapter.setFeedItemlist(unread);
adapter.close(); adapter.close();
@ -257,11 +245,10 @@ public class DBReaderTest extends InstrumentationTestCase {
} }
public void testGetUnreadItemsList() { public void testGetUnreadItemsList() {
final Context context = getInstrumentation().getTargetContext();
final int numItems = 10; final int numItems = 10;
List<FeedItem> unread = saveUnreadItems(numItems); List<FeedItem> unread = saveUnreadItems(numItems);
List<FeedItem> unreadSaved = DBReader.getUnreadItemsList(context); List<FeedItem> unreadSaved = DBReader.getUnreadItemsList();
assertNotNull(unreadSaved); assertNotNull(unreadSaved);
assertTrue(unread.size() == unreadSaved.size()); assertTrue(unread.size() == unreadSaved.size());
for (FeedItem item : unreadSaved) { for (FeedItem item : unreadSaved) {
@ -270,7 +257,6 @@ public class DBReaderTest extends InstrumentationTestCase {
} }
public void testGetNewItemIds() { public void testGetNewItemIds() {
final Context context = getInstrumentation().getTargetContext();
final int numItems = 10; final int numItems = 10;
List<FeedItem> unread = saveUnreadItems(numItems); List<FeedItem> unread = saveUnreadItems(numItems);
@ -278,7 +264,7 @@ public class DBReaderTest extends InstrumentationTestCase {
for (int i = 0; i < unread.size(); i++) { for (int i = 0; i < unread.size(); i++) {
unreadIds[i] = unread.get(i).getId(); unreadIds[i] = unread.get(i).getId();
} }
List<FeedItem> unreadSaved = DBReader.getUnreadItemsList(context); List<FeedItem> unreadSaved = DBReader.getUnreadItemsList();
assertNotNull(unreadSaved); assertNotNull(unreadSaved);
assertTrue(unread.size() == unreadSaved.size()); assertTrue(unread.size() == unreadSaved.size());
for(int i=0; i < unreadSaved.size(); i++) { for(int i=0; i < unreadSaved.size(); i++) {
@ -295,16 +281,15 @@ public class DBReaderTest extends InstrumentationTestCase {
} }
public void testGetPlaybackHistory() { public void testGetPlaybackHistory() {
final Context context = getInstrumentation().getTargetContext();
final int numItems = (DBReader.PLAYBACK_HISTORY_SIZE + 1) * 2; final int numItems = (DBReader.PLAYBACK_HISTORY_SIZE + 1) * 2;
final int playedItems = DBReader.PLAYBACK_HISTORY_SIZE + 1; final int playedItems = DBReader.PLAYBACK_HISTORY_SIZE + 1;
final int numReturnedItems = Math.min(playedItems, DBReader.PLAYBACK_HISTORY_SIZE); final int numReturnedItems = Math.min(playedItems, DBReader.PLAYBACK_HISTORY_SIZE);
final int numFeeds = 1; final int numFeeds = 1;
Feed feed = DBTestUtils.saveFeedlist(context, numFeeds, numItems, true).get(0); Feed feed = DBTestUtils.saveFeedlist(numFeeds, numItems, true).get(0);
long[] ids = new long[playedItems]; long[] ids = new long[playedItems];
PodDBAdapter adapter = new PodDBAdapter(context); PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
for (int i = 0; i < playedItems; i++) { for (int i = 0; i < playedItems; i++) {
FeedMedia m = feed.getItems().get(i).getMedia(); FeedMedia m = feed.getItems().get(i).getMedia();
@ -314,7 +299,7 @@ public class DBReaderTest extends InstrumentationTestCase {
} }
adapter.close(); adapter.close();
List<FeedItem> saved = DBReader.getPlaybackHistory(context); List<FeedItem> saved = DBReader.getPlaybackHistory();
assertNotNull(saved); assertNotNull(saved);
assertEquals("Wrong size: ", numReturnedItems, saved.size()); assertEquals("Wrong size: ", numReturnedItems, saved.size());
for (int i = 0; i < numReturnedItems; i++) { for (int i = 0; i < numReturnedItems; i++) {
@ -325,11 +310,10 @@ public class DBReaderTest extends InstrumentationTestCase {
} }
public void testGetFeedStatisticsCheckOrder() { public void testGetFeedStatisticsCheckOrder() {
final Context context = getInstrumentation().getTargetContext();
final int NUM_FEEDS = 10; final int NUM_FEEDS = 10;
final int NUM_ITEMS = 10; final int NUM_ITEMS = 10;
List<Feed> feeds = DBTestUtils.saveFeedlist(context, NUM_FEEDS, NUM_ITEMS, false); List<Feed> feeds = DBTestUtils.saveFeedlist(NUM_FEEDS, NUM_ITEMS, false);
List<FeedItemStatistics> statistics = DBReader.getFeedStatisticsList(context); List<FeedItemStatistics> statistics = DBReader.getFeedStatisticsList();
assertNotNull(statistics); assertNotNull(statistics);
assertEquals(feeds.size(), statistics.size()); assertEquals(feeds.size(), statistics.size());
for (int i = 0; i < NUM_FEEDS; i++) { for (int i = 0; i < NUM_FEEDS; i++) {
@ -338,31 +322,29 @@ public class DBReaderTest extends InstrumentationTestCase {
} }
public void testGetNavDrawerDataQueueEmptyNoUnreadItems() { public void testGetNavDrawerDataQueueEmptyNoUnreadItems() {
final Context context = getInstrumentation().getTargetContext();
final int NUM_FEEDS = 10; final int NUM_FEEDS = 10;
final int NUM_ITEMS = 10; final int NUM_ITEMS = 10;
List<Feed> feeds = DBTestUtils.saveFeedlist(context, NUM_FEEDS, NUM_ITEMS, true); List<Feed> feeds = DBTestUtils.saveFeedlist(NUM_FEEDS, NUM_ITEMS, true);
DBReader.NavDrawerData navDrawerData = DBReader.getNavDrawerData(context); DBReader.NavDrawerData navDrawerData = DBReader.getNavDrawerData();
assertEquals(NUM_FEEDS, navDrawerData.feeds.size()); assertEquals(NUM_FEEDS, navDrawerData.feeds.size());
assertEquals(0, navDrawerData.numNewItems); assertEquals(0, navDrawerData.numNewItems);
assertEquals(0, navDrawerData.queueSize); assertEquals(0, navDrawerData.queueSize);
} }
public void testGetNavDrawerDataQueueNotEmptyWithUnreadItems() { public void testGetNavDrawerDataQueueNotEmptyWithUnreadItems() {
final Context context = getInstrumentation().getTargetContext();
final int NUM_FEEDS = 10; final int NUM_FEEDS = 10;
final int NUM_ITEMS = 10; final int NUM_ITEMS = 10;
final int NUM_QUEUE = 1; final int NUM_QUEUE = 1;
final int NUM_NEW = 2; final int NUM_NEW = 2;
List<Feed> feeds = DBTestUtils.saveFeedlist(context, NUM_FEEDS, NUM_ITEMS, true); List<Feed> feeds = DBTestUtils.saveFeedlist(NUM_FEEDS, NUM_ITEMS, true);
PodDBAdapter adapter = new PodDBAdapter(context); PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
for (int i = 0; i < NUM_NEW; i++) { for (int i = 0; i < NUM_NEW; i++) {
FeedItem item = feeds.get(0).getItems().get(i); FeedItem item = feeds.get(0).getItems().get(i);
item.setNew(); item.setNew();
adapter.setSingleFeedItem(item); adapter.setSingleFeedItem(item);
} }
List<FeedItem> queue = new ArrayList<FeedItem>(); List<FeedItem> queue = new ArrayList<>();
for (int i = 0; i < NUM_QUEUE; i++) { for (int i = 0; i < NUM_QUEUE; i++) {
FeedItem item = feeds.get(1).getItems().get(i); FeedItem item = feeds.get(1).getItems().get(i);
queue.add(item); queue.add(item);
@ -371,7 +353,7 @@ public class DBReaderTest extends InstrumentationTestCase {
adapter.close(); adapter.close();
DBReader.NavDrawerData navDrawerData = DBReader.getNavDrawerData(context); DBReader.NavDrawerData navDrawerData = DBReader.getNavDrawerData();
assertEquals(NUM_FEEDS, navDrawerData.feeds.size()); assertEquals(NUM_FEEDS, navDrawerData.feeds.size());
assertEquals(NUM_NEW, navDrawerData.numNewItems); assertEquals(NUM_NEW, navDrawerData.numNewItems);
assertEquals(NUM_QUEUE, navDrawerData.queueSize); assertEquals(NUM_QUEUE, navDrawerData.queueSize);
@ -379,7 +361,7 @@ public class DBReaderTest extends InstrumentationTestCase {
public void testGetFeedItemlistCheckChaptersFalse() throws Exception { public void testGetFeedItemlistCheckChaptersFalse() throws Exception {
Context context = getInstrumentation().getTargetContext(); Context context = getInstrumentation().getTargetContext();
List<Feed> feeds = DBTestUtils.saveFeedlist(context, 10, 10, false, false, 0); List<Feed> feeds = DBTestUtils.saveFeedlist(10, 10, false, false, 0);
for (Feed feed : feeds) { for (Feed feed : feeds) {
for (FeedItem item : feed.getItems()) { for (FeedItem item : feed.getItems()) {
assertFalse(item.hasChapters()); assertFalse(item.hasChapters());
@ -388,8 +370,7 @@ public class DBReaderTest extends InstrumentationTestCase {
} }
public void testGetFeedItemlistCheckChaptersTrue() throws Exception { public void testGetFeedItemlistCheckChaptersTrue() throws Exception {
Context context = getInstrumentation().getTargetContext(); List<Feed> feeds = saveFeedlist(10, 10, false, true, 10);
List<Feed> feeds = saveFeedlist(context, 10, 10, false, true, 10);
for (Feed feed : feeds) { for (Feed feed : feeds) {
for (FeedItem item : feed.getItems()) { for (FeedItem item : feed.getItems()) {
assertTrue(item.hasChapters()); assertTrue(item.hasChapters());
@ -398,13 +379,12 @@ public class DBReaderTest extends InstrumentationTestCase {
} }
public void testLoadChaptersOfFeedItemNoChapters() throws Exception { public void testLoadChaptersOfFeedItemNoChapters() throws Exception {
Context context = getInstrumentation().getTargetContext(); List<Feed> feeds = saveFeedlist(1, 3, false, false, 0);
List<Feed> feeds = saveFeedlist(context, 1, 3, false, false, 0); saveFeedlist(1, 3, false, true, 3);
saveFeedlist(context, 1, 3, false, true, 3);
for (Feed feed : feeds) { for (Feed feed : feeds) {
for (FeedItem item : feed.getItems()) { for (FeedItem item : feed.getItems()) {
assertFalse(item.hasChapters()); assertFalse(item.hasChapters());
DBReader.loadChaptersOfFeedItem(context, item); DBReader.loadChaptersOfFeedItem(item);
assertFalse(item.hasChapters()); assertFalse(item.hasChapters());
assertNull(item.getChapters()); assertNull(item.getChapters());
} }
@ -412,14 +392,13 @@ public class DBReaderTest extends InstrumentationTestCase {
} }
public void testLoadChaptersOfFeedItemWithChapters() throws Exception { public void testLoadChaptersOfFeedItemWithChapters() throws Exception {
Context context = getInstrumentation().getTargetContext();
final int NUM_CHAPTERS = 3; final int NUM_CHAPTERS = 3;
DBTestUtils.saveFeedlist(context, 1, 3, false, false, 0); DBTestUtils.saveFeedlist(1, 3, false, false, 0);
List<Feed> feeds = saveFeedlist(context, 1, 3, false, true, NUM_CHAPTERS); List<Feed> feeds = saveFeedlist(1, 3, false, true, NUM_CHAPTERS);
for (Feed feed : feeds) { for (Feed feed : feeds) {
for (FeedItem item : feed.getItems()) { for (FeedItem item : feed.getItems()) {
assertTrue(item.hasChapters()); assertTrue(item.hasChapters());
DBReader.loadChaptersOfFeedItem(context, item); DBReader.loadChaptersOfFeedItem(item);
assertTrue(item.hasChapters()); assertTrue(item.hasChapters());
assertNotNull(item.getChapters()); assertNotNull(item.getChapters());
assertEquals(NUM_CHAPTERS, item.getChapters().size()); assertEquals(NUM_CHAPTERS, item.getChapters().size());
@ -428,11 +407,10 @@ public class DBReaderTest extends InstrumentationTestCase {
} }
public void testGetItemWithChapters() throws Exception { public void testGetItemWithChapters() throws Exception {
Context context = getInstrumentation().getTargetContext();
final int NUM_CHAPTERS = 3; final int NUM_CHAPTERS = 3;
List<Feed> feeds = saveFeedlist(context, 1, 1, false, true, NUM_CHAPTERS); List<Feed> feeds = saveFeedlist(1, 1, false, true, NUM_CHAPTERS);
FeedItem item1 = feeds.get(0).getItems().get(0); FeedItem item1 = feeds.get(0).getItems().get(0);
FeedItem item2 = DBReader.getFeedItem(context, item1.getId()); FeedItem item2 = DBReader.getFeedItem(item1.getId());
assertTrue(item2.hasChapters()); assertTrue(item2.hasChapters());
assertEquals(item1.getChapters(), item2.getChapters()); assertEquals(item1.getChapters(), item2.getChapters());
} }

View File

@ -12,7 +12,6 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.concurrent.TimeUnit;
import de.danoeh.antennapod.core.feed.Feed; import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.feed.FeedItem; import de.danoeh.antennapod.core.feed.FeedItem;
@ -21,7 +20,6 @@ import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.storage.DBReader; import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBTasks; import de.danoeh.antennapod.core.storage.DBTasks;
import de.danoeh.antennapod.core.storage.PodDBAdapter; import de.danoeh.antennapod.core.storage.PodDBAdapter;
import de.danoeh.antennapod.core.util.flattr.FlattrStatus;
import static de.test.antennapod.storage.DBTestUtils.saveFeedlist; import static de.test.antennapod.storage.DBTestUtils.saveFeedlist;
@ -40,7 +38,8 @@ public class DBTasksTest extends InstrumentationTestCase {
@Override @Override
protected void tearDown() throws Exception { protected void tearDown() throws Exception {
super.tearDown(); super.tearDown();
assertTrue(PodDBAdapter.deleteDatabase(context));
assertTrue(PodDBAdapter.deleteDatabase());
for (File f : destFolder.listFiles()) { for (File f : destFolder.listFiles()) {
assertTrue(f.delete()); assertTrue(f.delete());
@ -58,9 +57,9 @@ public class DBTasksTest extends InstrumentationTestCase {
assertTrue(destFolder.exists()); assertTrue(destFolder.exists());
assertTrue(destFolder.canWrite()); assertTrue(destFolder.canWrite());
context.deleteDatabase(PodDBAdapter.DATABASE_NAME); // create new database
// make sure database is created PodDBAdapter.deleteDatabase();
PodDBAdapter adapter = new PodDBAdapter(context); PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
adapter.close(); adapter.close();
@ -76,9 +75,9 @@ public class DBTasksTest extends InstrumentationTestCase {
final int NUM_ITEMS = EPISODE_CACHE_SIZE * 2; final int NUM_ITEMS = EPISODE_CACHE_SIZE * 2;
Feed feed = new Feed("url", new Date(), "title"); Feed feed = new Feed("url", new Date(), "title");
List<FeedItem> items = new ArrayList<FeedItem>(); List<FeedItem> items = new ArrayList<>();
feed.setItems(items); feed.setItems(items);
List<File> files = new ArrayList<File>(); List<File> files = new ArrayList<>();
for (int i = 0; i < NUM_ITEMS; i++) { for (int i = 0; i < NUM_ITEMS; i++) {
FeedItem item = new FeedItem(0, "title", "id", "link", new Date(), FeedItem.PLAYED, feed); FeedItem item = new FeedItem(0, "title", "id", "link", new Date(), FeedItem.PLAYED, feed);
@ -89,7 +88,7 @@ public class DBTasksTest extends InstrumentationTestCase {
items.add(item); items.add(item);
} }
PodDBAdapter adapter = new PodDBAdapter(context); PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
adapter.setCompleteFeed(feed); adapter.setCompleteFeed(feed);
adapter.close(); adapter.close();
@ -128,7 +127,7 @@ public class DBTasksTest extends InstrumentationTestCase {
items.add(item); items.add(item);
} }
PodDBAdapter adapter = new PodDBAdapter(context); PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
adapter.setCompleteFeed(feed); adapter.setCompleteFeed(feed);
adapter.close(); adapter.close();
@ -149,9 +148,9 @@ public class DBTasksTest extends InstrumentationTestCase {
final int NUM_ITEMS = EPISODE_CACHE_SIZE * 2; final int NUM_ITEMS = EPISODE_CACHE_SIZE * 2;
Feed feed = new Feed("url", new Date(), "title"); Feed feed = new Feed("url", new Date(), "title");
List<FeedItem> items = new ArrayList<FeedItem>(); List<FeedItem> items = new ArrayList<>();
feed.setItems(items); feed.setItems(items);
List<File> files = new ArrayList<File>(); List<File> files = new ArrayList<>();
for (int i = 0; i < NUM_ITEMS; i++) { for (int i = 0; i < NUM_ITEMS; i++) {
FeedItem item = new FeedItem(0, "title", "id", "link", new Date(), FeedItem.PLAYED, feed); FeedItem item = new FeedItem(0, "title", "id", "link", new Date(), FeedItem.PLAYED, feed);
@ -163,7 +162,7 @@ public class DBTasksTest extends InstrumentationTestCase {
items.add(item); items.add(item);
} }
PodDBAdapter adapter = new PodDBAdapter(context); PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
adapter.setCompleteFeed(feed); adapter.setCompleteFeed(feed);
adapter.setQueue(items); adapter.setQueue(items);
@ -188,14 +187,14 @@ public class DBTasksTest extends InstrumentationTestCase {
@FlakyTest(tolerance = 3) @FlakyTest(tolerance = 3)
public void testPerformAutoCleanupShouldNotDeleteBecauseInQueue_withFeedsWithNoMedia() throws IOException { public void testPerformAutoCleanupShouldNotDeleteBecauseInQueue_withFeedsWithNoMedia() throws IOException {
// add feed with no enclosures so that item ID != media ID // add feed with no enclosures so that item ID != media ID
saveFeedlist(context, 1, 10, false); saveFeedlist(1, 10, false);
// add candidate for performAutoCleanup // add candidate for performAutoCleanup
List<Feed> feeds = saveFeedlist(context, 1, 1, true); List<Feed> feeds = saveFeedlist(1, 1, true);
FeedMedia m = feeds.get(0).getItems().get(0).getMedia(); FeedMedia m = feeds.get(0).getItems().get(0).getMedia();
m.setDownloaded(true); m.setDownloaded(true);
m.setFile_url("file"); m.setFile_url("file");
PodDBAdapter adapter = new PodDBAdapter(context); PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
adapter.setMedia(m); adapter.setMedia(m);
adapter.close(); adapter.close();
@ -208,7 +207,7 @@ public class DBTasksTest extends InstrumentationTestCase {
final int NUM_ITEMS = 10; final int NUM_ITEMS = 10;
Feed feed = new Feed("url", new Date(), "title"); Feed feed = new Feed("url", new Date(), "title");
feed.setItems(new ArrayList<FeedItem>()); feed.setItems(new ArrayList<>());
for (int i = 0; i < NUM_ITEMS; i++) { for (int i = 0; i < NUM_ITEMS; i++) {
feed.getItems().add(new FeedItem(0, "item " + i, "id " + i, "link " + i, new Date(), FeedItem.UNPLAYED, feed)); feed.getItems().add(new FeedItem(0, "item " + i, "id " + i, "link " + i, new Date(), FeedItem.UNPLAYED, feed));
} }
@ -228,8 +227,8 @@ public class DBTasksTest extends InstrumentationTestCase {
Feed feed1 = new Feed("url1", new Date(), "title"); Feed feed1 = new Feed("url1", new Date(), "title");
Feed feed2 = new Feed("url2", new Date(), "title"); Feed feed2 = new Feed("url2", new Date(), "title");
feed1.setItems(new ArrayList<FeedItem>()); feed1.setItems(new ArrayList<>());
feed2.setItems(new ArrayList<FeedItem>()); feed2.setItems(new ArrayList<>());
Feed savedFeed1 = DBTasks.updateFeed(context, feed1)[0]; Feed savedFeed1 = DBTasks.updateFeed(context, feed1)[0];
Feed savedFeed2 = DBTasks.updateFeed(context, feed2)[0]; Feed savedFeed2 = DBTasks.updateFeed(context, feed2)[0];
@ -242,11 +241,11 @@ public class DBTasksTest extends InstrumentationTestCase {
final int NUM_ITEMS_NEW = 10; final int NUM_ITEMS_NEW = 10;
final Feed feed = new Feed("url", new Date(), "title"); final Feed feed = new Feed("url", new Date(), "title");
feed.setItems(new ArrayList<FeedItem>()); feed.setItems(new ArrayList<>());
for (int i = 0; i < NUM_ITEMS_OLD; i++) { for (int i = 0; i < NUM_ITEMS_OLD; i++) {
feed.getItems().add(new FeedItem(0, "item " + i, "id " + i, "link " + i, new Date(i), FeedItem.PLAYED, feed)); feed.getItems().add(new FeedItem(0, "item " + i, "id " + i, "link " + i, new Date(i), FeedItem.PLAYED, feed));
} }
PodDBAdapter adapter = new PodDBAdapter(context); PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
adapter.setCompleteFeed(feed); adapter.setCompleteFeed(feed);
adapter.close(); adapter.close();
@ -271,7 +270,7 @@ public class DBTasksTest extends InstrumentationTestCase {
updatedFeedTest(newFeed, feedID, itemIDs, NUM_ITEMS_OLD, NUM_ITEMS_NEW); updatedFeedTest(newFeed, feedID, itemIDs, NUM_ITEMS_OLD, NUM_ITEMS_NEW);
final Feed feedFromDB = DBReader.getFeed(context, newFeed.getId()); final Feed feedFromDB = DBReader.getFeed(newFeed.getId());
assertNotNull(feedFromDB); assertNotNull(feedFromDB);
assertTrue(feedFromDB.getId() == newFeed.getId()); assertTrue(feedFromDB.getId() == newFeed.getId());
updatedFeedTest(feedFromDB, feedID, itemIDs, NUM_ITEMS_OLD, NUM_ITEMS_NEW); updatedFeedTest(feedFromDB, feedID, itemIDs, NUM_ITEMS_OLD, NUM_ITEMS_NEW);

View File

@ -1,7 +1,5 @@
package de.test.antennapod.storage; package de.test.antennapod.storage;
import android.content.Context;
import junit.framework.Assert; import junit.framework.Assert;
import java.util.ArrayList; import java.util.ArrayList;
@ -26,14 +24,14 @@ public class DBTestUtils {
/** /**
* Use this method when tests don't involve chapters. * Use this method when tests don't involve chapters.
*/ */
public static List<Feed> saveFeedlist(Context context, int numFeeds, int numItems, boolean withMedia) { public static List<Feed> saveFeedlist(int numFeeds, int numItems, boolean withMedia) {
return saveFeedlist(context, numFeeds, numItems, withMedia, false, 0); return saveFeedlist(numFeeds, numItems, withMedia, false, 0);
} }
/** /**
* Use this method when tests involve chapters. * Use this method when tests involve chapters.
*/ */
public static List<Feed> saveFeedlist(Context context, int numFeeds, int numItems, boolean withMedia, public static List<Feed> saveFeedlist(int numFeeds, int numItems, boolean withMedia,
boolean withChapters, int numChapters) { boolean withChapters, int numChapters) {
if (numFeeds <= 0) { if (numFeeds <= 0) {
throw new IllegalArgumentException("numFeeds<=0"); throw new IllegalArgumentException("numFeeds<=0");
@ -42,13 +40,13 @@ public class DBTestUtils {
throw new IllegalArgumentException("numItems<0"); throw new IllegalArgumentException("numItems<0");
} }
List<Feed> feeds = new ArrayList<Feed>(); List<Feed> feeds = new ArrayList<>();
PodDBAdapter adapter = new PodDBAdapter(context); PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
for (int i = 0; i < numFeeds; i++) { for (int i = 0; i < numFeeds; i++) {
Feed f = new Feed(0, new Date(), "feed " + i, "link" + i, "descr", null, null, Feed f = new Feed(0, new Date(), "feed " + i, "link" + i, "descr", null, null,
null, null, "id" + i, null, null, "url" + i, false, new FlattrStatus(), false, null, null, false); null, null, "id" + i, null, null, "url" + i, false, new FlattrStatus(), false, null, null, false);
f.setItems(new ArrayList<FeedItem>()); f.setItems(new ArrayList<>());
for (int j = 0; j < numItems; j++) { for (int j = 0; j < numItems; j++) {
FeedItem item = new FeedItem(0, "item " + j, "id" + j, "link" + j, new Date(), FeedItem item = new FeedItem(0, "item " + j, "id" + j, "link" + j, new Date(),
FeedItem.PLAYED, f, withChapters); FeedItem.PLAYED, f, withChapters);

View File

@ -29,6 +29,7 @@ import de.danoeh.antennapod.core.storage.PodDBAdapter;
* Test class for DBWriter * Test class for DBWriter
*/ */
public class DBWriterTest extends InstrumentationTestCase { public class DBWriterTest extends InstrumentationTestCase {
private static final String TAG = "DBWriterTest"; private static final String TAG = "DBWriterTest";
private static final String TEST_FOLDER = "testDBWriter"; private static final String TEST_FOLDER = "testDBWriter";
private static final long TIMEOUT = 5L; private static final long TIMEOUT = 5L;
@ -36,9 +37,10 @@ public class DBWriterTest extends InstrumentationTestCase {
@Override @Override
protected void tearDown() throws Exception { protected void tearDown() throws Exception {
super.tearDown(); super.tearDown();
final Context context = getInstrumentation().getTargetContext();
assertTrue(PodDBAdapter.deleteDatabase(getInstrumentation().getTargetContext()));
assertTrue(PodDBAdapter.deleteDatabase());
final Context context = getInstrumentation().getTargetContext();
File testDir = context.getExternalFilesDir(TEST_FOLDER); File testDir = context.getExternalFilesDir(TEST_FOLDER);
assertNotNull(testDir); assertNotNull(testDir);
for (File f : testDir.listFiles()) { for (File f : testDir.listFiles()) {
@ -49,10 +51,10 @@ public class DBWriterTest extends InstrumentationTestCase {
@Override @Override
protected void setUp() throws Exception { protected void setUp() throws Exception {
super.setUp(); super.setUp();
final Context context = getInstrumentation().getTargetContext();
context.deleteDatabase(PodDBAdapter.DATABASE_NAME); // create new database
// make sure database is created PodDBAdapter.deleteDatabase();
PodDBAdapter adapter = new PodDBAdapter(context); PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
adapter.close(); adapter.close();
} }
@ -63,7 +65,7 @@ public class DBWriterTest extends InstrumentationTestCase {
assertTrue(dest.createNewFile()); assertTrue(dest.createNewFile());
Feed feed = new Feed("url", new Date(), "title"); Feed feed = new Feed("url", new Date(), "title");
List<FeedItem> items = new ArrayList<FeedItem>(); List<FeedItem> items = new ArrayList<>();
feed.setItems(items); feed.setItems(items);
FeedItem item = new FeedItem(0, "Item", "Item", "url", new Date(), FeedItem.PLAYED, feed); FeedItem item = new FeedItem(0, "Item", "Item", "url", new Date(), FeedItem.PLAYED, feed);
@ -72,7 +74,7 @@ public class DBWriterTest extends InstrumentationTestCase {
items.add(item); items.add(item);
PodDBAdapter adapter = new PodDBAdapter(getInstrumentation().getTargetContext()); PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
adapter.setCompleteFeed(feed); adapter.setCompleteFeed(feed);
adapter.close(); adapter.close();
@ -80,7 +82,7 @@ public class DBWriterTest extends InstrumentationTestCase {
assertTrue(item.getId() != 0); assertTrue(item.getId() != 0);
DBWriter.deleteFeedMediaOfItem(getInstrumentation().getTargetContext(), media.getId()).get(); DBWriter.deleteFeedMediaOfItem(getInstrumentation().getTargetContext(), media.getId()).get();
media = DBReader.getFeedMedia(getInstrumentation().getTargetContext(), media.getId()); media = DBReader.getFeedMedia(media.getId());
assertNotNull(media); assertNotNull(media);
assertFalse(dest.exists()); assertFalse(dest.exists());
assertFalse(media.isDownloaded()); assertFalse(media.isDownloaded());
@ -92,7 +94,7 @@ public class DBWriterTest extends InstrumentationTestCase {
assertNotNull(destFolder); assertNotNull(destFolder);
Feed feed = new Feed("url", new Date(), "title"); Feed feed = new Feed("url", new Date(), "title");
feed.setItems(new ArrayList<FeedItem>()); feed.setItems(new ArrayList<>());
// create Feed image // create Feed image
File imgFile = new File(destFolder, "image"); File imgFile = new File(destFolder, "image");
@ -118,7 +120,7 @@ public class DBWriterTest extends InstrumentationTestCase {
item.getChapters().add(new SimpleChapter(0, "item " + i, item, "example.com")); item.getChapters().add(new SimpleChapter(0, "item " + i, item, "example.com"));
} }
PodDBAdapter adapter = new PodDBAdapter(getInstrumentation().getContext()); PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
adapter.setCompleteFeed(feed); adapter.setCompleteFeed(feed);
adapter.close(); adapter.close();
@ -139,7 +141,7 @@ public class DBWriterTest extends InstrumentationTestCase {
assertFalse(f.exists()); assertFalse(f.exists());
} }
adapter = new PodDBAdapter(getInstrumentation().getContext()); adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
Cursor c = adapter.getFeedCursor(feed.getId()); Cursor c = adapter.getFeedCursor(feed.getId());
assertEquals(0, c.getCount()); assertEquals(0, c.getCount());
@ -164,7 +166,7 @@ public class DBWriterTest extends InstrumentationTestCase {
assertNotNull(destFolder); assertNotNull(destFolder);
Feed feed = new Feed("url", new Date(), "title"); Feed feed = new Feed("url", new Date(), "title");
feed.setItems(new ArrayList<FeedItem>()); feed.setItems(new ArrayList<>());
feed.setImage(null); feed.setImage(null);
@ -182,7 +184,7 @@ public class DBWriterTest extends InstrumentationTestCase {
item.setMedia(media); item.setMedia(media);
} }
PodDBAdapter adapter = new PodDBAdapter(getInstrumentation().getContext()); PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
adapter.setCompleteFeed(feed); adapter.setCompleteFeed(feed);
adapter.close(); adapter.close();
@ -200,7 +202,7 @@ public class DBWriterTest extends InstrumentationTestCase {
assertFalse(f.exists()); assertFalse(f.exists());
} }
adapter = new PodDBAdapter(getInstrumentation().getContext()); adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
Cursor c = adapter.getFeedCursor(feed.getId()); Cursor c = adapter.getFeedCursor(feed.getId());
assertTrue(c.getCount() == 0); assertTrue(c.getCount() == 0);
@ -229,7 +231,7 @@ public class DBWriterTest extends InstrumentationTestCase {
image.setOwner(feed); image.setOwner(feed);
feed.setImage(image); feed.setImage(image);
PodDBAdapter adapter = new PodDBAdapter(getInstrumentation().getContext()); PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
adapter.setCompleteFeed(feed); adapter.setCompleteFeed(feed);
adapter.close(); adapter.close();
@ -242,7 +244,7 @@ public class DBWriterTest extends InstrumentationTestCase {
// check if files still exist // check if files still exist
assertFalse(imgFile.exists()); assertFalse(imgFile.exists());
adapter = new PodDBAdapter(getInstrumentation().getContext()); adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
Cursor c = adapter.getFeedCursor(feed.getId()); Cursor c = adapter.getFeedCursor(feed.getId());
assertTrue(c.getCount() == 0); assertTrue(c.getCount() == 0);
@ -257,7 +259,7 @@ public class DBWriterTest extends InstrumentationTestCase {
assertNotNull(destFolder); assertNotNull(destFolder);
Feed feed = new Feed("url", new Date(), "title"); Feed feed = new Feed("url", new Date(), "title");
feed.setItems(new ArrayList<FeedItem>()); feed.setItems(new ArrayList<>());
// create Feed image // create Feed image
File imgFile = new File(destFolder, "image"); File imgFile = new File(destFolder, "image");
@ -273,7 +275,7 @@ public class DBWriterTest extends InstrumentationTestCase {
} }
PodDBAdapter adapter = new PodDBAdapter(getInstrumentation().getContext()); PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
adapter.setCompleteFeed(feed); adapter.setCompleteFeed(feed);
adapter.close(); adapter.close();
@ -289,7 +291,7 @@ public class DBWriterTest extends InstrumentationTestCase {
// check if files still exist // check if files still exist
assertFalse(imgFile.exists()); assertFalse(imgFile.exists());
adapter = new PodDBAdapter(getInstrumentation().getContext()); adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
Cursor c = adapter.getFeedCursor(feed.getId()); Cursor c = adapter.getFeedCursor(feed.getId());
assertTrue(c.getCount() == 0); assertTrue(c.getCount() == 0);
@ -309,7 +311,7 @@ public class DBWriterTest extends InstrumentationTestCase {
assertNotNull(destFolder); assertNotNull(destFolder);
Feed feed = new Feed("url", new Date(), "title"); Feed feed = new Feed("url", new Date(), "title");
feed.setItems(new ArrayList<FeedItem>()); feed.setItems(new ArrayList<>());
// create Feed image // create Feed image
File imgFile = new File(destFolder, "image"); File imgFile = new File(destFolder, "image");
@ -327,7 +329,7 @@ public class DBWriterTest extends InstrumentationTestCase {
item.setImage(itemImage); item.setImage(itemImage);
} }
PodDBAdapter adapter = new PodDBAdapter(getInstrumentation().getContext()); PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
adapter.setCompleteFeed(feed); adapter.setCompleteFeed(feed);
adapter.close(); adapter.close();
@ -344,7 +346,7 @@ public class DBWriterTest extends InstrumentationTestCase {
// check if files still exist // check if files still exist
assertFalse(imgFile.exists()); assertFalse(imgFile.exists());
adapter = new PodDBAdapter(getInstrumentation().getContext()); adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
Cursor c = adapter.getFeedCursor(feed.getId()); Cursor c = adapter.getFeedCursor(feed.getId());
assertTrue(c.getCount() == 0); assertTrue(c.getCount() == 0);
@ -367,7 +369,7 @@ public class DBWriterTest extends InstrumentationTestCase {
assertNotNull(destFolder); assertNotNull(destFolder);
Feed feed = new Feed("url", new Date(), "title"); Feed feed = new Feed("url", new Date(), "title");
feed.setItems(new ArrayList<FeedItem>()); feed.setItems(new ArrayList<>());
// create Feed image // create Feed image
File imgFile = new File(destFolder, "image"); File imgFile = new File(destFolder, "image");
@ -388,7 +390,7 @@ public class DBWriterTest extends InstrumentationTestCase {
item.setMedia(media); item.setMedia(media);
} }
PodDBAdapter adapter = new PodDBAdapter(getInstrumentation().getContext()); PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
adapter.setCompleteFeed(feed); adapter.setCompleteFeed(feed);
adapter.close(); adapter.close();
@ -460,7 +462,7 @@ public class DBWriterTest extends InstrumentationTestCase {
item.setMedia(media); item.setMedia(media);
} }
PodDBAdapter adapter = new PodDBAdapter(getInstrumentation().getContext()); PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
adapter.setCompleteFeed(feed); adapter.setCompleteFeed(feed);
adapter.close(); adapter.close();
@ -474,7 +476,7 @@ public class DBWriterTest extends InstrumentationTestCase {
DBWriter.deleteFeed(getInstrumentation().getTargetContext(), feed.getId()).get(TIMEOUT, TimeUnit.SECONDS); DBWriter.deleteFeed(getInstrumentation().getTargetContext(), feed.getId()).get(TIMEOUT, TimeUnit.SECONDS);
adapter = new PodDBAdapter(getInstrumentation().getContext()); adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
Cursor c = adapter.getFeedCursor(feed.getId()); Cursor c = adapter.getFeedCursor(feed.getId());
assertTrue(c.getCount() == 0); assertTrue(c.getCount() == 0);
@ -500,7 +502,7 @@ public class DBWriterTest extends InstrumentationTestCase {
FeedMedia media = new FeedMedia(0, item, 10, 0, 1, "mime", null, "url", false, playbackCompletionDate, 0); FeedMedia media = new FeedMedia(0, item, 10, 0, 1, "mime", null, "url", false, playbackCompletionDate, 0);
feed.getItems().add(item); feed.getItems().add(item);
item.setMedia(media); item.setMedia(media);
PodDBAdapter adapter = new PodDBAdapter(context); PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
adapter.setCompleteFeed(feed); adapter.setCompleteFeed(feed);
adapter.close(); adapter.close();
@ -509,13 +511,11 @@ public class DBWriterTest extends InstrumentationTestCase {
} }
public void testAddItemToPlaybackHistoryNotPlayedYet() throws ExecutionException, InterruptedException { public void testAddItemToPlaybackHistoryNotPlayedYet() throws ExecutionException, InterruptedException {
final Context context = getInstrumentation().getTargetContext();
FeedMedia media = playbackHistorySetup(null); FeedMedia media = playbackHistorySetup(null);
DBWriter.addItemToPlaybackHistory(context, media).get(); DBWriter.addItemToPlaybackHistory(media).get();
PodDBAdapter adapter = new PodDBAdapter(context); PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
media = DBReader.getFeedMedia(context, media.getId()); media = DBReader.getFeedMedia(media.getId());
adapter.close(); adapter.close();
assertNotNull(media); assertNotNull(media);
@ -524,13 +524,12 @@ public class DBWriterTest extends InstrumentationTestCase {
public void testAddItemToPlaybackHistoryAlreadyPlayed() throws ExecutionException, InterruptedException { public void testAddItemToPlaybackHistoryAlreadyPlayed() throws ExecutionException, InterruptedException {
final long OLD_DATE = 0; final long OLD_DATE = 0;
final Context context = getInstrumentation().getTargetContext();
FeedMedia media = playbackHistorySetup(new Date(OLD_DATE)); FeedMedia media = playbackHistorySetup(new Date(OLD_DATE));
DBWriter.addItemToPlaybackHistory(getInstrumentation().getTargetContext(), media).get(); DBWriter.addItemToPlaybackHistory(media).get();
PodDBAdapter adapter = new PodDBAdapter(context); PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
media = DBReader.getFeedMedia(context, media.getId()); media = DBReader.getFeedMedia(media.getId());
adapter.close(); adapter.close();
assertNotNull(media); assertNotNull(media);
@ -541,13 +540,13 @@ public class DBWriterTest extends InstrumentationTestCase {
private Feed queueTestSetupMultipleItems(final int NUM_ITEMS) throws InterruptedException, ExecutionException, TimeoutException { private Feed queueTestSetupMultipleItems(final int NUM_ITEMS) throws InterruptedException, ExecutionException, TimeoutException {
final Context context = getInstrumentation().getTargetContext(); final Context context = getInstrumentation().getTargetContext();
Feed feed = new Feed("url", new Date(), "title"); Feed feed = new Feed("url", new Date(), "title");
feed.setItems(new ArrayList<FeedItem>()); feed.setItems(new ArrayList<>());
for (int i = 0; i < NUM_ITEMS; i++) { for (int i = 0; i < NUM_ITEMS; i++) {
FeedItem item = new FeedItem(0, "title " + i, "id " + i, "link " + i, new Date(), FeedItem.PLAYED, feed); FeedItem item = new FeedItem(0, "title " + i, "id " + i, "link " + i, new Date(), FeedItem.PLAYED, feed);
feed.getItems().add(item); feed.getItems().add(item);
} }
PodDBAdapter adapter = new PodDBAdapter(context); PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
adapter.setCompleteFeed(feed); adapter.setCompleteFeed(feed);
adapter.close(); adapter.close();
@ -568,11 +567,11 @@ public class DBWriterTest extends InstrumentationTestCase {
public void testAddQueueItemSingleItem() throws InterruptedException, ExecutionException, TimeoutException { public void testAddQueueItemSingleItem() throws InterruptedException, ExecutionException, TimeoutException {
final Context context = getInstrumentation().getTargetContext(); final Context context = getInstrumentation().getTargetContext();
Feed feed = new Feed("url", new Date(), "title"); Feed feed = new Feed("url", new Date(), "title");
feed.setItems(new ArrayList<FeedItem>()); feed.setItems(new ArrayList<>());
FeedItem item = new FeedItem(0, "title", "id", "link", new Date(), FeedItem.PLAYED, feed); FeedItem item = new FeedItem(0, "title", "id", "link", new Date(), FeedItem.PLAYED, feed);
feed.getItems().add(item); feed.getItems().add(item);
PodDBAdapter adapter = new PodDBAdapter(context); PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
adapter.setCompleteFeed(feed); adapter.setCompleteFeed(feed);
adapter.close(); adapter.close();
@ -580,7 +579,7 @@ public class DBWriterTest extends InstrumentationTestCase {
assertTrue(item.getId() != 0); assertTrue(item.getId() != 0);
DBWriter.addQueueItem(context, item.getId()).get(TIMEOUT, TimeUnit.SECONDS); DBWriter.addQueueItem(context, item.getId()).get(TIMEOUT, TimeUnit.SECONDS);
adapter = new PodDBAdapter(context); adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
Cursor cursor = adapter.getQueueIDCursor(); Cursor cursor = adapter.getQueueIDCursor();
assertTrue(cursor.moveToFirst()); assertTrue(cursor.moveToFirst());
@ -592,11 +591,11 @@ public class DBWriterTest extends InstrumentationTestCase {
public void testAddQueueItemSingleItemAlreadyInQueue() throws InterruptedException, ExecutionException, TimeoutException { public void testAddQueueItemSingleItemAlreadyInQueue() throws InterruptedException, ExecutionException, TimeoutException {
final Context context = getInstrumentation().getTargetContext(); final Context context = getInstrumentation().getTargetContext();
Feed feed = new Feed("url", new Date(), "title"); Feed feed = new Feed("url", new Date(), "title");
feed.setItems(new ArrayList<FeedItem>()); feed.setItems(new ArrayList<>());
FeedItem item = new FeedItem(0, "title", "id", "link", new Date(), FeedItem.PLAYED, feed); FeedItem item = new FeedItem(0, "title", "id", "link", new Date(), FeedItem.PLAYED, feed);
feed.getItems().add(item); feed.getItems().add(item);
PodDBAdapter adapter = new PodDBAdapter(context); PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
adapter.setCompleteFeed(feed); adapter.setCompleteFeed(feed);
adapter.close(); adapter.close();
@ -604,7 +603,7 @@ public class DBWriterTest extends InstrumentationTestCase {
assertTrue(item.getId() != 0); assertTrue(item.getId() != 0);
DBWriter.addQueueItem(context, item.getId()).get(TIMEOUT, TimeUnit.SECONDS); DBWriter.addQueueItem(context, item.getId()).get(TIMEOUT, TimeUnit.SECONDS);
adapter = new PodDBAdapter(context); adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
Cursor cursor = adapter.getQueueIDCursor(); Cursor cursor = adapter.getQueueIDCursor();
assertTrue(cursor.moveToFirst()); assertTrue(cursor.moveToFirst());
@ -613,7 +612,7 @@ public class DBWriterTest extends InstrumentationTestCase {
adapter.close(); adapter.close();
DBWriter.addQueueItem(context, item.getId()).get(TIMEOUT, TimeUnit.SECONDS); DBWriter.addQueueItem(context, item.getId()).get(TIMEOUT, TimeUnit.SECONDS);
adapter = new PodDBAdapter(context); adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
cursor = adapter.getQueueIDCursor(); cursor = adapter.getQueueIDCursor();
assertTrue(cursor.moveToFirst()); assertTrue(cursor.moveToFirst());
@ -628,7 +627,7 @@ public class DBWriterTest extends InstrumentationTestCase {
final int NUM_ITEMS = 10; final int NUM_ITEMS = 10;
Feed feed = queueTestSetupMultipleItems(NUM_ITEMS); Feed feed = queueTestSetupMultipleItems(NUM_ITEMS);
PodDBAdapter adapter = new PodDBAdapter(context); PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
Cursor cursor = adapter.getQueueIDCursor(); Cursor cursor = adapter.getQueueIDCursor();
assertTrue(cursor.moveToFirst()); assertTrue(cursor.moveToFirst());
@ -642,12 +641,11 @@ public class DBWriterTest extends InstrumentationTestCase {
} }
public void testClearQueue() throws InterruptedException, ExecutionException, TimeoutException { public void testClearQueue() throws InterruptedException, ExecutionException, TimeoutException {
final Context context = getInstrumentation().getTargetContext();
final int NUM_ITEMS = 10; final int NUM_ITEMS = 10;
Feed feed = queueTestSetupMultipleItems(NUM_ITEMS); Feed feed = queueTestSetupMultipleItems(NUM_ITEMS);
DBWriter.clearQueue(context).get(TIMEOUT, TimeUnit.SECONDS); DBWriter.clearQueue().get(TIMEOUT, TimeUnit.SECONDS);
PodDBAdapter adapter = new PodDBAdapter(context); PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
Cursor cursor = adapter.getQueueIDCursor(); Cursor cursor = adapter.getQueueIDCursor();
assertFalse(cursor.moveToFirst()); assertFalse(cursor.moveToFirst());
@ -659,13 +657,13 @@ public class DBWriterTest extends InstrumentationTestCase {
final int NUM_ITEMS = 10; final int NUM_ITEMS = 10;
final Context context = getInstrumentation().getTargetContext(); final Context context = getInstrumentation().getTargetContext();
Feed feed = new Feed("url", new Date(), "title"); Feed feed = new Feed("url", new Date(), "title");
feed.setItems(new ArrayList<FeedItem>()); feed.setItems(new ArrayList<>());
for (int i = 0; i < NUM_ITEMS; i++) { for (int i = 0; i < NUM_ITEMS; i++) {
FeedItem item = new FeedItem(0, "title " + i, "id " + i, "link " + i, new Date(), FeedItem.PLAYED, feed); FeedItem item = new FeedItem(0, "title " + i, "id " + i, "link " + i, new Date(), FeedItem.PLAYED, feed);
feed.getItems().add(item); feed.getItems().add(item);
} }
PodDBAdapter adapter = new PodDBAdapter(context); PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
adapter.setCompleteFeed(feed); adapter.setCompleteFeed(feed);
adapter.close(); adapter.close();
@ -675,13 +673,13 @@ public class DBWriterTest extends InstrumentationTestCase {
} }
for (int removeIndex = 0; removeIndex < NUM_ITEMS; removeIndex++) { for (int removeIndex = 0; removeIndex < NUM_ITEMS; removeIndex++) {
final FeedItem item = feed.getItems().get(removeIndex); final FeedItem item = feed.getItems().get(removeIndex);
adapter = new PodDBAdapter(context); adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
adapter.setQueue(feed.getItems()); adapter.setQueue(feed.getItems());
adapter.close(); adapter.close();
DBWriter.removeQueueItem(context, item, false).get(TIMEOUT, TimeUnit.SECONDS); DBWriter.removeQueueItem(context, item, false).get(TIMEOUT, TimeUnit.SECONDS);
adapter = new PodDBAdapter(context); adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
Cursor queue = adapter.getQueueIDCursor(); Cursor queue = adapter.getQueueIDCursor();
assertTrue(queue.getCount() == NUM_ITEMS - 1); assertTrue(queue.getCount() == NUM_ITEMS - 1);
@ -703,15 +701,14 @@ public class DBWriterTest extends InstrumentationTestCase {
public void testMoveQueueItem() throws InterruptedException, ExecutionException, TimeoutException { public void testMoveQueueItem() throws InterruptedException, ExecutionException, TimeoutException {
final int NUM_ITEMS = 10; final int NUM_ITEMS = 10;
final Context context = getInstrumentation().getTargetContext();
Feed feed = new Feed("url", new Date(), "title"); Feed feed = new Feed("url", new Date(), "title");
feed.setItems(new ArrayList<FeedItem>()); feed.setItems(new ArrayList<>());
for (int i = 0; i < NUM_ITEMS; i++) { for (int i = 0; i < NUM_ITEMS; i++) {
FeedItem item = new FeedItem(0, "title " + i, "id " + i, "link " + i, new Date(), FeedItem.PLAYED, feed); FeedItem item = new FeedItem(0, "title " + i, "id " + i, "link " + i, new Date(), FeedItem.PLAYED, feed);
feed.getItems().add(item); feed.getItems().add(item);
} }
PodDBAdapter adapter = new PodDBAdapter(context); PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
adapter.setCompleteFeed(feed); adapter.setCompleteFeed(feed);
adapter.close(); adapter.close();
@ -727,13 +724,13 @@ public class DBWriterTest extends InstrumentationTestCase {
Log.d(TAG, String.format("testMoveQueueItem: From=%d, To=%d", from, to)); Log.d(TAG, String.format("testMoveQueueItem: From=%d, To=%d", from, to));
final long fromID = feed.getItems().get(from).getId(); final long fromID = feed.getItems().get(from).getId();
adapter = new PodDBAdapter(context); adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
adapter.setQueue(feed.getItems()); adapter.setQueue(feed.getItems());
adapter.close(); adapter.close();
DBWriter.moveQueueItem(context, from, to, false).get(TIMEOUT, TimeUnit.SECONDS); DBWriter.moveQueueItem(from, to, false).get(TIMEOUT, TimeUnit.SECONDS);
adapter = new PodDBAdapter(context); adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
Cursor queue = adapter.getQueueIDCursor(); Cursor queue = adapter.getQueueIDCursor();
assertTrue(queue.getCount() == NUM_ITEMS); assertTrue(queue.getCount() == NUM_ITEMS);
@ -749,7 +746,6 @@ public class DBWriterTest extends InstrumentationTestCase {
} }
public void testMarkFeedRead() throws InterruptedException, ExecutionException, TimeoutException { public void testMarkFeedRead() throws InterruptedException, ExecutionException, TimeoutException {
final Context context = getInstrumentation().getTargetContext();
final int NUM_ITEMS = 10; final int NUM_ITEMS = 10;
Feed feed = new Feed("url", new Date(), "title"); Feed feed = new Feed("url", new Date(), "title");
feed.setItems(new ArrayList<FeedItem>()); feed.setItems(new ArrayList<FeedItem>());
@ -758,7 +754,7 @@ public class DBWriterTest extends InstrumentationTestCase {
feed.getItems().add(item); feed.getItems().add(item);
} }
PodDBAdapter adapter = new PodDBAdapter(context); PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
adapter.setCompleteFeed(feed); adapter.setCompleteFeed(feed);
adapter.close(); adapter.close();
@ -768,24 +764,23 @@ public class DBWriterTest extends InstrumentationTestCase {
assertTrue(item.getId() != 0); assertTrue(item.getId() != 0);
} }
DBWriter.markFeedRead(context, feed.getId()).get(TIMEOUT, TimeUnit.SECONDS); DBWriter.markFeedRead(feed.getId()).get(TIMEOUT, TimeUnit.SECONDS);
List<FeedItem> loadedItems = DBReader.getFeedItemList(context, feed); List<FeedItem> loadedItems = DBReader.getFeedItemList(feed);
for (FeedItem item : loadedItems) { for (FeedItem item : loadedItems) {
assertTrue(item.isPlayed()); assertTrue(item.isPlayed());
} }
} }
public void testMarkAllItemsReadSameFeed() throws InterruptedException, ExecutionException, TimeoutException { public void testMarkAllItemsReadSameFeed() throws InterruptedException, ExecutionException, TimeoutException {
final Context context = getInstrumentation().getTargetContext();
final int NUM_ITEMS = 10; final int NUM_ITEMS = 10;
Feed feed = new Feed("url", new Date(), "title"); Feed feed = new Feed("url", new Date(), "title");
feed.setItems(new ArrayList<FeedItem>()); feed.setItems(new ArrayList<>());
for (int i = 0; i < NUM_ITEMS; i++) { for (int i = 0; i < NUM_ITEMS; i++) {
FeedItem item = new FeedItem(0, "title " + i, "id " + i, "link " + i, new Date(), FeedItem.UNPLAYED, feed); FeedItem item = new FeedItem(0, "title " + i, "id " + i, "link " + i, new Date(), FeedItem.UNPLAYED, feed);
feed.getItems().add(item); feed.getItems().add(item);
} }
PodDBAdapter adapter = new PodDBAdapter(context); PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
adapter.setCompleteFeed(feed); adapter.setCompleteFeed(feed);
adapter.close(); adapter.close();
@ -795,8 +790,8 @@ public class DBWriterTest extends InstrumentationTestCase {
assertTrue(item.getId() != 0); assertTrue(item.getId() != 0);
} }
DBWriter.markAllItemsRead(context).get(TIMEOUT, TimeUnit.SECONDS); DBWriter.markAllItemsRead().get(TIMEOUT, TimeUnit.SECONDS);
List<FeedItem> loadedItems = DBReader.getFeedItemList(context, feed); List<FeedItem> loadedItems = DBReader.getFeedItemList(feed);
for (FeedItem item : loadedItems) { for (FeedItem item : loadedItems) {
assertTrue(item.isPlayed()); assertTrue(item.isPlayed());
} }

View File

@ -44,8 +44,10 @@ public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActiv
solo = new Solo(getInstrumentation(), getActivity()); solo = new Solo(getInstrumentation(), getActivity());
uiTestUtils = new UITestUtils(getInstrumentation().getTargetContext()); uiTestUtils = new UITestUtils(getInstrumentation().getTargetContext());
uiTestUtils.setup(); uiTestUtils.setup();
// create database
PodDBAdapter adapter = new PodDBAdapter(getInstrumentation().getTargetContext()); // create new database
PodDBAdapter.deleteDatabase();
PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
adapter.close(); adapter.close();
@ -59,7 +61,7 @@ public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActiv
uiTestUtils.tearDown(); uiTestUtils.tearDown();
solo.finishOpenedActivities(); solo.finishOpenedActivities();
PodDBAdapter.deleteDatabase(getInstrumentation().getTargetContext()); PodDBAdapter.deleteDatabase();
// reset preferences // reset preferences
prefs.edit().clear().commit(); prefs.edit().clear().commit();

View File

@ -1,12 +1,14 @@
package de.test.antennapod.ui; package de.test.antennapod.ui;
import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.test.ActivityInstrumentationTestCase2; import android.test.ActivityInstrumentationTestCase2;
import android.test.FlakyTest;
import android.widget.ImageButton;
import com.robotium.solo.Condition;
import com.robotium.solo.Solo; import com.robotium.solo.Solo;
import com.robotium.solo.Timeout; import com.robotium.solo.Timeout;
@ -15,22 +17,120 @@ import java.util.List;
import de.danoeh.antennapod.R; import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.core.feed.FeedItem; import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.service.playback.PlaybackService; import de.danoeh.antennapod.core.service.playback.PlaybackService;
import de.danoeh.antennapod.core.service.playback.PlayerStatus;
import de.danoeh.antennapod.core.storage.DBReader; import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBWriter; import de.danoeh.antennapod.core.storage.DBWriter;
import de.danoeh.antennapod.core.storage.PodDBAdapter; import de.danoeh.antennapod.core.storage.PodDBAdapter;
import de.danoeh.antennapod.core.util.playback.Playable;
import de.danoeh.antennapod.core.util.playback.PlaybackController;
/** /**
* Test cases for starting and ending playback from the MainActivity and AudioPlayerActivity * test cases for starting and ending playback from the MainActivity and AudioPlayerActivity
*/ */
public class PlaybackTest extends ActivityInstrumentationTestCase2<MainActivity> { public class PlaybackTest extends ActivityInstrumentationTestCase2<MainActivity> {
private static final String TAG = PlaybackTest.class.getSimpleName();
private Solo solo; private Solo solo;
private UITestUtils uiTestUtils; private UITestUtils uiTestUtils;
private Context context; private Context context;
private PlaybackController controller;
protected FeedMedia currentMedia;
private PlaybackController createController(Activity activity) {
return new PlaybackController(activity, false) {
@Override
public void setupGUI() {
}
@Override
public void onPositionObserverUpdate() {
}
@Override
public void onBufferStart() {
}
@Override
public void onBufferEnd() {
}
@Override
public void onBufferUpdate(float progress) {
}
@Override
public void handleError(int code) {
}
@Override
public void onReloadNotification(int code) {
}
@Override
public void onSleepTimerUpdate() {
}
@Override
public ImageButton getPlayButton() {
return null;
}
@Override
public void postStatusMsg(int msg) {
}
@Override
public void clearStatusMsg() {
}
@Override
public boolean loadMediaInfo() {
Playable playable = controller.getMedia();
if(playable == null) {
currentMedia = null;
return true;
} else if(playable instanceof FeedMedia) {
currentMedia = (FeedMedia) playable;
return true;
} else {
return false;
}
}
@Override
public void onAwaitingVideoSurface() {
}
@Override
public void onServiceQueried() {
}
@Override
public void onShutdownNotification() {
}
@Override
public void onPlaybackEnd() {
currentMedia = null;
}
@Override
public void onPlaybackSpeedChange() {
}
@Override
protected void setScreenOn(boolean enable) {
}
};
}
public PlaybackTest() { public PlaybackTest() {
super(MainActivity.class); super(MainActivity.class);
} }
@ -38,30 +138,36 @@ public class PlaybackTest extends ActivityInstrumentationTestCase2<MainActivity>
@Override @Override
public void setUp() throws Exception { public void setUp() throws Exception {
super.setUp(); super.setUp();
solo = new Solo(getInstrumentation(), getActivity());
context = getInstrumentation().getContext();
PodDBAdapter.deleteDatabase();
controller = createController(getActivity());
controller.init();
solo = new Solo(getInstrumentation(), getActivity());
context = getInstrumentation().getTargetContext();
uiTestUtils = new UITestUtils(context); uiTestUtils = new UITestUtils(context);
uiTestUtils.setup(); uiTestUtils.setup();
// create database // create database
PodDBAdapter adapter = new PodDBAdapter(context); PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
adapter.close(); adapter.close();
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
prefs.edit() prefs.edit()
.clear()
.putBoolean(UserPreferences.PREF_UNPAUSE_ON_HEADSET_RECONNECT, false) .putBoolean(UserPreferences.PREF_UNPAUSE_ON_HEADSET_RECONNECT, false)
.putBoolean(UserPreferences.PREF_PAUSE_ON_HEADSET_DISCONNECT, false) .putBoolean(UserPreferences.PREF_PAUSE_ON_HEADSET_DISCONNECT, false)
.putString(UserPreferences.PREF_HIDDEN_DRAWER_ITEMS, "")
.commit(); .commit();
} }
@Override @Override
public void tearDown() throws Exception { public void tearDown() throws Exception {
uiTestUtils.tearDown(); controller.release();
solo.finishOpenedActivities(); solo.finishOpenedActivities();
PodDBAdapter.deleteDatabase(context); uiTestUtils.tearDown();
// shut down playback service // shut down playback service
skipEpisode(); skipEpisode();
@ -85,87 +191,106 @@ public class PlaybackTest extends ActivityInstrumentationTestCase2<MainActivity>
} }
private void startLocalPlayback() { private void startLocalPlayback() {
String allEpisodesLabel = solo.getString(R.string.all_episodes_label);
if(!getActivity().getSupportActionBar().getTitle().equals(allEpisodesLabel)) {
openNavDrawer(); openNavDrawer();
solo.clickOnText(solo.getString(R.string.episodes_label)); solo.clickOnText(solo.getString(R.string.episodes_label));
solo.clickOnText(solo.getString(R.string.all_episodes_short_label)); solo.clickOnText(solo.getString(R.string.all_episodes_short_label));
final List<FeedItem> episodes = DBReader.getRecentlyPublishedEpisodes(context, 10); }
final List<FeedItem> episodes = DBReader.getRecentlyPublishedEpisodes(10);
assertTrue(solo.waitForView(solo.getView(R.id.butSecondaryAction))); assertTrue(solo.waitForView(solo.getView(R.id.butSecondaryAction)));
solo.clickOnView(solo.getView(R.id.butSecondaryAction)); solo.clickOnView(solo.getView(R.id.butSecondaryAction));
assertTrue(solo.waitForView(solo.getView(R.id.butPlay))); long mediaId = episodes.get(0).getMedia().getId();
solo.waitForCondition(new Condition() { boolean playing = solo.waitForCondition(() -> {
@Override if (currentMedia != null) {
public boolean isSatisfied() { return currentMedia.getId() == mediaId;
return episodes.get(0).getMedia().isCurrentlyPlaying(); } else {
return false;
} }
}, Timeout.getLargeTimeout()); }, Timeout.getSmallTimeout());
assertTrue(playing);
} }
private void startLocalPlaybackFromQueue() { private void startLocalPlaybackFromQueue() {
openNavDrawer();
solo.clickOnText(solo.getString(R.string.queue_label));
assertTrue(solo.waitForView(solo.getView(R.id.butSecondaryAction))); assertTrue(solo.waitForView(solo.getView(R.id.butSecondaryAction)));
final List<FeedItem> queue = DBReader.getQueue(context); final List<FeedItem> queue = DBReader.getQueue();
solo.clickOnImageButton(1); solo.clickOnImageButton(1);
assertTrue(solo.waitForView(solo.getView(R.id.butPlay))); assertTrue(solo.waitForView(solo.getView(R.id.butPlay)));
solo.waitForCondition(new Condition() { long mediaId = queue.get(0).getMedia().getId();
@Override boolean playing = solo.waitForCondition(() -> {
public boolean isSatisfied() { if(currentMedia != null) {
return queue.get(0).getMedia().isCurrentlyPlaying(); return currentMedia.getId() == mediaId;
} else {
return false;
} }
}, Timeout.getLargeTimeout()); }, Timeout.getSmallTimeout());
assertTrue(playing);
} }
public void testStartLocal() throws Exception { public void testStartLocal() throws Exception {
uiTestUtils.addLocalFeedData(true); uiTestUtils.addLocalFeedData(true);
DBWriter.clearQueue(context).get(); DBWriter.clearQueue().get();
startLocalPlayback(); startLocalPlayback();
} }
public void testContinousPlaybackOffSingleEpisode() throws Exception { public void testContinousPlaybackOffSingleEpisode() throws Exception {
setContinuousPlaybackPreference(false); setContinuousPlaybackPreference(false);
uiTestUtils.addLocalFeedData(true); uiTestUtils.addLocalFeedData(true);
DBWriter.clearQueue(context).get(); DBWriter.clearQueue().get();
startLocalPlayback(); startLocalPlayback();
} }
@FlakyTest(tolerance = 3)
public void testContinousPlaybackOffMultipleEpisodes() throws Exception { public void testContinousPlaybackOffMultipleEpisodes() throws Exception {
setContinuousPlaybackPreference(false); setContinuousPlaybackPreference(false);
uiTestUtils.addLocalFeedData(true); uiTestUtils.addLocalFeedData(true);
List<FeedItem> queue = DBReader.getQueue(context); List<FeedItem> queue = DBReader.getQueue();
final FeedItem first = queue.get(0); final FeedItem first = queue.get(0);
final FeedItem second = queue.get(1);
startLocalPlaybackFromQueue(); startLocalPlaybackFromQueue();
solo.waitForCondition(new Condition() { boolean stopped = solo.waitForCondition(() -> {
@Override if (currentMedia != null) {
public boolean isSatisfied() { return currentMedia.getId() != first.getMedia().getId();
return first.getMedia().isCurrentlyPlaying() == false; } else {
return false;
} }
}, 10000); }, Timeout.getSmallTimeout());
assertTrue(stopped);
Thread.sleep(1000); Thread.sleep(1000);
assertTrue(second.getMedia().isCurrentlyPlaying() == false); PlayerStatus status = controller.getStatus();
assertFalse(status.equals(PlayerStatus.PLAYING));
} }
@FlakyTest(tolerance = 3)
public void testContinuousPlaybackOnMultipleEpisodes() throws Exception { public void testContinuousPlaybackOnMultipleEpisodes() throws Exception {
setContinuousPlaybackPreference(true); setContinuousPlaybackPreference(true);
uiTestUtils.addLocalFeedData(true); uiTestUtils.addLocalFeedData(true);
List<FeedItem> queue = DBReader.getQueue(context); List<FeedItem> queue = DBReader.getQueue();
final FeedItem first = queue.get(0); final FeedItem first = queue.get(0);
final FeedItem second = queue.get(1); final FeedItem second = queue.get(1);
startLocalPlaybackFromQueue(); startLocalPlaybackFromQueue();
solo.waitForCondition(new Condition() { boolean firstPlaying = solo.waitForCondition(() -> {
@Override if (currentMedia != null) {
public boolean isSatisfied() { return currentMedia.getId() == first.getMedia().getId();
return first.getMedia().isCurrentlyPlaying() == false; } else {
return false;
} }
}, 10000); }, Timeout.getSmallTimeout());
solo.waitForCondition(new Condition() { assertTrue(firstPlaying);
@Override boolean secondPlaying = solo.waitForCondition(() -> {
public boolean isSatisfied() { if (currentMedia != null) {
return second.getMedia().isCurrentlyPlaying() == true; return currentMedia.getId() == second.getMedia().getId();
} else {
return false;
} }
}, 10000); }, Timeout.getLargeTimeout());
assertTrue(secondPlaying);
} }
/** /**
@ -174,24 +299,34 @@ public class PlaybackTest extends ActivityInstrumentationTestCase2<MainActivity>
private void replayEpisodeCheck(boolean followQueue) throws Exception { private void replayEpisodeCheck(boolean followQueue) throws Exception {
setContinuousPlaybackPreference(followQueue); setContinuousPlaybackPreference(followQueue);
uiTestUtils.addLocalFeedData(true); uiTestUtils.addLocalFeedData(true);
DBWriter.clearQueue(context).get(); DBWriter.clearQueue().get();
final List<FeedItem> episodes = DBReader.getRecentlyPublishedEpisodes(context, 10); final List<FeedItem> episodes = DBReader.getRecentlyPublishedEpisodes(10);
startLocalPlayback(); startLocalPlayback();
solo.waitForCondition(new Condition() { long mediaId = episodes.get(0).getMedia().getId();
@Override boolean startedPlaying = solo.waitForCondition(() -> {
public boolean isSatisfied() { if (currentMedia != null) {
return false == episodes.get(0).getMedia().isCurrentlyPlaying(); return currentMedia.getId() == mediaId;
} else {
return false;
} }
}, Timeout.getSmallTimeout());
assertTrue(startedPlaying);
boolean stoppedPlaying = solo.waitForCondition(() -> {
return currentMedia == null || currentMedia.getId() != mediaId;
}, Timeout.getLargeTimeout()); }, Timeout.getLargeTimeout());
assertTrue(stoppedPlaying);
startLocalPlayback(); startLocalPlayback();
solo.waitForCondition(new Condition() { boolean startedReplay = solo.waitForCondition(() -> {
@Override if(currentMedia != null) {
public boolean isSatisfied() { return currentMedia.getId() == mediaId;
return false == episodes.get(0).getMedia().isCurrentlyPlaying(); } else {
return false;
} }
}, Timeout.getLargeTimeout()); }, Timeout.getLargeTimeout());
assertTrue(startedReplay);
} }
public void testReplayEpisodeContinuousPlaybackOn() throws Exception { public void testReplayEpisodeContinuousPlaybackOn() throws Exception {

View File

@ -4,6 +4,7 @@ import android.annotation.TargetApi;
import android.content.Context; import android.content.Context;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.os.Build; import android.os.Build;
import android.util.Log;
import junit.framework.Assert; import junit.framework.Assert;
@ -38,6 +39,8 @@ import de.test.antennapod.util.syndication.feedgenerator.RSS2Generator;
@TargetApi(Build.VERSION_CODES.HONEYCOMB) @TargetApi(Build.VERSION_CODES.HONEYCOMB)
public class UITestUtils { public class UITestUtils {
private static final String TAG = UITestUtils.class.getSimpleName();
private static final String DATA_FOLDER = "test/UITestUtils"; private static final String DATA_FOLDER = "test/UITestUtils";
public static final int NUM_FEEDS = 5; public static final int NUM_FEEDS = 5;
@ -79,7 +82,7 @@ public class UITestUtils {
server.stop(); server.stop();
if (localFeedDataAdded) { if (localFeedDataAdded) {
PodDBAdapter.deleteDatabase(context); PodDBAdapter.deleteDatabase();
} }
} }
@ -174,16 +177,15 @@ public class UITestUtils {
*/ */
public void addLocalFeedData(boolean downloadEpisodes) throws Exception { public void addLocalFeedData(boolean downloadEpisodes) throws Exception {
if (localFeedDataAdded) { if (localFeedDataAdded) {
throw new IllegalStateException("addLocalFeedData was called twice on the same instance"); Log.w(TAG, "addLocalFeedData was called twice on the same instance");
// might be a flaky test, this is actually not that severe
return;
} }
if (!feedDataHosted) { if (!feedDataHosted) {
addHostedFeedData(); addHostedFeedData();
} }
List<FeedItem> queue = new ArrayList<FeedItem>(); List<FeedItem> queue = new ArrayList<>();
PodDBAdapter adapter = new PodDBAdapter(context);
adapter.open();
for (Feed feed : hostedFeeds) { for (Feed feed : hostedFeeds) {
feed.setDownloaded(true); feed.setDownloaded(true);
if (feed.getImage() != null) { if (feed.getImage() != null) {
@ -206,6 +208,10 @@ public class UITestUtils {
queue.add(feed.getItems().get(0)); queue.add(feed.getItems().get(0));
feed.getItems().get(1).getMedia().setPlaybackCompletionDate(new Date()); feed.getItems().get(1).getMedia().setPlaybackCompletionDate(new Date());
} }
localFeedDataAdded = true;
PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open();
adapter.setCompleteFeed(hostedFeeds.toArray(new Feed[hostedFeeds.size()])); adapter.setCompleteFeed(hostedFeeds.toArray(new Feed[hostedFeeds.size()]));
adapter.setQueue(queue); adapter.setQueue(queue);
adapter.close(); adapter.close();

View File

@ -9,6 +9,7 @@ import com.joanzapata.iconify.fonts.FontAwesomeModule;
import de.danoeh.antennapod.core.feed.EventDistributor; import de.danoeh.antennapod.core.feed.EventDistributor;
import de.danoeh.antennapod.core.preferences.PlaybackPreferences; import de.danoeh.antennapod.core.preferences.PlaybackPreferences;
import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.storage.PodDBAdapter;
import de.danoeh.antennapod.core.util.NetworkUtils; import de.danoeh.antennapod.core.util.NetworkUtils;
import de.danoeh.antennapod.spa.SPAUtil; import de.danoeh.antennapod.spa.SPAUtil;
@ -40,6 +41,7 @@ public class PodcastApp extends Application {
singleton = this; singleton = this;
LOGICAL_DENSITY = getResources().getDisplayMetrics().density; LOGICAL_DENSITY = getResources().getDisplayMetrics().density;
PodDBAdapter.init(this);
UpdateManager.init(this); UpdateManager.init(this);
UserPreferences.init(this); UserPreferences.init(this);
PlaybackPreferences.init(this); PlaybackPreferences.init(this);

View File

@ -65,9 +65,9 @@ public class UpdateManager {
// from now on, Glide will handle caching images // from now on, Glide will handle caching images
new Thread() { new Thread() {
public void run() { public void run() {
List<Feed> feeds = DBReader.getFeedList(context); List<Feed> feeds = DBReader.getFeedList();
for (Feed podcast : feeds) { for (Feed podcast : feeds) {
List<FeedItem> episodes = DBReader.getFeedItemList(context, podcast); List<FeedItem> episodes = DBReader.getFeedItemList(podcast);
for (FeedItem episode : episodes) { for (FeedItem episode : episodes) {
FeedImage image = episode.getImage(); FeedImage image = episode.getImage();
if (image != null && image.isDownloaded() && image.getFile_url() != null) { if (image != null && image.isDownloaded() && image.getFile_url() != null) {
@ -76,7 +76,7 @@ public class UpdateManager {
imageFile.delete(); imageFile.delete();
} }
image.setFile_url(null); // calls setDownloaded(false) image.setFile_url(null); // calls setDownloaded(false)
DBWriter.setFeedImage(context, image); DBWriter.setFeedImage(image);
} }
} }
} }

View File

@ -6,7 +6,6 @@ import android.content.SharedPreferences;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.content.res.TypedArray; import android.content.res.TypedArray;
import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.BitmapDrawable;
import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction; import android.support.v4.app.FragmentTransaction;
@ -60,6 +59,10 @@ import de.danoeh.antennapod.fragment.CoverFragment;
import de.danoeh.antennapod.fragment.ItemDescriptionFragment; import de.danoeh.antennapod.fragment.ItemDescriptionFragment;
import de.danoeh.antennapod.menuhandler.NavDrawerActivity; import de.danoeh.antennapod.menuhandler.NavDrawerActivity;
import de.danoeh.antennapod.preferences.PreferenceController; import de.danoeh.antennapod.preferences.PreferenceController;
import rx.Observable;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;
/** /**
* Activity for playing audio files. * Activity for playing audio files.
@ -104,6 +107,8 @@ public class AudioplayerActivity extends MediaplayerActivity implements ItemDesc
private ImageButton butNavChaptersShownotes; private ImageButton butNavChaptersShownotes;
private ImageButton butShowCover; private ImageButton butShowCover;
private Subscription subscription;
private PopupWindow popupWindow; private PopupWindow popupWindow;
private void resetFragmentView() { private void resetFragmentView() {
@ -145,7 +150,9 @@ public class AudioplayerActivity extends MediaplayerActivity implements ItemDesc
protected void onStop() { protected void onStop() {
super.onStop(); super.onStop();
Log.d(TAG, "onStop()"); Log.d(TAG, "onStop()");
cancelLoadTask(); if(subscription != null) {
subscription.unsubscribe();
}
EventDistributor.getInstance().unregister(contentUpdate); EventDistributor.getInstance().unregister(contentUpdate);
} }
@ -716,10 +723,10 @@ public class AudioplayerActivity extends MediaplayerActivity implements ItemDesc
Feed feed = navDrawerData.feeds.get(position - navAdapter.getSubscriptionOffset()); Feed feed = navDrawerData.feeds.get(position - navAdapter.getSubscriptionOffset());
switch(item.getItemId()) { switch(item.getItemId()) {
case R.id.mark_all_seen_item: case R.id.mark_all_seen_item:
DBWriter.markFeedSeen(this, feed.getId()); DBWriter.markFeedSeen(feed.getId());
return true; return true;
case R.id.mark_all_read_item: case R.id.mark_all_read_item:
DBWriter.markFeedRead(this, feed.getId()); DBWriter.markFeedRead(feed.getId());
return true; return true;
case R.id.remove_item: case R.id.remove_item:
final FeedRemover remover = new FeedRemover(this, feed) { final FeedRemover remover = new FeedRemover(this, feed) {
@ -747,32 +754,22 @@ public class AudioplayerActivity extends MediaplayerActivity implements ItemDesc
private DBReader.NavDrawerData navDrawerData; private DBReader.NavDrawerData navDrawerData;
private AsyncTask<Void, Void, DBReader.NavDrawerData> loadTask;
private void loadData() { private void loadData() {
loadTask = new AsyncTask<Void, Void, DBReader.NavDrawerData>() { subscription = Observable.defer(() -> Observable.just(DBReader.getNavDrawerData()))
@Override .subscribeOn(Schedulers.newThread())
protected DBReader.NavDrawerData doInBackground(Void... params) { .observeOn(AndroidSchedulers.mainThread())
return DBReader.getNavDrawerData(AudioplayerActivity.this); .subscribe(result -> {
}
@Override
protected void onPostExecute(DBReader.NavDrawerData result) {
super.onPostExecute(result);
navDrawerData = result; navDrawerData = result;
if (navAdapter != null) { if (navAdapter != null) {
navAdapter.notifyDataSetChanged(); navAdapter.notifyDataSetChanged();
} }
} }, error -> {
}; Log.e(TAG, Log.getStackTraceString(error));
loadTask.execute(); });
} }
private void cancelLoadTask() {
if (loadTask != null) {
loadTask.cancel(true);
}
}
private EventDistributor.EventListener contentUpdate = new EventDistributor.EventListener() { private EventDistributor.EventListener contentUpdate = new EventDistributor.EventListener() {

View File

@ -26,7 +26,6 @@ import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import com.bumptech.glide.Glide; import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.joanzapata.iconify.Iconify; import com.joanzapata.iconify.Iconify;
import de.danoeh.antennapod.R; import de.danoeh.antennapod.R;
@ -111,7 +110,7 @@ public class FeedInfoActivity extends ActionBarActivity {
@Override @Override
protected Feed doInBackground(Long... params) { protected Feed doInBackground(Long... params) {
return DBReader.getFeed(FeedInfoActivity.this, params[0]); return DBReader.getFeed(params[0]);
} }
@Override @Override
@ -239,7 +238,7 @@ public class FeedInfoActivity extends ActionBarActivity {
prefs.setPassword(etxtPassword.getText().toString()); prefs.setPassword(etxtPassword.getText().toString());
} }
if (authInfoChanged || autoDeleteChanged) { if (authInfoChanged || autoDeleteChanged) {
DBWriter.setFeedPreferences(this, prefs); DBWriter.setFeedPreferences(prefs);
} }
authInfoChanged = false; authInfoChanged = false;
autoDeleteChanged = false; autoDeleteChanged = false;
@ -299,7 +298,7 @@ public class FeedInfoActivity extends ActionBarActivity {
@Override @Override
public void onConfirmButtonPressed(DialogInterface dialog) { public void onConfirmButtonPressed(DialogInterface dialog) {
DBWriter.setFeedsItemsAutoDownload(context, feed, autoDownload); DBWriter.setFeedsItemsAutoDownload(feed, autoDownload);
} }
} }

View File

@ -58,6 +58,10 @@ import de.danoeh.antennapod.fragment.QueueFragment;
import de.danoeh.antennapod.menuhandler.NavDrawerActivity; import de.danoeh.antennapod.menuhandler.NavDrawerActivity;
import de.danoeh.antennapod.preferences.PreferenceController; import de.danoeh.antennapod.preferences.PreferenceController;
import de.greenrobot.event.EventBus; import de.greenrobot.event.EventBus;
import rx.Observable;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;
/** /**
* The activity that is shown when the user launches the app. * The activity that is shown when the user launches the app.
@ -106,6 +110,8 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity
private ProgressDialog pd; private ProgressDialog pd;
private Subscription subscription;
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
setTheme(UserPreferences.getNoTitleTheme()); setTheme(UserPreferences.getNoTitleTheme());
@ -478,9 +484,11 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity
@Override @Override
protected void onStop() { protected void onStop() {
super.onStop(); super.onStop();
cancelLoadTask();
EventDistributor.getInstance().unregister(contentUpdate); EventDistributor.getInstance().unregister(contentUpdate);
EventBus.getDefault().unregister(this); EventBus.getDefault().unregister(this);
if(subscription != null) {
subscription.unsubscribe();
}
if(pd != null) { if(pd != null) {
pd.dismiss(); pd.dismiss();
} }
@ -551,10 +559,10 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity
Feed feed = navDrawerData.feeds.get(position - navAdapter.getSubscriptionOffset()); Feed feed = navDrawerData.feeds.get(position - navAdapter.getSubscriptionOffset());
switch(item.getItemId()) { switch(item.getItemId()) {
case R.id.mark_all_seen_item: case R.id.mark_all_seen_item:
DBWriter.markFeedSeen(this, feed.getId()); DBWriter.markFeedSeen(feed.getId());
return true; return true;
case R.id.mark_all_read_item: case R.id.mark_all_read_item:
DBWriter.markFeedRead(this, feed.getId()); DBWriter.markFeedRead(feed.getId());
return true; return true;
case R.id.remove_item: case R.id.remove_item:
final FeedRemover remover = new FeedRemover(this, feed) { final FeedRemover remover = new FeedRemover(this, feed) {
@ -629,16 +637,10 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity
}; };
private void loadData() { private void loadData() {
cancelLoadTask(); subscription = Observable.defer(() -> Observable.just(DBReader.getNavDrawerData()))
loadTask = new AsyncTask<Void, Void, DBReader.NavDrawerData>() { .subscribeOn(Schedulers.newThread())
@Override .observeOn(AndroidSchedulers.mainThread())
protected DBReader.NavDrawerData doInBackground(Void... params) { .subscribe(result -> {
return DBReader.getNavDrawerData(MainActivity.this);
}
@Override
protected void onPostExecute(DBReader.NavDrawerData result) {
super.onPostExecute(navDrawerData);
boolean handleIntent = (navDrawerData == null); boolean handleIntent = (navDrawerData == null);
navDrawerData = result; navDrawerData = result;
@ -647,15 +649,9 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity
if (handleIntent) { if (handleIntent) {
handleNavIntent(); handleNavIntent();
} }
} }, error -> {
}; Log.e(TAG, Log.getStackTraceString(error));
loadTask.execute(); });
}
private void cancelLoadTask() {
if (loadTask != null) {
loadTask.cancel(true);
}
} }
public void onEvent(QueueEvent event) { public void onEvent(QueueEvent event) {

View File

@ -109,7 +109,7 @@ public class OnlineFeedViewActivity extends ActionBarActivity {
@Override @Override
public void update(EventDistributor eventDistributor, Integer arg) { public void update(EventDistributor eventDistributor, Integer arg) {
if ((arg & EventDistributor.FEED_LIST_UPDATE) != 0) { if ((arg & EventDistributor.FEED_LIST_UPDATE) != 0) {
updater = Observable.defer(() -> Observable.just(DBReader.getFeedList(OnlineFeedViewActivity.this))) updater = Observable.defer(() -> Observable.just(DBReader.getFeedList()))
.subscribeOn(Schedulers.newThread()) .subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe(feeds -> { .subscribe(feeds -> {
@ -263,7 +263,7 @@ public class OnlineFeedViewActivity extends ActionBarActivity {
download = Observable.create(new Observable.OnSubscribe<DownloadStatus>() { download = Observable.create(new Observable.OnSubscribe<DownloadStatus>() {
@Override @Override
public void call(Subscriber<? super DownloadStatus> subscriber) { public void call(Subscriber<? super DownloadStatus> subscriber) {
feeds = DBReader.getFeedList(OnlineFeedViewActivity.this); feeds = DBReader.getFeedList();
downloader = new HttpDownloader(request); downloader = new HttpDownloader(request);
downloader.call(); downloader.call();
Log.d(TAG, "Download was completed"); Log.d(TAG, "Download was completed");

View File

@ -64,7 +64,7 @@ public class ActionButtonUtils {
butSecondary.setContentDescription(context.getString(labels[1])); butSecondary.setContentDescription(context.getString(labels[1]));
} else { } else {
// item is not downloaded and not being downloaded // item is not downloaded and not being downloaded
LongList queueIds = DBReader.getQueueIDList(context); LongList queueIds = DBReader.getQueueIDList();
if(DefaultActionButtonCallback.userAllowedMobileDownloads() || if(DefaultActionButtonCallback.userAllowedMobileDownloads() ||
!DefaultActionButtonCallback.userChoseAddToQueue() || queueIds.contains(item.getId())) { !DefaultActionButtonCallback.userChoseAddToQueue() || queueIds.contains(item.getId())) {
butSecondary.setVisibility(View.VISIBLE); butSecondary.setVisibility(View.VISIBLE);

View File

@ -57,7 +57,7 @@ public class DefaultActionButtonCallback implements ActionButtonCallback {
final FeedMedia media = item.getMedia(); final FeedMedia media = item.getMedia();
boolean isDownloading = DownloadRequester.getInstance().isDownloadingFile(media); boolean isDownloading = DownloadRequester.getInstance().isDownloadingFile(media);
if (!isDownloading && !media.isDownloaded()) { if (!isDownloading && !media.isDownloaded()) {
LongList queueIds = DBReader.getQueueIDList(context); LongList queueIds = DBReader.getQueueIDList();
if (NetworkUtils.isDownloadAllowed() || userAllowedMobileDownloads()) { if (NetworkUtils.isDownloadAllowed() || userAllowedMobileDownloads()) {
try { try {
DBTasks.downloadFeedItems(context, item); DBTasks.downloadFeedItems(context, item);
@ -75,7 +75,7 @@ public class DefaultActionButtonCallback implements ActionButtonCallback {
} else if (isDownloading) { } else if (isDownloading) {
DownloadRequester.getInstance().cancelDownload(context, media); DownloadRequester.getInstance().cancelDownload(context, media);
if(UserPreferences.isEnableAutodownload()) { if(UserPreferences.isEnableAutodownload()) {
DBWriter.setFeedItemAutoDownload(context, media.getItem(), false); DBWriter.setFeedItemAutoDownload(media.getItem(), false);
Toast.makeText(context, R.string.download_canceled_autodownload_enabled_msg, Toast.LENGTH_LONG).show(); Toast.makeText(context, R.string.download_canceled_autodownload_enabled_msg, Toast.LENGTH_LONG).show();
} else { } else {
Toast.makeText(context, R.string.download_canceled_msg, Toast.LENGTH_LONG).show(); Toast.makeText(context, R.string.download_canceled_msg, Toast.LENGTH_LONG).show();
@ -93,7 +93,7 @@ public class DefaultActionButtonCallback implements ActionButtonCallback {
} }
} else { } else {
if (!item.isPlayed()) { if (!item.isPlayed()) {
DBWriter.markItemPlayed(context, item, FeedItem.PLAYED, true); DBWriter.markItemPlayed(item, FeedItem.PLAYED, true);
} }
} }
} }
@ -117,7 +117,7 @@ public class DefaultActionButtonCallback implements ActionButtonCallback {
} }
} }
}); });
LongList queueIds = DBReader.getQueueIDList(context); LongList queueIds = DBReader.getQueueIDList();
if(!queueIds.contains(item.getId())) { if(!queueIds.contains(item.getId())) {
builder.setNeutralButton(context.getText(R.string.confirm_mobile_download_dialog_only_add_to_queue), builder.setNeutralButton(context.getText(R.string.confirm_mobile_download_dialog_only_add_to_queue),
new DialogInterface.OnClickListener() { new DialogInterface.OnClickListener() {

View File

@ -123,7 +123,7 @@ public class DownloadLogAdapter extends BaseAdapter {
public void onClick(View v) { public void onClick(View v) {
ButtonHolder holder = (ButtonHolder) v.getTag(); ButtonHolder holder = (ButtonHolder) v.getTag();
if(holder.typeId == Feed.FEEDFILETYPE_FEED) { if(holder.typeId == Feed.FEEDFILETYPE_FEED) {
Feed feed = DBReader.getFeed(context, holder.id); Feed feed = DBReader.getFeed(holder.id);
if (feed != null) { if (feed != null) {
feed.setLastUpdate(new Date(0)); // force refresh feed.setLastUpdate(new Date(0)); // force refresh
try { try {
@ -135,7 +135,7 @@ public class DownloadLogAdapter extends BaseAdapter {
Log.wtf(TAG, "Could not find feed for feed id: " + holder.id); Log.wtf(TAG, "Could not find feed for feed id: " + holder.id);
} }
} else if(holder.typeId == FeedMedia.FEEDFILETYPE_FEEDMEDIA) { } else if(holder.typeId == FeedMedia.FEEDFILETYPE_FEEDMEDIA) {
FeedMedia media = DBReader.getFeedMedia(context, holder.id); FeedMedia media = DBReader.getFeedMedia(holder.id);
try { try {
DBTasks.downloadFeedItems(context, media.getItem()); DBTasks.downloadFeedItems(context, media.getItem());
Toast.makeText(context, R.string.status_downloading_label, Toast.LENGTH_SHORT).show(); Toast.makeText(context, R.string.status_downloading_label, Toast.LENGTH_SHORT).show();

View File

@ -59,7 +59,7 @@ public class OpmlExportWorker extends AsyncTask<Void, Void, Void> {
OutputStreamWriter writer = null; OutputStreamWriter writer = null;
try { try {
writer = new OutputStreamWriter(new FileOutputStream(output), LangUtils.UTF_8); writer = new OutputStreamWriter(new FileOutputStream(output), LangUtils.UTF_8);
opmlWriter.writeDocument(DBReader.getFeedList(context), writer); opmlWriter.writeDocument(DBReader.getFeedList(), writer);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
exception = e; exception = e;

View File

@ -372,12 +372,12 @@ public class EpisodesApplyActionFragment extends Fragment {
} }
private void markedCheckedPlayed() { private void markedCheckedPlayed() {
DBWriter.markItemPlayed(getActivity(), FeedItem.PLAYED, checkedIds.toArray()); DBWriter.markItemPlayed(FeedItem.PLAYED, checkedIds.toArray());
close(); close();
} }
private void markedCheckedUnplayed() { private void markedCheckedUnplayed() {
DBWriter.markItemPlayed(getActivity(), FeedItem.UNPLAYED, checkedIds.toArray()); DBWriter.markItemPlayed(FeedItem.UNPLAYED, checkedIds.toArray());
close(); close();
} }

View File

@ -38,6 +38,7 @@ import de.danoeh.antennapod.core.feed.EventDistributor;
import de.danoeh.antennapod.core.feed.Feed; import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.feed.FeedItem; import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia; import de.danoeh.antennapod.core.feed.FeedMedia;
import de.danoeh.antennapod.core.feed.QueueEvent;
import de.danoeh.antennapod.core.service.download.DownloadService; import de.danoeh.antennapod.core.service.download.DownloadService;
import de.danoeh.antennapod.core.service.download.Downloader; import de.danoeh.antennapod.core.service.download.Downloader;
import de.danoeh.antennapod.core.storage.DBReader; import de.danoeh.antennapod.core.storage.DBReader;
@ -57,6 +58,7 @@ public class AllEpisodesFragment extends Fragment {
public static final String TAG = "AllEpisodesFragment"; public static final String TAG = "AllEpisodesFragment";
private static final int EVENTS = EventDistributor.DOWNLOAD_HANDLED | private static final int EVENTS = EventDistributor.DOWNLOAD_HANDLED |
EventDistributor.FEED_LIST_UPDATE |
EventDistributor.DOWNLOAD_QUEUED | EventDistributor.DOWNLOAD_QUEUED |
EventDistributor.UNREAD_ITEMS_UPDATE | EventDistributor.UNREAD_ITEMS_UPDATE |
EventDistributor.PLAYER_STATUS_UPDATE; EventDistributor.PLAYER_STATUS_UPDATE;
@ -251,7 +253,7 @@ public class AllEpisodesFragment extends Fragment {
public void onConfirmButtonPressed( public void onConfirmButtonPressed(
DialogInterface dialog) { DialogInterface dialog) {
dialog.dismiss(); dialog.dismiss();
DBWriter.markAllItemsRead(getActivity()); DBWriter.markAllItemsRead();
Toast.makeText(getActivity(), R.string.mark_all_read_msg, Toast.LENGTH_SHORT).show(); Toast.makeText(getActivity(), R.string.mark_all_read_msg, Toast.LENGTH_SHORT).show();
} }
}; };
@ -485,14 +487,14 @@ public class AllEpisodesFragment extends Fragment {
if (context != null) { if (context != null) {
if(showOnlyNewEpisodes) { if(showOnlyNewEpisodes) {
return new Object[] { return new Object[] {
DBReader.getNewItemsList(context), DBReader.getNewItemsList(),
DBReader.getQueueIDList(context), DBReader.getQueueIDList(),
null // see ItemAccess.isNew null // see ItemAccess.isNew
}; };
} else { } else {
return new Object[]{ return new Object[]{
DBReader.getRecentlyPublishedEpisodes(context, RECENT_EPISODES_LIMIT), DBReader.getRecentlyPublishedEpisodes(RECENT_EPISODES_LIMIT),
DBReader.getQueueIDList(context) DBReader.getQueueIDList()
}; };
} }
} else { } else {

View File

@ -179,7 +179,7 @@ public class CompletedDownloadsFragment extends ListFragment {
protected List<FeedItem> doInBackground(Void... params) { protected List<FeedItem> doInBackground(Void... params) {
Context context = getActivity(); Context context = getActivity();
if (context != null) { if (context != null) {
return DBReader.getDownloadedItems(context); return DBReader.getDownloadedItems();
} }
return Collections.emptyList(); return Collections.emptyList();
} }

View File

@ -142,7 +142,7 @@ public class DownloadLogFragment extends ListFragment {
if (!super.onOptionsItemSelected(item)) { if (!super.onOptionsItemSelected(item)) {
switch (item.getItemId()) { switch (item.getItemId()) {
case R.id.clear_history_item: case R.id.clear_history_item:
DBWriter.clearDownloadLog(getActivity()); DBWriter.clearDownloadLog();
return true; return true;
default: default:
return false; return false;
@ -170,7 +170,7 @@ public class DownloadLogFragment extends ListFragment {
protected List<DownloadStatus> doInBackground(Void... params) { protected List<DownloadStatus> doInBackground(Void... params) {
Context context = getActivity(); Context context = getActivity();
if (context != null) { if (context != null) {
return DBReader.getDownloadLog(context); return DBReader.getDownloadLog();
} }
return null; return null;
} }

View File

@ -210,7 +210,7 @@ public class ItemDescriptionFragment extends Fragment {
@Override @Override
protected FeedItem doInBackground(Void... voids) { protected FeedItem doInBackground(Void... voids) {
return DBReader.getFeedItem(getActivity(), getArguments().getLong(ARG_FEEDITEM_ID)); return DBReader.getFeedItem(getArguments().getLong(ARG_FEEDITEM_ID));
} }
@Override @Override

View File

@ -36,7 +36,6 @@ import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import com.bumptech.glide.Glide; import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import java.util.List; import java.util.List;
@ -497,12 +496,12 @@ public class ItemFragment extends Fragment implements LoaderManager.LoaderCallba
return new DBTaskLoader<Pair<FeedItem,LongList>>(getActivity()) { return new DBTaskLoader<Pair<FeedItem,LongList>>(getActivity()) {
@Override @Override
public Pair<FeedItem,LongList> loadInBackground() { public Pair<FeedItem,LongList> loadInBackground() {
FeedItem data1 = DBReader.getFeedItem(getContext(), itemID); FeedItem data1 = DBReader.getFeedItem(itemID);
if (data1 != null) { if (data1 != null) {
Timeline t = new Timeline(getActivity(), data1); Timeline t = new Timeline(getActivity(), data1);
webviewData = t.processShownotes(false); webviewData = t.processShownotes(false);
} }
LongList data2 = DBReader.getQueueIDList(getContext()); LongList data2 = DBReader.getQueueIDList();
return Pair.create(data1, data2); return Pair.create(data1, data2);
} }
}; };

View File

@ -630,12 +630,12 @@ public class ItemlistFragment extends ListFragment {
long feedID = params[0]; long feedID = params[0];
Context context = getActivity(); Context context = getActivity();
if (context != null) { if (context != null) {
Feed feed = DBReader.getFeed(context, feedID); Feed feed = DBReader.getFeed(feedID);
if(feed != null && feed.getItemFilter() != null) { if(feed != null && feed.getItemFilter() != null) {
FeedItemFilter filter = feed.getItemFilter(); FeedItemFilter filter = feed.getItemFilter();
feed.setItems(filter.filter(context, feed.getItems())); feed.setItems(filter.filter(context, feed.getItems()));
} }
LongList queuedItemsIds = DBReader.getQueueIDList(context); LongList queuedItemsIds = DBReader.getQueueIDList();
return new Object[] { feed, queuedItemsIds }; return new Object[] { feed, queuedItemsIds };
} else { } else {
return null; return null;

View File

@ -73,7 +73,7 @@ public class NewEpisodesFragment extends AllEpisodesFragment {
FeedItem item = (FeedItem) listView.getAdapter().getItem(which); FeedItem item = (FeedItem) listView.getAdapter().getItem(which);
// we're marking it as unplayed since the user didn't actually play it // we're marking it as unplayed since the user didn't actually play it
// but they don't want it considered 'NEW' anymore // but they don't want it considered 'NEW' anymore
DBWriter.markItemPlayed(getActivity(), FeedItem.UNPLAYED, item.getId()); DBWriter.markItemPlayed(FeedItem.UNPLAYED, item.getId());
undoBarController.showUndoBar(false, undoBarController.showUndoBar(false,
getString(R.string.marked_as_read_label), new FeedItemUndoToken(item, getString(R.string.marked_as_read_label), new FeedItemUndoToken(item,
which) which)
@ -89,14 +89,14 @@ public class NewEpisodesFragment extends AllEpisodesFragment {
public void onUndo(FeedItemUndoToken token) { public void onUndo(FeedItemUndoToken token) {
if (token != null) { if (token != null) {
long itemId = token.getFeedItemId(); long itemId = token.getFeedItemId();
DBWriter.markItemPlayed(context, FeedItem.NEW, itemId); DBWriter.markItemPlayed(FeedItem.NEW, itemId);
} }
} }
@Override @Override
public void onHide(FeedItemUndoToken token) { public void onHide(FeedItemUndoToken token) {
if (token != null && context != null) { if (token != null && context != null) {
long itemId = token.getFeedItemId(); long itemId = token.getFeedItemId();
FeedItem item = DBReader.getFeedItem(context, itemId); FeedItem item = DBReader.getFeedItem(itemId);
FeedMedia media = item.getMedia(); FeedMedia media = item.getMedia();
if(media != null && media.hasAlmostEnded() && item.getFeed().getPreferences().getCurrentAutoDelete()) { if(media != null && media.hasAlmostEnded() && item.getFeed().getPreferences().getCurrentAutoDelete()) {
DBWriter.deleteFeedMediaOfItem(context, media.getId()); DBWriter.deleteFeedMediaOfItem(context, media.getId());

View File

@ -164,7 +164,7 @@ public class PlaybackHistoryFragment extends ListFragment {
if (!super.onOptionsItemSelected(item)) { if (!super.onOptionsItemSelected(item)) {
switch (item.getItemId()) { switch (item.getItemId()) {
case R.id.clear_history_item: case R.id.clear_history_item:
DBWriter.clearPlaybackHistory(getActivity()); DBWriter.clearPlaybackHistory();
return true; return true;
default: default:
return false; return false;
@ -267,9 +267,9 @@ public class PlaybackHistoryFragment extends ListFragment {
protected Pair<List<FeedItem>,LongList> doInBackground(Void... params) { protected Pair<List<FeedItem>,LongList> doInBackground(Void... params) {
Context context = activity.get(); Context context = activity.get();
if (context != null) { if (context != null) {
List<FeedItem> history = DBReader.getPlaybackHistory(context); List<FeedItem> history = DBReader.getPlaybackHistory();
LongList queue = DBReader.getQueueIDList(context); LongList queue = DBReader.getQueueIDList();
DBReader.loadFeedDataOfFeedItemlist(context, history); DBReader.loadFeedDataOfFeedItemlist(history);
return Pair.create(history, queue); return Pair.create(history, queue);
} else { } else {
return null; return null;

View File

@ -269,7 +269,7 @@ public class QueueFragment extends Fragment {
public void onConfirmButtonPressed( public void onConfirmButtonPressed(
DialogInterface dialog) { DialogInterface dialog) {
dialog.dismiss(); dialog.dismiss();
DBWriter.clearQueue(getActivity()); DBWriter.clearQueue();
} }
}; };
conDialog.createNewDialog().show(); conDialog.createNewDialog().show();
@ -402,7 +402,7 @@ public class QueueFragment extends Fragment {
final FeedItem item = queue.remove(from); final FeedItem item = queue.remove(from);
queue.add(to, item); queue.add(to, item);
listAdapter.notifyDataSetChanged(); listAdapter.notifyDataSetChanged();
DBWriter.moveQueueItem(getActivity(), from, to, true); DBWriter.moveQueueItem(from, to, true);
} }
@Override @Override
@ -432,13 +432,15 @@ public class QueueFragment extends Fragment {
public void onHide(FeedItemUndoToken token) { public void onHide(FeedItemUndoToken token) {
if (token != null && context != null) { if (token != null && context != null) {
long itemId = token.getFeedItemId(); long itemId = token.getFeedItemId();
FeedItem item = DBReader.getFeedItem(context, itemId); FeedItem item = DBReader.getFeedItem(itemId);
if(item != null) {
FeedMedia media = item.getMedia(); FeedMedia media = item.getMedia();
if(media != null && media.hasAlmostEnded() && item.getFeed().getPreferences().getCurrentAutoDelete()) { if (media != null && media.hasAlmostEnded() && item.getFeed().getPreferences().getCurrentAutoDelete()) {
DBWriter.deleteFeedMediaOfItem(context, media.getId()); DBWriter.deleteFeedMediaOfItem(context, media.getId());
} }
} }
} }
}
}); });
@ -608,7 +610,7 @@ public class QueueFragment extends Fragment {
protected List<FeedItem> doInBackground(Void... params) { protected List<FeedItem> doInBackground(Void... params) {
Context context = activity.get(); Context context = activity.get();
if (context != null) { if (context != null) {
return DBReader.getQueue(context); return DBReader.getQueue();
} }
return null; return null;
} }

View File

@ -81,8 +81,8 @@ public class RunningDownloadsFragment extends ListFragment {
if(downloadRequest.getFeedfileType() == FeedMedia.FEEDFILETYPE_FEEDMEDIA && if(downloadRequest.getFeedfileType() == FeedMedia.FEEDFILETYPE_FEEDMEDIA &&
UserPreferences.isEnableAutodownload()) { UserPreferences.isEnableAutodownload()) {
FeedMedia media = DBReader.getFeedMedia(getActivity(), downloadRequest.getFeedfileId()); FeedMedia media = DBReader.getFeedMedia(downloadRequest.getFeedfileId());
DBWriter.setFeedItemAutoDownload(getActivity(), media.getItem(), false); DBWriter.setFeedItemAutoDownload(media.getItem(), false);
Toast.makeText(getActivity(), R.string.download_canceled_autodownload_enabled_msg, Toast.LENGTH_SHORT).show(); Toast.makeText(getActivity(), R.string.download_canceled_autodownload_enabled_msg, Toast.LENGTH_SHORT).show();
} else { } else {
Toast.makeText(getActivity(), R.string.download_canceled_msg, Toast.LENGTH_SHORT).show(); Toast.makeText(getActivity(), R.string.download_canceled_msg, Toast.LENGTH_SHORT).show();

View File

@ -155,7 +155,7 @@ public class FeedItemMenuHandler {
break; break;
case R.id.mark_read_item: case R.id.mark_read_item:
selectedItem.setPlayed(true); selectedItem.setPlayed(true);
DBWriter.markItemPlayed(context, selectedItem, FeedItem.PLAYED, false); DBWriter.markItemPlayed(selectedItem, FeedItem.PLAYED, false);
if(GpodnetPreferences.loggedIn()) { if(GpodnetPreferences.loggedIn()) {
FeedMedia media = selectedItem.getMedia(); FeedMedia media = selectedItem.getMedia();
// not all items have media, Gpodder only cares about those that do // not all items have media, Gpodder only cares about those that do
@ -173,7 +173,7 @@ public class FeedItemMenuHandler {
break; break;
case R.id.mark_unread_item: case R.id.mark_unread_item:
selectedItem.setPlayed(false); selectedItem.setPlayed(false);
DBWriter.markItemPlayed(context, selectedItem, FeedItem.UNPLAYED, false); DBWriter.markItemPlayed(selectedItem, FeedItem.UNPLAYED, false);
if(GpodnetPreferences.loggedIn()) { if(GpodnetPreferences.loggedIn()) {
GpodnetEpisodeAction actionNew = new GpodnetEpisodeAction.Builder(selectedItem, Action.NEW) GpodnetEpisodeAction actionNew = new GpodnetEpisodeAction.Builder(selectedItem, Action.NEW)
.currentDeviceId() .currentDeviceId()
@ -183,10 +183,10 @@ public class FeedItemMenuHandler {
} }
break; break;
case R.id.move_to_top_item: case R.id.move_to_top_item:
DBWriter.moveQueueItemToTop(context, selectedItem.getId(), true); DBWriter.moveQueueItemToTop(selectedItem.getId(), true);
return true; return true;
case R.id.move_to_bottom_item: case R.id.move_to_bottom_item:
DBWriter.moveQueueItemToBottom(context, selectedItem.getId(), true); DBWriter.moveQueueItemToBottom(selectedItem.getId(), true);
case R.id.add_to_queue_item: case R.id.add_to_queue_item:
DBWriter.addQueueItem(context, selectedItem.getId()); DBWriter.addQueueItem(context, selectedItem.getId());
break; break;
@ -195,15 +195,15 @@ public class FeedItemMenuHandler {
break; break;
case R.id.reset_position: case R.id.reset_position:
selectedItem.getMedia().setPosition(0); selectedItem.getMedia().setPosition(0);
DBWriter.markItemPlayed(context, selectedItem, FeedItem.UNPLAYED, true); DBWriter.markItemPlayed(selectedItem, FeedItem.UNPLAYED, true);
break; break;
case R.id.activate_auto_download: case R.id.activate_auto_download:
selectedItem.setAutoDownload(true); selectedItem.setAutoDownload(true);
DBWriter.setFeedItemAutoDownload(context, selectedItem, true); DBWriter.setFeedItemAutoDownload(selectedItem, true);
break; break;
case R.id.deactivate_auto_download: case R.id.deactivate_auto_download:
selectedItem.setAutoDownload(false); selectedItem.setAutoDownload(false);
DBWriter.setFeedItemAutoDownload(context, selectedItem, false); DBWriter.setFeedItemAutoDownload(selectedItem, false);
break; break;
case R.id.visit_website_item: case R.id.visit_website_item:
Uri uri = Uri.parse(selectedItem.getLink()); Uri uri = Uri.parse(selectedItem.getLink());

View File

@ -78,7 +78,7 @@ public class FeedMenuHandler {
public void onConfirmButtonPressed( public void onConfirmButtonPressed(
DialogInterface dialog) { DialogInterface dialog) {
dialog.dismiss(); dialog.dismiss();
DBWriter.markFeedRead(context, selectedFeed.getId()); DBWriter.markFeedRead(selectedFeed.getId());
} }
}; };
conDialog.createNewDialog().show(); conDialog.createNewDialog().show();
@ -138,7 +138,7 @@ public class FeedMenuHandler {
@Override @Override
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
feed.setHiddenItemProperties(hidden.toArray(new String[hidden.size()])); feed.setHiddenItemProperties(hidden.toArray(new String[hidden.size()]));
DBWriter.setFeedItemsFilter(context, feed.getId(), hidden); DBWriter.setFeedItemsFilter(feed.getId(), hidden);
} }
}); });
builder.setNegativeButton(R.string.cancel_label, null); builder.setNegativeButton(R.string.cancel_label, null);

View File

@ -58,9 +58,9 @@ public class PlayerWidgetService extends Service {
if (media.hasAlmostEnded()) { if (media.hasAlmostEnded()) {
Log.d(TAG, "smart mark as read"); Log.d(TAG, "smart mark as read");
FeedItem item = media.getItem(); FeedItem item = media.getItem();
DBWriter.markItemPlayed(this, item, FeedItem.PLAYED, false); DBWriter.markItemPlayed(item, FeedItem.PLAYED, false);
DBWriter.removeQueueItem(this, item, false); DBWriter.removeQueueItem(this, item, false);
DBWriter.addItemToPlaybackHistory(this, media); DBWriter.addItemToPlaybackHistory(media);
if (item.getFeed().getPreferences().getCurrentAutoDelete()) { if (item.getFeed().getPreferences().getCurrentAutoDelete()) {
Log.d(TAG, "Delete " + media.toString()); Log.d(TAG, "Delete " + media.toString());
DBWriter.deleteFeedMediaOfItem(this, media.getId()); DBWriter.deleteFeedMediaOfItem(this, media.getId());

View File

@ -94,7 +94,7 @@ public class FlattrClickWorker extends AsyncTask<Void, Integer, FlattrClickWorke
return ExitCode.NO_NETWORK; return ExitCode.NO_NETWORK;
} }
final List<FlattrThing> flattrQueue = DBReader.getFlattrQueue(context); final List<FlattrThing> flattrQueue = DBReader.getFlattrQueue();
if (extraFlattrThing != null) { if (extraFlattrThing != null) {
flattrQueue.add(extraFlattrThing); flattrQueue.add(extraFlattrThing);
} else if (flattrQueue.size() == 1) { } else if (flattrQueue.size() == 1) {

View File

@ -32,7 +32,7 @@ public class FlattrStatusFetcher extends Thread {
try { try {
List<Flattr> flattredThings = FlattrUtils.retrieveFlattredThings(); List<Flattr> flattredThings = FlattrUtils.retrieveFlattredThings();
DBWriter.setFlattredStatus(context, flattredThings).get(); DBWriter.setFlattredStatus(flattredThings).get();
} catch (FlattrException e) { } catch (FlattrException e) {
e.printStackTrace(); e.printStackTrace();
Log.d(TAG, "flattrQueue exception retrieving list with flattred items " + e.getMessage()); Log.d(TAG, "flattrQueue exception retrieving list with flattred items " + e.getMessage());

View File

@ -89,7 +89,7 @@ public class OpmlBackupAgent extends BackupAgentHelper {
try { try {
// Write OPML // Write OPML
new OpmlWriter().writeDocument(DBReader.getFeedList(mContext), writer); new OpmlWriter().writeDocument(DBReader.getFeedList(), writer);
// Compare checksum of new and old file to see if we need to perform a backup at all // Compare checksum of new and old file to see if we need to perform a backup at all
if (digester != null) { if (digester != null) {

View File

@ -1,5 +1,9 @@
package de.danoeh.antennapod.core.feed; package de.danoeh.antennapod.core.feed;
import android.database.Cursor;
import de.danoeh.antennapod.core.storage.PodDBAdapter;
public abstract class Chapter extends FeedComponent { public abstract class Chapter extends FeedComponent {
/** Defines starting point in milliseconds. */ /** Defines starting point in milliseconds. */
@ -22,6 +26,33 @@ public abstract class Chapter extends FeedComponent {
this.link = link; this.link = link;
} }
public static Chapter fromCursor(Cursor cursor, FeedItem item) {
int indexTitle = cursor.getColumnIndex(PodDBAdapter.KEY_TITLE);
int indexStart = cursor.getColumnIndex(PodDBAdapter.KEY_START);
int indexLink = cursor.getColumnIndex(PodDBAdapter.KEY_LINK);
int indexChapterType = cursor.getColumnIndex(PodDBAdapter.KEY_CHAPTER_TYPE);
String title = cursor.getString(indexTitle);
long start = cursor.getLong(indexStart);
String link = cursor.getString(indexLink);
int chapterType = cursor.getInt(indexChapterType);
Chapter chapter = null;
switch (chapterType) {
case SimpleChapter.CHAPTERTYPE_SIMPLECHAPTER:
chapter = new SimpleChapter(start, title, item, link);
break;
case ID3Chapter.CHAPTERTYPE_ID3CHAPTER:
chapter = new ID3Chapter(start, title, item, link);
break;
case VorbisCommentChapter.CHAPTERTYPE_VORBISCOMMENT_CHAPTER:
chapter = new VorbisCommentChapter(start, title, item, link);
break;
}
return chapter;
}
public abstract int getChapterType(); public abstract int getChapterType();
public long getStart() { public long getStart() {

View File

@ -1,6 +1,7 @@
package de.danoeh.antennapod.core.feed; package de.danoeh.antennapod.core.feed;
import android.content.Context; import android.content.Context;
import android.database.Cursor;
import android.net.Uri; import android.net.Uri;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
@ -12,6 +13,7 @@ import java.util.List;
import de.danoeh.antennapod.core.asynctask.ImageResource; import de.danoeh.antennapod.core.asynctask.ImageResource;
import de.danoeh.antennapod.core.storage.DBWriter; import de.danoeh.antennapod.core.storage.DBWriter;
import de.danoeh.antennapod.core.storage.PodDBAdapter;
import de.danoeh.antennapod.core.util.flattr.FlattrStatus; import de.danoeh.antennapod.core.util.flattr.FlattrStatus;
import de.danoeh.antennapod.core.util.flattr.FlattrThing; import de.danoeh.antennapod.core.util.flattr.FlattrThing;
@ -170,6 +172,55 @@ public class Feed extends FeedFile implements FlattrThing, ImageResource {
preferences = new FeedPreferences(0, true, FeedPreferences.AutoDeleteAction.GLOBAL, username, password); preferences = new FeedPreferences(0, true, FeedPreferences.AutoDeleteAction.GLOBAL, username, password);
} }
public static Feed fromCursor(Cursor cursor) {
int indexId = cursor.getColumnIndex(PodDBAdapter.KEY_ID);
int indexLastUpdate = cursor.getColumnIndex(PodDBAdapter.KEY_LASTUPDATE);
int indexTitle = cursor.getColumnIndex(PodDBAdapter.KEY_TITLE);
int indexLink = cursor.getColumnIndex(PodDBAdapter.KEY_LINK);
int indexDescription = cursor.getColumnIndex(PodDBAdapter.KEY_DESCRIPTION);
int indexPaymentLink = cursor.getColumnIndex(PodDBAdapter.KEY_PAYMENT_LINK);
int indexAuthor = cursor.getColumnIndex(PodDBAdapter.KEY_AUTHOR);
int indexLanguage = cursor.getColumnIndex(PodDBAdapter.KEY_LANGUAGE);
int indexType = cursor.getColumnIndex(PodDBAdapter.KEY_TYPE);
int indexFeedIdentifier = cursor.getColumnIndex(PodDBAdapter.KEY_FEED_IDENTIFIER);
int indexFileUrl = cursor.getColumnIndex(PodDBAdapter.KEY_FILE_URL);
int indexDownloadUrl = cursor.getColumnIndex(PodDBAdapter.KEY_DOWNLOAD_URL);
int indexDownloaded = cursor.getColumnIndex(PodDBAdapter.KEY_DOWNLOADED);
int indexFlattrStatus = cursor.getColumnIndex(PodDBAdapter.KEY_FLATTR_STATUS);
int indexIsPaged = cursor.getColumnIndex(PodDBAdapter.KEY_IS_PAGED);
int indexNextPageLink = cursor.getColumnIndex(PodDBAdapter.KEY_NEXT_PAGE_LINK);
int indexHide = cursor.getColumnIndex(PodDBAdapter.KEY_HIDE);
int indexLastUpdateFailed = cursor.getColumnIndex(PodDBAdapter.KEY_LAST_UPDATE_FAILED);
Date lastUpdate = new Date(cursor.getLong(indexLastUpdate));
Feed feed = new Feed(
cursor.getLong(indexId),
lastUpdate,
cursor.getString(indexTitle),
cursor.getString(indexLink),
cursor.getString(indexDescription),
cursor.getString(indexPaymentLink),
cursor.getString(indexAuthor),
cursor.getString(indexLanguage),
cursor.getString(indexType),
cursor.getString(indexFeedIdentifier),
null,
cursor.getString(indexFileUrl),
cursor.getString(indexDownloadUrl),
cursor.getInt(indexDownloaded) > 0,
new FlattrStatus(cursor.getLong(indexFlattrStatus)),
cursor.getInt(indexIsPaged) > 0,
cursor.getString(indexNextPageLink),
cursor.getString(indexHide),
cursor.getInt(indexLastUpdateFailed) > 0
);
FeedPreferences preferences = FeedPreferences.fromCursor(cursor);
feed.setPreferences(preferences);
return feed;
}
/** /**
* Returns true if at least one item in the itemlist is unread. * Returns true if at least one item in the itemlist is unread.
@ -444,7 +495,7 @@ public class Feed extends FeedFile implements FlattrThing, ImageResource {
} }
public void savePreferences(Context context) { public void savePreferences(Context context) {
DBWriter.setFeedPreferences(context, preferences); DBWriter.setFeedPreferences(preferences);
} }
@Override @Override

View File

@ -1,10 +1,12 @@
package de.danoeh.antennapod.core.feed; package de.danoeh.antennapod.core.feed;
import android.database.Cursor;
import android.net.Uri; import android.net.Uri;
import java.io.File; import java.io.File;
import de.danoeh.antennapod.core.asynctask.ImageResource; import de.danoeh.antennapod.core.asynctask.ImageResource;
import de.danoeh.antennapod.core.storage.PodDBAdapter;
public class FeedImage extends FeedFile implements ImageResource { public class FeedImage extends FeedFile implements ImageResource {
@ -31,6 +33,23 @@ public class FeedImage extends FeedFile implements ImageResource {
super(); super();
} }
public static FeedImage fromCursor(Cursor cursor) {
int indexId = cursor.getColumnIndex(PodDBAdapter.KEY_ID);
int indexTitle = cursor.getColumnIndex(PodDBAdapter.KEY_TITLE);
int indexFileUrl = cursor.getColumnIndex(PodDBAdapter.KEY_FILE_URL);
int indexDownloadUrl = cursor.getColumnIndex(PodDBAdapter.KEY_DOWNLOAD_URL);
int indexDownloaded = cursor.getColumnIndex(PodDBAdapter.KEY_DOWNLOADED);
return new FeedImage(
cursor.getLong(indexId),
cursor.getString(indexTitle),
cursor.getString(indexFileUrl),
cursor.getString(indexDownloadUrl),
cursor.getInt(indexDownloaded) > 0
);
}
@Override @Override
public String getHumanReadableIdentifier() { public String getHumanReadableIdentifier() {
if (owner != null && owner.getHumanReadableIdentifier() != null) { if (owner != null && owner.getHumanReadableIdentifier() != null) {

View File

@ -1,5 +1,6 @@
package de.danoeh.antennapod.core.feed; package de.danoeh.antennapod.core.feed;
import android.database.Cursor;
import android.net.Uri; import android.net.Uri;
import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringBuilder;
@ -9,9 +10,9 @@ import java.util.Date;
import java.util.List; import java.util.List;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import de.danoeh.antennapod.core.ClientConfig;
import de.danoeh.antennapod.core.asynctask.ImageResource; import de.danoeh.antennapod.core.asynctask.ImageResource;
import de.danoeh.antennapod.core.storage.DBReader; import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.PodDBAdapter;
import de.danoeh.antennapod.core.util.ShownotesProvider; import de.danoeh.antennapod.core.util.ShownotesProvider;
import de.danoeh.antennapod.core.util.flattr.FlattrStatus; import de.danoeh.antennapod.core.util.flattr.FlattrStatus;
import de.danoeh.antennapod.core.util.flattr.FlattrThing; import de.danoeh.antennapod.core.util.flattr.FlattrThing;
@ -125,6 +126,37 @@ public class FeedItem extends FeedComponent implements ShownotesProvider, Flattr
this.hasChapters = hasChapters; this.hasChapters = hasChapters;
} }
public static FeedItem fromCursor(Cursor cursor) {
int indexId = cursor.getColumnIndex(PodDBAdapter.KEY_ID);
int indexTitle = cursor.getColumnIndex(PodDBAdapter.KEY_TITLE);
int indexLink = cursor.getColumnIndex(PodDBAdapter.KEY_LINK);
int indexPubDate = cursor.getColumnIndex(PodDBAdapter.KEY_PUBDATE);
int indexPaymentLink = cursor.getColumnIndex(PodDBAdapter.KEY_PAYMENT_LINK);
int indexFeedId = cursor.getColumnIndex(PodDBAdapter.KEY_FEED);
int indexFlattrStatus = cursor.getColumnIndex(PodDBAdapter.KEY_FLATTR_STATUS);
int indexHasChapters = cursor.getColumnIndex(PodDBAdapter.KEY_HAS_CHAPTERS);
int indexRead = cursor.getColumnIndex(PodDBAdapter.KEY_READ);
int indexItemIdentifier = cursor.getColumnIndex(PodDBAdapter.KEY_ITEM_IDENTIFIER);
int indexAutoDownload = cursor.getColumnIndex(PodDBAdapter.KEY_AUTO_DOWNLOAD);
long id = cursor.getInt(indexId);
assert(id > 0);
String title = cursor.getString(indexTitle);
String link = cursor.getString(indexLink);
Date pubDate = new Date(cursor.getLong(indexPubDate));
String paymentLink = cursor.getString(indexPaymentLink);
long feedId = cursor.getLong(indexFeedId);
boolean hasChapters = cursor.getInt(indexHasChapters) > 0;
FlattrStatus flattrStatus = new FlattrStatus(cursor.getLong(indexFlattrStatus));
int state = cursor.getInt(indexRead);
String itemIdentifier = cursor.getString(indexItemIdentifier);
boolean autoDownload = cursor.getInt(indexAutoDownload) > 0;
FeedItem item = new FeedItem(id, title, link, pubDate, paymentLink, feedId, flattrStatus,
hasChapters, null, state, itemIdentifier, autoDownload);
return item;
}
public void updateFromOther(FeedItem other) { public void updateFromOther(FeedItem other) {
super.updateFromOther(other); super.updateFromOther(other);
if (other.title != null) { if (other.title != null) {
@ -321,7 +353,7 @@ public class FeedItem extends FeedComponent implements ShownotesProvider, Flattr
public String call() throws Exception { public String call() throws Exception {
if (contentEncoded == null || description == null) { if (contentEncoded == null || description == null) {
DBReader.loadExtraInformationOfFeedItem(ClientConfig.applicationCallbacks.getApplicationInstance(), FeedItem.this); DBReader.loadExtraInformationOfFeedItem(FeedItem.this);
} }
return (contentEncoded != null) ? contentEncoded : description; return (contentEncoded != null) ? contentEncoded : description;

View File

@ -64,7 +64,7 @@ public class FeedItemFilter {
if(hideUnplayed && false == item.isPlayed()) continue; if(hideUnplayed && false == item.isPlayed()) continue;
if(hidePaused && item.getState() == FeedItem.State.IN_PROGRESS) continue; if(hidePaused && item.getState() == FeedItem.State.IN_PROGRESS) continue;
if(hidePlayed && item.isPlayed()) continue; if(hidePlayed && item.isPlayed()) continue;
boolean isQueued = DBReader.getQueueIDList(context).contains(item.getId()); boolean isQueued = DBReader.getQueueIDList().contains(item.getId());
if(hideQueued && isQueued) continue; if(hideQueued && isQueued) continue;
if(hideNotQueued && false == isQueued) continue; if(hideNotQueued && false == isQueued) continue;
boolean isDownloaded = item.getMedia() != null && item.getMedia().isDownloaded(); boolean isDownloaded = item.getMedia() != null && item.getMedia().isDownloaded();

View File

@ -2,6 +2,7 @@ package de.danoeh.antennapod.core.feed;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor; import android.content.SharedPreferences.Editor;
import android.database.Cursor;
import android.media.MediaMetadataRetriever; import android.media.MediaMetadataRetriever;
import android.net.Uri; import android.net.Uri;
import android.os.Parcel; import android.os.Parcel;
@ -11,11 +12,11 @@ import java.util.Date;
import java.util.List; import java.util.List;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import de.danoeh.antennapod.core.ClientConfig;
import de.danoeh.antennapod.core.preferences.PlaybackPreferences; import de.danoeh.antennapod.core.preferences.PlaybackPreferences;
import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.storage.DBReader; import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBWriter; import de.danoeh.antennapod.core.storage.DBWriter;
import de.danoeh.antennapod.core.storage.PodDBAdapter;
import de.danoeh.antennapod.core.util.ChapterUtils; import de.danoeh.antennapod.core.util.ChapterUtils;
import de.danoeh.antennapod.core.util.playback.Playable; import de.danoeh.antennapod.core.util.playback.Playable;
@ -83,6 +84,55 @@ public class FeedMedia extends FeedFile implements Playable {
this.hasEmbeddedPicture = hasEmbeddedPicture; this.hasEmbeddedPicture = hasEmbeddedPicture;
} }
public static FeedMedia fromCursor(Cursor cursor) {
int indexId = cursor.getColumnIndex(PodDBAdapter.KEY_ID);
int indexPlaybackCompletionDate = cursor.getColumnIndex(PodDBAdapter.KEY_PLAYBACK_COMPLETION_DATE);
int indexDuration = cursor.getColumnIndex(PodDBAdapter.KEY_DURATION);
int indexPosition = cursor.getColumnIndex(PodDBAdapter.KEY_POSITION);
int indexSize = cursor.getColumnIndex(PodDBAdapter.KEY_SIZE);
int indexMimeType = cursor.getColumnIndex(PodDBAdapter.KEY_MIME_TYPE);
int indexFileUrl = cursor.getColumnIndex(PodDBAdapter.KEY_FILE_URL);
int indexDownloadUrl = cursor.getColumnIndex(PodDBAdapter.KEY_DOWNLOAD_URL);
int indexDownloaded = cursor.getColumnIndex(PodDBAdapter.KEY_DOWNLOADED);
int indexPlayedDuration = cursor.getColumnIndex(PodDBAdapter.KEY_PLAYED_DURATION);
long mediaId = cursor.getLong(indexId);
Date playbackCompletionDate = null;
long playbackCompletionTime = cursor.getLong(indexPlaybackCompletionDate);
if (playbackCompletionTime > 0) {
playbackCompletionDate = new Date(playbackCompletionTime);
}
Boolean hasEmbeddedPicture;
switch(cursor.getInt(cursor.getColumnIndex(PodDBAdapter.KEY_HAS_EMBEDDED_PICTURE))) {
case 1:
hasEmbeddedPicture = Boolean.TRUE;
break;
case 0:
hasEmbeddedPicture = Boolean.FALSE;
break;
default:
hasEmbeddedPicture = null;
break;
}
return new FeedMedia(
mediaId,
null,
cursor.getInt(indexDuration),
cursor.getInt(indexPosition),
cursor.getLong(indexSize),
cursor.getString(indexMimeType),
cursor.getString(indexFileUrl),
cursor.getString(indexDownloadUrl),
cursor.getInt(indexDownloaded) > 0,
playbackCompletionDate,
cursor.getInt(indexPlayedDuration),
hasEmbeddedPicture
);
}
@Override @Override
public String getHumanReadableIdentifier() { public String getHumanReadableIdentifier() {
if (item != null && item.getTitle() != null) { if (item != null && item.getTitle() != null) {
@ -297,22 +347,22 @@ public class FeedMedia extends FeedFile implements Playable {
@Override @Override
public void loadMetadata() throws PlayableException { public void loadMetadata() throws PlayableException {
if (item == null && itemID != 0) { if (item == null && itemID != 0) {
item = DBReader.getFeedItem(ClientConfig.applicationCallbacks.getApplicationInstance(), itemID); item = DBReader.getFeedItem(itemID);
} }
} }
@Override @Override
public void loadChapterMarks() { public void loadChapterMarks() {
if (item == null && itemID != 0) { if (item == null && itemID != 0) {
item = DBReader.getFeedItem(ClientConfig.applicationCallbacks.getApplicationInstance(), itemID); item = DBReader.getFeedItem(itemID);
} }
// check if chapters are stored in db and not loaded yet. // check if chapters are stored in db and not loaded yet.
if (item != null && item.hasChapters() && item.getChapters() == null) { if (item != null && item.hasChapters() && item.getChapters() == null) {
DBReader.loadChaptersOfFeedItem(ClientConfig.applicationCallbacks.getApplicationInstance(), item); DBReader.loadChaptersOfFeedItem(item);
} else if (item != null && item.getChapters() == null && !localFileAvailable()) { } else if (item != null && item.getChapters() == null && !localFileAvailable()) {
ChapterUtils.loadChaptersFromStreamUrl(this); ChapterUtils.loadChaptersFromStreamUrl(this);
if (getChapters() != null && item != null) { if (getChapters() != null && item != null) {
DBWriter.setFeedItem(ClientConfig.applicationCallbacks.getApplicationInstance(), DBWriter.setFeedItem(
item); item);
} }
} }
@ -389,9 +439,9 @@ public class FeedMedia extends FeedFile implements Playable {
@Override @Override
public void saveCurrentPosition(SharedPreferences pref, int newPosition) { public void saveCurrentPosition(SharedPreferences pref, int newPosition) {
DBWriter.setFeedMediaPlaybackInformation(ClientConfig.applicationCallbacks.getApplicationInstance(), this); DBWriter.setFeedMediaPlaybackInformation(this);
if(item.isNew()) { if(item.isNew()) {
DBWriter.markItemPlayed(ClientConfig.applicationCallbacks.getApplicationInstance(), FeedItem.UNPLAYED, item.getId()); DBWriter.markItemPlayed(FeedItem.UNPLAYED, item.getId());
} }
setPosition(newPosition); setPosition(newPosition);
} }
@ -421,11 +471,11 @@ public class FeedMedia extends FeedFile implements Playable {
public String call() throws Exception { public String call() throws Exception {
if (item == null) { if (item == null) {
item = DBReader.getFeedItem( item = DBReader.getFeedItem(
ClientConfig.applicationCallbacks.getApplicationInstance(), itemID); itemID);
} }
if (item.getContentEncoded() == null || item.getDescription() == null) { if (item.getContentEncoded() == null || item.getDescription() == null) {
DBReader.loadExtraInformationOfFeedItem( DBReader.loadExtraInformationOfFeedItem(
ClientConfig.applicationCallbacks.getApplicationInstance(), item); item);
} }
return (item.getContentEncoded() != null) ? item.getContentEncoded() : item.getDescription(); return (item.getContentEncoded() != null) ? item.getContentEncoded() : item.getDescription();

View File

@ -1,9 +1,13 @@
package de.danoeh.antennapod.core.feed; package de.danoeh.antennapod.core.feed;
import android.content.Context; import android.content.Context;
import de.danoeh.antennapod.core.storage.DBWriter; import android.database.Cursor;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.storage.DBWriter;
import de.danoeh.antennapod.core.storage.PodDBAdapter;
/** /**
* Contains preferences for a single feed. * Contains preferences for a single feed.
@ -29,6 +33,23 @@ public class FeedPreferences {
this.password = password; this.password = password;
} }
public static FeedPreferences fromCursor(Cursor cursor) {
int indexId = cursor.getColumnIndex(PodDBAdapter.KEY_ID);
int indexAutoDownload = cursor.getColumnIndex(PodDBAdapter.KEY_AUTO_DOWNLOAD);
int indexAutoDeleteAction = cursor.getColumnIndex(PodDBAdapter.KEY_AUTO_DELETE_ACTION);
int indexUsername = cursor.getColumnIndex(PodDBAdapter.KEY_USERNAME);
int indexPassword = cursor.getColumnIndex(PodDBAdapter.KEY_PASSWORD);
long feedId = cursor.getLong(indexId);
boolean autoDownload = cursor.getInt(indexAutoDownload) > 0;
int autoDeleteActionIndex = cursor.getInt(indexAutoDeleteAction);
AutoDeleteAction autoDeleteAction = AutoDeleteAction.values()[autoDeleteActionIndex];
String username = cursor.getString(indexUsername);
String password = cursor.getString(indexPassword);
return new FeedPreferences(feedId, autoDownload, autoDeleteAction, username, password);
}
/** /**
* Compare another FeedPreferences with this one. The feedID, autoDownload and AutoDeleteAction attribute are excluded from the * Compare another FeedPreferences with this one. The feedID, autoDownload and AutoDeleteAction attribute are excluded from the
@ -98,7 +119,7 @@ public class FeedPreferences {
} }
public void save(Context context) { public void save(Context context) {
DBWriter.setFeedPreferences(context, this); DBWriter.setFeedPreferences(this);
} }
public String getUsername() { public String getUsername() {

View File

@ -108,7 +108,7 @@ public class ApOkHttpUrlLoader implements ModelLoader<GlideUrl, InputStream> {
com.squareup.okhttp.Request request = chain.request(); com.squareup.okhttp.Request request = chain.request();
String url = request.urlString(); String url = request.urlString();
Context context = ClientConfig.applicationCallbacks.getApplicationInstance(); Context context = ClientConfig.applicationCallbacks.getApplicationInstance();
String authentication = DBReader.getImageAuthentication(context, url); String authentication = DBReader.getImageAuthentication(url);
if(TextUtils.isEmpty(authentication)) { if(TextUtils.isEmpty(authentication)) {
Log.d(TAG, "no credentials for '" + url + "'"); Log.d(TAG, "no credentials for '" + url + "'");

View File

@ -126,7 +126,7 @@ public class GpodnetSyncService extends Service {
private synchronized void syncSubscriptionChanges() { private synchronized void syncSubscriptionChanges() {
final long timestamp = GpodnetPreferences.getLastSubscriptionSyncTimestamp(); final long timestamp = GpodnetPreferences.getLastSubscriptionSyncTimestamp();
try { try {
final List<String> localSubscriptions = DBReader.getFeedListDownloadUrls(this); final List<String> localSubscriptions = DBReader.getFeedListDownloadUrls();
Collection<String> localAdded = GpodnetPreferences.getAddedFeedsCopy(); Collection<String> localAdded = GpodnetPreferences.getAddedFeedsCopy();
Collection<String> localRemoved = GpodnetPreferences.getRemovedFeedsCopy(); Collection<String> localRemoved = GpodnetPreferences.getRemovedFeedsCopy();
GpodnetService service = tryLogin(); GpodnetService service = tryLogin();
@ -242,9 +242,9 @@ public class GpodnetSyncService extends Service {
for (GpodnetEpisodeAction action : remoteActions) { for (GpodnetEpisodeAction action : remoteActions) {
switch (action.getAction()) { switch (action.getAction()) {
case NEW: case NEW:
FeedItem newItem = DBReader.getFeedItem(this, action.getPodcast(), action.getEpisode()); FeedItem newItem = DBReader.getFeedItem(action.getPodcast(), action.getEpisode());
if(newItem != null) { if(newItem != null) {
DBWriter.markItemPlayed(this, newItem, FeedItem.UNPLAYED, true); DBWriter.markItemPlayed(newItem, FeedItem.UNPLAYED, true);
} else { } else {
Log.i(TAG, "Unknown feed item: " + action); Log.i(TAG, "Unknown feed item: " + action);
} }
@ -273,14 +273,14 @@ public class GpodnetSyncService extends Service {
} }
} }
for (GpodnetEpisodeAction action : mostRecentPlayAction.values()) { for (GpodnetEpisodeAction action : mostRecentPlayAction.values()) {
FeedItem playItem = DBReader.getFeedItem(this, action.getPodcast(), action.getEpisode()); FeedItem playItem = DBReader.getFeedItem(action.getPodcast(), action.getEpisode());
if (playItem != null) { if (playItem != null) {
FeedMedia media = playItem.getMedia(); FeedMedia media = playItem.getMedia();
media.setPosition(action.getPosition() * 1000); media.setPosition(action.getPosition() * 1000);
DBWriter.setFeedMedia(this, media); DBWriter.setFeedMedia(media);
if(playItem.getMedia().hasAlmostEnded()) { if(playItem.getMedia().hasAlmostEnded()) {
DBWriter.markItemPlayed(this, playItem, FeedItem.PLAYED, true); DBWriter.markItemPlayed(playItem, FeedItem.PLAYED, true);
DBWriter.addItemToPlaybackHistory(this, playItem.getMedia()); DBWriter.addItemToPlaybackHistory(playItem.getMedia());
} }
} }
} }

View File

@ -20,7 +20,6 @@ import android.util.Log;
import android.webkit.URLUtil; import android.webkit.URLUtil;
import org.apache.commons.io.FileUtils; import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.Validate;
import org.apache.http.HttpStatus; import org.apache.http.HttpStatus;
@ -504,7 +503,7 @@ public class DownloadService extends Service {
*/ */
private void saveDownloadStatus(DownloadStatus status) { private void saveDownloadStatus(DownloadStatus status) {
reportQueue.add(status); reportQueue.add(status);
DBWriter.addDownloadStatus(this, status); DBWriter.addDownloadStatus(status);
} }
private void sendDownloadHandledIntent() { private void sendDownloadHandledIntent() {
@ -888,7 +887,7 @@ public class DownloadService extends Service {
if (successful) { if (successful) {
// we create a 'successful' download log if the feed's last refresh failed // we create a 'successful' download log if the feed's last refresh failed
List<DownloadStatus> log = DBReader.getFeedDownloadLog(DownloadService.this, feed); List<DownloadStatus> log = DBReader.getFeedDownloadLog(feed);
if(log.size() > 0 && log.get(0).isSuccessful() == false) { if(log.size() > 0 && log.get(0).isSuccessful() == false) {
saveDownloadStatus(new DownloadStatus(feed, saveDownloadStatus(new DownloadStatus(feed,
feed.getHumanReadableIdentifier(), DownloadError.SUCCESS, successful, feed.getHumanReadableIdentifier(), DownloadError.SUCCESS, successful,
@ -1011,17 +1010,17 @@ public class DownloadService extends Service {
@Override @Override
public void run() { public void run() {
if(request.getFeedfileType() == Feed.FEEDFILETYPE_FEED) { if(request.getFeedfileType() == Feed.FEEDFILETYPE_FEED) {
DBWriter.setFeedLastUpdateFailed(DownloadService.this, request.getFeedfileId(), true); DBWriter.setFeedLastUpdateFailed(request.getFeedfileId(), true);
} else if (request.isDeleteOnFailure()) { } else if (request.isDeleteOnFailure()) {
Log.d(TAG, "Ignoring failed download, deleteOnFailure=true"); Log.d(TAG, "Ignoring failed download, deleteOnFailure=true");
} else { } else {
File dest = new File(request.getDestination()); File dest = new File(request.getDestination());
if (dest.exists() && request.getFeedfileType() == FeedMedia.FEEDFILETYPE_FEEDMEDIA) { if (dest.exists() && request.getFeedfileType() == FeedMedia.FEEDFILETYPE_FEEDMEDIA) {
Log.d(TAG, "File has been partially downloaded. Writing file url"); Log.d(TAG, "File has been partially downloaded. Writing file url");
FeedMedia media = DBReader.getFeedMedia(DownloadService.this, request.getFeedfileId()); FeedMedia media = DBReader.getFeedMedia(request.getFeedfileId());
media.setFile_url(request.getDestination()); media.setFile_url(request.getDestination());
try { try {
DBWriter.setFeedMedia(DownloadService.this, media).get(); DBWriter.setFeedMedia(media).get();
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
} catch (ExecutionException e) { } catch (ExecutionException e) {
@ -1050,7 +1049,7 @@ public class DownloadService extends Service {
@Override @Override
public void run() { public void run() {
FeedImage image = DBReader.getFeedImage(DownloadService.this, request.getFeedfileId()); FeedImage image = DBReader.getFeedImage(request.getFeedfileId());
if (image == null) { if (image == null) {
throw new IllegalStateException("Could not find downloaded image in database"); throw new IllegalStateException("Could not find downloaded image in database");
} }
@ -1060,7 +1059,7 @@ public class DownloadService extends Service {
saveDownloadStatus(status); saveDownloadStatus(status);
sendDownloadHandledIntent(); sendDownloadHandledIntent();
DBWriter.setFeedImage(DownloadService.this, image); DBWriter.setFeedImage(image);
numberOfDownloads.decrementAndGet(); numberOfDownloads.decrementAndGet();
queryDownloadsAsync(); queryDownloadsAsync();
} }
@ -1084,7 +1083,7 @@ public class DownloadService extends Service {
@Override @Override
public void run() { public void run() {
FeedMedia media = DBReader.getFeedMedia(DownloadService.this, FeedMedia media = DBReader.getFeedMedia(
request.getFeedfileId()); request.getFeedfileId());
if (media == null) { if (media == null) {
throw new IllegalStateException( throw new IllegalStateException(
@ -1126,9 +1125,9 @@ public class DownloadService extends Service {
item.setAutoDownload(false); item.setAutoDownload(false);
// update the db // update the db
DBWriter.setFeedItem(DownloadService.this, item).get(); DBWriter.setFeedItem(item).get();
DBWriter.setFeedMedia(DownloadService.this, media).get(); DBWriter.setFeedMedia(media).get();
if (!DBTasks.isInQueue(DownloadService.this, item.getId())) { if (!DBTasks.isInQueue(DownloadService.this, item.getId())) {
DBWriter.addQueueItem(DownloadService.this, item.getId()).get(); DBWriter.addQueueItem(DownloadService.this, item.getId()).get();
} }

View File

@ -1,12 +1,15 @@
package de.danoeh.antennapod.core.service.download; package de.danoeh.antennapod.core.service.download;
import android.database.Cursor;
import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.Validate;
import de.danoeh.antennapod.core.feed.FeedFile;
import de.danoeh.antennapod.core.util.DownloadError;
import java.util.Date; import java.util.Date;
import de.danoeh.antennapod.core.feed.FeedFile;
import de.danoeh.antennapod.core.storage.PodDBAdapter;
import de.danoeh.antennapod.core.util.DownloadError;
/** Contains status attributes for one download */ /** Contains status attributes for one download */
public class DownloadStatus { public class DownloadStatus {
/** /**
@ -101,6 +104,30 @@ public class DownloadStatus {
this.reasonDetailed = reasonDetailed; this.reasonDetailed = reasonDetailed;
} }
public static DownloadStatus fromCursor(Cursor cursor) {
int indexId = cursor.getColumnIndex(PodDBAdapter.KEY_ID);
int indexTitle = cursor.getColumnIndex(PodDBAdapter.KEY_DOWNLOADSTATUS_TITLE);
int indexFeedFile = cursor.getColumnIndex(PodDBAdapter.KEY_FEEDFILE);
int indexFileFileType = cursor.getColumnIndex(PodDBAdapter.KEY_FEEDFILETYPE);
int indexSuccessful = cursor.getColumnIndex(PodDBAdapter.KEY_SUCCESSFUL);
int indexReason = cursor.getColumnIndex(PodDBAdapter.KEY_REASON);
int indexCompletionDate = cursor.getColumnIndex(PodDBAdapter.KEY_COMPLETION_DATE);
int indexReasonDetailed = cursor.getColumnIndex(PodDBAdapter.KEY_REASON_DETAILED);
long id = cursor.getLong(indexId);
String title = cursor.getString(indexTitle);
long feedfileId = cursor.getLong(indexFeedFile);
int feedfileType = cursor.getInt(indexFileFileType);
boolean successful = cursor.getInt(indexSuccessful) > 0;
int reason = cursor.getInt(indexReason);
Date completionDate = new Date(cursor.getLong(indexCompletionDate));
String reasonDetailed = cursor.getString(indexReasonDetailed);
return new DownloadStatus(id, title, feedfileId,
feedfileType, successful, DownloadError.fromCode(reason), completionDate,
reasonDetailed);
}
@Override @Override
public String toString() { public String toString() {
return "DownloadStatus [id=" + id + ", title=" + title + ", reason=" return "DownloadStatus [id=" + id + ", title=" + title + ", reason="

View File

@ -564,7 +564,7 @@ public class PlaybackService extends Service {
if (playable instanceof FeedMedia) { if (playable instanceof FeedMedia) {
FeedMedia media = (FeedMedia) playable; FeedMedia media = (FeedMedia) playable;
FeedItem item = media.getItem(); FeedItem item = media.getItem();
DBWriter.markItemPlayed(PlaybackService.this, item, FeedItem.PLAYED, true); DBWriter.markItemPlayed(item, FeedItem.PLAYED, true);
try { try {
final List<FeedItem> queue = taskManager.getQueue(); final List<FeedItem> queue = taskManager.getQueue();
@ -577,7 +577,7 @@ public class PlaybackService extends Service {
if (isInQueue) { if (isInQueue) {
DBWriter.removeQueueItem(PlaybackService.this, item, true); DBWriter.removeQueueItem(PlaybackService.this, item, true);
} }
DBWriter.addItemToPlaybackHistory(PlaybackService.this, media); DBWriter.addItemToPlaybackHistory(media);
// auto-flattr if enabled // auto-flattr if enabled
if (isAutoFlattrable(media) && UserPreferences.getAutoFlattrPlayedDurationThreshold() == 1.0f) { if (isAutoFlattrable(media) && UserPreferences.getAutoFlattrPlayedDurationThreshold() == 1.0f) {

View File

@ -201,9 +201,9 @@ public class PlaybackServiceMediaPlayer {
if(oldMedia.hasAlmostEnded()) { if(oldMedia.hasAlmostEnded()) {
Log.d(TAG, "smart mark as read"); Log.d(TAG, "smart mark as read");
FeedItem item = oldMedia.getItem(); FeedItem item = oldMedia.getItem();
DBWriter.markItemPlayed(context, item, FeedItem.PLAYED, false); DBWriter.markItemPlayed(item, FeedItem.PLAYED, false);
DBWriter.removeQueueItem(context, item, false); DBWriter.removeQueueItem(context, item, false);
DBWriter.addItemToPlaybackHistory(context, oldMedia); DBWriter.addItemToPlaybackHistory(oldMedia);
if (item.getFeed().getPreferences().getCurrentAutoDelete()) { if (item.getFeed().getPreferences().getCurrentAutoDelete()) {
Log.d(TAG, "Delete " + oldMedia.toString()); Log.d(TAG, "Delete " + oldMedia.toString());
DBWriter.deleteFeedMediaOfItem(context, oldMedia.getId()); DBWriter.deleteFeedMediaOfItem(context, oldMedia.getId());

View File

@ -100,7 +100,7 @@ public class PlaybackServiceTaskManager {
queueFuture = schedExecutor.submit(new Callable<List<FeedItem>>() { queueFuture = schedExecutor.submit(new Callable<List<FeedItem>>() {
@Override @Override
public List<FeedItem> call() throws Exception { public List<FeedItem> call() throws Exception {
return DBReader.getQueue(context); return DBReader.getQueue();
} }
}); });
} }

View File

@ -5,7 +5,6 @@ import android.util.Log;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
@ -18,13 +17,14 @@ import de.danoeh.antennapod.core.util.LongList;
* Implementation of the EpisodeCleanupAlgorithm interface used by AntennaPod. * Implementation of the EpisodeCleanupAlgorithm interface used by AntennaPod.
*/ */
public class APCleanupAlgorithm implements EpisodeCleanupAlgorithm<Integer> { public class APCleanupAlgorithm implements EpisodeCleanupAlgorithm<Integer> {
private static final String TAG = "APCleanupAlgorithm"; private static final String TAG = "APCleanupAlgorithm";
@Override @Override
public int performCleanup(Context context, Integer episodeNumber) { public int performCleanup(Context context, Integer episodeNumber) {
List<FeedItem> candidates = new ArrayList<FeedItem>(); List<FeedItem> candidates = new ArrayList<>();
List<FeedItem> downloadedItems = DBReader.getDownloadedItems(context); List<FeedItem> downloadedItems = DBReader.getDownloadedItems();
LongList queue = DBReader.getQueueIDList(context); LongList queue = DBReader.getQueueIDList();
List<FeedItem> delete; List<FeedItem> delete;
for (FeedItem item : downloadedItems) { for (FeedItem item : downloadedItems) {
if (item.hasMedia() && item.getMedia().isDownloaded() if (item.hasMedia() && item.getMedia().isDownloaded()
@ -34,9 +34,7 @@ public class APCleanupAlgorithm implements EpisodeCleanupAlgorithm<Integer> {
} }
Collections.sort(candidates, new Comparator<FeedItem>() { Collections.sort(candidates, (lhs, rhs) -> {
@Override
public int compare(FeedItem lhs, FeedItem rhs) {
Date l = lhs.getMedia().getPlaybackCompletionDate(); Date l = lhs.getMedia().getPlaybackCompletionDate();
Date r = rhs.getMedia().getPlaybackCompletionDate(); Date r = rhs.getMedia().getPlaybackCompletionDate();
@ -47,7 +45,6 @@ public class APCleanupAlgorithm implements EpisodeCleanupAlgorithm<Integer> {
r = new Date(); r = new Date();
} }
return l.compareTo(r); return l.compareTo(r);
}
}); });
if (candidates.size() > episodeNumber) { if (candidates.size() > episodeNumber) {
@ -75,22 +72,21 @@ public class APCleanupAlgorithm implements EpisodeCleanupAlgorithm<Integer> {
} }
@Override @Override
public Integer getDefaultCleanupParameter(Context context) { public Integer getDefaultCleanupParameter() {
return getPerformAutoCleanupArgs(context, 0); return getPerformAutoCleanupArgs(0);
} }
@Override @Override
public Integer getPerformCleanupParameter(Context context, List<FeedItem> items) { public Integer getPerformCleanupParameter(List<FeedItem> items) {
return getPerformAutoCleanupArgs(context, items.size()); return getPerformAutoCleanupArgs(items.size());
} }
static int getPerformAutoCleanupArgs(Context context, static int getPerformAutoCleanupArgs(final int episodeNumber) {
final int episodeNumber) {
if (episodeNumber >= 0 if (episodeNumber >= 0
&& UserPreferences.getEpisodeCacheSize() != UserPreferences && UserPreferences.getEpisodeCacheSize() != UserPreferences
.getEpisodeCacheSizeUnlimited()) { .getEpisodeCacheSizeUnlimited()) {
int downloadedEpisodes = DBReader int downloadedEpisodes = DBReader
.getNumberOfDownloadedEpisodes(context); .getNumberOfDownloadedEpisodes();
if (downloadedEpisodes + episodeNumber >= UserPreferences if (downloadedEpisodes + episodeNumber >= UserPreferences
.getEpisodeCacheSize()) { .getEpisodeCacheSize()) {

View File

@ -51,8 +51,8 @@ public class APDownloadAlgorithm implements AutomaticDownloadAlgorithm {
Log.d(TAG, "Performing auto-dl of undownloaded episodes"); Log.d(TAG, "Performing auto-dl of undownloaded episodes");
List<FeedItem> candidates; List<FeedItem> candidates;
final List<FeedItem> queue = DBReader.getQueue(context); final List<FeedItem> queue = DBReader.getQueue();
final List<FeedItem> newItems = DBReader.getNewItemsList(context); final List<FeedItem> newItems = DBReader.getNewItemsList();
candidates = new ArrayList<FeedItem>(queue.size() + newItems.size()); candidates = new ArrayList<FeedItem>(queue.size() + newItems.size());
candidates.addAll(queue); candidates.addAll(queue);
for(FeedItem newItem : newItems) { for(FeedItem newItem : newItems) {
@ -71,9 +71,9 @@ public class APDownloadAlgorithm implements AutomaticDownloadAlgorithm {
} }
int autoDownloadableEpisodes = candidates.size(); int autoDownloadableEpisodes = candidates.size();
int downloadedEpisodes = DBReader.getNumberOfDownloadedEpisodes(context); int downloadedEpisodes = DBReader.getNumberOfDownloadedEpisodes();
int deletedEpisodes = cleanupAlgorithm.performCleanup(context, int deletedEpisodes = cleanupAlgorithm.performCleanup(context,
APCleanupAlgorithm.getPerformAutoCleanupArgs(context, autoDownloadableEpisodes)); APCleanupAlgorithm.getPerformAutoCleanupArgs(autoDownloadableEpisodes));
boolean cacheIsUnlimited = UserPreferences.getEpisodeCacheSize() == UserPreferences boolean cacheIsUnlimited = UserPreferences.getEpisodeCacheSize() == UserPreferences
.getEpisodeCacheSizeUnlimited(); .getEpisodeCacheSizeUnlimited();
int episodeCacheSize = UserPreferences.getEpisodeCacheSize(); int episodeCacheSize = UserPreferences.getEpisodeCacheSize();

View File

@ -68,7 +68,7 @@ public final class DBTasks {
* @param downloadUrl URL of the feed. * @param downloadUrl URL of the feed.
*/ */
public static void removeFeedWithDownloadUrl(Context context, String downloadUrl) { public static void removeFeedWithDownloadUrl(Context context, String downloadUrl) {
PodDBAdapter adapter = new PodDBAdapter(context); PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
Cursor cursor = adapter.getFeedCursorDownloadUrls(); Cursor cursor = adapter.getFeedCursorDownloadUrls();
long feedID = 0; long feedID = 0;
@ -163,7 +163,7 @@ public final class DBTasks {
if (feeds != null) { if (feeds != null) {
refreshFeeds(context, feeds); refreshFeeds(context, feeds);
} else { } else {
refreshFeeds(context, DBReader.getFeedList(context)); refreshFeeds(context, DBReader.getFeedList());
} }
isRefreshing.set(false); isRefreshing.set(false);
@ -196,7 +196,6 @@ public final class DBTasks {
} catch (DownloadRequestException e) { } catch (DownloadRequestException e) {
e.printStackTrace(); e.printStackTrace();
DBWriter.addDownloadStatus( DBWriter.addDownloadStatus(
context,
new DownloadStatus(feed, feed new DownloadStatus(feed, feed
.getHumanReadableIdentifier(), .getHumanReadableIdentifier(),
DownloadError.ERROR_REQUEST_ERROR, false, e DownloadError.ERROR_REQUEST_ERROR, false, e
@ -220,7 +219,6 @@ public final class DBTasks {
} catch (DownloadRequestException e) { } catch (DownloadRequestException e) {
e.printStackTrace(); e.printStackTrace();
DBWriter.addDownloadStatus( DBWriter.addDownloadStatus(
context,
new DownloadStatus(feed, feed new DownloadStatus(feed, feed
.getHumanReadableIdentifier(), .getHumanReadableIdentifier(),
DownloadError.ERROR_REQUEST_ERROR, false, e DownloadError.ERROR_REQUEST_ERROR, false, e
@ -287,7 +285,7 @@ public final class DBTasks {
"The feedmanager was notified about a missing episode. It will update its database now."); "The feedmanager was notified about a missing episode. It will update its database now.");
media.setDownloaded(false); media.setDownloaded(false);
media.setFile_url(null); media.setFile_url(null);
DBWriter.setFeedMedia(context, media); DBWriter.setFeedMedia(media);
EventDistributor.getInstance().sendFeedUpdateBroadcast(); EventDistributor.getInstance().sendFeedUpdateBroadcast();
} }
@ -299,7 +297,7 @@ public final class DBTasks {
public static void downloadAllItemsInQueue(final Context context) { public static void downloadAllItemsInQueue(final Context context) {
new Thread() { new Thread() {
public void run() { public void run() {
List<FeedItem> queue = DBReader.getQueue(context); List<FeedItem> queue = DBReader.getQueue();
if (!queue.isEmpty()) { if (!queue.isEmpty()) {
try { try {
downloadFeedItems(context, downloadFeedItems(context,
@ -336,7 +334,7 @@ public final class DBTasks {
ClientConfig.dbTasksCallbacks.getEpisodeCacheCleanupAlgorithm() ClientConfig.dbTasksCallbacks.getEpisodeCacheCleanupAlgorithm()
.performCleanup(context, .performCleanup(context,
ClientConfig.dbTasksCallbacks.getEpisodeCacheCleanupAlgorithm() ClientConfig.dbTasksCallbacks.getEpisodeCacheCleanupAlgorithm()
.getPerformCleanupParameter(context, Arrays.asList(items))); .getPerformCleanupParameter(Arrays.asList(items)));
} }
}.start(); }.start();
@ -350,7 +348,7 @@ public final class DBTasks {
requester.downloadMedia(context, item.getMedia()); requester.downloadMedia(context, item.getMedia());
} catch (DownloadRequestException e) { } catch (DownloadRequestException e) {
e.printStackTrace(); e.printStackTrace();
DBWriter.addDownloadStatus(context, DBWriter.addDownloadStatus(
new DownloadStatus(item.getMedia(), item new DownloadStatus(item.getMedia(), item
.getMedia() .getMedia()
.getHumanReadableIdentifier(), .getHumanReadableIdentifier(),
@ -393,7 +391,7 @@ public final class DBTasks {
*/ */
public static void performAutoCleanup(final Context context) { public static void performAutoCleanup(final Context context) {
ClientConfig.dbTasksCallbacks.getEpisodeCacheCleanupAlgorithm().performCleanup(context, ClientConfig.dbTasksCallbacks.getEpisodeCacheCleanupAlgorithm().performCleanup(context,
ClientConfig.dbTasksCallbacks.getEpisodeCacheCleanupAlgorithm().getDefaultCleanupParameter(context)); ClientConfig.dbTasksCallbacks.getEpisodeCacheCleanupAlgorithm().getDefaultCleanupParameter());
} }
/** /**
@ -409,7 +407,7 @@ public final class DBTasks {
final long itemId, List<FeedItem> queue) { final long itemId, List<FeedItem> queue) {
FeedItem result = null; FeedItem result = null;
if (queue == null) { if (queue == null) {
queue = DBReader.getQueue(context); queue = DBReader.getQueue();
} }
if (queue != null) { if (queue != null) {
Iterator<FeedItem> iterator = queue.iterator(); Iterator<FeedItem> iterator = queue.iterator();
@ -434,19 +432,19 @@ public final class DBTasks {
* @param feedItemId ID of the FeedItem * @param feedItemId ID of the FeedItem
*/ */
public static boolean isInQueue(Context context, final long feedItemId) { public static boolean isInQueue(Context context, final long feedItemId) {
LongList queue = DBReader.getQueueIDList(context); LongList queue = DBReader.getQueueIDList();
return queue.contains(feedItemId); return queue.contains(feedItemId);
} }
private static Feed searchFeedByIdentifyingValueOrID(Context context, PodDBAdapter adapter, private static Feed searchFeedByIdentifyingValueOrID(Context context, PodDBAdapter adapter,
Feed feed) { Feed feed) {
if (feed.getId() != 0) { if (feed.getId() != 0) {
return DBReader.getFeed(context, feed.getId(), adapter); return DBReader.getFeed(feed.getId(), adapter);
} else { } else {
List<Feed> feeds = DBReader.getFeedList(context); List<Feed> feeds = DBReader.getFeedList();
for (Feed f : feeds) { for (Feed f : feeds) {
if (f.getIdentifyingValue().equals(feed.getIdentifyingValue())) { if (f.getIdentifyingValue().equals(feed.getIdentifyingValue())) {
f.setItems(DBReader.getFeedItemList(context, f)); f.setItems(DBReader.getFeedItemList(f));
return f; return f;
} }
} }
@ -485,7 +483,7 @@ public final class DBTasks {
List<Feed> newFeedsList = new ArrayList<Feed>(); List<Feed> newFeedsList = new ArrayList<Feed>();
List<Feed> updatedFeedsList = new ArrayList<Feed>(); List<Feed> updatedFeedsList = new ArrayList<Feed>();
Feed[] resultFeeds = new Feed[newFeeds.length]; Feed[] resultFeeds = new Feed[newFeeds.length];
PodDBAdapter adapter = new PodDBAdapter(context); PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
for (int feedIdx = 0; feedIdx < newFeeds.length; feedIdx++) { for (int feedIdx = 0; feedIdx < newFeeds.length; feedIdx++) {
@ -574,7 +572,7 @@ public final class DBTasks {
try { try {
DBWriter.addNewFeed(context, newFeedsList.toArray(new Feed[newFeedsList.size()])).get(); DBWriter.addNewFeed(context, newFeedsList.toArray(new Feed[newFeedsList.size()])).get();
DBWriter.setCompleteFeed(context, updatedFeedsList.toArray(new Feed[updatedFeedsList.size()])).get(); DBWriter.setCompleteFeed(updatedFeedsList.toArray(new Feed[updatedFeedsList.size()])).get();
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
} catch (ExecutionException e) { } catch (ExecutionException e) {
@ -602,8 +600,8 @@ public final class DBTasks {
public void execute(PodDBAdapter adapter) { public void execute(PodDBAdapter adapter) {
Cursor searchResult = adapter.searchItemTitles(feedID, Cursor searchResult = adapter.searchItemTitles(feedID,
query); query);
List<FeedItem> items = DBReader.extractItemlistFromCursor(context, searchResult); List<FeedItem> items = DBReader.extractItemlistFromCursor(searchResult);
DBReader.loadFeedDataOfFeedItemlist(context, items); DBReader.loadFeedDataOfFeedItemlist(items);
setResult(items); setResult(items);
searchResult.close(); searchResult.close();
} }
@ -626,8 +624,8 @@ public final class DBTasks {
public void execute(PodDBAdapter adapter) { public void execute(PodDBAdapter adapter) {
Cursor searchResult = adapter.searchItemDescriptions(feedID, Cursor searchResult = adapter.searchItemDescriptions(feedID,
query); query);
List<FeedItem> items = DBReader.extractItemlistFromCursor(context, searchResult); List<FeedItem> items = DBReader.extractItemlistFromCursor(searchResult);
DBReader.loadFeedDataOfFeedItemlist(context, items); DBReader.loadFeedDataOfFeedItemlist(items);
setResult(items); setResult(items);
searchResult.close(); searchResult.close();
} }
@ -650,8 +648,8 @@ public final class DBTasks {
public void execute(PodDBAdapter adapter) { public void execute(PodDBAdapter adapter) {
Cursor searchResult = adapter.searchItemContentEncoded(feedID, Cursor searchResult = adapter.searchItemContentEncoded(feedID,
query); query);
List<FeedItem> items = DBReader.extractItemlistFromCursor(context, searchResult); List<FeedItem> items = DBReader.extractItemlistFromCursor(searchResult);
DBReader.loadFeedDataOfFeedItemlist(context, items); DBReader.loadFeedDataOfFeedItemlist(items);
setResult(items); setResult(items);
searchResult.close(); searchResult.close();
} }
@ -673,8 +671,8 @@ public final class DBTasks {
public void execute(PodDBAdapter adapter) { public void execute(PodDBAdapter adapter) {
Cursor searchResult = adapter.searchItemChapters(feedID, Cursor searchResult = adapter.searchItemChapters(feedID,
query); query);
List<FeedItem> items = DBReader.extractItemlistFromCursor(context, searchResult); List<FeedItem> items = DBReader.extractItemlistFromCursor(searchResult);
DBReader.loadFeedDataOfFeedItemlist(context, items); DBReader.loadFeedDataOfFeedItemlist(items);
setResult(items); setResult(items);
searchResult.close(); searchResult.close();
} }
@ -697,7 +695,7 @@ public final class DBTasks {
@Override @Override
public T call() throws Exception { public T call() throws Exception {
PodDBAdapter adapter = new PodDBAdapter(context); PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
execute(adapter); execute(adapter);
adapter.close(); adapter.close();

View File

@ -22,7 +22,6 @@ import java.util.Map;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.Future; import java.util.concurrent.Future;
import java.util.concurrent.ThreadFactory;
import de.danoeh.antennapod.core.BuildConfig; import de.danoeh.antennapod.core.BuildConfig;
import de.danoeh.antennapod.core.ClientConfig; import de.danoeh.antennapod.core.ClientConfig;
@ -56,19 +55,16 @@ import de.greenrobot.event.EventBus;
* This class will use the {@link EventDistributor} to notify listeners about changes in the database. * This class will use the {@link EventDistributor} to notify listeners about changes in the database.
*/ */
public class DBWriter { public class DBWriter {
private static final String TAG = "DBWriter"; private static final String TAG = "DBWriter";
private static final ExecutorService dbExec; private static final ExecutorService dbExec;
static { static {
dbExec = Executors.newSingleThreadExecutor(new ThreadFactory() { dbExec = Executors.newSingleThreadExecutor(r -> {
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r); Thread t = new Thread(r);
t.setPriority(Thread.MIN_PRIORITY); t.setPriority(Thread.MIN_PRIORITY);
return t; return t;
}
}); });
} }
@ -83,11 +79,8 @@ public class DBWriter {
*/ */
public static Future<?> deleteFeedMediaOfItem(final Context context, public static Future<?> deleteFeedMediaOfItem(final Context context,
final long mediaId) { final long mediaId) {
return dbExec.submit(new Runnable() { return dbExec.submit(() -> {
@Override final FeedMedia media = DBReader.getFeedMedia(mediaId);
public void run() {
final FeedMedia media = DBReader.getFeedMedia(context, mediaId);
if (media != null) { if (media != null) {
Log.i(TAG, String.format("Requested to delete FeedMedia [id=%d, title=%s, downloaded=%s", Log.i(TAG, String.format("Requested to delete FeedMedia [id=%d, title=%s, downloaded=%s",
media.getId(), media.getEpisodeTitle(), String.valueOf(media.isDownloaded()))); media.getId(), media.getEpisodeTitle(), String.valueOf(media.isDownloaded())));
@ -101,7 +94,7 @@ public class DBWriter {
media.setDownloaded(false); media.setDownloaded(false);
media.setFile_url(null); media.setFile_url(null);
media.setHasEmbeddedPicture(false); media.setHasEmbeddedPicture(false);
PodDBAdapter adapter = new PodDBAdapter(context); PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
adapter.setMedia(media); adapter.setMedia(media);
adapter.close(); adapter.close();
@ -140,7 +133,6 @@ public class DBWriter {
EventBus.getDefault().post(new QueueEvent(QueueEvent.Action.DELETED_MEDIA, media.getItem())); EventBus.getDefault().post(new QueueEvent(QueueEvent.Action.DELETED_MEDIA, media.getItem()));
EventDistributor.getInstance().sendUnreadItemsUpdateBroadcast(); EventDistributor.getInstance().sendUnreadItemsUpdateBroadcast();
} }
}
}); });
} }
@ -151,14 +143,13 @@ public class DBWriter {
* @param feedId ID of the Feed that should be deleted. * @param feedId ID of the Feed that should be deleted.
*/ */
public static Future<?> deleteFeed(final Context context, final long feedId) { public static Future<?> deleteFeed(final Context context, final long feedId) {
return dbExec.submit(new Runnable() { return dbExec.submit(() -> {
@Override
public void run() {
DownloadRequester requester = DownloadRequester.getInstance(); DownloadRequester requester = DownloadRequester.getInstance();
SharedPreferences prefs = PreferenceManager SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(context .getDefaultSharedPreferences(context
.getApplicationContext()); .getApplicationContext());
final Feed feed = DBReader.getFeed(context, feedId); final Feed feed = DBReader.getFeed(feedId);
if (feed != null) { if (feed != null) {
if (PlaybackPreferences.getCurrentlyPlayingMedia() == FeedMedia.PLAYABLE_TYPE_FEEDMEDIA if (PlaybackPreferences.getCurrentlyPlayingMedia() == FeedMedia.PLAYABLE_TYPE_FEEDMEDIA
&& PlaybackPreferences.getLastPlayedFeedId() == feed && PlaybackPreferences.getLastPlayedFeedId() == feed
@ -184,10 +175,10 @@ public class DBWriter {
} }
} }
// delete stored media files and mark them as read // delete stored media files and mark them as read
List<FeedItem> queue = DBReader.getQueue(context); List<FeedItem> queue = DBReader.getQueue();
List<FeedItem> removed = new ArrayList<>(); List<FeedItem> removed = new ArrayList<>();
if (feed.getItems() == null) { if (feed.getItems() == null) {
DBReader.getFeedItemList(context, feed); DBReader.getFeedItemList(feed);
} }
for (FeedItem item : feed.getItems()) { for (FeedItem item : feed.getItems()) {
@ -214,7 +205,7 @@ public class DBWriter {
} }
} }
} }
PodDBAdapter adapter = new PodDBAdapter(context); PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
if (removed.size() > 0) { if (removed.size() > 0) {
adapter.setQueue(queue); adapter.setQueue(queue);
@ -232,46 +223,33 @@ public class DBWriter {
BackupManager backupManager = new BackupManager(context); BackupManager backupManager = new BackupManager(context);
backupManager.dataChanged(); backupManager.dataChanged();
} }
}
}); });
} }
/** /**
* Deletes the entire playback history. * Deletes the entire playback history.
* *
* @param context A context that is used for opening a database connection.
*/ */
public static Future<?> clearPlaybackHistory(final Context context) { public static Future<?> clearPlaybackHistory() {
return dbExec.submit(new Runnable() { return dbExec.submit(() -> {
PodDBAdapter adapter = PodDBAdapter.getInstance();
@Override
public void run() {
PodDBAdapter adapter = new PodDBAdapter(context);
adapter.open(); adapter.open();
adapter.clearPlaybackHistory(); adapter.clearPlaybackHistory();
adapter.close(); adapter.close();
EventDistributor.getInstance() EventDistributor.getInstance().sendPlaybackHistoryUpdateBroadcast();
.sendPlaybackHistoryUpdateBroadcast();
}
}); });
} }
/** /**
* Deletes the entire download log. * Deletes the entire download log.
*
* @param context A context that is used for opening a database connection.
*/ */
public static Future<?> clearDownloadLog(final Context context) { public static Future<?> clearDownloadLog() {
return dbExec.submit(new Runnable() { return dbExec.submit(() -> {
@Override PodDBAdapter adapter = PodDBAdapter.getInstance();
public void run() {
PodDBAdapter adapter = new PodDBAdapter(context);
adapter.open(); adapter.open();
adapter.clearDownloadLog(); adapter.clearDownloadLog();
adapter.close(); adapter.close();
EventDistributor.getInstance() EventDistributor.getInstance().sendDownloadLogUpdateBroadcast();
.sendDownloadLogUpdateBroadcast();
}
}); });
} }
@ -281,58 +259,36 @@ public class DBWriter {
* its playback completion date is set to a non-null value. This method will set the playback completion date to the * its playback completion date is set to a non-null value. This method will set the playback completion date to the
* current date regardless of the current value. * current date regardless of the current value.
* *
* @param context A context that is used for opening a database connection.
* @param media FeedMedia that should be added to the playback history. * @param media FeedMedia that should be added to the playback history.
*/ */
public static Future<?> addItemToPlaybackHistory(final Context context, public static Future<?> addItemToPlaybackHistory(final FeedMedia media) {
final FeedMedia media) { return dbExec.submit(() -> {
return dbExec.submit(new Runnable() {
@Override
public void run() {
if (BuildConfig.DEBUG)
Log.d(TAG, "Adding new item to playback history"); Log.d(TAG, "Adding new item to playback history");
media.setPlaybackCompletionDate(new Date()); media.setPlaybackCompletionDate(new Date());
// reset played_duration to 0 so that it behaves correctly when the episode is played again // reset played_duration to 0 so that it behaves correctly when the episode is played again
media.setPlayedDuration(0); media.setPlayedDuration(0);
PodDBAdapter adapter = new PodDBAdapter(context); PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
adapter.setFeedMediaPlaybackCompletionDate(media); adapter.setFeedMediaPlaybackCompletionDate(media);
adapter.close(); adapter.close();
EventDistributor.getInstance().sendPlaybackHistoryUpdateBroadcast(); EventDistributor.getInstance().sendPlaybackHistoryUpdateBroadcast();
}
}); });
} }
private static void cleanupDownloadLog(final PodDBAdapter adapter) {
final long logSize = adapter.getDownloadLogSize();
if (logSize > DBReader.DOWNLOAD_LOG_SIZE) {
if (BuildConfig.DEBUG)
Log.d(TAG, "Cleaning up download log");
adapter.removeDownloadLogItems(logSize - DBReader.DOWNLOAD_LOG_SIZE);
}
}
/** /**
* Adds a Download status object to the download log. * Adds a Download status object to the download log.
* *
* @param context A context that is used for opening a database connection.
* @param status The DownloadStatus object. * @param status The DownloadStatus object.
*/ */
public static Future<?> addDownloadStatus(final Context context, public static Future<?> addDownloadStatus(final DownloadStatus status) {
final DownloadStatus status) { return dbExec.submit(() -> {
return dbExec.submit(new Runnable() { PodDBAdapter adapter = PodDBAdapter.getInstance();
@Override
public void run() {
PodDBAdapter adapter = new PodDBAdapter(context);
adapter.open(); adapter.open();
adapter.setDownloadStatus(status); adapter.setDownloadStatus(status);
adapter.close(); adapter.close();
EventDistributor.getInstance().sendDownloadLogUpdateBroadcast(); EventDistributor.getInstance().sendDownloadLogUpdateBroadcast();
}
}); });
} }
@ -349,24 +305,21 @@ public class DBWriter {
*/ */
public static Future<?> addQueueItemAt(final Context context, final long itemId, public static Future<?> addQueueItemAt(final Context context, final long itemId,
final int index, final boolean performAutoDownload) { final int index, final boolean performAutoDownload) {
return dbExec.submit(new Runnable() { return dbExec.submit(() -> {
final PodDBAdapter adapter = PodDBAdapter.getInstance();
@Override
public void run() {
final PodDBAdapter adapter = new PodDBAdapter(context);
adapter.open(); adapter.open();
final List<FeedItem> queue = DBReader.getQueue(context, adapter); final List<FeedItem> queue = DBReader.getQueue(adapter);
FeedItem item; FeedItem item;
if (queue != null) { if (queue != null) {
if (!itemListContains(queue, itemId)) { if (!itemListContains(queue, itemId)) {
item = DBReader.getFeedItem(context, itemId); item = DBReader.getFeedItem(itemId);
if (item != null) { if (item != null) {
queue.add(index, item); queue.add(index, item);
adapter.setQueue(queue); adapter.setQueue(queue);
EventBus.getDefault().post(new QueueEvent(QueueEvent.Action.ADDED, item, index)); EventBus.getDefault().post(new QueueEvent(QueueEvent.Action.ADDED, item, index));
if(item.isNew()) { if (item.isNew()) {
DBWriter.markItemPlayed(context, FeedItem.UNPLAYED, item.getId()); DBWriter.markItemPlayed(FeedItem.UNPLAYED, item.getId());
} }
} }
} }
@ -377,7 +330,6 @@ public class DBWriter {
DBTasks.autodownloadUndownloadedItems(context); DBTasks.autodownloadUndownloadedItems(context);
} }
}
}); });
} }
@ -397,21 +349,18 @@ public class DBWriter {
*/ */
public static Future<?> addQueueItem(final Context context, final boolean performAutoDownload, public static Future<?> addQueueItem(final Context context, final boolean performAutoDownload,
final long... itemIds) { final long... itemIds) {
return dbExec.submit(new Runnable() { return dbExec.submit(() -> {
@Override
public void run() {
if (itemIds.length > 0) { if (itemIds.length > 0) {
final PodDBAdapter adapter = new PodDBAdapter(context); final PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
final List<FeedItem> queue = DBReader.getQueue(context, adapter); final List<FeedItem> queue = DBReader.getQueue(adapter);
if (queue != null) { if (queue != null) {
boolean queueModified = false; boolean queueModified = false;
LongList markAsUnplayedIds = new LongList(); LongList markAsUnplayedIds = new LongList();
for (int i = 0; i < itemIds.length; i++) { for (int i = 0; i < itemIds.length; i++) {
if (!itemListContains(queue, itemIds[i])) { if (!itemListContains(queue, itemIds[i])) {
final FeedItem item = DBReader.getFeedItem(context, itemIds[i]); final FeedItem item = DBReader.getFeedItem(itemIds[i]);
if (item != null) { if (item != null) {
// add item to either front ot back of queue // add item to either front ot back of queue
@ -432,7 +381,7 @@ public class DBWriter {
adapter.setQueue(queue); adapter.setQueue(queue);
EventBus.getDefault().post(new QueueEvent(QueueEvent.Action.ADDED_ITEMS, queue)); EventBus.getDefault().post(new QueueEvent(QueueEvent.Action.ADDED_ITEMS, queue));
if(markAsUnplayedIds.size() > 0) { if(markAsUnplayedIds.size() > 0) {
DBWriter.markItemPlayed(context, FeedItem.UNPLAYED, markAsUnplayedIds.toArray()); DBWriter.markItemPlayed(FeedItem.UNPLAYED, markAsUnplayedIds.toArray());
} }
} }
} }
@ -441,27 +390,21 @@ public class DBWriter {
DBTasks.autodownloadUndownloadedItems(context); DBTasks.autodownloadUndownloadedItems(context);
} }
} }
}
}); });
} }
/** /**
* Removes all FeedItem objects from the queue. * Removes all FeedItem objects from the queue.
* *
* @param context A context that is used for opening a database connection.
*/ */
public static Future<?> clearQueue(final Context context) { public static Future<?> clearQueue() {
return dbExec.submit(new Runnable() { return dbExec.submit(() -> {
PodDBAdapter adapter = PodDBAdapter.getInstance();
@Override
public void run() {
PodDBAdapter adapter = new PodDBAdapter(context);
adapter.open(); adapter.open();
adapter.clearQueue(); adapter.clearQueue();
adapter.close(); adapter.close();
EventBus.getDefault().post(new QueueEvent(QueueEvent.Action.CLEARED)); EventBus.getDefault().post(new QueueEvent(QueueEvent.Action.CLEARED));
}
}); });
} }
@ -474,13 +417,10 @@ public class DBWriter {
*/ */
public static Future<?> removeQueueItem(final Context context, public static Future<?> removeQueueItem(final Context context,
final FeedItem item, final boolean performAutoDownload) { final FeedItem item, final boolean performAutoDownload) {
return dbExec.submit(new Runnable() { return dbExec.submit(() -> {
final PodDBAdapter adapter = PodDBAdapter.getInstance();
@Override
public void run() {
final PodDBAdapter adapter = new PodDBAdapter(context);
adapter.open(); adapter.open();
final List<FeedItem> queue = DBReader.getQueue(context, adapter); final List<FeedItem> queue = DBReader.getQueue(adapter);
if (queue != null) { if (queue != null) {
int position = queue.indexOf(item); int position = queue.indexOf(item);
@ -498,77 +438,59 @@ public class DBWriter {
if (performAutoDownload) { if (performAutoDownload) {
DBTasks.autodownloadUndownloadedItems(context); DBTasks.autodownloadUndownloadedItems(context);
} }
}
}); });
} }
/** /**
* Moves the specified item to the top of the queue. * Moves the specified item to the top of the queue.
*
* @param context A context that is used for opening a database connection.
* @param itemId The item to move to the top of the queue * @param itemId The item to move to the top of the queue
* @param broadcastUpdate true if this operation should trigger a QueueUpdateBroadcast. This option should be set to * @param broadcastUpdate true if this operation should trigger a QueueUpdateBroadcast. This option should be set to
* false if the caller wants to avoid unexpected updates of the GUI.
*/ */
public static Future<?> moveQueueItemToTop(final Context context, final long itemId, final boolean broadcastUpdate) { public static Future<?> moveQueueItemToTop(final long itemId, final boolean broadcastUpdate) {
return dbExec.submit(new Runnable() { return dbExec.submit(() -> {
@Override LongList queueIdList = DBReader.getQueueIDList();
public void run() {
LongList queueIdList = DBReader.getQueueIDList(context);
int index = queueIdList.indexOf(itemId); int index = queueIdList.indexOf(itemId);
if (index >=0) { if (index >=0) {
moveQueueItemHelper(context, index, 0, broadcastUpdate); moveQueueItemHelper(index, 0, broadcastUpdate);
} else { } else {
Log.e(TAG, "moveQueueItemToTop: item not found"); Log.e(TAG, "moveQueueItemToTop: item not found");
} }
}
}); });
} }
/** /**
* Moves the specified item to the bottom of the queue. * Moves the specified item to the bottom of the queue.
*
* @param context A context that is used for opening a database connection.
* @param itemId The item to move to the bottom of the queue * @param itemId The item to move to the bottom of the queue
* @param broadcastUpdate true if this operation should trigger a QueueUpdateBroadcast. This option should be set to * @param broadcastUpdate true if this operation should trigger a QueueUpdateBroadcast. This option should be set to
* false if the caller wants to avoid unexpected updates of the GUI.
*/ */
public static Future<?> moveQueueItemToBottom(final Context context, final long itemId, public static Future<?> moveQueueItemToBottom(final long itemId,
final boolean broadcastUpdate) { final boolean broadcastUpdate) {
return dbExec.submit(new Runnable() { return dbExec.submit(() -> {
@Override LongList queueIdList = DBReader.getQueueIDList();
public void run() {
LongList queueIdList = DBReader.getQueueIDList(context);
int index = queueIdList.indexOf(itemId); int index = queueIdList.indexOf(itemId);
if(index >= 0) { if(index >= 0) {
moveQueueItemHelper(context, index, queueIdList.size() - 1, moveQueueItemHelper(index, queueIdList.size() - 1,
broadcastUpdate); broadcastUpdate);
} else { } else {
Log.e(TAG, "moveQueueItemToBottom: item not found"); Log.e(TAG, "moveQueueItemToBottom: item not found");
} }
}
}); });
} }
/** /**
* Changes the position of a FeedItem in the queue. * Changes the position of a FeedItem in the queue.
* *
* @param context A context that is used for opening a database connection.
* @param from Source index. Must be in range 0..queue.size()-1. * @param from Source index. Must be in range 0..queue.size()-1.
* @param to Destination index. Must be in range 0..queue.size()-1. * @param to Destination index. Must be in range 0..queue.size()-1.
* @param broadcastUpdate true if this operation should trigger a QueueUpdateBroadcast. This option should be set to * @param broadcastUpdate true if this operation should trigger a QueueUpdateBroadcast. This option should be set to
* false if the caller wants to avoid unexpected updates of the GUI. * false if the caller wants to avoid unexpected updates of the GUI.
* @throws IndexOutOfBoundsException if (to < 0 || to >= queue.size()) || (from < 0 || from >= queue.size()) * @throws IndexOutOfBoundsException if (to < 0 || to >= queue.size()) || (from < 0 || from >= queue.size())
*/ */
public static Future<?> moveQueueItem(final Context context, final int from, public static Future<?> moveQueueItem(final int from,
final int to, final boolean broadcastUpdate) { final int to, final boolean broadcastUpdate) {
return dbExec.submit(new Runnable() { return dbExec.submit(() -> {
moveQueueItemHelper(from, to, broadcastUpdate);
@Override
public void run() {
moveQueueItemHelper(context, from, to, broadcastUpdate);
}
}); });
} }
@ -577,24 +499,20 @@ public class DBWriter {
* <p/> * <p/>
* This function must be run using the ExecutorService (dbExec). * This function must be run using the ExecutorService (dbExec).
* *
* @param context A context that is used for opening a database connection.
* @param from Source index. Must be in range 0..queue.size()-1. * @param from Source index. Must be in range 0..queue.size()-1.
* @param to Destination index. Must be in range 0..queue.size()-1. * @param to Destination index. Must be in range 0..queue.size()-1.
* @param broadcastUpdate true if this operation should trigger a QueueUpdateBroadcast. This option should be set to * @param broadcastUpdate true if this operation should trigger a QueueUpdateBroadcast. This option should be set to
* false if the caller wants to avoid unexpected updates of the GUI. * false if the caller wants to avoid unexpected updates of the GUI.
* @throws IndexOutOfBoundsException if (to < 0 || to >= queue.size()) || (from < 0 || from >= queue.size()) * @throws IndexOutOfBoundsException if (to < 0 || to >= queue.size()) || (from < 0 || from >= queue.size())
*/ */
private static void moveQueueItemHelper(final Context context, final int from, private static void moveQueueItemHelper(final int from,
final int to, final boolean broadcastUpdate) { final int to, final boolean broadcastUpdate) {
final PodDBAdapter adapter = new PodDBAdapter(context); final PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
final List<FeedItem> queue = DBReader final List<FeedItem> queue = DBReader.getQueue(adapter);
.getQueue(context, adapter);
if (queue != null) { if (queue != null) {
if (from >= 0 && from < queue.size() && to >= 0 if (from >= 0 && from < queue.size() && to >= 0 && to < queue.size()) {
&& to < queue.size()) {
final FeedItem item = queue.remove(from); final FeedItem item = queue.remove(from);
queue.add(to, item); queue.add(to, item);
@ -602,7 +520,6 @@ public class DBWriter {
if (broadcastUpdate) { if (broadcastUpdate) {
EventBus.getDefault().post(new QueueEvent(QueueEvent.Action.MOVED, item, to)); EventBus.getDefault().post(new QueueEvent(QueueEvent.Action.MOVED, item, to));
} }
} }
} else { } else {
Log.e(TAG, "moveQueueItemHelper: Could not load queue"); Log.e(TAG, "moveQueueItemHelper: Could not load queue");
@ -618,9 +535,9 @@ public class DBWriter {
* FeedItem.UNPLAYED * FeedItem.UNPLAYED
* @param itemIds IDs of the FeedItems. * @param itemIds IDs of the FeedItems.
*/ */
public static Future<?> markItemPlayed(final Context context, final int played, final long... itemIds) { public static Future<?> markItemPlayed(final int played, final long... itemIds) {
return dbExec.submit(() -> { return dbExec.submit(() -> {
final PodDBAdapter adapter = new PodDBAdapter(context); final PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
adapter.setFeedItemRead(played, itemIds); adapter.setFeedItemRead(played, itemIds);
adapter.close(); adapter.close();
@ -631,24 +548,22 @@ public class DBWriter {
/** /**
* Sets the 'read'-attribute of a FeedItem to the specified value. * Sets the 'read'-attribute of a FeedItem to the specified value.
*
* @param context A context that is used for opening a database connection.
* @param item The FeedItem object * @param item The FeedItem object
* @param played New value of the 'read'-attribute one of FeedItem.PLAYED, * @param played New value of the 'read'-attribute one of FeedItem.PLAYED,
* FeedItem.NEW, FeedItem.UNPLAYED * FeedItem.NEW, FeedItem.UNPLAYED
* @param resetMediaPosition true if this method should also reset the position of the FeedItem's FeedMedia object. * @param resetMediaPosition true if this method should also reset the position of the FeedItem's FeedMedia object.
* If the FeedItem has no FeedMedia object, this parameter will be ignored.
*/ */
public static Future<?> markItemPlayed(Context context, FeedItem item, int played, boolean resetMediaPosition) { public static Future<?> markItemPlayed(FeedItem item, int played, boolean resetMediaPosition) {
long mediaId = (item.hasMedia()) ? item.getMedia().getId() : 0; long mediaId = (item.hasMedia()) ? item.getMedia().getId() : 0;
return markItemPlayed(context, item.getId(), played, mediaId, resetMediaPosition); return markItemPlayed(item.getId(), played, mediaId, resetMediaPosition);
} }
private static Future<?> markItemPlayed(final Context context, final long itemId, private static Future<?> markItemPlayed(final long itemId,
final int played, final long mediaId, final int played,
final long mediaId,
final boolean resetMediaPosition) { final boolean resetMediaPosition) {
return dbExec.submit(() -> { return dbExec.submit(() -> {
final PodDBAdapter adapter = new PodDBAdapter(context); final PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open(); adapter.open();
adapter.setFeedItemRead(played, itemId, mediaId, adapter.setFeedItemRead(played, itemId, mediaId,
resetMediaPosition); resetMediaPosition);
@ -661,15 +576,11 @@ public class DBWriter {
/** /**
* Sets the 'read'-attribute of all FeedItems of a specific Feed to true. * Sets the 'read'-attribute of all FeedItems of a specific Feed to true.
* *
* @param context A context that is used for opening a database connection.
* @param feedId ID of the Feed. * @param feedId ID of the Feed.
*/ */
public static Future<?> markFeedSeen(final Context context, final long feedId) { public static Future<?> markFeedSeen(final long feedId) {
return dbExec.submit(new Runnable() { return dbExec.submit(() -> {
final PodDBAdapter adapter = PodDBAdapter.getInstance();
@Override
public void run() {
final PodDBAdapter adapter = new PodDBAdapter(context);
adapter.open(); adapter.open();
Cursor itemCursor = adapter.getNewItemsIdsCursor(feedId); Cursor itemCursor = adapter.getNewItemsIdsCursor(feedId);
long[] ids = new long[itemCursor.getCount()]; long[] ids = new long[itemCursor.getCount()];
@ -683,28 +594,24 @@ public class DBWriter {
adapter.close(); adapter.close();
EventDistributor.getInstance().sendUnreadItemsUpdateBroadcast(); EventDistributor.getInstance().sendUnreadItemsUpdateBroadcast();
}
}); });
} }
/** /**
* Sets the 'read'-attribute of all FeedItems of a specific Feed to true. * Sets the 'read'-attribute of all FeedItems of a specific Feed to true.
* *
* @param context A context that is used for opening a database connection.
* @param feedId ID of the Feed. * @param feedId ID of the Feed.
*/ */
public static Future<?> markFeedRead(final Context context, final long feedId) { public static Future<?> markFeedRead(final long feedId) {
return dbExec.submit(new Runnable() { return dbExec.submit(() -> {
final PodDBAdapter adapter = PodDBAdapter.getInstance();
@Override
public void run() {
final PodDBAdapter adapter = new PodDBAdapter(context);
adapter.open(); adapter.open();
Cursor itemCursor = adapter.getAllItemsOfFeedCursor(feedId); Cursor itemCursor = adapter.getAllItemsOfFeedCursor(feedId);
long[] itemIds = new long[itemCursor.getCount()]; long[] itemIds = new long[itemCursor.getCount()];
itemCursor.moveToFirst(); itemCursor.moveToFirst();
for (int i = 0; i < itemIds.length; i++) { for (int i = 0; i < itemIds.length; i++) {
itemIds[i] = itemCursor.getLong(PodDBAdapter.KEY_ID_INDEX); int indexId = itemCursor.getColumnIndex(PodDBAdapter.KEY_ID);
itemIds[i] = itemCursor.getLong(indexId);
itemCursor.moveToNext(); itemCursor.moveToNext();
} }
itemCursor.close(); itemCursor.close();
@ -712,27 +619,22 @@ public class DBWriter {
adapter.close(); adapter.close();
EventDistributor.getInstance().sendUnreadItemsUpdateBroadcast(); EventDistributor.getInstance().sendUnreadItemsUpdateBroadcast();
}
}); });
} }
/** /**
* Sets the 'read'-attribute of all FeedItems to true. * Sets the 'read'-attribute of all FeedItems to true.
*
* @param context A context that is used for opening a database connection.
*/ */
public static Future<?> markAllItemsRead(final Context context) { public static Future<?> markAllItemsRead() {
return dbExec.submit(new Runnable() { return dbExec.submit(() -> {
final PodDBAdapter adapter = PodDBAdapter.getInstance();
@Override
public void run() {
final PodDBAdapter adapter = new PodDBAdapter(context);
adapter.open(); adapter.open();
Cursor itemCursor = adapter.getUnreadItemsCursor(); Cursor itemCursor = adapter.getUnreadItemsCursor();
long[] itemIds = new long[itemCursor.getCount()]; long[] itemIds = new long[itemCursor.getCount()];
itemCursor.moveToFirst(); itemCursor.moveToFirst();
for (int i = 0; i < itemIds.length; i++) { for (int i = 0; i < itemIds.length; i++) {
itemIds[i] = itemCursor.getLong(PodDBAdapter.KEY_ID_INDEX); int indexId = itemCursor.getColumnIndex(PodDBAdapter.KEY_ID);
itemIds[i] = itemCursor.getLong(indexId);
itemCursor.moveToNext(); itemCursor.moveToNext();
} }
itemCursor.close(); itemCursor.close();
@ -740,17 +642,13 @@ public class DBWriter {
adapter.close(); adapter.close();
EventDistributor.getInstance().sendUnreadItemsUpdateBroadcast(); EventDistributor.getInstance().sendUnreadItemsUpdateBroadcast();
}
}); });
} }
static Future<?> addNewFeed(final Context context, final Feed... feeds) { static Future<?> addNewFeed(final Context context, final Feed... feeds) {
return dbExec.submit(new Runnable() { return dbExec.submit(() -> {
final PodDBAdapter adapter = PodDBAdapter.getInstance();
@Override
public void run() {
final PodDBAdapter adapter = new PodDBAdapter(context);
adapter.open(); adapter.open();
adapter.setCompleteFeed(feeds); adapter.setCompleteFeed(feeds);
adapter.close(); adapter.close();
@ -763,61 +661,44 @@ public class DBWriter {
BackupManager backupManager = new BackupManager(context); BackupManager backupManager = new BackupManager(context);
backupManager.dataChanged(); backupManager.dataChanged();
}
}); });
} }
static Future<?> setCompleteFeed(final Context context, final Feed... feeds) { static Future<?> setCompleteFeed(final Feed... feeds) {
return dbExec.submit(new Runnable() { return dbExec.submit(() -> {
PodDBAdapter adapter = PodDBAdapter.getInstance();
@Override
public void run() {
PodDBAdapter adapter = new PodDBAdapter(context);
adapter.open(); adapter.open();
adapter.setCompleteFeed(feeds); adapter.setCompleteFeed(feeds);
adapter.close(); adapter.close();
}
}); });
} }
/** /**
* Saves a FeedMedia object in the database. This method will save all attributes of the FeedMedia object. The * Saves a FeedMedia object in the database. This method will save all attributes of the FeedMedia object. The
* contents of FeedComponent-attributes (e.g. the FeedMedia's 'item'-attribute) will not be saved. * contents of FeedComponent-attributes (e.g. the FeedMedia's 'item'-attribute) will not be saved.
* *
* @param context A context that is used for opening a database connection.
* @param media The FeedMedia object. * @param media The FeedMedia object.
*/ */
public static Future<?> setFeedMedia(final Context context, public static Future<?> setFeedMedia(final FeedMedia media) {
final FeedMedia media) { return dbExec.submit(() -> {
return dbExec.submit(new Runnable() { PodDBAdapter adapter = PodDBAdapter.getInstance();
@Override
public void run() {
PodDBAdapter adapter = new PodDBAdapter(context);
adapter.open(); adapter.open();
adapter.setMedia(media); adapter.setMedia(media);
adapter.close(); adapter.close();
}
}); });
} }
/** /**
* Saves the 'position' and 'duration' attributes of a FeedMedia object * Saves the 'position' and 'duration' attributes of a FeedMedia object
* *
* @param context A context that is used for opening a database connection.
* @param media The FeedMedia object. * @param media The FeedMedia object.
*/ */
public static Future<?> setFeedMediaPlaybackInformation(final Context context, final FeedMedia media) { public static Future<?> setFeedMediaPlaybackInformation(final FeedMedia media) {
return dbExec.submit(new Runnable() { return dbExec.submit(() -> {
@Override PodDBAdapter adapter = PodDBAdapter.getInstance();
public void run() {
PodDBAdapter adapter = new PodDBAdapter(context);
adapter.open(); adapter.open();
adapter.setFeedMediaPlaybackInformation(media); adapter.setFeedMediaPlaybackInformation(media);
adapter.close(); adapter.close();
}
}); });
} }
@ -825,20 +706,14 @@ public class DBWriter {
* Saves a FeedItem object in the database. This method will save all attributes of the FeedItem object including * Saves a FeedItem object in the database. This method will save all attributes of the FeedItem object including
* the content of FeedComponent-attributes. * the content of FeedComponent-attributes.
* *
* @param context A context that is used for opening a database connection.
* @param item The FeedItem object. * @param item The FeedItem object.
*/ */
public static Future<?> setFeedItem(final Context context, public static Future<?> setFeedItem(final FeedItem item) {
final FeedItem item) { return dbExec.submit(() -> {
return dbExec.submit(new Runnable() { PodDBAdapter adapter = PodDBAdapter.getInstance();
@Override
public void run() {
PodDBAdapter adapter = new PodDBAdapter(context);
adapter.open(); adapter.open();
adapter.setSingleFeedItem(item); adapter.setSingleFeedItem(item);
adapter.close(); adapter.close();
}
}); });
} }
@ -846,20 +721,14 @@ public class DBWriter {
* Saves a FeedImage object in the database. This method will save all attributes of the FeedImage object. The * Saves a FeedImage object in the database. This method will save all attributes of the FeedImage object. The
* contents of FeedComponent-attributes (e.g. the FeedImages's 'feed'-attribute) will not be saved. * contents of FeedComponent-attributes (e.g. the FeedImages's 'feed'-attribute) will not be saved.
* *
* @param context A context that is used for opening a database connection.
* @param image The FeedImage object. * @param image The FeedImage object.
*/ */
public static Future<?> setFeedImage(final Context context, public static Future<?> setFeedImage(final FeedImage image) {
final FeedImage image) { return dbExec.submit(() -> {
return dbExec.submit(new Runnable() { PodDBAdapter adapter = PodDBAdapter.getInstance();
@Override
public void run() {
PodDBAdapter adapter = new PodDBAdapter(context);
adapter.open(); adapter.open();
adapter.setImage(image); adapter.setImage(image);
adapter.close(); adapter.close();
}
}); });
} }
@ -867,11 +736,9 @@ public class DBWriter {
* Updates download URLs of feeds from a given Map. The key of the Map is the original URL of the feed * Updates download URLs of feeds from a given Map. The key of the Map is the original URL of the feed
* and the value is the updated URL * and the value is the updated URL
*/ */
public static Future<?> updateFeedDownloadURLs(final Context context, final Map<String, String> urls) { public static Future<?> updateFeedDownloadURLs(final Map<String, String> urls) {
return dbExec.submit(new Runnable() { return dbExec.submit(() -> {
@Override PodDBAdapter adapter = PodDBAdapter.getInstance();
public void run() {
PodDBAdapter adapter = new PodDBAdapter(context);
adapter.open(); adapter.open();
for (String key : urls.keySet()) { for (String key : urls.keySet()) {
if (BuildConfig.DEBUG) if (BuildConfig.DEBUG)
@ -880,26 +747,21 @@ public class DBWriter {
adapter.setFeedDownloadUrl(key, urls.get(key)); adapter.setFeedDownloadUrl(key, urls.get(key));
} }
adapter.close(); adapter.close();
}
}); });
} }
/** /**
* Saves a FeedPreferences object in the database. The Feed ID of the FeedPreferences-object MUST NOT be 0. * Saves a FeedPreferences object in the database. The Feed ID of the FeedPreferences-object MUST NOT be 0.
* *
* @param context Used for opening a database connection.
* @param preferences The FeedPreferences object. * @param preferences The FeedPreferences object.
*/ */
public static Future<?> setFeedPreferences(final Context context, final FeedPreferences preferences) { public static Future<?> setFeedPreferences(final FeedPreferences preferences) {
return dbExec.submit(new Runnable() { return dbExec.submit(() -> {
@Override PodDBAdapter adapter = PodDBAdapter.getInstance();
public void run() {
PodDBAdapter adapter = new PodDBAdapter(context);
adapter.open(); adapter.open();
adapter.setFeedPreferences(preferences); adapter.setFeedPreferences(preferences);
adapter.close(); adapter.close();
EventDistributor.getInstance().sendFeedUpdateBroadcast(); EventDistributor.getInstance().sendFeedUpdateBroadcast();
}
}); });
} }
@ -920,18 +782,14 @@ public class DBWriter {
public static Future<?> setFeedItemFlattrStatus(final Context context, public static Future<?> setFeedItemFlattrStatus(final Context context,
final FeedItem item, final FeedItem item,
final boolean startFlattrClickWorker) { final boolean startFlattrClickWorker) {
return dbExec.submit(new Runnable() { return dbExec.submit(() -> {
PodDBAdapter adapter = PodDBAdapter.getInstance();
@Override
public void run() {
PodDBAdapter adapter = new PodDBAdapter(context);
adapter.open(); adapter.open();
adapter.setFeedItemFlattrStatus(item); adapter.setFeedItemFlattrStatus(item);
adapter.close(); adapter.close();
if (startFlattrClickWorker) { if (startFlattrClickWorker) {
new FlattrClickWorker(context).executeAsync(); new FlattrClickWorker(context).executeAsync();
} }
}
}); });
} }
@ -943,18 +801,14 @@ public class DBWriter {
private static Future<?> setFeedFlattrStatus(final Context context, private static Future<?> setFeedFlattrStatus(final Context context,
final Feed feed, final Feed feed,
final boolean startFlattrClickWorker) { final boolean startFlattrClickWorker) {
return dbExec.submit(new Runnable() { return dbExec.submit(() -> {
PodDBAdapter adapter = PodDBAdapter.getInstance();
@Override
public void run() {
PodDBAdapter adapter = new PodDBAdapter(context);
adapter.open(); adapter.open();
adapter.setFeedFlattrStatus(feed); adapter.setFeedFlattrStatus(feed);
adapter.close(); adapter.close();
if (startFlattrClickWorker) { if (startFlattrClickWorker) {
new FlattrClickWorker(context).executeAsync(); new FlattrClickWorker(context).executeAsync();
} }
}
}); });
} }
@ -963,18 +817,13 @@ public class DBWriter {
* *
* @param lastUpdateFailed true if last update failed * @param lastUpdateFailed true if last update failed
*/ */
public static Future<?> setFeedLastUpdateFailed(final Context context, public static Future<?> setFeedLastUpdateFailed(final long feedId,
final long feedId,
final boolean lastUpdateFailed) { final boolean lastUpdateFailed) {
return dbExec.submit(new Runnable() { return dbExec.submit(() -> {
PodDBAdapter adapter = PodDBAdapter.getInstance();
@Override
public void run() {
PodDBAdapter adapter = new PodDBAdapter(context);
adapter.open(); adapter.open();
adapter.setFeedLastUpdateFailed(feedId, lastUpdateFailed); adapter.setFeedLastUpdateFailed(feedId, lastUpdateFailed);
adapter.close(); adapter.close();
}
}); });
} }
@ -1002,14 +851,15 @@ public class DBWriter {
*/ */
public static Future<?> setFlattredStatus(Context context, FlattrThing thing, boolean startFlattrClickWorker) { public static Future<?> setFlattredStatus(Context context, FlattrThing thing, boolean startFlattrClickWorker) {
// must propagate this to back db // must propagate this to back db
if (thing instanceof FeedItem) if (thing instanceof FeedItem) {
return setFeedItemFlattrStatus(context, (FeedItem) thing, startFlattrClickWorker); return setFeedItemFlattrStatus(context, (FeedItem) thing, startFlattrClickWorker);
else if (thing instanceof Feed) } else if (thing instanceof Feed) {
return setFeedFlattrStatus(context, (Feed) thing, startFlattrClickWorker); return setFeedFlattrStatus(context, (Feed) thing, startFlattrClickWorker);
else if (thing instanceof SimpleFlattrThing) { } else if (thing instanceof SimpleFlattrThing) {
} // SimpleFlattrThings are generated on the fly and do not have DB backing // SimpleFlattrThings are generated on the fly and do not have DB backing
else } else {
Log.e(TAG, "flattrQueue processing - thing is neither FeedItem nor Feed nor SimpleFlattrThing"); Log.e(TAG, "flattrQueue processing - thing is neither FeedItem nor Feed nor SimpleFlattrThing");
}
return null; return null;
} }
@ -1017,16 +867,13 @@ public class DBWriter {
/** /**
* Reset flattr status to unflattrd for all items * Reset flattr status to unflattrd for all items
*/ */
public static Future<?> clearAllFlattrStatus(final Context context) { public static Future<?> clearAllFlattrStatus() {
Log.d(TAG, "clearAllFlattrStatus()"); Log.d(TAG, "clearAllFlattrStatus()");
return dbExec.submit(new Runnable() { return dbExec.submit(() -> {
@Override PodDBAdapter adapter = PodDBAdapter.getInstance();
public void run() {
PodDBAdapter adapter = new PodDBAdapter(context);
adapter.open(); adapter.open();
adapter.clearAllFlattrStatus(); adapter.clearAllFlattrStatus();
adapter.close(); adapter.close();
}
}); });
} }
@ -1034,40 +881,32 @@ public class DBWriter {
* Set flattr status of the feeds/feeditems in flattrList to flattred at the given timestamp, * Set flattr status of the feeds/feeditems in flattrList to flattred at the given timestamp,
* where the information has been retrieved from the flattr API * where the information has been retrieved from the flattr API
*/ */
public static Future<?> setFlattredStatus(final Context context, final List<Flattr> flattrList) { public static Future<?> setFlattredStatus(final List<Flattr> flattrList) {
Log.d(TAG, "setFlattredStatus to status retrieved from flattr api running with " + flattrList.size() + " items"); Log.d(TAG, "setFlattredStatus to status retrieved from flattr api running with " + flattrList.size() + " items");
// clear flattr status in db // clear flattr status in db
clearAllFlattrStatus(context); clearAllFlattrStatus();
// submit list with flattred things having normalized URLs to db // submit list with flattred things having normalized URLs to db
return dbExec.submit(new Runnable() { return dbExec.submit(() -> {
@Override PodDBAdapter adapter = PodDBAdapter.getInstance();
public void run() {
PodDBAdapter adapter = new PodDBAdapter(context);
adapter.open(); adapter.open();
for (Flattr flattr : flattrList) { for (Flattr flattr : flattrList) {
adapter.setItemFlattrStatus(formatURIForQuery(flattr.getThing().getUrl()), new FlattrStatus(flattr.getCreated().getTime())); adapter.setItemFlattrStatus(formatURIForQuery(flattr.getThing().getUrl()), new FlattrStatus(flattr.getCreated().getTime()));
} }
adapter.close(); adapter.close();
}
}); });
} }
/** /**
* Sort the FeedItems in the queue with the given Comparator. * Sort the FeedItems in the queue with the given Comparator.
*
* @param context A context that is used for opening a database connection.
* @param comparator FeedItem comparator * @param comparator FeedItem comparator
* @param broadcastUpdate true if this operation should trigger a QueueUpdateBroadcast. This option should be set to * @param broadcastUpdate true if this operation should trigger a QueueUpdateBroadcast. This option should be set to
* false if the caller wants to avoid unexpected updates of the GUI.
*/ */
public static Future<?> sortQueue(final Context context, final Comparator<FeedItem> comparator, final boolean broadcastUpdate) { public static Future<?> sortQueue(final Comparator<FeedItem> comparator, final boolean broadcastUpdate) {
return dbExec.submit(new Runnable() { return dbExec.submit(() -> {
@Override final PodDBAdapter adapter = PodDBAdapter.getInstance();
public void run() {
final PodDBAdapter adapter = new PodDBAdapter(context);
adapter.open(); adapter.open();
final List<FeedItem> queue = DBReader.getQueue(context, adapter); final List<FeedItem> queue = DBReader.getQueue(adapter);
if (queue != null) { if (queue != null) {
Collections.sort(queue, comparator); Collections.sort(queue, comparator);
@ -1079,79 +918,58 @@ public class DBWriter {
Log.e(TAG, "sortQueue: Could not load queue"); Log.e(TAG, "sortQueue: Could not load queue");
} }
adapter.close(); adapter.close();
}
}); });
} }
/** /**
* Sets the 'auto_download'-attribute of specific FeedItem. * Sets the 'auto_download'-attribute of specific FeedItem.
* *
* @param context A context that is used for opening a database connection.
* @param feedItem FeedItem. * @param feedItem FeedItem.
*/ */
public static Future<?> setFeedItemAutoDownload(final Context context, final FeedItem feedItem, public static Future<?> setFeedItemAutoDownload(final FeedItem feedItem,
final boolean autoDownload) { final boolean autoDownload) {
Log.d(TAG, "FeedItem[id=" + feedItem.getId() + "] SET auto_download " + autoDownload); Log.d(TAG, "FeedItem[id=" + feedItem.getId() + "] SET auto_download " + autoDownload);
return dbExec.submit(new Runnable() { return dbExec.submit(() -> {
final PodDBAdapter adapter = PodDBAdapter.getInstance();
@Override
public void run() {
final PodDBAdapter adapter = new PodDBAdapter(context);
adapter.open(); adapter.open();
adapter.setFeedItemAutoDownload(feedItem, autoDownload); adapter.setFeedItemAutoDownload(feedItem, autoDownload);
adapter.close(); adapter.close();
EventDistributor.getInstance().sendUnreadItemsUpdateBroadcast(); EventDistributor.getInstance().sendUnreadItemsUpdateBroadcast();
}
}); });
} }
/** /**
* Sets the 'auto_download'-attribute of specific FeedItem. * Sets the 'auto_download'-attribute of specific FeedItem.
*
* @param context A context that is used for opening a database connection.
* @param feed This feed's episodes will be processed. * @param feed This feed's episodes will be processed.
* @param autoDownload If true, auto download will be enabled for the feed's episodes. Else, * @param autoDownload If true, auto download will be enabled for the feed's episodes. Else,
* it will be disabled.
*/ */
public static Future<?> setFeedsItemsAutoDownload(final Context context, final Feed feed, public static Future<?> setFeedsItemsAutoDownload(final Feed feed,
final boolean autoDownload) { final boolean autoDownload) {
Log.d(TAG, (autoDownload ? "Enabling" : "Disabling") + " auto download for items of feed " + feed.getId()); Log.d(TAG, (autoDownload ? "Enabling" : "Disabling") + " auto download for items of feed " + feed.getId());
return dbExec.submit(new Runnable() { return dbExec.submit(() -> {
final PodDBAdapter adapter = PodDBAdapter.getInstance();
@Override
public void run() {
final PodDBAdapter adapter = new PodDBAdapter(context);
adapter.open(); adapter.open();
adapter.setFeedsItemsAutoDownload(feed, autoDownload); adapter.setFeedsItemsAutoDownload(feed, autoDownload);
adapter.close(); adapter.close();
EventDistributor.getInstance().sendUnreadItemsUpdateBroadcast(); EventDistributor.getInstance().sendUnreadItemsUpdateBroadcast();
}
}); });
} }
/** /**
* Set filter of the feed * Set filter of the feed
*
* @param context Used for opening a database connection.
* @param feedId The feed's ID * @param feedId The feed's ID
* @param filterValues Values that represent properties to filter by * @param filterValues Values that represent properties to filter by
*/ */
public static Future<?> setFeedItemsFilter(final Context context, final long feedId, public static Future<?> setFeedItemsFilter(final long feedId,
final List<String> filterValues) { final List<String> filterValues) {
Log.d(TAG, "setFeedFilter"); Log.d(TAG, "setFeedFilter");
return dbExec.submit(() -> {
return dbExec.submit(new Runnable() { PodDBAdapter adapter = PodDBAdapter.getInstance();
@Override
public void run() {
PodDBAdapter adapter = new PodDBAdapter(context);
adapter.open(); adapter.open();
adapter.setFeedItemFilter(feedId, filterValues); adapter.setFeedItemFilter(feedId, filterValues);
adapter.close(); adapter.close();
EventBus.getDefault().post(new FeedEvent(FeedEvent.Action.FILTER_CHANGED, feedId)); EventBus.getDefault().post(new FeedEvent(FeedEvent.Action.FILTER_CHANGED, feedId));
}
}); });
} }

View File

@ -24,7 +24,7 @@ public interface EpisodeCleanupAlgorithm<T> {
* space to free to satisfy the episode cache conditions. If the conditions are already satisfied, this * space to free to satisfy the episode cache conditions. If the conditions are already satisfied, this
* method should not have any effects. * method should not have any effects.
*/ */
public T getDefaultCleanupParameter(Context context); public T getDefaultCleanupParameter();
/** /**
* Returns a parameter for performCleanup. * Returns a parameter for performCleanup.
@ -32,5 +32,5 @@ public interface EpisodeCleanupAlgorithm<T> {
* @param items A list of FeedItems that are about to be downloaded. The implementation of this interface * @param items A list of FeedItems that are about to be downloaded. The implementation of this interface
* should decide how much space to free to satisfy the episode cache conditions. * should decide how much space to free to satisfy the episode cache conditions.
*/ */
public T getPerformCleanupParameter(Context context, List<FeedItem> items); public T getPerformCleanupParameter(List<FeedItem> items);
} }

View File

@ -1,5 +1,7 @@
package de.danoeh.antennapod.core.storage; package de.danoeh.antennapod.core.storage;
import android.database.Cursor;
import java.util.Date; import java.util.Date;
/** /**
@ -36,6 +38,15 @@ public class FeedItemStatistics {
} }
} }
public static FeedItemStatistics fromCursor(Cursor cursor) {
return new FeedItemStatistics(
cursor.getLong(0),
cursor.getInt(1),
cursor.getInt(2),
cursor.getInt(4),
new Date(cursor.getLong(3)));
}
public long getFeedID() { public long getFeedID() {
return feedID; return feedID;
} }

View File

@ -17,8 +17,8 @@ import org.apache.commons.lang3.Validate;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import de.danoeh.antennapod.core.BuildConfig;
import de.danoeh.antennapod.core.R; import de.danoeh.antennapod.core.R;
import de.danoeh.antennapod.core.event.ProgressEvent; import de.danoeh.antennapod.core.event.ProgressEvent;
import de.danoeh.antennapod.core.feed.Chapter; import de.danoeh.antennapod.core.feed.Chapter;
@ -40,6 +40,7 @@ import de.greenrobot.event.EventBus;
* Implements methods for accessing the database * Implements methods for accessing the database
*/ */
public class PodDBAdapter { public class PodDBAdapter {
private static final String TAG = "PodDBAdapter"; private static final String TAG = "PodDBAdapter";
public static final String DATABASE_NAME = "Antennapod.db"; public static final String DATABASE_NAME = "Antennapod.db";
@ -53,63 +54,6 @@ public class PodDBAdapter {
*/ */
public static final int SEARCH_LIMIT = 30; public static final int SEARCH_LIMIT = 30;
// ----------- Column indices
// ----------- General indices
public static final int KEY_ID_INDEX = 0;
public static final int KEY_TITLE_INDEX = 1;
public static final int KEY_FILE_URL_INDEX = 2;
public static final int KEY_DOWNLOAD_URL_INDEX = 3;
public static final int KEY_DOWNLOADED_INDEX = 4;
public static final int KEY_LINK_INDEX = 5;
public static final int KEY_DESCRIPTION_INDEX = 6;
public static final int KEY_PAYMENT_LINK_INDEX = 7;
// ----------- Feed indices
public static final int KEY_LAST_UPDATE_INDEX = 8;
public static final int KEY_LANGUAGE_INDEX = 9;
public static final int KEY_AUTHOR_INDEX = 10;
public static final int KEY_IMAGE_INDEX = 11;
public static final int KEY_TYPE_INDEX = 12;
public static final int KEY_FEED_IDENTIFIER_INDEX = 13;
public static final int KEY_FEED_FLATTR_STATUS_INDEX = 14;
public static final int KEY_FEED_USERNAME_INDEX = 15;
public static final int KEY_FEED_PASSWORD_INDEX = 16;
public static final int KEY_IS_PAGED_INDEX = 17;
public static final int KEY_LOAD_ALL_PAGES_INDEX = 18;
public static final int KEY_NEXT_PAGE_LINK_INDEX = 19;
// ----------- FeedItem indices
public static final int KEY_CONTENT_ENCODED_INDEX = 2;
public static final int KEY_PUBDATE_INDEX = 3;
public static final int KEY_READ_INDEX = 4;
public static final int KEY_MEDIA_INDEX = 8;
public static final int KEY_FEED_INDEX = 9;
public static final int KEY_HAS_SIMPLECHAPTERS_INDEX = 10;
public static final int KEY_ITEM_IDENTIFIER_INDEX = 11;
public static final int KEY_ITEM_FLATTR_STATUS_INDEX = 12;
// ---------- FeedMedia indices
public static final int KEY_DURATION_INDEX = 1;
public static final int KEY_POSITION_INDEX = 5;
public static final int KEY_SIZE_INDEX = 6;
public static final int KEY_MIME_TYPE_INDEX = 7;
public static final int KEY_PLAYBACK_COMPLETION_DATE_INDEX = 8;
public static final int KEY_MEDIA_FEEDITEM_INDEX = 9;
public static final int KEY_PLAYED_DURATION_INDEX = 10;
// --------- Download log indices
public static final int KEY_FEEDFILE_INDEX = 1;
public static final int KEY_FEEDFILETYPE_INDEX = 2;
public static final int KEY_REASON_INDEX = 3;
public static final int KEY_SUCCESSFUL_INDEX = 4;
public static final int KEY_COMPLETION_DATE_INDEX = 5;
public static final int KEY_REASON_DETAILED_INDEX = 6;
public static final int KEY_DOWNLOADSTATUS_TITLE_INDEX = 7;
// --------- Queue indices
public static final int KEY_FEEDITEM_INDEX = 1;
public static final int KEY_QUEUE_FEED_INDEX = 2;
// --------- Chapters indices
public static final int KEY_CHAPTER_START_INDEX = 2;
public static final int KEY_CHAPTER_FEEDITEM_INDEX = 3;
public static final int KEY_CHAPTER_LINK_INDEX = 4;
public static final int KEY_CHAPTER_TYPE_INDEX = 5;
// Key-constants // Key-constants
public static final String KEY_ID = "id"; public static final String KEY_ID = "id";
public static final String KEY_TITLE = "title"; public static final String KEY_TITLE = "title";
@ -254,11 +198,6 @@ public class PodDBAdapter {
+ TABLE_NAME_SIMPLECHAPTERS + "_" + KEY_FEEDITEM + " ON " + TABLE_NAME_SIMPLECHAPTERS + " (" + TABLE_NAME_SIMPLECHAPTERS + "_" + KEY_FEEDITEM + " ON " + TABLE_NAME_SIMPLECHAPTERS + " ("
+ KEY_FEEDITEM + ")"; + KEY_FEEDITEM + ")";
private SQLiteDatabase db;
private final Context context;
private PodDBHelper helper;
/** /**
* Select all columns from the feed-table * Select all columns from the feed-table
*/ */
@ -288,29 +227,6 @@ public class PodDBAdapter {
TABLE_NAME_FEEDS + "." + KEY_AUTO_DELETE_ACTION, TABLE_NAME_FEEDS + "." + KEY_AUTO_DELETE_ACTION,
}; };
// column indices for FEED_SEL_STD
public static final int IDX_FEED_SEL_STD_ID = 0;
public static final int IDX_FEED_SEL_STD_TITLE = 1;
public static final int IDX_FEED_SEL_STD_FILE_URL = 2;
public static final int IDX_FEED_SEL_STD_DOWNLOAD_URL = 3;
public static final int IDX_FEED_SEL_STD_DOWNLOADED = 4;
public static final int IDX_FEED_SEL_STD_LINK = 5;
public static final int IDX_FEED_SEL_STD_DESCRIPTION = 6;
public static final int IDX_FEED_SEL_STD_PAYMENT_LINK = 7;
public static final int IDX_FEED_SEL_STD_LASTUPDATE = 8;
public static final int IDX_FEED_SEL_STD_LANGUAGE = 9;
public static final int IDX_FEED_SEL_STD_AUTHOR = 10;
public static final int IDX_FEED_SEL_STD_IMAGE = 11;
public static final int IDX_FEED_SEL_STD_TYPE = 12;
public static final int IDX_FEED_SEL_STD_FEED_IDENTIFIER = 13;
public static final int IDX_FEED_SEL_PREFERENCES_AUTO_DOWNLOAD = 14;
public static final int IDX_FEED_SEL_STD_FLATTR_STATUS = 15;
public static final int IDX_FEED_SEL_STD_IS_PAGED = 16;
public static final int IDX_FEED_SEL_STD_NEXT_PAGE_LINK = 17;
public static final int IDX_FEED_SEL_PREFERENCES_USERNAME = 18;
public static final int IDX_FEED_SEL_PREFERENCES_PASSWORD = 19;
public static final int IDX_FEED_SEL_PREFERENCES_AUTO_DELETE_ACTION = 22;
/** /**
* Select all columns from the feeditems-table except description and * Select all columns from the feeditems-table except description and
* content-encoded. * content-encoded.
@ -321,7 +237,8 @@ public class PodDBAdapter {
TABLE_NAME_FEED_ITEMS + "." + KEY_PUBDATE, TABLE_NAME_FEED_ITEMS + "." + KEY_PUBDATE,
TABLE_NAME_FEED_ITEMS + "." + KEY_READ, TABLE_NAME_FEED_ITEMS + "." + KEY_READ,
TABLE_NAME_FEED_ITEMS + "." + KEY_LINK, TABLE_NAME_FEED_ITEMS + "." + KEY_LINK,
TABLE_NAME_FEED_ITEMS + "." + KEY_PAYMENT_LINK, KEY_MEDIA, TABLE_NAME_FEED_ITEMS + "." + KEY_PAYMENT_LINK,
TABLE_NAME_FEED_ITEMS + "." + KEY_MEDIA,
TABLE_NAME_FEED_ITEMS + "." + KEY_FEED, TABLE_NAME_FEED_ITEMS + "." + KEY_FEED,
TABLE_NAME_FEED_ITEMS + "." + KEY_HAS_CHAPTERS, TABLE_NAME_FEED_ITEMS + "." + KEY_HAS_CHAPTERS,
TABLE_NAME_FEED_ITEMS + "." + KEY_ITEM_IDENTIFIER, TABLE_NAME_FEED_ITEMS + "." + KEY_ITEM_IDENTIFIER,
@ -340,73 +257,59 @@ public class PodDBAdapter {
SEL_FI_SMALL_STR = selFiSmall.substring(1, selFiSmall.length() - 1); SEL_FI_SMALL_STR = selFiSmall.substring(1, selFiSmall.length() - 1);
} }
// column indices for FEEDITEM_SEL_FI_SMALL
public static final int IDX_FI_SMALL_ID = 0;
public static final int IDX_FI_SMALL_TITLE = 1;
public static final int IDX_FI_SMALL_PUBDATE = 2;
public static final int IDX_FI_SMALL_READ = 3;
public static final int IDX_FI_SMALL_LINK = 4;
public static final int IDX_FI_SMALL_PAYMENT_LINK = 5;
public static final int IDX_FI_SMALL_MEDIA = 6;
public static final int IDX_FI_SMALL_FEED = 7;
public static final int IDX_FI_SMALL_HAS_CHAPTERS = 8;
public static final int IDX_FI_SMALL_ITEM_IDENTIFIER = 9;
public static final int IDX_FI_SMALL_FLATTR_STATUS = 10;
public static final int IDX_FI_SMALL_IMAGE = 11;
/** /**
* Select id, description and content-encoded column from feeditems. * Select id, description and content-encoded column from feeditems.
*/ */
private static final String[] SEL_FI_EXTRA = {KEY_ID, KEY_DESCRIPTION, private static final String[] SEL_FI_EXTRA = {KEY_ID, KEY_DESCRIPTION,
KEY_CONTENT_ENCODED, KEY_FEED}; KEY_CONTENT_ENCODED, KEY_FEED};
// column indices for SEL_FI_EXTRA
public static final int IDX_FI_EXTRA_ID = 0; private SQLiteDatabase db;
public static final int IDX_FI_EXTRA_DESCRIPTION = 1; private static Context context;
public static final int IDX_FI_EXTRA_CONTENT_ENCODED = 2; private static PodDBHelper dbHelper;
public static final int IDX_FI_EXTRA_FEED = 3; private static AtomicInteger counter = new AtomicInteger(0);
static PodDBHelper dbHelperSingleton; public static void init(Context context) {
PodDBAdapter.context = context.getApplicationContext();
private static synchronized PodDBHelper getDbHelperSingleton(Context appContext) {
if (dbHelperSingleton == null) {
dbHelperSingleton = new PodDBHelper(appContext, DATABASE_NAME, null);
}
return dbHelperSingleton;
} }
public PodDBAdapter(Context c) { public static synchronized PodDBAdapter getInstance() {
this.context = c; if(dbHelper == null) {
helper = getDbHelperSingleton(c.getApplicationContext()); dbHelper = new PodDBHelper(PodDBAdapter.context, DATABASE_NAME, null);
} }
return new PodDBAdapter();
}
private PodDBAdapter() {}
public PodDBAdapter open() { public PodDBAdapter open() {
counter.incrementAndGet();
if (db == null || !db.isOpen() || db.isReadOnly()) { if (db == null || !db.isOpen() || db.isReadOnly()) {
if (BuildConfig.DEBUG) Log.v(TAG, "Opening DB");
Log.d(TAG, "Opening DB");
try { try {
db = helper.getWritableDatabase(); db = dbHelper.getWritableDatabase();
} catch (SQLException ex) { } catch (SQLException ex) {
ex.printStackTrace(); Log.e(TAG, Log.getStackTraceString(ex));
db = helper.getReadableDatabase(); db = dbHelper.getReadableDatabase();
} }
} }
return this; return this;
} }
public void close() { public void close() {
if (BuildConfig.DEBUG) if(counter.decrementAndGet() == 0) {
Log.d(TAG, "Closing DB"); Log.v(TAG, "Closing DB");
//db.close(); db.close();
}
db = null;
} }
public static boolean deleteDatabase(Context context) { public static boolean deleteDatabase() {
Log.w(TAG, "Deleting database"); if(dbHelper != null) {
dbHelperSingleton.close(); dbHelper.close();
dbHelperSingleton = null; dbHelper = null;
return context.deleteDatabase(DATABASE_NAME); }
return context.deleteDatabase(PodDBAdapter.DATABASE_NAME);
} }
/** /**
@ -484,7 +387,12 @@ public class PodDBAdapter {
* @return the id of the entry * @return the id of the entry
*/ */
public long setImage(FeedImage image) { public long setImage(FeedImage image) {
boolean startedTransaction = false;
if(false == db.inTransaction()) {
db.beginTransaction(); db.beginTransaction();
startedTransaction = true;
}
ContentValues values = new ContentValues(); ContentValues values = new ContentValues();
values.put(KEY_TITLE, image.getTitle()); values.put(KEY_TITLE, image.getTitle());
values.put(KEY_DOWNLOAD_URL, image.getDownload_url()); values.put(KEY_DOWNLOAD_URL, image.getDownload_url());
@ -505,8 +413,10 @@ public class PodDBAdapter {
db.update(TABLE_NAME_FEEDS, values, KEY_ID + "=?", new String[]{String.valueOf(image.getOwner().getId())}); db.update(TABLE_NAME_FEEDS, values, KEY_ID + "=?", new String[]{String.valueOf(image.getOwner().getId())});
} }
} }
if(startedTransaction) {
db.setTransactionSuccessful(); db.setTransactionSuccessful();
db.endTransaction(); db.endTransaction();
}
return image.getId(); return image.getId();
} }
@ -527,8 +437,7 @@ public class PodDBAdapter {
values.put(KEY_HAS_EMBEDDED_PICTURE, media.hasEmbeddedPicture()); values.put(KEY_HAS_EMBEDDED_PICTURE, media.hasEmbeddedPicture());
if (media.getPlaybackCompletionDate() != null) { if (media.getPlaybackCompletionDate() != null) {
values.put(KEY_PLAYBACK_COMPLETION_DATE, media values.put(KEY_PLAYBACK_COMPLETION_DATE, media.getPlaybackCompletionDate().getTime());
.getPlaybackCompletionDate().getTime());
} else { } else {
values.put(KEY_PLAYBACK_COMPLETION_DATE, 0); values.put(KEY_PLAYBACK_COMPLETION_DATE, 0);
} }
@ -822,8 +731,7 @@ public class PodDBAdapter {
values.put(KEY_LINK, chapter.getLink()); values.put(KEY_LINK, chapter.getLink());
values.put(KEY_CHAPTER_TYPE, chapter.getChapterType()); values.put(KEY_CHAPTER_TYPE, chapter.getChapterType());
if (chapter.getId() == 0) { if (chapter.getId() == 0) {
chapter.setId(db chapter.setId(db.insert(TABLE_NAME_SIMPLECHAPTERS, null, values));
.insert(TABLE_NAME_SIMPLECHAPTERS, null, values));
} else { } else {
db.update(TABLE_NAME_SIMPLECHAPTERS, values, KEY_ID + "=?", db.update(TABLE_NAME_SIMPLECHAPTERS, values, KEY_ID + "=?",
new String[]{String.valueOf(chapter.getId())}); new String[]{String.valueOf(chapter.getId())});
@ -884,14 +792,6 @@ public class PodDBAdapter {
return count; return count;
} }
public void removeDownloadLogItems(long count) {
if (count > 0) {
final String sql = String.format("DELETE FROM %s WHERE %s in (SELECT %s from %s ORDER BY %s ASC LIMIT %d)",
TABLE_NAME_DOWNLOAD_LOG, KEY_ID, KEY_ID, TABLE_NAME_DOWNLOAD_LOG, KEY_COMPLETION_DATE, count);
db.execSQL(sql, null);
}
}
public void setQueue(List<FeedItem> queue) { public void setQueue(List<FeedItem> queue) {
ContentValues values = new ContentValues(); ContentValues values = new ContentValues();
db.beginTransaction(); db.beginTransaction();
@ -963,11 +863,6 @@ public class PodDBAdapter {
db.endTransaction(); db.endTransaction();
} }
public void removeDownloadStatus(DownloadStatus remove) {
db.delete(TABLE_NAME_DOWNLOAD_LOG, KEY_ID + "=?",
new String[]{String.valueOf(remove.getId())});
}
public void clearPlaybackHistory() { public void clearPlaybackHistory() {
ContentValues values = new ContentValues(); ContentValues values = new ContentValues();
values.put(KEY_PLAYBACK_COMPLETION_DATE, 0); values.put(KEY_PLAYBACK_COMPLETION_DATE, 0);
@ -1075,21 +970,14 @@ public class PodDBAdapter {
* cursor uses the FEEDITEM_SEL_FI_SMALL selection. * cursor uses the FEEDITEM_SEL_FI_SMALL selection.
*/ */
public final Cursor getQueueCursor() { public final Cursor getQueueCursor() {
Object[] args = (Object[]) new String[]{ Object[] args = new String[] {
SEL_FI_SMALL_STR + "," + TABLE_NAME_QUEUE + "." + KEY_ID, SEL_FI_SMALL_STR,
TABLE_NAME_FEED_ITEMS, TABLE_NAME_QUEUE, TABLE_NAME_FEED_ITEMS, TABLE_NAME_QUEUE,
TABLE_NAME_FEED_ITEMS + "." + KEY_ID, TABLE_NAME_FEED_ITEMS + "." + KEY_ID,
TABLE_NAME_QUEUE + "." + KEY_FEEDITEM, TABLE_NAME_QUEUE + "." + KEY_FEEDITEM,
TABLE_NAME_QUEUE + "." + KEY_ID}; TABLE_NAME_QUEUE + "." + KEY_ID };
String query = String.format( String query = String.format("SELECT %s FROM %s INNER JOIN %s ON %s=%s ORDER BY %s", args);
"SELECT %s FROM %s INNER JOIN %s ON %s=%s ORDER BY %s", args);
Cursor c = db.rawQuery(query, null); Cursor c = db.rawQuery(query, null);
/*
* Cursor c = db.query(TABLE_NAME_FEED_ITEMS, FEEDITEM_SEL_FI_SMALL,
* "INNER JOIN ? ON ?=?", new String[] { TABLE_NAME_QUEUE,
* TABLE_NAME_FEED_ITEMS + "." + KEY_ID, TABLE_NAME_QUEUE + "." +
* KEY_FEEDITEM }, null, null, TABLE_NAME_QUEUE + "." + KEY_FEEDITEM);
*/
return c; return c;
} }

View File

@ -148,7 +148,7 @@ public class NetworkUtils {
} }
subscriber.onNext(size); subscriber.onNext(size);
subscriber.onCompleted(); subscriber.onCompleted();
DBWriter.setFeedMedia(context, media); DBWriter.setFeedMedia(media);
} }
}) })
.subscribeOn(Schedulers.newThread()) .subscribeOn(Schedulers.newThread())

View File

@ -83,7 +83,7 @@ public class QueueSorter {
} }
if (comparator != null) { if (comparator != null) {
DBWriter.sortQueue(context, comparator, broadcastUpdate); DBWriter.sortQueue(comparator, broadcastUpdate);
} }
} }
} }

View File

@ -167,7 +167,7 @@ public class FlattrUtils {
deleteToken(); deleteToken();
FlattrServiceCreator.deleteFlattrService(); FlattrServiceCreator.deleteFlattrService();
showRevokeDialog(context); showRevokeDialog(context);
DBWriter.clearAllFlattrStatus(context); DBWriter.clearAllFlattrStatus();
} }
// ------------------------------------------------ DIALOGS // ------------------------------------------------ DIALOGS

View File

@ -89,8 +89,10 @@ public class UndoBarController<T> {
public void close() { public void close() {
hideUndoBar(true); hideUndoBar(true);
if(mUndoListener != null) {
mUndoListener.onHide(mUndoToken); mUndoListener.onHide(mUndoToken);
} }
}
public void hideUndoBar(boolean immediate) { public void hideUndoBar(boolean immediate) {
mHideHandler.removeCallbacks(mHideRunnable); mHideHandler.removeCallbacks(mHideRunnable);

View File

@ -164,7 +164,7 @@ public interface Playable extends Parcelable,
case FeedMedia.PLAYABLE_TYPE_FEEDMEDIA: case FeedMedia.PLAYABLE_TYPE_FEEDMEDIA:
long mediaId = pref.getLong(FeedMedia.PREF_MEDIA_ID, -1); long mediaId = pref.getLong(FeedMedia.PREF_MEDIA_ID, -1);
if (mediaId != -1) { if (mediaId != -1) {
return DBReader.getFeedMedia(context, mediaId); return DBReader.getFeedMedia(mediaId);
} }
break; break;
case ExternalMedia.PLAYABLE_TYPE_EXTERNAL_MEDIA: case ExternalMedia.PLAYABLE_TYPE_EXTERNAL_MEDIA:

View File

@ -56,7 +56,7 @@ public abstract class PlaybackController {
private final Activity activity; private final Activity activity;
private PlaybackService playbackService; private PlaybackService playbackService;
private Playable media; protected Playable media;
private PlayerStatus status; private PlayerStatus status;
private ScheduledThreadPoolExecutor schedExecutor; private ScheduledThreadPoolExecutor schedExecutor;
@ -479,9 +479,11 @@ public abstract class PlaybackController {
private void updatePlayButtonAppearance(int resource, CharSequence contentDescription) { private void updatePlayButtonAppearance(int resource, CharSequence contentDescription) {
ImageButton butPlay = getPlayButton(); ImageButton butPlay = getPlayButton();
if(butPlay != null) {
butPlay.setImageResource(resource); butPlay.setImageResource(resource);
butPlay.setContentDescription(contentDescription); butPlay.setContentDescription(contentDescription);
} }
}
public abstract ImageButton getPlayButton(); public abstract ImageButton getPlayButton();