From 278e93880e9a4bc0b54e36c8d486cad84ed7fd6e Mon Sep 17 00:00:00 2001 From: Andrew Gaul Date: Sun, 21 Jan 2018 13:03:35 -0800 Subject: Prefer StringBuilder over StringBuffer The latter has unnecessary synchronization. Found via error-prone. --- .../de/danoeh/antennapod/core/syndication/handler/HandlerState.java | 4 ++-- .../de/danoeh/antennapod/core/syndication/handler/SyndHandler.java | 2 +- .../de/danoeh/antennapod/core/util/id3reader/ChapterReader.java | 6 +++--- .../java/de/danoeh/antennapod/core/util/id3reader/ID3Reader.java | 6 +++--- 4 files changed, 9 insertions(+), 9 deletions(-) (limited to 'core/src/main') diff --git a/core/src/main/java/de/danoeh/antennapod/core/syndication/handler/HandlerState.java b/core/src/main/java/de/danoeh/antennapod/core/syndication/handler/HandlerState.java index 66513a12e..fe9f335b1 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/syndication/handler/HandlerState.java +++ b/core/src/main/java/de/danoeh/antennapod/core/syndication/handler/HandlerState.java @@ -37,7 +37,7 @@ public class HandlerState { /** * Buffer for saving characters. */ - protected StringBuffer contentBuf; + protected StringBuilder contentBuf; /** * Temporarily saved objects. @@ -97,7 +97,7 @@ public class HandlerState { return third; } - public StringBuffer getContentBuf() { + public StringBuilder getContentBuf() { return contentBuf; } diff --git a/core/src/main/java/de/danoeh/antennapod/core/syndication/handler/SyndHandler.java b/core/src/main/java/de/danoeh/antennapod/core/syndication/handler/SyndHandler.java index ae91c0743..c3db59382 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/syndication/handler/SyndHandler.java +++ b/core/src/main/java/de/danoeh/antennapod/core/syndication/handler/SyndHandler.java @@ -33,7 +33,7 @@ public class SyndHandler extends DefaultHandler { @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { - state.contentBuf = new StringBuffer(); + state.contentBuf = new StringBuilder(); Namespace handler = getHandlingNamespace(uri, qName); if (handler != null) { SyndElement element = handler.handleElementStart(localName, state, diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/id3reader/ChapterReader.java b/core/src/main/java/de/danoeh/antennapod/core/util/id3reader/ChapterReader.java index 36588102c..f681b8062 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/id3reader/ChapterReader.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/id3reader/ChapterReader.java @@ -43,7 +43,7 @@ public class ChapterReader extends ID3Reader { currentChapter = null; } } - StringBuffer elementId = new StringBuffer(); + StringBuilder elementId = new StringBuilder(); readISOString(elementId, input, Integer.MAX_VALUE); char[] startTimeSource = readBytes(input, 4); long startTime = ((int) startTimeSource[0] << 24) @@ -54,7 +54,7 @@ public class ChapterReader extends ID3Reader { return ID3Reader.ACTION_DONT_SKIP; case FRAME_ID_TITLE: if (currentChapter != null && currentChapter.getTitle() == null) { - StringBuffer title = new StringBuffer(); + StringBuilder title = new StringBuilder(); readString(title, input, header.getSize()); currentChapter .setTitle(title.toString()); @@ -67,7 +67,7 @@ public class ChapterReader extends ID3Reader { if (currentChapter != null) { // skip description int descriptionLength = readString(null, input, header.getSize()); - StringBuffer link = new StringBuffer(); + StringBuilder link = new StringBuilder(); readISOString(link, input, header.getSize() - descriptionLength); String decodedLink = URLDecoder.decode(link.toString(), "UTF-8"); diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/id3reader/ID3Reader.java b/core/src/main/java/de/danoeh/antennapod/core/util/id3reader/ID3Reader.java index 241082213..5a2b6f37f 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/id3reader/ID3Reader.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/id3reader/ID3Reader.java @@ -170,7 +170,7 @@ public class ID3Reader { return out; } - protected int readString(StringBuffer buffer, InputStream input, int max) throws IOException, + protected int readString(StringBuilder buffer, InputStream input, int max) throws IOException, ID3ReaderException { if (max > 0) { char[] encoding = readBytes(input, 1); @@ -191,7 +191,7 @@ public class ID3Reader { } } - protected int readISOString(StringBuffer buffer, InputStream input, int max) + protected int readISOString(StringBuilder buffer, InputStream input, int max) throws IOException, ID3ReaderException { int bytesRead = 0; @@ -204,7 +204,7 @@ public class ID3Reader { return bytesRead; } - private int readUnicodeString(StringBuffer strBuffer, InputStream input, int max, Charset charset) + private int readUnicodeString(StringBuilder strBuffer, InputStream input, int max, Charset charset) throws IOException, ID3ReaderException { byte[] buffer = new byte[max]; int c, cZero = -1; -- cgit v1.2.3 From 8b041be8aac7f3d6f6f0ece37b4107126c8f3ea2 Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Sun, 21 Jan 2018 22:58:18 +0100 Subject: Improved export success wording (Closes #2545) --- core/src/main/res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'core/src/main') diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml index 2ee295997..f0eed3e38 100644 --- a/core/src/main/res/values/strings.xml +++ b/core/src/main/res/values/strings.xml @@ -667,7 +667,7 @@ Import Export Select file to import - Export successful. The database was written to the SD card. + Export successful. Import successful.\n\nPlease press OK to restart AntennaPod -- cgit v1.2.3 From f7de8a0e440d2f25f568630a70954603c7ab1f07 Mon Sep 17 00:00:00 2001 From: Martin Fietz Date: Mon, 22 Jan 2018 21:04:34 +0100 Subject: Synchronize opening and closing of the database --- .../antennapod/core/storage/PodDBAdapter.java | 39 ++++++++-------------- 1 file changed, 13 insertions(+), 26 deletions(-) (limited to 'core/src/main') diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java b/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java index 7d6ba0e32..3fd46951d 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java +++ b/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java @@ -309,8 +309,7 @@ public class PodDBAdapter { private static PodDBHelper dbHelper; private static volatile SQLiteDatabase db; - private static final Lock dbLock = new ReentrantLock(); - private static final AtomicInteger counter = new AtomicInteger(0); + private static int counter = 0; public static void init(Context context) { PodDBAdapter.context = context.getApplicationContext(); @@ -328,25 +327,18 @@ public class PodDBAdapter { private PodDBAdapter() { } - public PodDBAdapter open() { - int adapters = counter.incrementAndGet(); - Log.v(TAG, "Opening DB #" + adapters); + public synchronized PodDBAdapter open() { + counter++; + Log.v(TAG, "Opening DB #" + counter); - if ((db == null) || (!db.isOpen()) || (db.isReadOnly())) { - try { - dbLock.lock(); - if ((db == null) || (!db.isOpen()) || (db.isReadOnly())) { - db = openDb(); - } - } finally { - dbLock.unlock(); - } + if (db == null || !db.isOpen() || db.isReadOnly()) { + db = openDb(); } return this; } private SQLiteDatabase openDb() { - SQLiteDatabase newDb = null; + SQLiteDatabase newDb; try { newDb = dbHelper.getWritableDatabase(); newDb.enableWriteAheadLogging(); @@ -357,19 +349,14 @@ public class PodDBAdapter { return newDb; } - public void close() { - int adapters = counter.decrementAndGet(); - Log.v(TAG, "Closing DB #" + adapters); + public synchronized void close() { + counter--; + Log.v(TAG, "Closing DB #" + counter); - if (adapters == 0) { + if (counter == 0) { Log.v(TAG, "Closing DB, really"); - try { - dbLock.lock(); - db.close(); - db = null; - } finally { - dbLock.unlock(); - } + db.close(); + db = null; } } -- cgit v1.2.3 From bc9d39dedf3bd1caf4cf06e92b6c56513538ba03 Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Tue, 23 Jan 2018 23:31:05 +0100 Subject: Hotfix for servers not accepting the Range header Because of #2339, the file always exists when starting a download. There is still an issue with the server parsing "Range: bytes=0-" incorrectly, but this commit should make the error appear less often. Related to #2539 --- .../java/de/danoeh/antennapod/core/service/download/HttpDownloader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'core/src/main') diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/download/HttpDownloader.java b/core/src/main/java/de/danoeh/antennapod/core/service/download/HttpDownloader.java index 181a6f619..7ab0931d6 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/download/HttpDownloader.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/download/HttpDownloader.java @@ -93,7 +93,7 @@ public class HttpDownloader extends Downloader { // add range header if necessary - if (fileExists) { + if (fileExists && destination.length() > 0) { request.setSoFar(destination.length()); httpReq.addHeader("Range", "bytes=" + request.getSoFar() + "-"); Log.d(TAG, "Adding range header: " + request.getSoFar()); -- cgit v1.2.3 From 6e5b6396085178db915f9267637db53bc9cd144a Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Sat, 17 Feb 2018 18:09:04 +0100 Subject: Removed large icon Closes #2541. We do not need the same icon twice. As the icon is displayed white-on-white, it is not visible anyways. This also gives more space to the notification text --- .../danoeh/antennapod/core/service/download/DownloadService.java | 8 -------- 1 file changed, 8 deletions(-) (limited to 'core/src/main') diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadService.java b/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadService.java index d66af22ef..a62c9d8bf 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadService.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadService.java @@ -339,12 +339,9 @@ public class DownloadService extends Service { } private void setupNotificationBuilders() { - Bitmap icon = BitmapFactory.decodeResource(getResources(), R.drawable.stat_notify_sync); - notificationCompatBuilder = new NotificationCompat.Builder(this) .setOngoing(true) .setContentIntent(ClientConfig.downloadServiceCallbacks.getNotificationContentIntent(this)) - .setLargeIcon(icon) .setSmallIcon(R.drawable.stat_notify_sync); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { notificationCompatBuilder.setVisibility(Notification.VISIBILITY_PUBLIC); @@ -511,10 +508,6 @@ public class DownloadService extends Service { successfulDownloads, failedDownloads) ) .setSmallIcon(R.drawable.stat_notify_sync_error) - .setLargeIcon( - BitmapFactory.decodeResource(getResources(), - R.drawable.stat_notify_sync_error) - ) .setContentIntent( ClientConfig.downloadServiceCallbacks.getReportNotificationContentIntent(this) ) @@ -565,7 +558,6 @@ public class DownloadService extends Service { .setStyle(new NotificationCompat.BigTextStyle().bigText(getText(R.string.authentication_notification_msg) + ": " + resourceTitle)) .setSmallIcon(R.drawable.ic_stat_authentication) - .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_stat_authentication)) .setAutoCancel(true) .setContentIntent(ClientConfig.downloadServiceCallbacks.getAuthentificationNotificationContentIntent(DownloadService.this, downloadRequest)); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { -- cgit v1.2.3 From f90d3c2e7b7197e8189729b421aa2fed63085d87 Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Tue, 20 Feb 2018 23:22:49 +0100 Subject: Backup corrupted db This might allow some forensics if #2463 happens. Maybe it also allows to recover some of the files manually. --- .../antennapod/core/storage/PodDBAdapter.java | 32 +++++++++++++++++++--- 1 file changed, 28 insertions(+), 4 deletions(-) (limited to 'core/src/main') diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java b/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java index 3fd46951d..5ff3f70df 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java +++ b/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java @@ -3,7 +3,9 @@ package de.danoeh.antennapod.core.storage; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; +import android.database.DatabaseErrorHandler; import android.database.DatabaseUtils; +import android.database.DefaultDatabaseErrorHandler; import android.database.MergeCursor; import android.database.SQLException; import android.database.sqlite.SQLiteDatabase; @@ -13,13 +15,12 @@ import android.media.MediaMetadataRetriever; import android.text.TextUtils; import android.util.Log; +import java.io.File; +import java.io.IOException; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Set; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; import de.danoeh.antennapod.core.R; import de.danoeh.antennapod.core.event.ProgressEvent; @@ -35,6 +36,7 @@ import de.danoeh.antennapod.core.service.download.DownloadStatus; import de.danoeh.antennapod.core.util.LongIntMap; import de.danoeh.antennapod.core.util.flattr.FlattrStatus; import de.greenrobot.event.EventBus; +import org.apache.commons.io.FileUtils; // TODO Remove media column from feeditem table @@ -1643,6 +1645,28 @@ public class PodDBAdapter { return db.rawQuery(FEED_STATISTICS_QUERY, null); } + /** + * Called when a database corruption happens + */ + public static class PodDbErrorHandler implements DatabaseErrorHandler { + @Override + public void onCorruption(SQLiteDatabase db) { + Log.e(TAG, "Database corrupted: " + db.getPath()); + + File dbPath = new File(db.getPath()); + File backupFolder = PodDBAdapter.context.getExternalFilesDir(null); + File backupFile = new File(backupFolder, "CorruptedDatabaseBackup.db"); + try { + FileUtils.copyFile(dbPath, backupFile); + Log.d(TAG, "Dumped database to " + backupFile.getPath()); + } catch (IOException e) { + Log.d(TAG, Log.getStackTraceString(e)); + } + + new DefaultDatabaseErrorHandler().onCorruption(db); // This deletes the database + } + } + /** * Helper class for opening the Antennapod database. */ @@ -1661,7 +1685,7 @@ public class PodDBAdapter { */ public PodDBHelper(final Context context, final String name, final CursorFactory factory) { - super(context, name, factory, VERSION); + super(context, name, factory, VERSION, new PodDbErrorHandler()); this.context = context; } -- cgit v1.2.3 From f514a439e22db0563f9cf1be712d2ec8873dbc22 Mon Sep 17 00:00:00 2001 From: Jan Niehusmann Date: Sun, 4 Mar 2018 22:12:57 +0100 Subject: Fix possible NPE accessing image.download_url May fix #2386. If so, thanks to @cyplo who provided the logcat output which directed me to that code path. --- core/src/main/java/de/danoeh/antennapod/core/feed/Feed.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'core/src/main') diff --git a/core/src/main/java/de/danoeh/antennapod/core/feed/Feed.java b/core/src/main/java/de/danoeh/antennapod/core/feed/Feed.java index 746dd43c4..78df74ee7 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/feed/Feed.java +++ b/core/src/main/java/de/danoeh/antennapod/core/feed/Feed.java @@ -305,8 +305,10 @@ public class Feed extends FeedFile implements FlattrThing, ImageResource { if (super.compareWithOther(other)) { return true; } - if(other.image != null && !TextUtils.equals(image.download_url, other.image.download_url)) { - return true; + if (other.image != null) { + if (image == null || !TextUtils.equals(image.download_url, other.image.download_url)) { + return true; + } } if (!TextUtils.equals(feedTitle, other.feedTitle)) { return true; -- cgit v1.2.3 From b71e61a221466fe9cbaaa031733f3ffff9209829 Mon Sep 17 00:00:00 2001 From: orionlee Date: Tue, 13 Mar 2018 09:51:50 -0700 Subject: Upgrade to Android Gradle Plugin v3.0.1 - bare minimal to get it built, ignoring depercation warnings Details: - upgraded buildtools to the latest (minimum 26.0.2 required) - retired retrolambda - added flavorDimensions (v3 requirement) - Migrate dependency configurations for local modules (:core) - Declaration of resources update in styles.xml (AAPT2 requirement) - upgraded plugin github play-publisher to v1.2.0 --- core/src/main/res/values/styles.xml | 404 ++++++++++++++++++------------------ 1 file changed, 202 insertions(+), 202 deletions(-) (limited to 'core/src/main') diff --git a/core/src/main/res/values/styles.xml b/core/src/main/res/values/styles.xml index b9a9fb293..13d956bab 100644 --- a/core/src/main/res/values/styles.xml +++ b/core/src/main/res/values/styles.xml @@ -11,57 +11,57 @@ @style/ProgressBarLight @style/Widget.AntennaPod.Button @style/AntennaPod.Dialog.Light - @color/grey600 - @drawable/ic_info_grey600_24dp - @drawable/ic_search_grey600_24dp - @drawable/ic_settings_input_antenna_grey600_24dp - @drawable/ic_file_download_grey600_24dp - @drawable/ic_fast_forward_grey600_24dp - @drawable/ic_pause_grey600_24dp - @drawable/ic_play_arrow_grey600_24dp - @drawable/ic_fast_rewind_grey600_24dp - @drawable/ic_delete_grey600_24dp - @drawable/ic_add_grey600_24dp - @drawable/ic_feed_grey600_24dp - @drawable/ic_web_grey600_24dp - @drawable/ic_done_grey600_24dp - @drawable/ic_cancel_grey600_24dp - @drawable/ic_expand_more_grey600_36dp - @drawable/ic_refresh_grey600_24dp - @drawable/navigation_up - @drawable/ic_share_grey600_24dp - @drawable/ic_list_grey600_24dp - @drawable/ic_hearing_grey600_18dp - @drawable/ic_remove_red_eye_grey600_18dp - @color/white - @color/overlay_light - @drawable/overlay_drawable - @drawable/ic_drag_vertical_grey600_48dp - @color/white - @color/white - @drawable/ic_new_releases_grey600_24dp - @drawable/ic_history_grey600_24dp - @drawable/ic_folder_grey600_24dp - @drawable/ic_play_arrow_grey600_36dp - @drawable/ic_pause_grey600_36dp - @drawable/ic_fast_forward_grey600_36dp - @drawable/ic_fast_rewind_grey600_36dp - @drawable/ic_skip_grey600_36dp - @drawable/ic_star_border_grey600_24dp - @drawable/ic_star_grey600_24dp - @drawable/ic_settings_grey600_24dp - @drawable/ic_lock_open_grey600_24dp - @drawable/ic_lock_closed_grey600_24dp - @drawable/ic_filter_grey600_24dp - @drawable/ic_sleep_grey600_24dp - @drawable/ic_sleep_off_grey600_24dp - @drawable/ic_check_box_grey600_24dp - @drawable/ic_check_box_outline_blank_grey600_24dp - @drawable/ic_indeterminate_check_box_grey600_24dp - @drawable/ic_sort_grey600_24dp - @drawable/ic_sd_storage_grey600_36dp - @drawable/ic_create_new_folder_grey600_24dp - @drawable/ic_cast_disconnect_grey600_36dp + @color/grey600 + @drawable/ic_info_grey600_24dp + @drawable/ic_search_grey600_24dp + @drawable/ic_settings_input_antenna_grey600_24dp + @drawable/ic_file_download_grey600_24dp + @drawable/ic_fast_forward_grey600_24dp + @drawable/ic_pause_grey600_24dp + @drawable/ic_play_arrow_grey600_24dp + @drawable/ic_fast_rewind_grey600_24dp + @drawable/ic_delete_grey600_24dp + @drawable/ic_add_grey600_24dp + @drawable/ic_feed_grey600_24dp + @drawable/ic_web_grey600_24dp + @drawable/ic_done_grey600_24dp + @drawable/ic_cancel_grey600_24dp + @drawable/ic_expand_more_grey600_36dp + @drawable/ic_refresh_grey600_24dp + @drawable/navigation_up + @drawable/ic_share_grey600_24dp + @drawable/ic_list_grey600_24dp + @drawable/ic_hearing_grey600_18dp + @drawable/ic_remove_red_eye_grey600_18dp + @color/white + @color/overlay_light + @drawable/overlay_drawable + @drawable/ic_drag_vertical_grey600_48dp + @color/white + @color/white + @drawable/ic_new_releases_grey600_24dp + @drawable/ic_history_grey600_24dp + @drawable/ic_folder_grey600_24dp + @drawable/ic_play_arrow_grey600_36dp + @drawable/ic_pause_grey600_36dp + @drawable/ic_fast_forward_grey600_36dp + @drawable/ic_fast_rewind_grey600_36dp + @drawable/ic_skip_grey600_36dp + @drawable/ic_star_border_grey600_24dp + @drawable/ic_star_grey600_24dp + @drawable/ic_settings_grey600_24dp + @drawable/ic_lock_open_grey600_24dp + @drawable/ic_lock_closed_grey600_24dp + @drawable/ic_filter_grey600_24dp + @drawable/ic_sleep_grey600_24dp + @drawable/ic_sleep_off_grey600_24dp + @drawable/ic_check_box_grey600_24dp + @drawable/ic_check_box_outline_blank_grey600_24dp + @drawable/ic_indeterminate_check_box_grey600_24dp + @drawable/ic_sort_grey600_24dp + @drawable/ic_sd_storage_grey600_36dp + @drawable/ic_create_new_folder_grey600_24dp + @drawable/ic_cast_disconnect_grey600_36dp