diff options
Diffstat (limited to 'src/de/danoeh/antennapod/util')
54 files changed, 0 insertions, 4777 deletions
diff --git a/src/de/danoeh/antennapod/util/ChapterUtils.java b/src/de/danoeh/antennapod/util/ChapterUtils.java deleted file mode 100644 index 2d9022eed..000000000 --- a/src/de/danoeh/antennapod/util/ChapterUtils.java +++ /dev/null @@ -1,274 +0,0 @@ -package de.danoeh.antennapod.util; - -import android.util.Log; - -import org.apache.commons.io.IOUtils; - -import java.io.BufferedInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.Collections; -import java.util.List; - -import de.danoeh.antennapod.BuildConfig; -import de.danoeh.antennapod.feed.Chapter; -import de.danoeh.antennapod.util.comparator.ChapterStartTimeComparator; -import de.danoeh.antennapod.util.id3reader.ChapterReader; -import de.danoeh.antennapod.util.id3reader.ID3ReaderException; -import de.danoeh.antennapod.util.playback.Playable; -import de.danoeh.antennapod.util.vorbiscommentreader.VorbisCommentChapterReader; -import de.danoeh.antennapod.util.vorbiscommentreader.VorbisCommentReaderException; - -/** - * Utility class for getting chapter data from media files. - */ -public class ChapterUtils { - private static final String TAG = "ChapterUtils"; - - private ChapterUtils() { - } - - /** - * Uses the download URL of a media object of a feeditem to read its ID3 - * chapters. - */ - public static void readID3ChaptersFromPlayableStreamUrl(Playable p) { - if (p != null && p.getStreamUrl() != null) { - if (BuildConfig.DEBUG) - Log.d(TAG, "Reading id3 chapters from item " + p.getEpisodeTitle()); - InputStream in = null; - try { - URL url = new URL(p.getStreamUrl()); - ChapterReader reader = new ChapterReader(); - - in = url.openStream(); - reader.readInputStream(in); - List<Chapter> chapters = reader.getChapters(); - - if (chapters != null) { - Collections - .sort(chapters, new ChapterStartTimeComparator()); - processChapters(chapters, p); - if (chaptersValid(chapters)) { - p.setChapters(chapters); - Log.i(TAG, "Chapters loaded"); - } else { - Log.e(TAG, "Chapter data was invalid"); - } - } else { - Log.i(TAG, "ChapterReader could not find any ID3 chapters"); - } - } catch (MalformedURLException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } catch (ID3ReaderException e) { - e.printStackTrace(); - } finally { - if (in != null) { - try { - in.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - } else { - Log.e(TAG, - "Unable to read ID3 chapters: media or download URL was null"); - } - } - - /** - * Uses the file URL of a media object of a feeditem to read its ID3 - * chapters. - */ - public static void readID3ChaptersFromPlayableFileUrl(Playable p) { - if (p != null && p.localFileAvailable() && p.getLocalMediaUrl() != null) { - if (BuildConfig.DEBUG) - Log.d(TAG, "Reading id3 chapters from item " + p.getEpisodeTitle()); - File source = new File(p.getLocalMediaUrl()); - if (source.exists()) { - ChapterReader reader = new ChapterReader(); - InputStream in = null; - - try { - in = new BufferedInputStream(new FileInputStream(source)); - reader.readInputStream(in); - List<Chapter> chapters = reader.getChapters(); - - if (chapters != null) { - Collections.sort(chapters, - new ChapterStartTimeComparator()); - processChapters(chapters, p); - if (chaptersValid(chapters)) { - p.setChapters(chapters); - Log.i(TAG, "Chapters loaded"); - } else { - Log.e(TAG, "Chapter data was invalid"); - } - } else { - Log.i(TAG, - "ChapterReader could not find any ID3 chapters"); - } - } catch (IOException e) { - e.printStackTrace(); - } catch (ID3ReaderException e) { - e.printStackTrace(); - } finally { - if (in != null) { - try { - in.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - } else { - Log.e(TAG, "Unable to read id3 chapters: Source doesn't exist"); - } - } - } - - public static void readOggChaptersFromPlayableStreamUrl(Playable media) { - if (media != null && media.streamAvailable()) { - InputStream input = null; - try { - URL url = new URL(media.getStreamUrl()); - input = url.openStream(); - if (input != null) { - readOggChaptersFromInputStream(media, input); - } - } catch (MalformedURLException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } finally { - IOUtils.closeQuietly(input); - } - } - } - - public static void readOggChaptersFromPlayableFileUrl(Playable media) { - if (media != null && media.getLocalMediaUrl() != null) { - File source = new File(media.getLocalMediaUrl()); - if (source.exists()) { - InputStream input = null; - try { - input = new BufferedInputStream(new FileInputStream(source)); - readOggChaptersFromInputStream(media, input); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } finally { - IOUtils.closeQuietly(input); - } - } - } - } - - private static void readOggChaptersFromInputStream(Playable p, - InputStream input) { - if (BuildConfig.DEBUG) - Log.d(TAG, - "Trying to read chapters from item with title " - + p.getEpisodeTitle()); - try { - VorbisCommentChapterReader reader = new VorbisCommentChapterReader(); - reader.readInputStream(input); - List<Chapter> chapters = reader.getChapters(); - if (chapters != null) { - Collections.sort(chapters, new ChapterStartTimeComparator()); - processChapters(chapters, p); - if (chaptersValid(chapters)) { - p.setChapters(chapters); - Log.i(TAG, "Chapters loaded"); - } else { - Log.e(TAG, "Chapter data was invalid"); - } - } else { - Log.i(TAG, - "ChapterReader could not find any Ogg vorbis chapters"); - } - } catch (VorbisCommentReaderException e) { - e.printStackTrace(); - } - } - - /** - * Makes sure that chapter does a title and an item attribute. - */ - private static void processChapters(List<Chapter> chapters, Playable p) { - for (int i = 0; i < chapters.size(); i++) { - Chapter c = chapters.get(i); - if (c.getTitle() == null) { - c.setTitle(Integer.toString(i)); - } - } - } - - private static boolean chaptersValid(List<Chapter> chapters) { - if (chapters.isEmpty()) { - return false; - } - for (Chapter c : chapters) { - if (c.getTitle() == null) { - return false; - } - if (c.getStart() < 0) { - return false; - } - } - return true; - } - - /** - * Calls getCurrentChapter with current position. - */ - public static Chapter getCurrentChapter(Playable media) { - if (media.getChapters() != null) { - List<Chapter> chapters = media.getChapters(); - Chapter current = null; - if (chapters != null) { - current = chapters.get(0); - for (Chapter sc : chapters) { - if (sc.getStart() > media.getPosition()) { - break; - } else { - current = sc; - } - } - } - return current; - } else { - return null; - } - } - - public static void loadChaptersFromStreamUrl(Playable media) { - if (BuildConfig.DEBUG) - Log.d(TAG, "Starting chapterLoader thread"); - ChapterUtils.readID3ChaptersFromPlayableStreamUrl(media); - if (media.getChapters() == null) { - ChapterUtils.readOggChaptersFromPlayableStreamUrl(media); - } - - if (BuildConfig.DEBUG) - Log.d(TAG, "ChapterLoaderThread has finished"); - } - - public static void loadChaptersFromFileUrl(Playable media) { - if (media.localFileAvailable()) { - ChapterUtils.readID3ChaptersFromPlayableFileUrl(media); - if (media.getChapters() == null) { - ChapterUtils.readOggChaptersFromPlayableFileUrl(media); - } - } else { - Log.e(TAG, "Could not load chapters from file url: local file not available"); - } - } -} diff --git a/src/de/danoeh/antennapod/util/Converter.java b/src/de/danoeh/antennapod/util/Converter.java deleted file mode 100644 index f4c2b2f66..000000000 --- a/src/de/danoeh/antennapod/util/Converter.java +++ /dev/null @@ -1,103 +0,0 @@ -package de.danoeh.antennapod.util; - -import android.util.Log; - -/** Provides methods for converting various units. */ -public final class Converter { - /** Class shall not be instantiated. */ - private Converter() { - } - - /** Logging tag. */ - private static final String TAG = "Converter"; - - - /** Indicates that the value is in the Byte range.*/ - private static final int B_RANGE = 0; - /** Indicates that the value is in the Kilobyte range.*/ - private static final int KB_RANGE = 1; - /** Indicates that the value is in the Megabyte range.*/ - private static final int MB_RANGE = 2; - /** Indicates that the value is in the Gigabyte range.*/ - private static final int GB_RANGE = 3; - /** Determines the length of the number for best readability.*/ - private static final int NUM_LENGTH = 1024; - - - private static final int HOURS_MIL = 3600000; - private static final int MINUTES_MIL = 60000; - private static final int SECONDS_MIL = 1000; - - /** Takes a byte-value and converts it into a more readable - * String. - * @param input The value to convert - * @return The converted String with a unit - * */ - public static String byteToString(final long input) { - int i = 0; - int result = 0; - - for (i = 0; i < GB_RANGE + 1; i++) { - result = (int) (input / Math.pow(1024, i)); - if (result < NUM_LENGTH) { - break; - } - } - - switch (i) { - case B_RANGE: - return result + " B"; - case KB_RANGE: - return result + " KB"; - case MB_RANGE: - return result + " MB"; - case GB_RANGE: - return result + " GB"; - default: - Log.e(TAG, "Error happened in byteToString"); - return "ERROR"; - } - } - - /** Converts milliseconds to a string containing hours, minutes and seconds */ - public static String getDurationStringLong(int duration) { - int h = duration / HOURS_MIL; - int rest = duration - h * HOURS_MIL; - int m = rest / MINUTES_MIL; - rest -= m * MINUTES_MIL; - int s = rest / SECONDS_MIL; - - return String.format("%02d:%02d:%02d", h, m, s); - } - - /** Converts milliseconds to a string containing hours and minutes */ - public static String getDurationStringShort(int duration) { - int h = duration / HOURS_MIL; - int rest = duration - h * HOURS_MIL; - int m = rest / MINUTES_MIL; - - return String.format("%02d:%02d", h, m); - } - - /** Converts long duration string (HH:MM:SS) to milliseconds. */ - public static int durationStringLongToMs(String input) { - String[] parts = input.split(":"); - if (parts.length != 3) { - return 0; - } - return Integer.valueOf(parts[0]) * 3600 * 1000 + - Integer.valueOf(parts[1]) * 60 * 1000 + - Integer.valueOf(parts[2]) * 1000; - } - - /** Converts short duration string (HH:MM) to milliseconds. */ - public static int durationStringShortToMs(String input) { - String[] parts = input.split(":"); - if (parts.length != 2) { - return 0; - } - return Integer.valueOf(parts[0]) * 3600 * 1000 + - Integer.valueOf(parts[1]) * 1000 * 60; - } - -} diff --git a/src/de/danoeh/antennapod/util/DownloadError.java b/src/de/danoeh/antennapod/util/DownloadError.java deleted file mode 100644 index 1a64991a6..000000000 --- a/src/de/danoeh/antennapod/util/DownloadError.java +++ /dev/null @@ -1,52 +0,0 @@ -package de.danoeh.antennapod.util; - -import android.content.Context; -import de.danoeh.antennapod.R; - -/** Utility class for Download Errors. */ -public enum DownloadError { - SUCCESS(0, R.string.download_successful), - ERROR_PARSER_EXCEPTION(1, R.string.download_error_parser_exception), - ERROR_UNSUPPORTED_TYPE(2, R.string.download_error_unsupported_type), - ERROR_CONNECTION_ERROR(3, R.string.download_error_connection_error), - ERROR_MALFORMED_URL(4, R.string.download_error_error_unknown), - ERROR_IO_ERROR(5, R.string.download_error_io_error), - ERROR_FILE_EXISTS(6, R.string.download_error_error_unknown), - ERROR_DOWNLOAD_CANCELLED(7, R.string.download_error_error_unknown), - ERROR_DEVICE_NOT_FOUND(8, R.string.download_error_device_not_found), - ERROR_HTTP_DATA_ERROR(9, R.string.download_error_http_data_error), - ERROR_NOT_ENOUGH_SPACE(10, R.string.download_error_insufficient_space), - ERROR_UNKNOWN_HOST(11, R.string.download_error_unknown_host), - ERROR_REQUEST_ERROR(12, R.string.download_error_request_error), - ERROR_DB_ACCESS_ERROR(13, R.string.download_error_db_access), - ERROR_UNAUTHORIZED(14, R.string.download_error_unauthorized); - - private final int code; - private final int resId; - - private DownloadError(int code, int resId) { - this.code = code; - this.resId = resId; - } - - /** Return DownloadError from its associated code. */ - public static DownloadError fromCode(int code) { - for (DownloadError reason : values()) { - if (reason.getCode() == code) { - return reason; - } - } - throw new IllegalArgumentException("unknown code: " + code); - } - - /** Get machine-readable code. */ - public int getCode() { - return code; - } - - /** Get a human-readable string. */ - public String getErrorString(Context context) { - return context.getString(resId); - } - -} diff --git a/src/de/danoeh/antennapod/util/DuckType.java b/src/de/danoeh/antennapod/util/DuckType.java deleted file mode 100644 index 163110418..000000000 --- a/src/de/danoeh/antennapod/util/DuckType.java +++ /dev/null @@ -1,117 +0,0 @@ -/* Adapted from: http://thinking-in-code.blogspot.com/2008/11/duck-typing-in-java-using-dynamic.html */ - -package de.danoeh.antennapod.util; - -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; - -import de.danoeh.antennapod.BuildConfig; - -/** - * Allows "duck typing" or dynamic invocation based on method signature rather - * than type hierarchy. In other words, rather than checking whether something - * IS-a duck, check whether it WALKS-like-a duck or QUACKS-like a duck. - * - * To use first use the coerce static method to indicate the object you want to - * do Duck Typing for, then specify an interface to the to method which you want - * to coerce the type to, e.g: - * - * public interface Foo { void aMethod(); } class Bar { ... public void - * aMethod() { ... } ... } Bar bar = ...; Foo foo = - * DuckType.coerce(bar).to(Foo.class); foo.aMethod(); - * - * - */ -public class DuckType { - - private final Object objectToCoerce; - - private DuckType(Object objectToCoerce) { - this.objectToCoerce = objectToCoerce; - } - - private class CoercedProxy implements InvocationHandler { - @Override - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - Method delegateMethod = findMethodBySignature(method); - assert delegateMethod != null; - return delegateMethod.invoke(DuckType.this.objectToCoerce, args); - } - } - - /** - * Specify the duck typed object to coerce. - * - * @param object - * the object to coerce - * @return - */ - public static DuckType coerce(Object object) { - return new DuckType(object); - } - - /** - * Coerce the Duck Typed object to the given interface providing it - * implements all the necessary methods. - * - * @param - * @param iface - * @return an instance of the given interface that wraps the duck typed - * class - * @throws ClassCastException - * if the object being coerced does not implement all the - * methods in the given interface. - */ - @SuppressWarnings({ "rawtypes", "unchecked" }) - public <T> T to(Class iface) { - if (BuildConfig.DEBUG && !iface.isInterface()) throw new AssertionError("cannot coerce object to a class, must be an interface"); - if (isA(iface)) { - return (T) iface.cast(objectToCoerce); - } - if (quacksLikeA(iface)) { - return generateProxy(iface); - } - throw new ClassCastException("Could not coerce object of type " + objectToCoerce.getClass() + " to " + iface); - } - - @SuppressWarnings("rawtypes") - private boolean isA(Class iface) { - return objectToCoerce.getClass().isInstance(iface); - } - - /** - * Determine whether the duck typed object can be used with the given - * interface. - * - * @param Type - * of the interface to check. - * @param iface - * Interface class to check - * @return true if the object will support all the methods in the interface, - * false otherwise. - */ - @SuppressWarnings("rawtypes") - public boolean quacksLikeA(Class iface) { - for (Method method : iface.getMethods()) { - if (findMethodBySignature(method) == null) { - return false; - } - } - return true; - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - private <T> T generateProxy(Class iface) { - return (T) Proxy.newProxyInstance(iface.getClassLoader(), new Class[] { iface }, new CoercedProxy()); - } - - private Method findMethodBySignature(Method method) { - try { - return objectToCoerce.getClass().getMethod(method.getName(), method.getParameterTypes()); - } catch (NoSuchMethodException e) { - return null; - } - } - -}
\ No newline at end of file diff --git a/src/de/danoeh/antennapod/util/EpisodeFilter.java b/src/de/danoeh/antennapod/util/EpisodeFilter.java deleted file mode 100644 index 115913bca..000000000 --- a/src/de/danoeh/antennapod/util/EpisodeFilter.java +++ /dev/null @@ -1,49 +0,0 @@ -package de.danoeh.antennapod.util; - -import de.danoeh.antennapod.feed.FeedItem; - -import java.util.ArrayList; -import java.util.List; - -public class EpisodeFilter { - private EpisodeFilter() { - - } - - /** Return a copy of the itemlist without items which have no media. */ - public static ArrayList<FeedItem> getEpisodeList(List<FeedItem> items) { - ArrayList<FeedItem> episodes = new ArrayList<FeedItem>(items); - for (FeedItem item : items) { - if (item.getMedia() == null) { - episodes.remove(item); - } - } - return episodes; - } - - public static int countItemsWithEpisodes(List<FeedItem> items) { - int count = 0; - for (FeedItem item : items) { - if (item.getMedia() != null) { - count++; - } - } - return count; - } - - public static FeedItem accessEpisodeByIndex(List<FeedItem> items, - int position) { - int count = 0; - for (FeedItem item : items) { - - if (item.getMedia() != null) { - if (count == position) { - return item; - } else { - count++; - } - } - } - return null; - } -} diff --git a/src/de/danoeh/antennapod/util/FeedtitleComparator.java b/src/de/danoeh/antennapod/util/FeedtitleComparator.java deleted file mode 100644 index 112b6678d..000000000 --- a/src/de/danoeh/antennapod/util/FeedtitleComparator.java +++ /dev/null @@ -1,15 +0,0 @@ -package de.danoeh.antennapod.util; - -import de.danoeh.antennapod.feed.Feed; - -import java.util.Comparator; - -/** Compares the title of two feeds for sorting. */ -public class FeedtitleComparator implements Comparator<Feed> { - - @Override - public int compare(Feed lhs, Feed rhs) { - return lhs.getTitle().compareToIgnoreCase(rhs.getTitle()); - } - -} diff --git a/src/de/danoeh/antennapod/util/FileNameGenerator.java b/src/de/danoeh/antennapod/util/FileNameGenerator.java deleted file mode 100644 index 702df62b8..000000000 --- a/src/de/danoeh/antennapod/util/FileNameGenerator.java +++ /dev/null @@ -1,36 +0,0 @@ -package de.danoeh.antennapod.util; - -import java.util.Arrays; - -/** Generates valid filenames for a given string. */ -public class FileNameGenerator { - - private static final char[] ILLEGAL_CHARACTERS = { '/', '\\', '?', '%', - '*', ':', '|', '"', '<', '>' }; - static { - Arrays.sort(ILLEGAL_CHARACTERS); - } - - private FileNameGenerator() { - - } - - /** - * This method will return a new string that doesn't contain any illegal - * characters of the given string. - */ - public static String generateFileName(String string) { - StringBuilder builder = new StringBuilder(); - for (int i = 0; i < string.length(); i++) { - char c = string.charAt(i); - if (Arrays.binarySearch(ILLEGAL_CHARACTERS, c) < 0) { - builder.append(c); - } - } - return builder.toString().replaceFirst(" *$",""); - } - - public static long generateLong(final String str) { - return str.hashCode(); - } -} diff --git a/src/de/danoeh/antennapod/util/InvalidFeedException.java b/src/de/danoeh/antennapod/util/InvalidFeedException.java deleted file mode 100644 index 50adae216..000000000 --- a/src/de/danoeh/antennapod/util/InvalidFeedException.java +++ /dev/null @@ -1,21 +0,0 @@ -package de.danoeh.antennapod.util; - -/** Thrown if a feed has invalid attribute values. */ -public class InvalidFeedException extends Exception { - - public InvalidFeedException() { - } - - public InvalidFeedException(String detailMessage) { - super(detailMessage); - } - - public InvalidFeedException(Throwable throwable) { - super(throwable); - } - - public InvalidFeedException(String detailMessage, Throwable throwable) { - super(detailMessage, throwable); - } - -} diff --git a/src/de/danoeh/antennapod/util/LangUtils.java b/src/de/danoeh/antennapod/util/LangUtils.java deleted file mode 100644 index e6e1d8399..000000000 --- a/src/de/danoeh/antennapod/util/LangUtils.java +++ /dev/null @@ -1,120 +0,0 @@ -package de.danoeh.antennapod.util; - -import java.nio.charset.Charset; -import java.util.HashMap; - -public class LangUtils { - public static final Charset UTF_8 = Charset.forName("UTF-8"); - - private static HashMap<String, String> languages; - static { - languages = new HashMap<String, String>(); - languages.put("af", "Afrikaans"); - languages.put("sq", "Albanian"); - languages.put("sq", "Albanian"); - languages.put("eu", "Basque"); - languages.put("be", "Belarusian"); - languages.put("bg", "Bulgarian"); - languages.put("ca", "Catalan"); - languages.put("Chinese (Simplified)", "zh-cn"); - languages.put("Chinese (Traditional)", "zh-tw"); - languages.put("hr", "Croatian"); - languages.put("cs", "Czech"); - languages.put("da", "Danish"); - languages.put("nl", "Dutch"); - languages.put("nl-be", "Dutch (Belgium)"); - languages.put("nl-nl", "Dutch (Netherlands)"); - languages.put("en", "English"); - languages.put("en-au", "English (Australia)"); - languages.put("en-bz", "English (Belize)"); - languages.put("en-ca", "English (Canada)"); - languages.put("en-ie", "English (Ireland)"); - languages.put("en-jm", "English (Jamaica)"); - languages.put("en-nz", "English (New Zealand)"); - languages.put("en-ph", "English (Phillipines)"); - languages.put("en-za", "English (South Africa)"); - languages.put("en-tt", "English (Trinidad)"); - languages.put("en-gb", "English (United Kingdom)"); - languages.put("en-us", "English (United States)"); - languages.put("en-zw", "English (Zimbabwe)"); - languages.put("et", "Estonian"); - languages.put("fo", "Faeroese"); - languages.put("fi", "Finnish"); - languages.put("fr", "French"); - languages.put("fr-be", "French (Belgium)"); - languages.put("fr-ca", "French (Canada)"); - languages.put("fr-fr", "French (France)"); - languages.put("fr-lu", "French (Luxembourg)"); - languages.put("fr-mc", "French (Monaco)"); - languages.put("fr-ch", "French (Switzerland)"); - languages.put("gl", "Galician"); - languages.put("gd", "Gaelic"); - languages.put("de", "German"); - languages.put("de-at", "German (Austria)"); - languages.put("de-de", "German (Germany)"); - languages.put("de-li", "German (Liechtenstein)"); - languages.put("de-lu", "German (Luxembourg)"); - languages.put("de-ch", "German (Switzerland)"); - languages.put("el", "Greek"); - languages.put("haw", "Hawaiian"); - languages.put("hu", "Hungarian"); - languages.put("is", "Icelandic"); - languages.put("in", "Indonesian"); - languages.put("ga", "Irish"); - languages.put("it", "Italian"); - languages.put("it-it", "Italian (Italy)"); - languages.put("it-ch", "Italian (Switzerland)"); - languages.put("ja", "Japanese"); - languages.put("ko", "Korean"); - languages.put("mk", "Macedonian"); - languages.put("no", "Norwegian"); - languages.put("pl", "Polish"); - languages.put("pt", "Portugese"); - languages.put("pt-br", "Portugese (Brazil)"); - languages.put("pt-pt", "Portugese (Portugal"); - languages.put("ro", "Romanian"); - languages.put("ro-mo", "Romanian (Moldova)"); - languages.put("ro-ro", "Romanian (Romania"); - languages.put("ru", "Russian"); - languages.put("ru-mo", "Russian (Moldova)"); - languages.put("ru-ru", "Russian (Russia)"); - languages.put("sr", "Serbian"); - languages.put("sk", "Slovak"); - languages.put("sl", "Slovenian"); - languages.put("es", "Spanish"); - languages.put("es-ar", "Spanish (Argentinia)"); - languages.put("es=bo", "Spanish (Bolivia)"); - languages.put("es-cl", "Spanish (Chile)"); - languages.put("es-co", "Spanish (Colombia)"); - languages.put("es-cr", "Spanish (Costa Rica)"); - languages.put("es-do", "Spanish (Dominican Republic)"); - languages.put("es-ec", "Spanish (Ecuador)"); - languages.put("es-sv", "Spanish (El Salvador)"); - languages.put("es-gt", "Spanish (Guatemala)"); - languages.put("es-hn", "Spanish (Honduras)"); - languages.put("es-mx", "Spanish (Mexico)"); - languages.put("es-ni", "Spanish (Nicaragua)"); - languages.put("es-pa", "Spanish (Panama)"); - languages.put("es-py", "Spanish (Paraguay)"); - languages.put("es-pe", "Spanish (Peru)"); - languages.put("es-pr", "Spanish (Puerto Rico)"); - languages.put("es-es", "Spanish (Spain)"); - languages.put("es-uy", "Spanish (Uruguay)"); - languages.put("es-ve", "Spanish (Venezuela)"); - languages.put("sv", "Swedish"); - languages.put("sv-fi", "Swedish (Finland)"); - languages.put("sv-se", "Swedish (Sweden)"); - languages.put("tr", "Turkish"); - languages.put("uk", "Ukranian"); - } - - /** Finds language string for key or returns the language key if it can't be found. */ - public static String getLanguageString(String key) { - String language = languages.get(key); - if (language != null) { - return language; - } else { - return key; - } - } -} diff --git a/src/de/danoeh/antennapod/util/NetworkUtils.java b/src/de/danoeh/antennapod/util/NetworkUtils.java deleted file mode 100644 index 0c8065e94..000000000 --- a/src/de/danoeh/antennapod/util/NetworkUtils.java +++ /dev/null @@ -1,69 +0,0 @@ -package de.danoeh.antennapod.util; - -import android.content.Context; -import android.net.ConnectivityManager; -import android.net.NetworkInfo; -import android.net.wifi.WifiInfo; -import android.net.wifi.WifiManager; -import android.util.Log; -import de.danoeh.antennapod.BuildConfig; -import de.danoeh.antennapod.preferences.UserPreferences; - -import java.util.Arrays; -import java.util.List; - -public class NetworkUtils { - private static final String TAG = "NetworkUtils"; - - private NetworkUtils() { - - } - - /** - * Returns true if the device is connected to Wi-Fi and the Wi-Fi filter for - * automatic downloads is disabled or the device is connected to a Wi-Fi - * network that is on the 'selected networks' list of the Wi-Fi filter for - * automatic downloads and false otherwise. - * */ - public static boolean autodownloadNetworkAvailable(Context context) { - ConnectivityManager cm = (ConnectivityManager) context - .getSystemService(Context.CONNECTIVITY_SERVICE); - NetworkInfo networkInfo = cm.getActiveNetworkInfo(); - if (networkInfo != null) { - if (networkInfo.getType() == ConnectivityManager.TYPE_WIFI) { - if (BuildConfig.DEBUG) - Log.d(TAG, "Device is connected to Wi-Fi"); - if (networkInfo.isConnected()) { - if (!UserPreferences.isEnableAutodownloadWifiFilter()) { - if (BuildConfig.DEBUG) - Log.d(TAG, "Auto-dl filter is disabled"); - return true; - } else { - WifiManager wm = (WifiManager) context - .getSystemService(Context.WIFI_SERVICE); - WifiInfo wifiInfo = wm.getConnectionInfo(); - List<String> selectedNetworks = Arrays - .asList(UserPreferences - .getAutodownloadSelectedNetworks()); - if (selectedNetworks.contains(Integer.toString(wifiInfo - .getNetworkId()))) { - if (BuildConfig.DEBUG) - Log.d(TAG, - "Current network is on the selected networks list"); - return true; - } - } - } - } - } - if (BuildConfig.DEBUG) - Log.d(TAG, "Network for auto-dl is not available"); - return false; - } - - public static boolean networkAvailable(Context context) { - ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); - NetworkInfo info = cm.getActiveNetworkInfo(); - return info != null && info.isConnected(); - } -} diff --git a/src/de/danoeh/antennapod/util/QueueAccess.java b/src/de/danoeh/antennapod/util/QueueAccess.java deleted file mode 100644 index 7a1c7fef2..000000000 --- a/src/de/danoeh/antennapod/util/QueueAccess.java +++ /dev/null @@ -1,93 +0,0 @@ -package de.danoeh.antennapod.util; - -import de.danoeh.antennapod.feed.FeedItem; - -import java.util.Iterator; -import java.util.List; - -/** - * Provides methods for accessing the queue. It is possible to load only a part of the information about the queue that - * is stored in the database (e.g. sometimes the user just has to test if a specific item is contained in the List. - * QueueAccess provides an interface for accessing the queue without having to care about the type of the queue - * representation. - */ -public abstract class QueueAccess { - /** - * Returns true if the item is in the queue, false otherwise. - */ - public abstract boolean contains(long id); - - /** - * Removes the item from the queue. - * - * @return true if the queue was modified by this operation. - */ - public abstract boolean remove(long id); - - private QueueAccess() { - - } - - public static QueueAccess IDListAccess(final List<Long> ids) { - return new QueueAccess() { - @Override - public boolean contains(long id) { - return (ids != null) && ids.contains(id); - } - - @Override - public boolean remove(long id) { - return ids.remove(id); - } - - - }; - } - - public static QueueAccess ItemListAccess(final List<FeedItem> items) { - return new QueueAccess() { - @Override - public boolean contains(long id) { - if (items == null) { - return false; - } - for (FeedItem item : items) { - if (item.getId() == id) { - return true; - } - } - return false; - } - - @Override - public boolean remove(long id) { - Iterator<FeedItem> it = items.iterator(); - FeedItem item; - while (it.hasNext()) { - item = it.next(); - if (item.getId() == id) { - it.remove(); - return true; - } - } - return false; - } - }; - } - - public static QueueAccess NotInQueueAccess() { - return new QueueAccess() { - @Override - public boolean contains(long id) { - return false; - } - - @Override - public boolean remove(long id) { - return false; - } - }; - - } - -} diff --git a/src/de/danoeh/antennapod/util/ShareUtils.java b/src/de/danoeh/antennapod/util/ShareUtils.java deleted file mode 100644 index 941fc62ae..000000000 --- a/src/de/danoeh/antennapod/util/ShareUtils.java +++ /dev/null @@ -1,34 +0,0 @@ -package de.danoeh.antennapod.util; - -import android.content.Context; -import android.content.Intent; -import de.danoeh.antennapod.feed.Feed; -import de.danoeh.antennapod.feed.FeedItem; - -/** Utility methods for sharing data */ -public class ShareUtils { - private static final String TAG = "ShareUtils"; - - private ShareUtils() {} - - public static void shareLink(Context context, String link) { - Intent i = new Intent(Intent.ACTION_SEND); - i.setType("text/plain"); - i.putExtra(Intent.EXTRA_SUBJECT, "Sharing URL"); - i.putExtra(Intent.EXTRA_TEXT, link); - context.startActivity(Intent.createChooser(i, "Share URL")); - } - - public static void shareFeedItemLink(Context context, FeedItem item) { - shareLink(context, item.getLink()); - } - - public static void shareFeedDownloadLink(Context context, Feed feed) { - shareLink(context, feed.getDownload_url()); - } - - public static void shareFeedlink(Context context, Feed feed) { - shareLink(context, feed.getLink()); - } - -} diff --git a/src/de/danoeh/antennapod/util/ShownotesProvider.java b/src/de/danoeh/antennapod/util/ShownotesProvider.java deleted file mode 100644 index 8345ca34d..000000000 --- a/src/de/danoeh/antennapod/util/ShownotesProvider.java +++ /dev/null @@ -1,16 +0,0 @@ -package de.danoeh.antennapod.util; - -import java.util.concurrent.Callable; - -/** - * Created by daniel on 04.08.13. - */ -public interface ShownotesProvider { - /** - * Loads shownotes. If the shownotes have to be loaded from a file or from a - * database, it should be done in a separate thread. After the shownotes - * have been loaded, callback.onShownotesLoaded should be called. - */ - public Callable<String> loadShownotes(); - -} diff --git a/src/de/danoeh/antennapod/util/StorageUtils.java b/src/de/danoeh/antennapod/util/StorageUtils.java deleted file mode 100644 index ff0bde280..000000000 --- a/src/de/danoeh/antennapod/util/StorageUtils.java +++ /dev/null @@ -1,66 +0,0 @@ -package de.danoeh.antennapod.util; - -import android.app.Activity; -import android.content.Context; -import android.content.Intent; -import android.os.Build; -import android.os.StatFs; -import android.util.Log; -import de.danoeh.antennapod.BuildConfig; -import de.danoeh.antennapod.PodcastApp; -import de.danoeh.antennapod.activity.StorageErrorActivity; -import de.danoeh.antennapod.preferences.UserPreferences; - -import java.io.File; - -/** Utility functions for handling storage errors */ -public class StorageUtils { - private static final String TAG = "StorageUtils"; - - public static boolean storageAvailable(Context context) { - File dir = UserPreferences.getDataFolder(context, null); - if (dir != null) { - return dir.exists() && dir.canRead() && dir.canWrite(); - } else { - if (BuildConfig.DEBUG) - Log.d(TAG, "Storage not available: data folder is null"); - return false; - } - } - - /** - * Checks if external storage is available. If external storage isn't - * available, the current activity is finsished an an error activity is - * launched. - * - * @param activity - * the activity which would be finished if no storage is - * available - * @return true if external storage is available - */ - public static boolean checkStorageAvailability(Activity activity) { - boolean storageAvailable = storageAvailable(activity); - if (!storageAvailable) { - activity.finish(); - activity.startActivity(new Intent(activity, - StorageErrorActivity.class)); - } - return storageAvailable; - } - - /** Get the number of free bytes that are available on the external storage. */ - public static long getFreeSpaceAvailable() { - StatFs stat = new StatFs(UserPreferences.getDataFolder( - PodcastApp.getInstance(), null).getAbsolutePath()); - long availableBlocks; - long blockSize; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { - availableBlocks = stat.getAvailableBlocksLong(); - blockSize = stat.getBlockSizeLong(); - } else { - availableBlocks = stat.getAvailableBlocks(); - blockSize = stat.getBlockSize(); - } - return availableBlocks * blockSize; - } -} diff --git a/src/de/danoeh/antennapod/util/ThemeUtils.java b/src/de/danoeh/antennapod/util/ThemeUtils.java deleted file mode 100644 index 8e593f3fb..000000000 --- a/src/de/danoeh/antennapod/util/ThemeUtils.java +++ /dev/null @@ -1,22 +0,0 @@ -package de.danoeh.antennapod.util; - -import android.util.Log; -import de.danoeh.antennapod.R; -import de.danoeh.antennapod.preferences.UserPreferences; - -public class ThemeUtils { - private static final String TAG = "ThemeUtils"; - - public static int getSelectionBackgroundColor() { - switch (UserPreferences.getTheme()) { - case R.style.Theme_AntennaPod_Dark: - return R.color.selection_background_color_dark; - case R.style.Theme_AntennaPod_Light: - return R.color.selection_background_color_light; - default: - Log.e(TAG, - "getSelectionBackgroundColor could not match the current theme to any color!"); - return R.color.selection_background_color_light; - } - } -} diff --git a/src/de/danoeh/antennapod/util/URIUtil.java b/src/de/danoeh/antennapod/util/URIUtil.java deleted file mode 100644 index 5af40d591..000000000 --- a/src/de/danoeh/antennapod/util/URIUtil.java +++ /dev/null @@ -1,35 +0,0 @@ -package de.danoeh.antennapod.util; - -import android.util.Log; -import de.danoeh.antennapod.BuildConfig; - -import java.net.MalformedURLException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; - -/** - * Utility methods for dealing with URL encoding. - */ -public class URIUtil { - private static final String TAG = "URIUtil"; - - private URIUtil() {} - - public static URI getURIFromRequestUrl(String source) { - // try without encoding the URI - try { - return new URI(source); - } catch (URISyntaxException e) { - if (BuildConfig.DEBUG) Log.d(TAG, "Source is not encoded, encoding now"); - } - try { - URL url = new URL(source); - return new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef()); - } catch (MalformedURLException e) { - throw new IllegalArgumentException(e); - } catch (URISyntaxException e) { - throw new IllegalArgumentException(e); - } - } -} diff --git a/src/de/danoeh/antennapod/util/URLChecker.java b/src/de/danoeh/antennapod/util/URLChecker.java deleted file mode 100644 index 2352adddf..000000000 --- a/src/de/danoeh/antennapod/util/URLChecker.java +++ /dev/null @@ -1,54 +0,0 @@ -package de.danoeh.antennapod.util; - -import android.util.Log; - -import org.apache.commons.lang3.StringUtils; - -import de.danoeh.antennapod.BuildConfig; - -/** - * Provides methods for checking and editing a URL. - */ -public final class URLChecker { - - /** - * Class shall not be instantiated. - */ - private URLChecker() { - } - - /** - * Logging tag. - */ - private static final String TAG = "URLChecker"; - - private static final String AP_SUBSCRIBE = "antennapod-subscribe://"; - - /** - * Checks if URL is valid and modifies it if necessary. - * - * @param url The url which is going to be prepared - * @return The prepared url - */ - public static String prepareURL(String url) { - url = StringUtils.trim(url); - if (url.startsWith("feed://")) { - if (BuildConfig.DEBUG) Log.d(TAG, "Replacing feed:// with http://"); - return url.replaceFirst("feed://", "http://"); - } else if (url.startsWith("pcast://")) { - if (BuildConfig.DEBUG) Log.d(TAG, "Removing pcast://"); - return prepareURL(StringUtils.removeStart(url, "pcast://")); - } else if (url.startsWith("itpc")) { - if (BuildConfig.DEBUG) Log.d(TAG, "Replacing itpc:// with http://"); - return url.replaceFirst("itpc://", "http://"); - } else if (url.startsWith(AP_SUBSCRIBE)) { - if (BuildConfig.DEBUG) Log.d(TAG, "Removing antennapod-subscribe://"); - return prepareURL(StringUtils.removeStart(url, AP_SUBSCRIBE)); - } else if (!(url.startsWith("http://") || url.startsWith("https://"))) { - if (BuildConfig.DEBUG) Log.d(TAG, "Adding http:// at the beginning of the URL"); - return "http://" + url; - } else { - return url; - } - } -} diff --git a/src/de/danoeh/antennapod/util/UndoBarController.java b/src/de/danoeh/antennapod/util/UndoBarController.java deleted file mode 100644 index 332cc22e0..000000000 --- a/src/de/danoeh/antennapod/util/UndoBarController.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright 2012 Roman Nurik - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package de.danoeh.antennapod.util; - -import android.os.Bundle; -import android.os.Handler; -import android.os.Parcelable; -import android.text.TextUtils; -import android.view.View; -import android.widget.TextView; -import com.nineoldandroids.animation.Animator; -import com.nineoldandroids.animation.AnimatorListenerAdapter; -import com.nineoldandroids.view.ViewHelper; -import com.nineoldandroids.view.ViewPropertyAnimator; -import de.danoeh.antennapod.R; - -import static com.nineoldandroids.view.ViewPropertyAnimator.animate; - -public class UndoBarController { - private View mBarView; - private TextView mMessageView; - private ViewPropertyAnimator mBarAnimator; - private Handler mHideHandler = new Handler(); - - private UndoListener mUndoListener; - - // State objects - private Parcelable mUndoToken; - private CharSequence mUndoMessage; - - public interface UndoListener { - void onUndo(Parcelable token); - } - - public UndoBarController(View undoBarView, UndoListener undoListener) { - mBarView = undoBarView; - mBarAnimator = animate(mBarView); - mUndoListener = undoListener; - - mMessageView = (TextView) mBarView.findViewById(R.id.undobar_message); - mBarView.findViewById(R.id.undobar_button) - .setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - hideUndoBar(false); - mUndoListener.onUndo(mUndoToken); - } - }); - - hideUndoBar(true); - } - - public void showUndoBar(boolean immediate, CharSequence message, Parcelable undoToken) { - mUndoToken = undoToken; - mUndoMessage = message; - mMessageView.setText(mUndoMessage); - - mHideHandler.removeCallbacks(mHideRunnable); - mHideHandler.postDelayed(mHideRunnable, - mBarView.getResources().getInteger(R.integer.undobar_hide_delay)); - - mBarView.setVisibility(View.VISIBLE); - if (immediate) { - ViewHelper.setAlpha(mBarView, 1); - } else { - mBarAnimator.cancel(); - mBarAnimator - .alpha(1) - .setDuration( - mBarView.getResources() - .getInteger(android.R.integer.config_shortAnimTime)) - .setListener(null); - } - } - - public void hideUndoBar(boolean immediate) { - mHideHandler.removeCallbacks(mHideRunnable); - if (immediate) { - mBarView.setVisibility(View.GONE); - ViewHelper.setAlpha(mBarView, 0); - mUndoMessage = null; - mUndoToken = null; - - } else { - mBarAnimator.cancel(); - mBarAnimator - .alpha(0) - .setDuration(mBarView.getResources() - .getInteger(android.R.integer.config_shortAnimTime)) - .setListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - mBarView.setVisibility(View.GONE); - mUndoMessage = null; - mUndoToken = null; - } - }); - } - } - - public void onSaveInstanceState(Bundle outState) { - outState.putCharSequence("undo_message", mUndoMessage); - outState.putParcelable("undo_token", mUndoToken); - } - - public void onRestoreInstanceState(Bundle savedInstanceState) { - if (savedInstanceState != null) { - mUndoMessage = savedInstanceState.getCharSequence("undo_message"); - mUndoToken = savedInstanceState.getParcelable("undo_token"); - - if (mUndoToken != null || !TextUtils.isEmpty(mUndoMessage)) { - showUndoBar(true, mUndoMessage, mUndoToken); - } - } - } - - private Runnable mHideRunnable = new Runnable() { - @Override - public void run() { - hideUndoBar(false); - } - }; -} diff --git a/src/de/danoeh/antennapod/util/comparator/ChapterStartTimeComparator.java b/src/de/danoeh/antennapod/util/comparator/ChapterStartTimeComparator.java deleted file mode 100644 index bfc2fd057..000000000 --- a/src/de/danoeh/antennapod/util/comparator/ChapterStartTimeComparator.java +++ /dev/null @@ -1,20 +0,0 @@ -package de.danoeh.antennapod.util.comparator; - -import de.danoeh.antennapod.feed.Chapter; - -import java.util.Comparator; - -public class ChapterStartTimeComparator implements Comparator<Chapter> { - - @Override - public int compare(Chapter lhs, Chapter rhs) { - if (lhs.getStart() == rhs.getStart()) { - return 0; - } else if (lhs.getStart() < rhs.getStart()) { - return -1; - } else { - return 1; - } - } - -} diff --git a/src/de/danoeh/antennapod/util/comparator/DownloadStatusComparator.java b/src/de/danoeh/antennapod/util/comparator/DownloadStatusComparator.java deleted file mode 100644 index 14b8f1194..000000000 --- a/src/de/danoeh/antennapod/util/comparator/DownloadStatusComparator.java +++ /dev/null @@ -1,15 +0,0 @@ -package de.danoeh.antennapod.util.comparator; - -import de.danoeh.antennapod.service.download.DownloadStatus; - -import java.util.Comparator; - -/** Compares the completion date of two Downloadstatus objects. */ -public class DownloadStatusComparator implements Comparator<DownloadStatus> { - - @Override - public int compare(DownloadStatus lhs, DownloadStatus rhs) { - return rhs.getCompletionDate().compareTo(lhs.getCompletionDate()); - } - -} diff --git a/src/de/danoeh/antennapod/util/comparator/FeedItemPubdateComparator.java b/src/de/danoeh/antennapod/util/comparator/FeedItemPubdateComparator.java deleted file mode 100644 index f92c23d05..000000000 --- a/src/de/danoeh/antennapod/util/comparator/FeedItemPubdateComparator.java +++ /dev/null @@ -1,19 +0,0 @@ -package de.danoeh.antennapod.util.comparator; - -import de.danoeh.antennapod.feed.FeedItem; - -import java.util.Comparator; - -/** Compares the pubDate of two FeedItems for sorting*/ -public class FeedItemPubdateComparator implements Comparator<FeedItem> { - - /** Returns a new instance of this comparator in reverse order. - public static FeedItemPubdateComparator newInstance() { - FeedItemPubdateComparator - }*/ - @Override - public int compare(FeedItem lhs, FeedItem rhs) { - return rhs.getPubDate().compareTo(lhs.getPubDate()); - } - -} diff --git a/src/de/danoeh/antennapod/util/comparator/PlaybackCompletionDateComparator.java b/src/de/danoeh/antennapod/util/comparator/PlaybackCompletionDateComparator.java deleted file mode 100644 index 0147e0cdc..000000000 --- a/src/de/danoeh/antennapod/util/comparator/PlaybackCompletionDateComparator.java +++ /dev/null @@ -1,19 +0,0 @@ -package de.danoeh.antennapod.util.comparator; - -import de.danoeh.antennapod.feed.FeedItem; - -import java.util.Comparator; - -public class PlaybackCompletionDateComparator implements Comparator<FeedItem> { - - public int compare(FeedItem lhs, FeedItem rhs) { - if (lhs.getMedia() != null - && lhs.getMedia().getPlaybackCompletionDate() != null - && rhs.getMedia() != null - && rhs.getMedia().getPlaybackCompletionDate() != null) { - return rhs.getMedia().getPlaybackCompletionDate() - .compareTo(lhs.getMedia().getPlaybackCompletionDate()); - } - return 0; - } -} diff --git a/src/de/danoeh/antennapod/util/comparator/SearchResultValueComparator.java b/src/de/danoeh/antennapod/util/comparator/SearchResultValueComparator.java deleted file mode 100644 index 02b084a01..000000000 --- a/src/de/danoeh/antennapod/util/comparator/SearchResultValueComparator.java +++ /dev/null @@ -1,14 +0,0 @@ -package de.danoeh.antennapod.util.comparator; - -import de.danoeh.antennapod.feed.SearchResult; - -import java.util.Comparator; - -public class SearchResultValueComparator implements Comparator<SearchResult> { - - @Override - public int compare(SearchResult lhs, SearchResult rhs) { - return rhs.getValue() - lhs.getValue(); - } - -} diff --git a/src/de/danoeh/antennapod/util/exception/MediaFileNotFoundException.java b/src/de/danoeh/antennapod/util/exception/MediaFileNotFoundException.java deleted file mode 100644 index 4586cea87..000000000 --- a/src/de/danoeh/antennapod/util/exception/MediaFileNotFoundException.java +++ /dev/null @@ -1,23 +0,0 @@ -package de.danoeh.antennapod.util.exception; - -import de.danoeh.antennapod.feed.FeedMedia; - -public class MediaFileNotFoundException extends Exception { - private static final long serialVersionUID = 1L; - - private FeedMedia media; - - public MediaFileNotFoundException(String msg, FeedMedia media) { - super(msg); - this.media = media; - } - - public MediaFileNotFoundException(FeedMedia media) { - super(); - this.media = media; - } - - public FeedMedia getMedia() { - return media; - } -} diff --git a/src/de/danoeh/antennapod/util/flattr/FlattrServiceCreator.java b/src/de/danoeh/antennapod/util/flattr/FlattrServiceCreator.java deleted file mode 100644 index eda83b7aa..000000000 --- a/src/de/danoeh/antennapod/util/flattr/FlattrServiceCreator.java +++ /dev/null @@ -1,25 +0,0 @@ -package de.danoeh.antennapod.util.flattr; - -import android.util.Log; -import de.danoeh.antennapod.BuildConfig; -import org.shredzone.flattr4j.FlattrFactory; -import org.shredzone.flattr4j.FlattrService; -import org.shredzone.flattr4j.oauth.AccessToken; - -/** Ensures that only one instance of the FlattrService class exists at a time */ - -public class FlattrServiceCreator { - public static final String TAG = "FlattrServiceCreator"; - - private static volatile FlattrService flattrService; - - public static FlattrService getService(AccessToken token) { - return FlattrFactory.getInstance().createFlattrService(token); - } - - public static void deleteFlattrService() { - if (BuildConfig.DEBUG) Log.d(TAG, "Deleting service instance"); - flattrService = null; - } -} - diff --git a/src/de/danoeh/antennapod/util/flattr/FlattrStatus.java b/src/de/danoeh/antennapod/util/flattr/FlattrStatus.java deleted file mode 100644 index a1d6d3bc4..000000000 --- a/src/de/danoeh/antennapod/util/flattr/FlattrStatus.java +++ /dev/null @@ -1,68 +0,0 @@ -package de.danoeh.antennapod.util.flattr; - -import java.util.Calendar; - -public class FlattrStatus { - public static final int STATUS_UNFLATTERED = 0; - public static final int STATUS_QUEUE = 1; - public static final int STATUS_FLATTRED = 2; - - private int status = STATUS_UNFLATTERED; - private Calendar lastFlattred; - - public FlattrStatus() { - status = STATUS_UNFLATTERED; - lastFlattred = Calendar.getInstance(); - } - - public FlattrStatus(long status) { - lastFlattred = Calendar.getInstance(); - fromLong(status); - } - - public void setFlattred() { - status = STATUS_FLATTRED; - lastFlattred = Calendar.getInstance(); - } - - public void setUnflattred() { - status = STATUS_UNFLATTERED; - } - - public boolean getUnflattred() { - return status == STATUS_UNFLATTERED; - } - - public void setFlattrQueue() { - if (flattrable()) - status = STATUS_QUEUE; - } - - public void fromLong(long status) { - if (status == STATUS_UNFLATTERED || status == STATUS_QUEUE) - this.status = (int) status; - else { - this.status = STATUS_FLATTRED; - lastFlattred.setTimeInMillis(status); - } - } - - public long toLong() { - if (status == STATUS_UNFLATTERED || status == STATUS_QUEUE) - return status; - else { - return lastFlattred.getTimeInMillis(); - } - } - - public boolean flattrable() { - Calendar firstOfMonth = Calendar.getInstance(); - firstOfMonth.set(Calendar.DAY_OF_MONTH, Calendar.getInstance().getActualMinimum(Calendar.DAY_OF_MONTH)); - - return (status == STATUS_UNFLATTERED) || (status == STATUS_FLATTRED && firstOfMonth.after(lastFlattred) ); - } - - public boolean getFlattrQueue() { - return status == STATUS_QUEUE; - } -} diff --git a/src/de/danoeh/antennapod/util/flattr/FlattrThing.java b/src/de/danoeh/antennapod/util/flattr/FlattrThing.java deleted file mode 100644 index f17ef1d83..000000000 --- a/src/de/danoeh/antennapod/util/flattr/FlattrThing.java +++ /dev/null @@ -1,7 +0,0 @@ -package de.danoeh.antennapod.util.flattr; - -public interface FlattrThing { - public String getTitle(); - public String getPaymentLink(); - public FlattrStatus getFlattrStatus(); -} diff --git a/src/de/danoeh/antennapod/util/flattr/FlattrUtils.java b/src/de/danoeh/antennapod/util/flattr/FlattrUtils.java deleted file mode 100644 index 96d3bbedd..000000000 --- a/src/de/danoeh/antennapod/util/flattr/FlattrUtils.java +++ /dev/null @@ -1,305 +0,0 @@ -package de.danoeh.antennapod.util.flattr; - -import android.app.AlertDialog; -import android.content.Context; -import android.content.DialogInterface; -import android.content.DialogInterface.OnClickListener; -import android.content.Intent; -import android.content.SharedPreferences; -import android.net.Uri; -import android.preference.PreferenceManager; -import android.util.Log; - -import org.apache.commons.lang3.StringUtils; -import org.shredzone.flattr4j.FlattrService; -import org.shredzone.flattr4j.exception.FlattrException; -import org.shredzone.flattr4j.model.Flattr; -import org.shredzone.flattr4j.model.Thing; -import org.shredzone.flattr4j.oauth.AccessToken; -import org.shredzone.flattr4j.oauth.AndroidAuthenticator; -import org.shredzone.flattr4j.oauth.Scope; - -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Date; -import java.util.EnumSet; -import java.util.List; -import java.util.TimeZone; - -import de.danoeh.antennapod.BuildConfig; -import de.danoeh.antennapod.PodcastApp; -import de.danoeh.antennapod.R; -import de.danoeh.antennapod.activity.FlattrAuthActivity; -import de.danoeh.antennapod.asynctask.FlattrTokenFetcher; -import de.danoeh.antennapod.storage.DBWriter; - -/** - * Utility methods for doing something with flattr. - */ - -public class FlattrUtils { - private static final String TAG = "FlattrUtils"; - - private static final String HOST_NAME = "de.danoeh.antennapod"; - - private static final String PREF_ACCESS_TOKEN = "de.danoeh.antennapod.preference.flattrAccessToken"; - - // Flattr URL for this app. - public static final String APP_URL = "http://antennapod.com"; - // Human-readable flattr-page. - public static final String APP_LINK = "https://flattr.com/thing/745609/"; - public static final String APP_THING_ID = "745609"; - - private static volatile AccessToken cachedToken; - - private static AndroidAuthenticator createAuthenticator() { - return new AndroidAuthenticator(HOST_NAME, BuildConfig.FLATTR_APP_KEY, - BuildConfig.FLATTR_APP_SECRET); - } - - public static void startAuthProcess(Context context) throws FlattrException { - AndroidAuthenticator auth = createAuthenticator(); - auth.setScope(EnumSet.of(Scope.FLATTR)); - Intent intent = auth.createAuthenticateIntent(); - context.startActivity(intent); - } - - private static AccessToken retrieveToken() { - if (cachedToken == null) { - if (BuildConfig.DEBUG) - Log.d(TAG, "Retrieving access token"); - String token = PreferenceManager.getDefaultSharedPreferences( - PodcastApp.getInstance()) - .getString(PREF_ACCESS_TOKEN, null); - if (token != null) { - if (BuildConfig.DEBUG) - Log.d(TAG, "Found access token. Caching."); - cachedToken = new AccessToken(token); - } else { - if (BuildConfig.DEBUG) - Log.d(TAG, "No access token found"); - return null; - } - } - return cachedToken; - - } - - /** - * Returns true if FLATTR_APP_KEY and FLATTR_APP_SECRET in BuildConfig are not null and not empty - */ - public static boolean hasAPICredentials() { - return StringUtils.isNotEmpty(BuildConfig.FLATTR_APP_KEY) - && StringUtils.isNotEmpty(BuildConfig.FLATTR_APP_SECRET); - } - - public static boolean hasToken() { - return retrieveToken() != null; - } - - public static void storeToken(AccessToken token) { - if (BuildConfig.DEBUG) - Log.d(TAG, "Storing token"); - SharedPreferences.Editor editor = PreferenceManager - .getDefaultSharedPreferences(PodcastApp.getInstance()).edit(); - if (token != null) { - editor.putString(PREF_ACCESS_TOKEN, token.getToken()); - } else { - editor.putString(PREF_ACCESS_TOKEN, null); - } - editor.commit(); - cachedToken = token; - } - - public static void deleteToken() { - if (BuildConfig.DEBUG) - Log.d(TAG, "Deleting flattr token"); - storeToken(null); - } - - public static Thing getAppThing(Context context) { - FlattrService fs = FlattrServiceCreator.getService(retrieveToken()); - try { - Thing thing = fs.getThing(Thing.withId(APP_THING_ID)); - return thing; - } catch (FlattrException e) { - e.printStackTrace(); - showErrorDialog(context, e.getMessage()); - return null; - } - } - - public static void clickUrl(Context context, String url) - throws FlattrException { - if (hasToken()) { - FlattrService fs = FlattrServiceCreator.getService(retrieveToken()); - fs.flattr(url); - } else { - Log.e(TAG, "clickUrl was called with null access token"); - } - } - - public static List<Flattr> retrieveFlattredThings() - throws FlattrException { - ArrayList<Flattr> myFlattrs = new ArrayList<Flattr>(); - - if (hasToken()) { - FlattrService fs = FlattrServiceCreator.getService(retrieveToken()); - - Calendar firstOfMonth = Calendar.getInstance(TimeZone.getTimeZone("UTC")); - firstOfMonth.set(Calendar.MILLISECOND, 0); - firstOfMonth.set(Calendar.SECOND, 0); - firstOfMonth.set(Calendar.MINUTE, 0); - firstOfMonth.set(Calendar.HOUR_OF_DAY, 0); - firstOfMonth.set(Calendar.DAY_OF_MONTH, Calendar.getInstance().getActualMinimum(Calendar.DAY_OF_MONTH)); - - Date firstOfMonthDate = firstOfMonth.getTime(); - - // subscriptions some times get flattrd slightly before midnight - give it an hour leeway - firstOfMonthDate = new Date(firstOfMonthDate.getTime() - 60 * 60 * 1000); - - final int FLATTR_COUNT = 30; - final int FLATTR_MAXPAGE = 5; - - for (int page = 0; page < FLATTR_MAXPAGE; page++) { - for (Flattr fl : fs.getMyFlattrs(FLATTR_COUNT, page)) { - if (fl.getCreated().after(firstOfMonthDate)) - myFlattrs.add(fl); - else - break; - } - } - - if (BuildConfig.DEBUG) { - Log.d(TAG, "Got my flattrs list of length " + Integer.toString(myFlattrs.size()) + " comparison date" + firstOfMonthDate); - - for (Flattr fl : myFlattrs) { - Thing thing = fl.getThing(); - Log.d(TAG, "Flattr thing: " + fl.getThingId() + " name: " + thing.getTitle() + " url: " + thing.getUrl() + " on: " + fl.getCreated()); - } - } - - } else { - Log.e(TAG, "retrieveFlattrdThings was called with null access token"); - } - - return myFlattrs; - } - - public static void handleCallback(Context context, Uri uri) { - AndroidAuthenticator auth = createAuthenticator(); - new FlattrTokenFetcher(context, auth, uri).executeAsync(); - } - - public static void revokeAccessToken(Context context) { - if (BuildConfig.DEBUG) - Log.d(TAG, "Revoking access token"); - deleteToken(); - FlattrServiceCreator.deleteFlattrService(); - showRevokeDialog(context); - DBWriter.clearAllFlattrStatus(context); - } - - // ------------------------------------------------ DIALOGS - - public static void showRevokeDialog(final Context context) { - AlertDialog.Builder builder = new AlertDialog.Builder(context); - builder.setTitle(R.string.access_revoked_title); - builder.setMessage(R.string.access_revoked_info); - builder.setNeutralButton(android.R.string.ok, new OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - dialog.cancel(); - } - }); - builder.create().show(); - } - - /** - * Opens a dialog that ask the user to either connect the app with flattr or to be redirected to - * the thing's website. - * If no API credentials are available, the user will immediately be redirected to the thing's website. - * */ - public static void showNoTokenDialogOrRedirect(final Context context, final String url) { - if (hasAPICredentials()) { - AlertDialog.Builder builder = new AlertDialog.Builder(context); - builder.setTitle(R.string.no_flattr_token_title); - builder.setMessage(R.string.no_flattr_token_msg); - builder.setPositiveButton(R.string.authenticate_now_label, - new OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - context.startActivity(new Intent(context, - FlattrAuthActivity.class)); - } - - } - ); - - builder.setNegativeButton(R.string.visit_website_label, - new OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - Uri uri = Uri.parse(url); - context.startActivity(new Intent(Intent.ACTION_VIEW, - uri)); - } - - } - ); - builder.create().show(); - } else { - Uri uri = Uri.parse(url); - context.startActivity(new Intent(Intent.ACTION_VIEW, uri)); - } - } - - public static void showForbiddenDialog(final Context context, - final String url) { - AlertDialog.Builder builder = new AlertDialog.Builder(context); - builder.setTitle(R.string.action_forbidden_title); - builder.setMessage(R.string.action_forbidden_msg); - builder.setPositiveButton(R.string.authenticate_now_label, - new OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - context.startActivity(new Intent(context, - FlattrAuthActivity.class)); - } - - } - ); - builder.setNegativeButton(R.string.visit_website_label, - new OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - Uri uri = Uri.parse(url); - context.startActivity(new Intent(Intent.ACTION_VIEW, - uri)); - } - - } - ); - builder.create().show(); - } - - public static void showErrorDialog(final Context context, final String msg) { - AlertDialog.Builder builder = new AlertDialog.Builder(context); - builder.setTitle(R.string.error_label); - builder.setMessage(msg); - builder.setNeutralButton(android.R.string.ok, new OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - dialog.cancel(); - } - }); - builder.create().show(); - } - -}
\ No newline at end of file diff --git a/src/de/danoeh/antennapod/util/flattr/SimpleFlattrThing.java b/src/de/danoeh/antennapod/util/flattr/SimpleFlattrThing.java deleted file mode 100644 index 296610871..000000000 --- a/src/de/danoeh/antennapod/util/flattr/SimpleFlattrThing.java +++ /dev/null @@ -1,30 +0,0 @@ -package de.danoeh.antennapod.util.flattr; - -/* SimpleFlattrThing is a trivial implementation of the FlattrThing interface */ -public class SimpleFlattrThing implements FlattrThing { - public SimpleFlattrThing(String title, String url, FlattrStatus status) - { - this.title = title; - this.url = url; - this.status = status; - } - - public String getTitle() - { - return this.title; - } - - public String getPaymentLink() - { - return this.url; - } - - public FlattrStatus getFlattrStatus() - { - return this.status; - } - - private String title; - private String url; - private FlattrStatus status; -} diff --git a/src/de/danoeh/antennapod/util/gui/FeedItemUndoToken.java b/src/de/danoeh/antennapod/util/gui/FeedItemUndoToken.java deleted file mode 100644 index b920559db..000000000 --- a/src/de/danoeh/antennapod/util/gui/FeedItemUndoToken.java +++ /dev/null @@ -1,55 +0,0 @@ -package de.danoeh.antennapod.util.gui; - -import android.os.Parcel; -import android.os.Parcelable; -import de.danoeh.antennapod.feed.FeedItem; - -/** - * Used by an UndoBarController for saving a removed FeedItem - */ -public class FeedItemUndoToken implements Parcelable { - private long itemId; - private long feedId; - private int position; - - public FeedItemUndoToken(FeedItem item, int position) { - this.itemId = item.getId(); - this.feedId = item.getFeed().getId(); - this.position = position; - } - - private FeedItemUndoToken(Parcel in) { - itemId = in.readLong(); - feedId = in.readLong(); - position = in.readInt(); - } - - public static final Parcelable.Creator<FeedItemUndoToken> CREATOR = new Parcelable.Creator<FeedItemUndoToken>() { - public FeedItemUndoToken createFromParcel(Parcel in) { - return new FeedItemUndoToken(in); - } - - public FeedItemUndoToken[] newArray(int size) { - return new FeedItemUndoToken[size]; - } - }; - - public int describeContents() { - return 0; - } - - public void writeToParcel(Parcel out, int flags) { - out.writeLong(itemId); - out.writeLong(feedId); - out.writeInt(position); - } - - public long getFeedItemId() { - return itemId; - } - - public int getPosition() { - return position; - } -} - diff --git a/src/de/danoeh/antennapod/util/id3reader/ChapterReader.java b/src/de/danoeh/antennapod/util/id3reader/ChapterReader.java deleted file mode 100644 index 257635129..000000000 --- a/src/de/danoeh/antennapod/util/id3reader/ChapterReader.java +++ /dev/null @@ -1,118 +0,0 @@ -package de.danoeh.antennapod.util.id3reader; - -import android.util.Log; -import de.danoeh.antennapod.BuildConfig; -import de.danoeh.antennapod.feed.Chapter; -import de.danoeh.antennapod.feed.ID3Chapter; -import de.danoeh.antennapod.util.id3reader.model.FrameHeader; -import de.danoeh.antennapod.util.id3reader.model.TagHeader; - -import java.io.IOException; -import java.io.InputStream; -import java.net.URLDecoder; -import java.util.ArrayList; -import java.util.List; - -public class ChapterReader extends ID3Reader { - private static final String TAG = "ID3ChapterReader"; - - private static final String FRAME_ID_CHAPTER = "CHAP"; - private static final String FRAME_ID_TITLE = "TIT2"; - private static final String FRAME_ID_LINK = "WXXX"; - - private List<Chapter> chapters; - private ID3Chapter currentChapter; - - @Override - public int onStartTagHeader(TagHeader header) { - chapters = new ArrayList<Chapter>(); - System.out.println(header.toString()); - return ID3Reader.ACTION_DONT_SKIP; - } - - @Override - public int onStartFrameHeader(FrameHeader header, InputStream input) - throws IOException, ID3ReaderException { - System.out.println(header.toString()); - if (header.getId().equals(FRAME_ID_CHAPTER)) { - if (currentChapter != null) { - if (!hasId3Chapter(currentChapter)) { - chapters.add(currentChapter); - if (BuildConfig.DEBUG) Log.d(TAG, "Found chapter: " + currentChapter); - currentChapter = null; - } - } - StringBuffer elementId = new StringBuffer(); - readISOString(elementId, input, Integer.MAX_VALUE); - char[] startTimeSource = readBytes(input, 4); - long startTime = ((int) startTimeSource[0] << 24) - | ((int) startTimeSource[1] << 16) - | ((int) startTimeSource[2] << 8) | startTimeSource[3]; - currentChapter = new ID3Chapter(elementId.toString(), startTime); - skipBytes(input, 12); - return ID3Reader.ACTION_DONT_SKIP; - } else if (header.getId().equals(FRAME_ID_TITLE)) { - if (currentChapter != null && currentChapter.getTitle() == null) { - StringBuffer title = new StringBuffer(); - readString(title, input, header.getSize()); - currentChapter - .setTitle(title.toString()); - if (BuildConfig.DEBUG) Log.d(TAG, "Found title: " + currentChapter.getTitle()); - - return ID3Reader.ACTION_DONT_SKIP; - } - } else if (header.getId().equals(FRAME_ID_LINK)) { - if (currentChapter != null) { - // skip description - int descriptionLength = readString(null, input, header.getSize()); - StringBuffer link = new StringBuffer(); - readISOString(link, input, header.getSize() - descriptionLength); - String decodedLink = URLDecoder.decode(link.toString(), "UTF-8"); - - currentChapter.setLink(decodedLink); - - if (BuildConfig.DEBUG) Log.d(TAG, "Found link: " + currentChapter.getLink()); - return ID3Reader.ACTION_DONT_SKIP; - } - } else if (header.getId().equals("APIC")) { - Log.d(TAG, header.toString()); - } - - return super.onStartFrameHeader(header, input); - } - - private boolean hasId3Chapter(ID3Chapter chapter) { - for (Chapter c : chapters) { - if (((ID3Chapter) c).getId3ID().equals(chapter.getId3ID())) { - return true; - } - } - return false; - } - - @Override - public void onEndTag() { - if (currentChapter != null) { - if (!hasId3Chapter(currentChapter)) { - chapters.add(currentChapter); - } - } - System.out.println("Reached end of tag"); - if (chapters != null) { - for (Chapter c : chapters) { - System.out.println(c.toString()); - } - } - } - - @Override - public void onNoTagHeaderFound() { - System.out.println("No tag header found"); - super.onNoTagHeaderFound(); - } - - public List<Chapter> getChapters() { - return chapters; - } - -} diff --git a/src/de/danoeh/antennapod/util/id3reader/ID3Reader.java b/src/de/danoeh/antennapod/util/id3reader/ID3Reader.java deleted file mode 100644 index 252d64107..000000000 --- a/src/de/danoeh/antennapod/util/id3reader/ID3Reader.java +++ /dev/null @@ -1,250 +0,0 @@ -package de.danoeh.antennapod.util.id3reader; - -import de.danoeh.antennapod.util.id3reader.model.FrameHeader; -import de.danoeh.antennapod.util.id3reader.model.TagHeader; -import org.apache.commons.io.IOUtils; - -import java.io.IOException; -import java.io.InputStream; -import java.nio.ByteBuffer; -import java.nio.charset.Charset; - -/** - * Reads the ID3 Tag of a given file. In order to use this class, you should - * create a subclass of it and overwrite the onStart* - or onEnd* - methods. - */ -public class ID3Reader { - private static final int HEADER_LENGTH = 10; - private static final int ID3_LENGTH = 3; - private static final int FRAME_ID_LENGTH = 4; - - protected static final int ACTION_SKIP = 1; - protected static final int ACTION_DONT_SKIP = 2; - - protected int readerPosition; - - private static final byte ENCODING_UTF16_WITH_BOM = 1; - private static final byte ENCODING_UTF16_WITHOUT_BOM = 2; - private static final byte ENCODING_UTF8 = 3; - - private TagHeader tagHeader; - - public ID3Reader() { - } - - public final void readInputStream(InputStream input) throws IOException, - ID3ReaderException { - int rc; - readerPosition = 0; - char[] tagHeaderSource = readBytes(input, HEADER_LENGTH); - tagHeader = createTagHeader(tagHeaderSource); - if (tagHeader == null) { - onNoTagHeaderFound(); - } else { - rc = onStartTagHeader(tagHeader); - if (rc == ACTION_SKIP) { - onEndTag(); - } else { - while (readerPosition < tagHeader.getSize()) { - FrameHeader frameHeader = createFrameHeader(readBytes( - input, HEADER_LENGTH)); - if (checkForNullString(frameHeader.getId())) { - break; - } else { - rc = onStartFrameHeader(frameHeader, input); - if (rc == ACTION_SKIP) { - - if (frameHeader.getSize() + readerPosition > tagHeader - .getSize()) { - break; - } else { - skipBytes(input, frameHeader.getSize()); - } - } - } - } - onEndTag(); - } - } - } - - /** Returns true if string only contains null-bytes. */ - private boolean checkForNullString(String s) { - if (!s.isEmpty()) { - int i = 0; - if (s.charAt(i) == 0) { - for (i = 1; i < s.length(); i++) { - if (s.charAt(i) != 0) { - return false; - } - } - return true; - } - return false; - } else { - return true; - } - - } - - /** - * Read a certain number of bytes from the given input stream. This method - * changes the readerPosition-attribute. - */ - protected char[] readBytes(InputStream input, int number) - throws IOException, ID3ReaderException { - char[] header = new char[number]; - for (int i = 0; i < number; i++) { - int b = input.read(); - readerPosition++; - if (b != -1) { - header[i] = (char) b; - } else { - throw new ID3ReaderException("Unexpected end of stream"); - } - } - return header; - } - - /** - * Skip a certain number of bytes on the given input stream. This method - * changes the readerPosition-attribute. - */ - protected void skipBytes(InputStream input, int number) throws IOException { - if (number <= 0) { - number = 1; - } - IOUtils.skipFully(input, number); - - readerPosition += number; - } - - private TagHeader createTagHeader(char[] source) throws ID3ReaderException { - boolean hasTag = (source[0] == 0x49) && (source[1] == 0x44) - && (source[2] == 0x33); - if (source.length != HEADER_LENGTH) { - throw new ID3ReaderException("Length of header must be " - + HEADER_LENGTH); - } - if (hasTag) { - String id = new String(source, 0, ID3_LENGTH); - char version = (char) ((source[3] << 8) | source[4]); - byte flags = (byte) source[5]; - int size = (source[6] << 24) | (source[7] << 16) | (source[8] << 8) - | source[9]; - size = unsynchsafe(size); - return new TagHeader(id, size, version, flags); - } else { - return null; - } - } - - private FrameHeader createFrameHeader(char[] source) - throws ID3ReaderException { - if (source.length != HEADER_LENGTH) { - throw new ID3ReaderException("Length of header must be " - + HEADER_LENGTH); - } - String id = new String(source, 0, FRAME_ID_LENGTH); - - int size = (((int) source[4]) << 24) | (((int) source[5]) << 16) - | (((int) source[6]) << 8) | source[7]; - if (tagHeader != null && tagHeader.getVersion() >= 0x0400) { - size = unsynchsafe(size); - } - char flags = (char) ((source[8] << 8) | source[9]); - return new FrameHeader(id, size, flags); - } - - private int unsynchsafe(int in) { - int out = 0; - int mask = 0x7F000000; - - while (mask != 0) { - out >>= 1; - out |= in & mask; - mask >>= 8; - } - - return out; - } - - protected int readString(StringBuffer buffer, InputStream input, int max) throws IOException, - ID3ReaderException { - if (max > 0) { - char[] encoding = readBytes(input, 1); - max--; - - if (encoding[0] == ENCODING_UTF16_WITH_BOM || encoding[0] == ENCODING_UTF16_WITHOUT_BOM) { - return readUnicodeString(buffer, input, max, Charset.forName("UTF-16")) + 1; // take encoding byte into account - } else if (encoding[0] == ENCODING_UTF8) { - return readUnicodeString(buffer, input, max, Charset.forName("UTF-8")) + 1; // take encoding byte into account - } else { - return readISOString(buffer, input, max) + 1; // take encoding byte into account - } - } else { - if (buffer != null) { - buffer.append(""); - } - return 0; - } - } - - protected int readISOString(StringBuffer buffer, InputStream input, int max) - throws IOException, ID3ReaderException { - - int bytesRead = 0; - char c; - while (++bytesRead <= max && (c = (char) input.read()) > 0) { - if (buffer != null) { - buffer.append(c); - } - } - return bytesRead; - } - - private int readUnicodeString(StringBuffer strBuffer, InputStream input, int max, Charset charset) - throws IOException, ID3ReaderException { - byte[] buffer = new byte[max]; - int c, cZero = -1; - int i = 0; - for (; i < max; i++) { - c = input.read(); - if (c == -1) { - break; - } else if (c == 0) { - if (cZero == 0) { - // termination character found - break; - } else { - cZero = 0; - } - } else { - buffer[i] = (byte) c; - cZero = -1; - } - } - if (strBuffer != null) { - strBuffer.append(charset.newDecoder().decode(ByteBuffer.wrap(buffer)).toString()); - } - return i; - } - - public int onStartTagHeader(TagHeader header) { - return ACTION_SKIP; - } - - public int onStartFrameHeader(FrameHeader header, InputStream input) - throws IOException, ID3ReaderException { - return ACTION_SKIP; - } - - public void onEndTag() { - - } - - public void onNoTagHeaderFound() { - - } - -} diff --git a/src/de/danoeh/antennapod/util/id3reader/ID3ReaderException.java b/src/de/danoeh/antennapod/util/id3reader/ID3ReaderException.java deleted file mode 100644 index c458540ee..000000000 --- a/src/de/danoeh/antennapod/util/id3reader/ID3ReaderException.java +++ /dev/null @@ -1,20 +0,0 @@ -package de.danoeh.antennapod.util.id3reader; - -public class ID3ReaderException extends Exception { - - public ID3ReaderException() { - } - - public ID3ReaderException(String arg0) { - super(arg0); - } - - public ID3ReaderException(Throwable arg0) { - super(arg0); - } - - public ID3ReaderException(String arg0, Throwable arg1) { - super(arg0, arg1); - } - -} diff --git a/src/de/danoeh/antennapod/util/id3reader/model/FrameHeader.java b/src/de/danoeh/antennapod/util/id3reader/model/FrameHeader.java deleted file mode 100644 index df73393a5..000000000 --- a/src/de/danoeh/antennapod/util/id3reader/model/FrameHeader.java +++ /dev/null @@ -1,17 +0,0 @@ -package de.danoeh.antennapod.util.id3reader.model; - -public class FrameHeader extends Header { - - protected char flags; - - public FrameHeader(String id, int size, char flags) { - super(id, size); - this.flags = flags; - } - - @Override - public String toString() { - return String.format("FrameHeader [flags=%s, id=%s, size=%s]", Integer.toBinaryString(flags), id, Integer.toBinaryString(size)); - } - -} diff --git a/src/de/danoeh/antennapod/util/id3reader/model/Header.java b/src/de/danoeh/antennapod/util/id3reader/model/Header.java deleted file mode 100644 index 22d5b6376..000000000 --- a/src/de/danoeh/antennapod/util/id3reader/model/Header.java +++ /dev/null @@ -1,29 +0,0 @@ -package de.danoeh.antennapod.util.id3reader.model; - -public abstract class Header { - - protected String id; - protected int size; - - public Header(String id, int size) { - super(); - this.id = id; - this.size = size; - } - - public String getId() { - return id; - } - - public int getSize() { - return size; - } - - @Override - public String toString() { - return "Header [id=" + id + ", size=" + size + "]"; - } - - - -} diff --git a/src/de/danoeh/antennapod/util/id3reader/model/TagHeader.java b/src/de/danoeh/antennapod/util/id3reader/model/TagHeader.java deleted file mode 100644 index ec99ef14e..000000000 --- a/src/de/danoeh/antennapod/util/id3reader/model/TagHeader.java +++ /dev/null @@ -1,26 +0,0 @@ -package de.danoeh.antennapod.util.id3reader.model; - -public class TagHeader extends Header { - - protected char version; - protected byte flags; - - public TagHeader(String id, int size, char version, byte flags) { - super(id, size); - this.version = version; - this.flags = flags; - } - - @Override - public String toString() { - return "TagHeader [version=" + version + ", flags=" + flags + ", id=" - + id + ", size=" + size + "]"; - } - - public char getVersion() { - return version; - } - - - -} diff --git a/src/de/danoeh/antennapod/util/menuhandler/FeedItemMenuHandler.java b/src/de/danoeh/antennapod/util/menuhandler/FeedItemMenuHandler.java deleted file mode 100644 index 2c7a7f074..000000000 --- a/src/de/danoeh/antennapod/util/menuhandler/FeedItemMenuHandler.java +++ /dev/null @@ -1,191 +0,0 @@ -package de.danoeh.antennapod.util.menuhandler; - -import android.content.Context; -import android.content.Intent; -import android.net.Uri; - -import de.danoeh.antennapod.BuildConfig; -import de.danoeh.antennapod.R; -import de.danoeh.antennapod.feed.FeedItem; -import de.danoeh.antennapod.service.playback.PlaybackService; -import de.danoeh.antennapod.storage.DBTasks; -import de.danoeh.antennapod.storage.DBWriter; -import de.danoeh.antennapod.storage.DownloadRequestException; -import de.danoeh.antennapod.storage.DownloadRequester; -import de.danoeh.antennapod.util.QueueAccess; -import de.danoeh.antennapod.util.ShareUtils; - -/** - * Handles interactions with the FeedItemMenu. - */ -public class FeedItemMenuHandler { - private static final String TAG = "FeedItemMenuHandler"; - - private FeedItemMenuHandler() { - - } - - /** - * Used by the MenuHandler to access different types of menus through one - * interface - */ - public interface MenuInterface { - /** - * Implementations of this method should call findItem(id) on their - * menu-object and call setVisibility(visibility) on the returned - * MenuItem object. - */ - abstract void setItemVisibility(int id, boolean visible); - } - - /** - * This method should be called in the prepare-methods of menus. It changes - * the visibility of the menu items depending on a FeedItem's attributes. - * - * @param mi An instance of MenuInterface that the method uses to change a - * MenuItem's visibility - * @param selectedItem The FeedItem for which the menu is supposed to be prepared - * @param showExtendedMenu True if MenuItems that let the user share information about - * the FeedItem and visit its website should be set visible. This - * parameter should be set to false if the menu space is limited. - * @param queueAccess Used for testing if the queue contains the selected item - * @return Returns true if selectedItem is not null. - */ - public static boolean onPrepareMenu(MenuInterface mi, - FeedItem selectedItem, boolean showExtendedMenu, QueueAccess queueAccess) { - if (selectedItem == null) { - return false; - } - DownloadRequester requester = DownloadRequester.getInstance(); - boolean hasMedia = selectedItem.getMedia() != null; - boolean downloaded = hasMedia && selectedItem.getMedia().isDownloaded(); - boolean downloading = hasMedia - && requester.isDownloadingFile(selectedItem.getMedia()); - boolean notLoadedAndNotLoading = hasMedia && (!downloaded) - && (!downloading); - boolean isPlaying = hasMedia - && selectedItem.getState() == FeedItem.State.PLAYING; - - FeedItem.State state = selectedItem.getState(); - - if (!isPlaying) { - mi.setItemVisibility(R.id.skip_episode_item, false); - } - if (!downloaded || isPlaying) { - mi.setItemVisibility(R.id.play_item, false); - mi.setItemVisibility(R.id.remove_item, false); - } - if (!notLoadedAndNotLoading) { - mi.setItemVisibility(R.id.download_item, false); - } - if (!(notLoadedAndNotLoading | downloading) | isPlaying) { - mi.setItemVisibility(R.id.stream_item, false); - } - if (!downloading) { - mi.setItemVisibility(R.id.cancel_download_item, false); - } - - boolean isInQueue = queueAccess.contains(selectedItem.getId()); - if (!isInQueue || isPlaying) { - mi.setItemVisibility(R.id.remove_from_queue_item, false); - } - if (!(!isInQueue && selectedItem.getMedia() != null)) { - mi.setItemVisibility(R.id.add_to_queue_item, false); - } - if (!showExtendedMenu || selectedItem.getLink() == null) { - mi.setItemVisibility(R.id.share_link_item, false); - } - - if (!BuildConfig.DEBUG - || !(state == FeedItem.State.IN_PROGRESS || state == FeedItem.State.READ)) { - mi.setItemVisibility(R.id.mark_unread_item, false); - } - if (!(state == FeedItem.State.NEW || state == FeedItem.State.IN_PROGRESS)) { - mi.setItemVisibility(R.id.mark_read_item, false); - } - - if (!showExtendedMenu || selectedItem.getLink() == null) { - mi.setItemVisibility(R.id.visit_website_item, false); - } - - if (selectedItem.getPaymentLink() == null || !selectedItem.getFlattrStatus().flattrable()) { - mi.setItemVisibility(R.id.support_item, false); - } - return true; - } - - /** - * The same method as onPrepareMenu(MenuInterface, FeedItem, boolean, QueueAccess), but lets the - * caller also specify a list of menu items that should not be shown. - * - * @param excludeIds Menu item that should be excluded - * @return true if selectedItem is not null. - */ - public static boolean onPrepareMenu(MenuInterface mi, - FeedItem selectedItem, boolean showExtendedMenu, QueueAccess queueAccess, int... excludeIds) { - boolean rc = onPrepareMenu(mi, selectedItem, showExtendedMenu, queueAccess); - if (rc && excludeIds != null) { - for (int id : excludeIds) { - mi.setItemVisibility(id, false); - } - } - - return rc; - } - - public static boolean onMenuItemClicked(Context context, int menuItemId, - FeedItem selectedItem) throws DownloadRequestException { - DownloadRequester requester = DownloadRequester.getInstance(); - switch (menuItemId) { - case R.id.skip_episode_item: - context.sendBroadcast(new Intent( - PlaybackService.ACTION_SKIP_CURRENT_EPISODE)); - break; - case R.id.download_item: - DBTasks.downloadFeedItems(context, selectedItem); - break; - case R.id.play_item: - DBTasks.playMedia(context, selectedItem.getMedia(), true, true, - false); - break; - case R.id.remove_item: - DBWriter.deleteFeedMediaOfItem(context, selectedItem.getMedia().getId()); - break; - case R.id.cancel_download_item: - requester.cancelDownload(context, selectedItem.getMedia()); - break; - case R.id.mark_read_item: - DBWriter.markItemRead(context, selectedItem, true, true); - break; - case R.id.mark_unread_item: - DBWriter.markItemRead(context, selectedItem, false, true); - break; - case R.id.add_to_queue_item: - DBWriter.addQueueItem(context, selectedItem.getId()); - break; - case R.id.remove_from_queue_item: - DBWriter.removeQueueItem(context, selectedItem.getId(), true); - break; - case R.id.stream_item: - DBTasks.playMedia(context, selectedItem.getMedia(), true, true, - true); - break; - case R.id.visit_website_item: - Uri uri = Uri.parse(selectedItem.getLink()); - context.startActivity(new Intent(Intent.ACTION_VIEW, uri)); - break; - case R.id.support_item: - DBTasks.flattrItemIfLoggedIn(context, selectedItem); - break; - case R.id.share_link_item: - ShareUtils.shareFeedItemLink(context, selectedItem); - break; - default: - return false; - } - // Refresh menu state - - return true; - } - -} diff --git a/src/de/danoeh/antennapod/util/menuhandler/FeedMenuHandler.java b/src/de/danoeh/antennapod/util/menuhandler/FeedMenuHandler.java deleted file mode 100644 index a3adec66d..000000000 --- a/src/de/danoeh/antennapod/util/menuhandler/FeedMenuHandler.java +++ /dev/null @@ -1,87 +0,0 @@ -package de.danoeh.antennapod.util.menuhandler; - -import android.content.Context; -import android.content.Intent; -import android.net.Uri; -import android.util.Log; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; -import de.danoeh.antennapod.BuildConfig; -import de.danoeh.antennapod.R; -import de.danoeh.antennapod.activity.FeedInfoActivity; -import de.danoeh.antennapod.feed.Feed; -import de.danoeh.antennapod.service.download.DownloadService; -import de.danoeh.antennapod.storage.DBTasks; -import de.danoeh.antennapod.storage.DBWriter; -import de.danoeh.antennapod.storage.DownloadRequestException; -import de.danoeh.antennapod.storage.DownloadRequester; -import de.danoeh.antennapod.util.ShareUtils; - -/** Handles interactions with the FeedItemMenu. */ -public class FeedMenuHandler { - private static final String TAG = "FeedMenuHandler"; - - public static boolean onCreateOptionsMenu(MenuInflater inflater, Menu menu) { - inflater.inflate(R.menu.feedlist, menu); - return true; - } - - public static boolean onPrepareOptionsMenu(Menu menu, Feed selectedFeed) { - if (selectedFeed == null) { - return true; - } - - if (BuildConfig.DEBUG) - Log.d(TAG, "Preparing options menu"); - menu.findItem(R.id.mark_all_read_item).setVisible( - selectedFeed.hasNewItems(true)); - if (selectedFeed.getPaymentLink() != null && selectedFeed.getFlattrStatus().flattrable()) - menu.findItem(R.id.support_item).setVisible(true); - else - menu.findItem(R.id.support_item).setVisible(false); - MenuItem refresh = menu.findItem(R.id.refresh_item); - if (DownloadService.isRunning - && DownloadRequester.getInstance().isDownloadingFile( - selectedFeed)) { - refresh.setVisible(false); - } else { - refresh.setVisible(true); - } - - return true; - } - - /** - * NOTE: This method does not handle clicks on the 'remove feed' - item. - * - * @throws DownloadRequestException - */ - public static boolean onOptionsItemClicked(Context context, MenuItem item, - Feed selectedFeed) throws DownloadRequestException { - switch (item.getItemId()) { - case R.id.refresh_item: - DBTasks.refreshFeed(context, selectedFeed); - break; - case R.id.mark_all_read_item: - DBWriter.markFeedRead(context, selectedFeed.getId()); - break; - case R.id.visit_website_item: - Uri uri = Uri.parse(selectedFeed.getLink()); - context.startActivity(new Intent(Intent.ACTION_VIEW, uri)); - break; - case R.id.support_item: - DBTasks.flattrFeedIfLoggedIn(context, selectedFeed); - break; - case R.id.share_link_item: - ShareUtils.shareFeedlink(context, selectedFeed); - break; - case R.id.share_source_item: - ShareUtils.shareFeedDownloadLink(context, selectedFeed); - break; - default: - return false; - } - return true; - } -} diff --git a/src/de/danoeh/antennapod/util/menuhandler/MenuItemUtils.java b/src/de/danoeh/antennapod/util/menuhandler/MenuItemUtils.java deleted file mode 100644 index 7aa04d24c..000000000 --- a/src/de/danoeh/antennapod/util/menuhandler/MenuItemUtils.java +++ /dev/null @@ -1,31 +0,0 @@ -package de.danoeh.antennapod.util.menuhandler; - -import android.support.v4.view.MenuItemCompat; -import android.support.v7.widget.SearchView; -import android.view.Menu; -import android.view.MenuItem; - -import de.danoeh.antennapod.R; - -/** - * Utilities for menu items - */ -public class MenuItemUtils { - - public static MenuItem addSearchItem(Menu menu, SearchView searchView) { - MenuItem item = menu.add(Menu.NONE, R.id.search_item, Menu.NONE, R.string.search_label); - MenuItemCompat.setShowAsAction(item, MenuItemCompat.SHOW_AS_ACTION_IF_ROOM); - MenuItemCompat.setActionView(item, searchView); - return item; - } - - /** - * Checks if the navigation drawer of the DrawerActivity is opened. This can be useful for Fragments - * that hide their menu if the navigation drawer is open. - * - * @return True if the drawer is open, false otherwise (also if the parameter is null) - */ - public static boolean isActivityDrawerOpen(NavDrawerActivity activity) { - return activity != null && activity.isDrawerOpen(); - } -} diff --git a/src/de/danoeh/antennapod/util/menuhandler/NavDrawerActivity.java b/src/de/danoeh/antennapod/util/menuhandler/NavDrawerActivity.java deleted file mode 100644 index 9c611a452..000000000 --- a/src/de/danoeh/antennapod/util/menuhandler/NavDrawerActivity.java +++ /dev/null @@ -1,9 +0,0 @@ -package de.danoeh.antennapod.util.menuhandler; - -/** - * Defines useful methods for activities that have a navigation drawer - */ -public interface NavDrawerActivity { - - public boolean isDrawerOpen(); -} diff --git a/src/de/danoeh/antennapod/util/playback/AudioPlayer.java b/src/de/danoeh/antennapod/util/playback/AudioPlayer.java deleted file mode 100644 index bd49b0d18..000000000 --- a/src/de/danoeh/antennapod/util/playback/AudioPlayer.java +++ /dev/null @@ -1,34 +0,0 @@ -package de.danoeh.antennapod.util.playback; - -import android.content.Context; -import android.util.Log; -import android.view.SurfaceHolder; -import com.aocate.media.MediaPlayer; - -public class AudioPlayer extends MediaPlayer implements IPlayer { - private static final String TAG = "AudioPlayer"; - - public AudioPlayer(Context context) { - super(context); - } - - @Override - public void setScreenOnWhilePlaying(boolean screenOn) { - Log.e(TAG, "Setting screen on while playing not supported in Audio Player"); - throw new UnsupportedOperationException("Setting screen on while playing not supported in Audio Player"); - - } - - @Override - public void setDisplay(SurfaceHolder sh) { - if (sh != null) { - Log.e(TAG, "Setting display not supported in Audio Player"); - throw new UnsupportedOperationException("Setting display not supported in Audio Player"); - } - } - - @Override - public void setVideoScalingMode(int mode) { - throw new UnsupportedOperationException("Setting scaling mode is not supported in Audio Player"); - } -} diff --git a/src/de/danoeh/antennapod/util/playback/ExternalMedia.java b/src/de/danoeh/antennapod/util/playback/ExternalMedia.java deleted file mode 100644 index 3f6e6ae0a..000000000 --- a/src/de/danoeh/antennapod/util/playback/ExternalMedia.java +++ /dev/null @@ -1,237 +0,0 @@ -package de.danoeh.antennapod.util.playback; - -import android.content.SharedPreferences; -import android.content.SharedPreferences.Editor; -import android.media.MediaMetadataRetriever; -import android.net.Uri; -import android.os.Parcel; -import android.os.Parcelable; -import de.danoeh.antennapod.feed.Chapter; -import de.danoeh.antennapod.feed.MediaType; -import de.danoeh.antennapod.util.ChapterUtils; - -import java.io.File; -import java.io.InputStream; -import java.util.List; -import java.util.concurrent.Callable; - -/** Represents a media file that is stored on the local storage device. */ -public class ExternalMedia implements Playable { - - public static final int PLAYABLE_TYPE_EXTERNAL_MEDIA = 2; - public static final String PREF_SOURCE_URL = "ExternalMedia.PrefSourceUrl"; - public static final String PREF_POSITION = "ExternalMedia.PrefPosition"; - public static final String PREF_MEDIA_TYPE = "ExternalMedia.PrefMediaType"; - - private String source; - - private String episodeTitle; - private String feedTitle; - private MediaType mediaType = MediaType.AUDIO; - private List<Chapter> chapters; - private int duration; - private int position; - - public ExternalMedia(String source, MediaType mediaType) { - super(); - this.source = source; - this.mediaType = mediaType; - } - - public ExternalMedia(String source, MediaType mediaType, int position) { - this(source, mediaType); - this.position = position; - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeString(source); - dest.writeString(mediaType.toString()); - dest.writeInt(position); - } - - @Override - public void writeToPreferences(Editor prefEditor) { - prefEditor.putString(PREF_SOURCE_URL, source); - prefEditor.putString(PREF_MEDIA_TYPE, mediaType.toString()); - prefEditor.putInt(PREF_POSITION, position); - } - - @Override - public void loadMetadata() throws PlayableException { - MediaMetadataRetriever mmr = new MediaMetadataRetriever(); - try { - mmr.setDataSource(source); - } catch (IllegalArgumentException e) { - e.printStackTrace(); - throw new PlayableException( - "IllegalArgumentException when setting up MediaMetadataReceiver"); - } catch (RuntimeException e) { - // http://code.google.com/p/android/issues/detail?id=39770 - e.printStackTrace(); - throw new PlayableException( - "RuntimeException when setting up MediaMetadataRetriever"); - } - episodeTitle = mmr - .extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE); - feedTitle = mmr - .extractMetadata(MediaMetadataRetriever.METADATA_KEY_ALBUM); - try { - duration = Integer.parseInt(mmr - .extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)); - } catch (NumberFormatException e) { - e.printStackTrace(); - throw new PlayableException("NumberFormatException when reading duration of media file"); - } - ChapterUtils.loadChaptersFromFileUrl(this); - } - - @Override - public void loadChapterMarks() { - - } - - @Override - public String getEpisodeTitle() { - return episodeTitle; - } - - @Override - public Callable<String> loadShownotes() { - return new Callable<String>() { - @Override - public String call() throws Exception { - return ""; - } - }; - } - - @Override - public List<Chapter> getChapters() { - return chapters; - } - - @Override - public String getWebsiteLink() { - return null; - } - - @Override - public String getPaymentLink() { - return null; - } - - @Override - public String getFeedTitle() { - return feedTitle; - } - - @Override - public Object getIdentifier() { - return source; - } - - @Override - public int getDuration() { - return duration; - } - - @Override - public int getPosition() { - return position; - } - - @Override - public MediaType getMediaType() { - return mediaType; - } - - @Override - public String getLocalMediaUrl() { - return source; - } - - @Override - public String getStreamUrl() { - return null; - } - - @Override - public boolean localFileAvailable() { - return true; - } - - @Override - public boolean streamAvailable() { - return false; - } - - @Override - public void saveCurrentPosition(SharedPreferences pref, int newPosition) { - SharedPreferences.Editor editor = pref.edit(); - editor.putInt(PREF_POSITION, newPosition); - position = newPosition; - editor.commit(); - } - - @Override - public void setPosition(int newPosition) { - position = newPosition; - } - - @Override - public void setDuration(int newDuration) { - duration = newDuration; - } - - @Override - public void onPlaybackStart() { - - } - - @Override - public void onPlaybackCompleted() { - - } - - @Override - public int getPlayableType() { - return PLAYABLE_TYPE_EXTERNAL_MEDIA; - } - - @Override - public void setChapters(List<Chapter> chapters) { - this.chapters = chapters; - } - - public static final Parcelable.Creator<ExternalMedia> CREATOR = new Parcelable.Creator<ExternalMedia>() { - public ExternalMedia createFromParcel(Parcel in) { - String source = in.readString(); - MediaType type = MediaType.valueOf(in.readString()); - int position = 0; - if (in.dataAvail() > 0) { - position = in.readInt(); - } - ExternalMedia extMedia = new ExternalMedia(source, type, position); - return extMedia; - } - - public ExternalMedia[] newArray(int size) { - return new ExternalMedia[size]; - } - }; - - @Override - public Uri getImageUri() { - if (localFileAvailable()) { - return new Uri.Builder().scheme(SCHEME_MEDIA).encodedPath(getLocalMediaUrl()).build(); - } else { - return null; - } - } -} diff --git a/src/de/danoeh/antennapod/util/playback/IPlayer.java b/src/de/danoeh/antennapod/util/playback/IPlayer.java deleted file mode 100644 index 2d4551b13..000000000 --- a/src/de/danoeh/antennapod/util/playback/IPlayer.java +++ /dev/null @@ -1,69 +0,0 @@ -package de.danoeh.antennapod.util.playback; - -import android.content.Context; -import android.view.SurfaceHolder; - -import java.io.IOException; - -public interface IPlayer { - boolean canSetPitch(); - - boolean canSetSpeed(); - - float getCurrentPitchStepsAdjustment(); - - int getCurrentPosition(); - - float getCurrentSpeedMultiplier(); - - int getDuration(); - - float getMaxSpeedMultiplier(); - - float getMinSpeedMultiplier(); - - boolean isLooping(); - - boolean isPlaying(); - - void pause(); - - void prepare() throws IllegalStateException, IOException; - - void prepareAsync(); - - void release(); - - void reset(); - - void seekTo(int msec); - - void setAudioStreamType(int streamtype); - - void setScreenOnWhilePlaying(boolean screenOn); - - void setDataSource(String path) throws IllegalStateException, IOException, - IllegalArgumentException, SecurityException; - - void setDisplay(SurfaceHolder sh); - - void setEnableSpeedAdjustment(boolean enableSpeedAdjustment); - - void setLooping(boolean looping); - - void setPitchStepsAdjustment(float pitchSteps); - - void setPlaybackPitch(float f); - - void setPlaybackSpeed(float f); - - void setVolume(float left, float right); - - void start(); - - void stop(); - - public void setVideoScalingMode(int mode); - - public void setWakeMode(Context context, int mode); -} diff --git a/src/de/danoeh/antennapod/util/playback/MediaPlayerError.java b/src/de/danoeh/antennapod/util/playback/MediaPlayerError.java deleted file mode 100644 index 23ead581f..000000000 --- a/src/de/danoeh/antennapod/util/playback/MediaPlayerError.java +++ /dev/null @@ -1,23 +0,0 @@ -package de.danoeh.antennapod.util.playback; - -import android.content.Context; -import android.media.MediaPlayer; -import de.danoeh.antennapod.R; - -/** Utility class for MediaPlayer errors. */ -public class MediaPlayerError { - - /** Get a human-readable string for a specific error code. */ - public static String getErrorString(Context context, int code) { - int resId; - switch(code) { - case MediaPlayer.MEDIA_ERROR_SERVER_DIED: - resId = R.string.playback_error_server_died; - break; - default: - resId = R.string.playback_error_unknown; - break; - } - return context.getString(resId); - } -} diff --git a/src/de/danoeh/antennapod/util/playback/Playable.java b/src/de/danoeh/antennapod/util/playback/Playable.java deleted file mode 100644 index 004ae56bb..000000000 --- a/src/de/danoeh/antennapod/util/playback/Playable.java +++ /dev/null @@ -1,207 +0,0 @@ -package de.danoeh.antennapod.util.playback; - -import android.content.Context; -import android.content.SharedPreferences; -import android.os.Parcelable; -import android.util.Log; - -import java.util.List; - -import de.danoeh.antennapod.asynctask.PicassoImageResource; -import de.danoeh.antennapod.feed.Chapter; -import de.danoeh.antennapod.feed.FeedMedia; -import de.danoeh.antennapod.feed.MediaType; -import de.danoeh.antennapod.storage.DBReader; -import de.danoeh.antennapod.util.ShownotesProvider; - -/** - * Interface for objects that can be played by the PlaybackService. - */ -public interface Playable extends Parcelable, - ShownotesProvider, PicassoImageResource { - - /** - * Save information about the playable in a preference so that it can be - * restored later via PlayableUtils.createInstanceFromPreferences. - * Implementations must NOT call commit() after they have written the values - * to the preferences file. - */ - public void writeToPreferences(SharedPreferences.Editor prefEditor); - - /** - * This method is called from a separate thread by the PlaybackService. - * Playable objects should load their metadata in this method. This method - * should execute as quickly as possible and NOT load chapter marks if no - * local file is available. - */ - public void loadMetadata() throws PlayableException; - - /** - * This method is called from a separate thread by the PlaybackService. - * Playable objects should load their chapter marks in this method if no - * local file was available when loadMetadata() was called. - */ - public void loadChapterMarks(); - - /** - * Returns the title of the episode that this playable represents - */ - public String getEpisodeTitle(); - - /** - * Returns a list of chapter marks or null if this Playable has no chapters. - */ - public List<Chapter> getChapters(); - - /** - * Returns a link to a website that is meant to be shown in a browser - */ - public String getWebsiteLink(); - - public String getPaymentLink(); - - /** - * Returns the title of the feed this Playable belongs to. - */ - public String getFeedTitle(); - - /** - * Returns a unique identifier, for example a file url or an ID from a - * database. - */ - public Object getIdentifier(); - - /** - * Return duration of object or 0 if duration is unknown. - */ - public int getDuration(); - - /** - * Return position of object or 0 if position is unknown. - */ - public int getPosition(); - - /** - * Returns the type of media. This method should return the correct value - * BEFORE loadMetadata() is called. - */ - public MediaType getMediaType(); - - /** - * Returns an url to a local file that can be played or null if this file - * does not exist. - */ - public String getLocalMediaUrl(); - - /** - * Returns an url to a file that can be streamed by the player or null if - * this url is not known. - */ - public String getStreamUrl(); - - /** - * Returns true if a local file that can be played is available. getFileUrl - * MUST return a non-null string if this method returns true. - */ - public boolean localFileAvailable(); - - /** - * Returns true if a streamable file is available. getStreamUrl MUST return - * a non-null string if this method returns true. - */ - public boolean streamAvailable(); - - /** - * Saves the current position of this object. Implementations can use the - * provided SharedPreference to save this information and retrieve it later - * via PlayableUtils.createInstanceFromPreferences. - */ - public void saveCurrentPosition(SharedPreferences pref, int newPosition); - - public void setPosition(int newPosition); - - public void setDuration(int newDuration); - - /** - * Is called by the PlaybackService when playback starts. - */ - public void onPlaybackStart(); - - /** - * Is called by the PlaybackService when playback is completed. - */ - public void onPlaybackCompleted(); - - /** - * Returns an integer that must be unique among all Playable classes. The - * return value is later used by PlayableUtils to determine the type of the - * Playable object that is restored. - */ - public int getPlayableType(); - - public void setChapters(List<Chapter> chapters); - - /** - * Provides utility methods for Playable objects. - */ - public static class PlayableUtils { - private static final String TAG = "PlayableUtils"; - - /** - * Restores a playable object from a sharedPreferences file. This method might load data from the database, - * depending on the type of playable that was restored. - * - * @param type An integer that represents the type of the Playable object - * that is restored. - * @param pref The SharedPreferences file from which the Playable object - * is restored - * @return The restored Playable object - */ - public static Playable createInstanceFromPreferences(Context context, int type, - SharedPreferences pref) { - // ADD new Playable types here: - switch (type) { - case FeedMedia.PLAYABLE_TYPE_FEEDMEDIA: - long mediaId = pref.getLong(FeedMedia.PREF_MEDIA_ID, -1); - if (mediaId != -1) { - return DBReader.getFeedMedia(context, mediaId); - } - break; - case ExternalMedia.PLAYABLE_TYPE_EXTERNAL_MEDIA: - String source = pref.getString(ExternalMedia.PREF_SOURCE_URL, - null); - String mediaType = pref.getString( - ExternalMedia.PREF_MEDIA_TYPE, null); - if (source != null && mediaType != null) { - int position = pref.getInt(ExternalMedia.PREF_POSITION, 0); - return new ExternalMedia(source, - MediaType.valueOf(mediaType), position); - } - break; - } - Log.e(TAG, "Could not restore Playable object from preferences"); - return null; - } - } - - public static class PlayableException extends Exception { - private static final long serialVersionUID = 1L; - - public PlayableException() { - super(); - } - - public PlayableException(String detailMessage, Throwable throwable) { - super(detailMessage, throwable); - } - - public PlayableException(String detailMessage) { - super(detailMessage); - } - - public PlayableException(Throwable throwable) { - super(throwable); - } - - } -} diff --git a/src/de/danoeh/antennapod/util/playback/PlaybackController.java b/src/de/danoeh/antennapod/util/playback/PlaybackController.java deleted file mode 100644 index 64dbf4868..000000000 --- a/src/de/danoeh/antennapod/util/playback/PlaybackController.java +++ /dev/null @@ -1,784 +0,0 @@ -package de.danoeh.antennapod.util.playback; - -import android.app.Activity; -import android.content.*; -import android.content.res.TypedArray; -import android.media.MediaPlayer; -import android.os.AsyncTask; -import android.os.IBinder; -import android.preference.PreferenceManager; -import android.util.Log; -import android.util.Pair; -import android.view.SurfaceHolder; -import android.view.View; -import android.view.View.OnClickListener; -import android.widget.ImageButton; -import android.widget.SeekBar; -import android.widget.TextView; - -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.Validate; - -import de.danoeh.antennapod.BuildConfig; -import de.danoeh.antennapod.R; -import de.danoeh.antennapod.feed.Chapter; -import de.danoeh.antennapod.feed.FeedMedia; -import de.danoeh.antennapod.feed.MediaType; -import de.danoeh.antennapod.preferences.PlaybackPreferences; -import de.danoeh.antennapod.preferences.UserPreferences; -import de.danoeh.antennapod.service.playback.PlaybackService; -import de.danoeh.antennapod.service.playback.PlaybackServiceMediaPlayer; -import de.danoeh.antennapod.service.playback.PlayerStatus; -import de.danoeh.antennapod.storage.DBTasks; -import de.danoeh.antennapod.util.Converter; -import de.danoeh.antennapod.util.playback.Playable.PlayableUtils; - -import java.util.concurrent.*; - -/** - * Communicates with the playback service. GUI classes should use this class to - * control playback instead of communicating with the PlaybackService directly. - */ -public abstract class PlaybackController { - private static final String TAG = "PlaybackController"; - - public static final int INVALID_TIME = -1; - - private final Activity activity; - - private PlaybackService playbackService; - private Playable media; - private PlayerStatus status; - - private ScheduledThreadPoolExecutor schedExecutor; - private static final int SCHED_EX_POOLSIZE = 1; - - protected MediaPositionObserver positionObserver; - protected ScheduledFuture positionObserverFuture; - - private boolean mediaInfoLoaded = false; - private boolean released = false; - - /** - * True if controller should reinit playback service if 'pause' button is - * pressed. - */ - private boolean reinitOnPause; - - public PlaybackController(Activity activity, boolean reinitOnPause) { - Validate.notNull(activity); - - this.activity = activity; - this.reinitOnPause = reinitOnPause; - schedExecutor = new ScheduledThreadPoolExecutor(SCHED_EX_POOLSIZE, - new ThreadFactory() { - - @Override - public Thread newThread(Runnable r) { - Thread t = new Thread(r); - t.setPriority(Thread.MIN_PRIORITY); - return t; - } - }, new RejectedExecutionHandler() { - - @Override - public void rejectedExecution(Runnable r, - ThreadPoolExecutor executor) { - Log.w(TAG, - "Rejected execution of runnable in schedExecutor"); - } - } - ); - } - - /** - * Creates a new connection to the playbackService. Should be called in the - * activity's onResume() method. - */ - public void init() { - activity.registerReceiver(statusUpdate, new IntentFilter( - PlaybackService.ACTION_PLAYER_STATUS_CHANGED)); - - activity.registerReceiver(notificationReceiver, new IntentFilter( - PlaybackService.ACTION_PLAYER_NOTIFICATION)); - - activity.registerReceiver(shutdownReceiver, new IntentFilter( - PlaybackService.ACTION_SHUTDOWN_PLAYBACK_SERVICE)); - - if (!released) { - bindToService(); - } else { - throw new IllegalStateException( - "Can't call init() after release() has been called"); - } - } - - /** - * Should be called if the PlaybackController is no longer needed, for - * example in the activity's onStop() method. - */ - public void release() { - if (BuildConfig.DEBUG) - Log.d(TAG, "Releasing PlaybackController"); - - try { - activity.unregisterReceiver(statusUpdate); - } catch (IllegalArgumentException e) { - // ignore - } - - try { - activity.unregisterReceiver(notificationReceiver); - } catch (IllegalArgumentException e) { - // ignore - } - - try { - activity.unbindService(mConnection); - } catch (IllegalArgumentException e) { - // ignore - } - - try { - activity.unregisterReceiver(shutdownReceiver); - } catch (IllegalArgumentException e) { - // ignore - } - cancelPositionObserver(); - schedExecutor.shutdownNow(); - media = null; - released = true; - - } - - /** - * Should be called in the activity's onPause() method. - */ - public void pause() { - mediaInfoLoaded = false; - } - - /** - * Tries to establish a connection to the PlaybackService. If it isn't - * running, the PlaybackService will be started with the last played media - * as the arguments of the launch intent. - */ - private void bindToService() { - if (BuildConfig.DEBUG) - Log.d(TAG, "Trying to connect to service"); - AsyncTask<Void, Void, Intent> intentLoader = new AsyncTask<Void, Void, Intent>() { - @Override - protected Intent doInBackground(Void... voids) { - return getPlayLastPlayedMediaIntent(); - } - - @Override - protected void onPostExecute(Intent serviceIntent) { - boolean bound = false; - if (!PlaybackService.started) { - if (serviceIntent != null) { - if (BuildConfig.DEBUG) Log.d(TAG, "Calling start service"); - activity.startService(serviceIntent); - bound = activity.bindService(serviceIntent, mConnection, 0); - } else { - status = PlayerStatus.STOPPED; - setupGUI(); - handleStatus(); - } - } else { - if (BuildConfig.DEBUG) - Log.d(TAG, - "PlaybackService is running, trying to connect without start command."); - bound = activity.bindService(new Intent(activity, - PlaybackService.class), mConnection, 0); - } - if (BuildConfig.DEBUG) - Log.d(TAG, "Result for service binding: " + bound); - } - }; - intentLoader.execute(); - } - - /** - * Returns an intent that starts the PlaybackService and plays the last - * played media or null if no last played media could be found. - */ - private Intent getPlayLastPlayedMediaIntent() { - if (BuildConfig.DEBUG) - Log.d(TAG, "Trying to restore last played media"); - SharedPreferences prefs = PreferenceManager - .getDefaultSharedPreferences(activity.getApplicationContext()); - long currentlyPlayingMedia = PlaybackPreferences - .getCurrentlyPlayingMedia(); - if (currentlyPlayingMedia != PlaybackPreferences.NO_MEDIA_PLAYING) { - Playable media = PlayableUtils.createInstanceFromPreferences(activity, - (int) currentlyPlayingMedia, prefs); - if (media != null) { - Intent serviceIntent = new Intent(activity, - PlaybackService.class); - serviceIntent.putExtra(PlaybackService.EXTRA_PLAYABLE, media); - serviceIntent.putExtra( - PlaybackService.EXTRA_START_WHEN_PREPARED, false); - serviceIntent.putExtra( - PlaybackService.EXTRA_PREPARE_IMMEDIATELY, false); - boolean fileExists = media.localFileAvailable(); - boolean lastIsStream = PlaybackPreferences - .getCurrentEpisodeIsStream(); - if (!fileExists && !lastIsStream && media instanceof FeedMedia) { - DBTasks.notifyMissingFeedMediaFile( - activity, (FeedMedia) media); - } - serviceIntent.putExtra(PlaybackService.EXTRA_SHOULD_STREAM, - lastIsStream || !fileExists); - return serviceIntent; - } - } - if (BuildConfig.DEBUG) - Log.d(TAG, "No last played media found"); - return null; - } - - public abstract void setupGUI(); - - private void setupPositionObserver() { - if ((positionObserverFuture != null && positionObserverFuture - .isCancelled()) - || (positionObserverFuture != null && positionObserverFuture - .isDone()) || positionObserverFuture == null) { - - if (BuildConfig.DEBUG) - Log.d(TAG, "Setting up position observer"); - positionObserver = new MediaPositionObserver(); - positionObserverFuture = schedExecutor.scheduleWithFixedDelay( - positionObserver, MediaPositionObserver.WAITING_INTERVALL, - MediaPositionObserver.WAITING_INTERVALL, - TimeUnit.MILLISECONDS); - } - } - - private void cancelPositionObserver() { - if (positionObserverFuture != null) { - boolean result = positionObserverFuture.cancel(true); - if (BuildConfig.DEBUG) - Log.d(TAG, "PositionObserver cancelled. Result: " + result); - } - } - - public abstract void onPositionObserverUpdate(); - - private ServiceConnection mConnection = new ServiceConnection() { - public void onServiceConnected(ComponentName className, IBinder service) { - playbackService = ((PlaybackService.LocalBinder) service) - .getService(); - if (!released) { - queryService(); - if (BuildConfig.DEBUG) - Log.d(TAG, "Connection to Service established"); - } else { - Log.i(TAG, "Connection to playback service has been established, but controller has already been released"); - } - } - - @Override - public void onServiceDisconnected(ComponentName name) { - playbackService = null; - if (BuildConfig.DEBUG) - Log.d(TAG, "Disconnected from Service"); - - } - }; - - protected BroadcastReceiver statusUpdate = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - if (BuildConfig.DEBUG) - Log.d(TAG, "Received statusUpdate Intent."); - if (isConnectedToPlaybackService()) { - PlaybackServiceMediaPlayer.PSMPInfo info = playbackService.getPSMPInfo(); - status = info.playerStatus; - media = info.playable; - handleStatus(); - } else { - Log.w(TAG, - "Couldn't receive status update: playbackService was null"); - bindToService(); - } - } - }; - - protected BroadcastReceiver notificationReceiver = new BroadcastReceiver() { - - @Override - public void onReceive(Context context, Intent intent) { - if (isConnectedToPlaybackService()) { - int type = intent.getIntExtra( - PlaybackService.EXTRA_NOTIFICATION_TYPE, -1); - int code = intent.getIntExtra( - PlaybackService.EXTRA_NOTIFICATION_CODE, -1); - if (code != -1 && type != -1) { - switch (type) { - case PlaybackService.NOTIFICATION_TYPE_ERROR: - handleError(code); - break; - case PlaybackService.NOTIFICATION_TYPE_BUFFER_UPDATE: - float progress = ((float) code) / 100; - onBufferUpdate(progress); - break; - case PlaybackService.NOTIFICATION_TYPE_RELOAD: - cancelPositionObserver(); - mediaInfoLoaded = false; - queryService(); - onReloadNotification(intent.getIntExtra( - PlaybackService.EXTRA_NOTIFICATION_CODE, -1)); - break; - case PlaybackService.NOTIFICATION_TYPE_SLEEPTIMER_UPDATE: - onSleepTimerUpdate(); - break; - case PlaybackService.NOTIFICATION_TYPE_BUFFER_START: - onBufferStart(); - break; - case PlaybackService.NOTIFICATION_TYPE_BUFFER_END: - onBufferEnd(); - break; - case PlaybackService.NOTIFICATION_TYPE_PLAYBACK_END: - onPlaybackEnd(); - break; - case PlaybackService.NOTIFICATION_TYPE_PLAYBACK_SPEED_CHANGE: - onPlaybackSpeedChange(); - break; - } - - } else { - if (BuildConfig.DEBUG) - Log.d(TAG, "Bad arguments. Won't handle intent"); - } - } else { - bindToService(); - } - } - - }; - - private BroadcastReceiver shutdownReceiver = new BroadcastReceiver() { - - @Override - public void onReceive(Context context, Intent intent) { - if (isConnectedToPlaybackService()) { - if (StringUtils.equals(intent.getAction(), - PlaybackService.ACTION_SHUTDOWN_PLAYBACK_SERVICE)) { - release(); - onShutdownNotification(); - } - } - } - }; - - public abstract void onPlaybackSpeedChange(); - - public abstract void onShutdownNotification(); - - /** - * Called when the currently displayed information should be refreshed. - */ - public abstract void onReloadNotification(int code); - - public abstract void onBufferStart(); - - public abstract void onBufferEnd(); - - public abstract void onBufferUpdate(float progress); - - public abstract void onSleepTimerUpdate(); - - public abstract void handleError(int code); - - public abstract void onPlaybackEnd(); - - /** - * Is called whenever the PlaybackService changes it's status. This method - * should be used to update the GUI or start/cancel background threads. - */ - private void handleStatus() { - final int playResource; - final int pauseResource; - final CharSequence playText = activity.getString(R.string.play_label); - final CharSequence pauseText = activity.getString(R.string.pause_label); - - if (PlaybackService.getCurrentMediaType() == MediaType.AUDIO) { - TypedArray res = activity.obtainStyledAttributes(new int[]{ - R.attr.av_play, R.attr.av_pause}); - playResource = res.getResourceId(0, R.drawable.av_play); - pauseResource = res.getResourceId(1, R.drawable.av_pause); - res.recycle(); - } else { - playResource = R.drawable.ic_action_play_over_video; - pauseResource = R.drawable.ic_action_pause_over_video; - } - - switch (status) { - - case ERROR: - postStatusMsg(R.string.player_error_msg); - handleError(MediaPlayer.MEDIA_ERROR_UNKNOWN); - break; - case PAUSED: - clearStatusMsg(); - checkMediaInfoLoaded(); - cancelPositionObserver(); - updatePlayButtonAppearance(playResource, playText); - if (PlaybackService.getCurrentMediaType() == MediaType.VIDEO) { - setScreenOn(false); - } - break; - case PLAYING: - clearStatusMsg(); - checkMediaInfoLoaded(); - if (PlaybackService.getCurrentMediaType() == MediaType.VIDEO) { - onAwaitingVideoSurface(); - setScreenOn(true); - } - setupPositionObserver(); - updatePlayButtonAppearance(pauseResource, pauseText); - break; - case PREPARING: - postStatusMsg(R.string.player_preparing_msg); - checkMediaInfoLoaded(); - if (playbackService != null) { - if (playbackService.isStartWhenPrepared()) { - updatePlayButtonAppearance(pauseResource, pauseText); - } else { - updatePlayButtonAppearance(playResource, playText); - } - } - break; - case STOPPED: - postStatusMsg(R.string.player_stopped_msg); - break; - case PREPARED: - checkMediaInfoLoaded(); - postStatusMsg(R.string.player_ready_msg); - updatePlayButtonAppearance(playResource, playText); - break; - case SEEKING: - postStatusMsg(R.string.player_seeking_msg); - break; - case INITIALIZED: - checkMediaInfoLoaded(); - clearStatusMsg(); - updatePlayButtonAppearance(playResource, playText); - break; - } - } - - private void checkMediaInfoLoaded() { - mediaInfoLoaded = (mediaInfoLoaded || loadMediaInfo()); - } - - private void updatePlayButtonAppearance(int resource, CharSequence contentDescription) { - ImageButton butPlay = getPlayButton(); - butPlay.setImageResource(resource); - butPlay.setContentDescription(contentDescription); - } - - public abstract ImageButton getPlayButton(); - - public abstract void postStatusMsg(int msg); - - public abstract void clearStatusMsg(); - - public abstract boolean loadMediaInfo(); - - public abstract void onAwaitingVideoSurface(); - - /** - * Called when connection to playback service has been established or - * information has to be refreshed - */ - void queryService() { - if (BuildConfig.DEBUG) - Log.d(TAG, "Querying service info"); - if (playbackService != null) { - status = playbackService.getStatus(); - media = playbackService.getPlayable(); - /* - if (media == null) { - Log.w(TAG, - "PlaybackService has no media object. Trying to restore last played media."); - Intent serviceIntent = getPlayLastPlayedMediaIntent(); - if (serviceIntent != null) { - activity.startService(serviceIntent); - } - } - */ - onServiceQueried(); - - setupGUI(); - handleStatus(); - // make sure that new media is loaded if it's available - mediaInfoLoaded = false; - - } else { - Log.e(TAG, - "queryService() was called without an existing connection to playbackservice"); - } - } - - public abstract void onServiceQueried(); - - /** - * Should be used by classes which implement the OnSeekBarChanged interface. - */ - public float onSeekBarProgressChanged(SeekBar seekBar, int progress, - boolean fromUser, TextView txtvPosition) { - if (fromUser && playbackService != null && media != null) { - float prog = progress / ((float) seekBar.getMax()); - int duration = media.getDuration(); - txtvPosition.setText(Converter - .getDurationStringLong((int) (prog * duration))); - return prog; - } - return 0; - - } - - /** - * Should be used by classes which implement the OnSeekBarChanged interface. - */ - public void onSeekBarStartTrackingTouch(SeekBar seekBar) { - // interrupt position Observer, restart later - cancelPositionObserver(); - } - - /** - * Should be used by classes which implement the OnSeekBarChanged interface. - */ - public void onSeekBarStopTrackingTouch(SeekBar seekBar, float prog) { - if (playbackService != null) { - playbackService.seekTo((int) (prog * media.getDuration())); - setupPositionObserver(); - } - } - - /** - * Should be implemented by classes that show a video. The default implementation - * does nothing - * - * @param enable True if the screen should be kept on, false otherwise - */ - protected void setScreenOn(boolean enable) { - - } - - public OnClickListener newOnPlayButtonClickListener() { - return new OnClickListener() { - @Override - public void onClick(View v) { - if (playbackService != null) { - switch (status) { - case PLAYING: - playbackService.pause(true, reinitOnPause); - break; - case PAUSED: - case PREPARED: - playbackService.resume(); - break; - case PREPARING: - playbackService.setStartWhenPrepared(!playbackService - .isStartWhenPrepared()); - if (reinitOnPause - && playbackService.isStartWhenPrepared() == false) { - playbackService.reinit(); - } - break; - case INITIALIZED: - playbackService.setStartWhenPrepared(true); - playbackService.prepare(); - break; - } - } else { - Log.w(TAG, - "Play/Pause button was pressed, but playbackservice was null!"); - } - } - - }; - } - - public OnClickListener newOnRevButtonClickListener() { - return new OnClickListener() { - @Override - public void onClick(View v) { - if (status == PlayerStatus.PLAYING) { - playbackService.seekDelta(-UserPreferences.getSeekDeltaMs()); - } - } - }; - } - - public OnClickListener newOnFFButtonClickListener() { - return new OnClickListener() { - @Override - public void onClick(View v) { - if (status == PlayerStatus.PLAYING) { - playbackService.seekDelta(UserPreferences.getSeekDeltaMs()); - } - } - }; - } - - public boolean serviceAvailable() { - return playbackService != null; - } - - public int getPosition() { - if (playbackService != null) { - return playbackService.getCurrentPosition(); - } else { - return PlaybackService.INVALID_TIME; - } - } - - public int getDuration() { - if (playbackService != null) { - return playbackService.getDuration(); - } else { - return PlaybackService.INVALID_TIME; - } - } - - public Playable getMedia() { - return media; - } - - public boolean sleepTimerActive() { - return playbackService != null && playbackService.sleepTimerActive(); - } - - public boolean sleepTimerNotActive() { - return playbackService != null && !playbackService.sleepTimerActive(); - } - - public void disableSleepTimer() { - if (playbackService != null) { - playbackService.disableSleepTimer(); - } - } - - public long getSleepTimerTimeLeft() { - if (playbackService != null) { - return playbackService.getSleepTimerTimeLeft(); - } else { - return INVALID_TIME; - } - } - - public void setSleepTimer(long time) { - if (playbackService != null) { - playbackService.setSleepTimer(time); - } - } - - public void seekToChapter(Chapter chapter) { - if (playbackService != null) { - playbackService.seekToChapter(chapter); - } - } - - public void seekTo(int time) { - if (playbackService != null) { - playbackService.seekTo(time); - } - } - - public void setVideoSurface(SurfaceHolder holder) { - if (playbackService != null) { - playbackService.setVideoSurface(holder); - } - } - - public PlayerStatus getStatus() { - return status; - } - - public boolean canSetPlaybackSpeed() { - return playbackService != null && playbackService.canSetSpeed(); - } - - public void setPlaybackSpeed(float speed) { - if (playbackService != null) { - playbackService.setSpeed(speed); - } - } - - public float getCurrentPlaybackSpeedMultiplier() { - if (canSetPlaybackSpeed()) { - return playbackService.getCurrentPlaybackSpeed(); - } else { - return -1; - } - } - - public boolean isPlayingVideo() { - if (playbackService != null) { - return PlaybackService.getCurrentMediaType() == MediaType.VIDEO; - } - return false; - } - - public Pair<Integer, Integer> getVideoSize() { - if (playbackService != null) { - return playbackService.getVideoSize(); - } else { - return null; - } - } - - - /** - * Returns true if PlaybackController can communicate with the playback - * service. - */ - public boolean isConnectedToPlaybackService() { - return playbackService != null; - } - - public void notifyVideoSurfaceAbandoned() { - if (playbackService != null) { - playbackService.notifyVideoSurfaceAbandoned(); - } - } - - /** - * Move service into INITIALIZED state if it's paused to save bandwidth - */ - public void reinitServiceIfPaused() { - if (playbackService != null - && playbackService.isStreaming() - && (playbackService.getStatus() == PlayerStatus.PAUSED || (playbackService - .getStatus() == PlayerStatus.PREPARING && playbackService - .isStartWhenPrepared() == false))) { - playbackService.reinit(); - } - } - - /** - * Refreshes the current position of the media file that is playing. - */ - public class MediaPositionObserver implements Runnable { - - public static final int WAITING_INTERVALL = 1000; - - @Override - public void run() { - if (playbackService != null && playbackService.getStatus() == PlayerStatus.PLAYING) { - activity.runOnUiThread(new Runnable() { - - @Override - public void run() { - onPositionObserverUpdate(); - } - }); - } - } - } -} diff --git a/src/de/danoeh/antennapod/util/playback/Timeline.java b/src/de/danoeh/antennapod/util/playback/Timeline.java deleted file mode 100644 index ceed68183..000000000 --- a/src/de/danoeh/antennapod/util/playback/Timeline.java +++ /dev/null @@ -1,161 +0,0 @@ -package de.danoeh.antennapod.util.playback; - -import android.content.Context; -import android.content.res.TypedArray; -import android.util.Log; -import android.util.TypedValue; - -import org.apache.commons.lang3.Validate; -import org.jsoup.Jsoup; -import org.jsoup.nodes.Document; -import org.jsoup.nodes.Element; -import org.jsoup.select.Elements; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import de.danoeh.antennapod.BuildConfig; -import de.danoeh.antennapod.util.Converter; -import de.danoeh.antennapod.util.ShownotesProvider; - -/** - * Connects chapter information and shownotes of a shownotesProvider, for example by making it possible to use the - * shownotes to navigate to another position in the podcast or by highlighting certain parts of the shownotesProvider's - * shownotes. - * <p/> - * A timeline object needs a shownotesProvider from which the chapter information is retrieved and shownotes are generated. - */ -public class Timeline { - private static final String TAG = "Timeline"; - - private static final String WEBVIEW_STYLE = "@font-face { font-family: 'Roboto-Light'; src: url('file:///android_asset/Roboto-Light.ttf'); } * { color: %s; font-family: roboto-Light; font-size: 11pt; } a { font-style: normal; text-decoration: none; font-weight: normal; color: #00A8DF; } a.timecode { color: #669900; } img { display: block; margin: 10 auto; max-width: %s; height: auto; } body { margin: %dpx %dpx %dpx %dpx; }"; - - - private ShownotesProvider shownotesProvider; - - - private final String colorString; - private final int pageMargin; - - public Timeline(Context context, ShownotesProvider shownotesProvider) { - if (shownotesProvider == null) throw new IllegalArgumentException("shownotesProvider = null"); - this.shownotesProvider = shownotesProvider; - - TypedArray res = context - .getTheme() - .obtainStyledAttributes( - new int[]{android.R.attr.textColorPrimary}); - int colorResource = res.getColor(0, 0); - colorString = String.format("#%06X", - 0xFFFFFF & colorResource); - res.recycle(); - - pageMargin = (int) TypedValue.applyDimension( - TypedValue.COMPLEX_UNIT_DIP, 8, context.getResources() - .getDisplayMetrics() - ); - } - - private static final Pattern TIMECODE_LINK_REGEX = Pattern.compile("antennapod://timecode/((\\d+))"); - private static final String TIMECODE_LINK = "<a class=\"timecode\" href=\"antennapod://timecode/%d\">%s</a>"; - private static final Pattern TIMECODE_REGEX = Pattern.compile("\\b(?:(?:(([0-9][0-9])):))?(([0-9][0-9])):(([0-9][0-9]))\\b"); - - /** - * Applies an app-specific CSS stylesheet and adds timecode links (optional). - * <p/> - * This method does NOT change the original shownotes string of the shownotesProvider object and it should - * also not be changed by the caller. - * - * @param addTimecodes True if this method should add timecode links - * @return The processed HTML string. - */ - public String processShownotes(final boolean addTimecodes) { - final Playable playable = (shownotesProvider instanceof Playable) ? (Playable) shownotesProvider : null; - - // load shownotes - - String shownotes; - try { - shownotes = shownotesProvider.loadShownotes().call(); - } catch (Exception e) { - e.printStackTrace(); - return null; - } - if (shownotes == null) { - if (BuildConfig.DEBUG) - Log.d(TAG, "shownotesProvider contained no shownotes. Returning empty string"); - return ""; - } - - Document document = Jsoup.parse(shownotes); - - // apply style - String styleStr = String.format(WEBVIEW_STYLE, colorString, "100%", pageMargin, - pageMargin, pageMargin, pageMargin); - document.head().appendElement("style").attr("type", "text/css").text(styleStr); - - // apply timecode links - if (addTimecodes) { - Elements elementsWithTimeCodes = document.body().getElementsMatchingOwnText(TIMECODE_REGEX); - if (BuildConfig.DEBUG) - Log.d(TAG, "Recognized " + elementsWithTimeCodes.size() + " timecodes"); - for (Element element : elementsWithTimeCodes) { - Matcher matcherLong = TIMECODE_REGEX.matcher(element.text()); - StringBuffer buffer = new StringBuffer(); - while (matcherLong.find()) { - String h = matcherLong.group(1); - String group = matcherLong.group(0); - int time = (h != null) ? Converter.durationStringLongToMs(group) : - Converter.durationStringShortToMs(group); - - String rep; - if (playable == null || playable.getDuration() > time) { - rep = String.format(TIMECODE_LINK, time, group); - } else { - rep = group; - } - matcherLong.appendReplacement(buffer, rep); - } - matcherLong.appendTail(buffer); - - element.html(buffer.toString()); - } - } - - Log.i(TAG, "Out: " + document.toString()); - return document.toString(); - } - - - /** - * Returns true if the given link is a timecode link. - */ - public static boolean isTimecodeLink(String link) { - return link != null && link.matches(TIMECODE_LINK_REGEX.pattern()); - } - - /** - * Returns the time in milliseconds that is attached to this link or -1 - * if the link is no valid timecode link. - */ - public static int getTimecodeLinkTime(String link) { - if (isTimecodeLink(link)) { - Matcher m = TIMECODE_LINK_REGEX.matcher(link); - - try { - if (m.find()) { - return Integer.valueOf(m.group(1)); - } - } catch (NumberFormatException e) { - e.printStackTrace(); - } - } - return -1; - } - - - public void setShownotesProvider(ShownotesProvider shownotesProvider) { - Validate.notNull(shownotesProvider); - this.shownotesProvider = shownotesProvider; - } -} diff --git a/src/de/danoeh/antennapod/util/playback/VideoPlayer.java b/src/de/danoeh/antennapod/util/playback/VideoPlayer.java deleted file mode 100644 index ea9c692ab..000000000 --- a/src/de/danoeh/antennapod/util/playback/VideoPlayer.java +++ /dev/null @@ -1,67 +0,0 @@ -package de.danoeh.antennapod.util.playback; - -import android.media.MediaPlayer; -import android.util.Log; - -public class VideoPlayer extends MediaPlayer implements IPlayer { - private static final String TAG = "VideoPlayer"; - - @Override - public boolean canSetPitch() { - return false; - } - - @Override - public boolean canSetSpeed() { - return false; - } - - @Override - public float getCurrentPitchStepsAdjustment() { - return 1; - } - - @Override - public float getCurrentSpeedMultiplier() { - return 1; - } - - @Override - public float getMaxSpeedMultiplier() { - return 1; - } - - @Override - public float getMinSpeedMultiplier() { - return 1; - } - - @Override - public void setEnableSpeedAdjustment(boolean enableSpeedAdjustment) throws UnsupportedOperationException { - Log.e(TAG, "Setting enable speed adjustment unsupported in video player"); - throw new UnsupportedOperationException("Setting enable speed adjustment unsupported in video player"); - } - - @Override - public void setPitchStepsAdjustment(float pitchSteps) { - Log.e(TAG, "Setting pitch steps adjustment unsupported in video player"); - throw new UnsupportedOperationException("Setting pitch steps adjustment unsupported in video player"); - } - - @Override - public void setPlaybackPitch(float f) { - Log.e(TAG, "Setting playback pitch unsupported in video player"); - throw new UnsupportedOperationException("Setting playback pitch unsupported in video player"); - } - - @Override - public void setPlaybackSpeed(float f) { - Log.e(TAG, "Setting playback speed unsupported in video player"); - throw new UnsupportedOperationException("Setting playback speed unsupported in video player"); - } - - @Override - public void setVideoScalingMode(int mode) { - super.setVideoScalingMode(mode); - } -} diff --git a/src/de/danoeh/antennapod/util/syndication/FeedDiscoverer.java b/src/de/danoeh/antennapod/util/syndication/FeedDiscoverer.java deleted file mode 100644 index ac38ec876..000000000 --- a/src/de/danoeh/antennapod/util/syndication/FeedDiscoverer.java +++ /dev/null @@ -1,78 +0,0 @@ -package de.danoeh.antennapod.util.syndication; - -import android.net.Uri; -import org.apache.commons.lang3.StringUtils; -import org.jsoup.Jsoup; -import org.jsoup.nodes.Document; -import org.jsoup.nodes.Element; -import org.jsoup.select.Elements; - -import java.io.File; -import java.io.IOException; -import java.util.LinkedHashMap; -import java.util.Map; - -/** - * Finds RSS/Atom URLs in a HTML document using the auto-discovery techniques described here: - * <p/> - * http://www.rssboard.org/rss-autodiscovery - * <p/> - * http://blog.whatwg.org/feed-autodiscovery - */ -public class FeedDiscoverer { - - private static final String MIME_RSS = "application/rss+xml"; - private static final String MIME_ATOM = "application/atom+xml"; - - /** - * Discovers links to RSS and Atom feeds in the given File which must be a HTML document. - * - * @return A map which contains the feed URLs as keys and titles as values (the feed URL is also used as a title if - * a title cannot be found). - */ - public Map<String, String> findLinks(File in, String baseUrl) throws IOException { - return findLinks(Jsoup.parse(in, null), baseUrl); - } - - /** - * Discovers links to RSS and Atom feeds in the given File which must be a HTML document. - * - * @return A map which contains the feed URLs as keys and titles as values (the feed URL is also used as a title if - * a title cannot be found). - */ - public Map<String, String> findLinks(String in, String baseUrl) throws IOException { - return findLinks(Jsoup.parse(in), baseUrl); - } - - private Map<String, String> findLinks(Document document, String baseUrl) { - Map<String, String> res = new LinkedHashMap<String, String>(); - Elements links = document.head().getElementsByTag("link"); - for (Element link : links) { - String rel = link.attr("rel"); - String href = link.attr("href"); - if (!StringUtils.isEmpty(href) && - (rel.equals("alternate") || rel.equals("feed"))) { - String type = link.attr("type"); - if (type.equals(MIME_RSS) || type.equals(MIME_ATOM)) { - String title = link.attr("title"); - String processedUrl = processURL(baseUrl, href); - if (processedUrl != null) { - res.put(processedUrl, - (StringUtils.isEmpty(title)) ? href : title); - } - } - } - } - return res; - } - - private String processURL(String baseUrl, String strUrl) { - Uri uri = Uri.parse(strUrl); - if (uri.isRelative()) { - Uri res = Uri.parse(baseUrl).buildUpon().path(strUrl).build(); - return (res != null) ? res.toString() : null; - } else { - return strUrl; - } - } -} diff --git a/src/de/danoeh/antennapod/util/vorbiscommentreader/OggInputStream.java b/src/de/danoeh/antennapod/util/vorbiscommentreader/OggInputStream.java deleted file mode 100644 index 767034ed2..000000000 --- a/src/de/danoeh/antennapod/util/vorbiscommentreader/OggInputStream.java +++ /dev/null @@ -1,81 +0,0 @@ -package de.danoeh.antennapod.util.vorbiscommentreader; - -import org.apache.commons.io.IOUtils; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Arrays; - -public class OggInputStream extends InputStream { - private InputStream input; - - /** True if OggInputStream is currently inside an Ogg page. */ - private boolean isInPage; - private long bytesLeft; - - public OggInputStream(InputStream input) { - super(); - isInPage = false; - this.input = input; - } - - @Override - public int read() throws IOException { - if (!isInPage) { - readOggPage(); - } - - if (isInPage && bytesLeft > 0) { - int result = input.read(); - bytesLeft -= 1; - if (bytesLeft == 0) { - isInPage = false; - } - return result; - } - return -1; - } - - private void readOggPage() throws IOException { - // find OggS - int[] buffer = new int[4]; - int c = 0; - boolean isInOggS = false; - while ((c = input.read()) != -1) { - switch (c) { - case 'O': - isInOggS = true; - buffer[0] = c; - break; - case 'g': - if (buffer[1] != c) { - buffer[1] = c; - } else { - buffer[2] = c; - } - break; - case 'S': - buffer[3] = c; - break; - default: - if (isInOggS) { - Arrays.fill(buffer, 0); - isInOggS = false; - } - } - if (buffer[0] == 'O' && buffer[1] == 'g' && buffer[2] == 'g' - && buffer[3] == 'S') { - break; - } - } - // read segments - IOUtils.skipFully(input, 22); - bytesLeft = 0; - int numSegments = input.read(); - for (int i = 0; i < numSegments; i++) { - bytesLeft += input.read(); - } - isInPage = true; - } - -} diff --git a/src/de/danoeh/antennapod/util/vorbiscommentreader/VorbisCommentChapterReader.java b/src/de/danoeh/antennapod/util/vorbiscommentreader/VorbisCommentChapterReader.java deleted file mode 100644 index b2f149ddd..000000000 --- a/src/de/danoeh/antennapod/util/vorbiscommentreader/VorbisCommentChapterReader.java +++ /dev/null @@ -1,101 +0,0 @@ -package de.danoeh.antennapod.util.vorbiscommentreader; - -import android.util.Log; -import de.danoeh.antennapod.BuildConfig; -import de.danoeh.antennapod.feed.Chapter; -import de.danoeh.antennapod.feed.VorbisCommentChapter; - -import java.util.ArrayList; -import java.util.List; - -public class VorbisCommentChapterReader extends VorbisCommentReader { - private static final String TAG = "VorbisCommentChapterReader"; - - private static final String CHAPTER_KEY = "chapter\\d\\d\\d.*"; - private static final String CHAPTER_ATTRIBUTE_TITLE = "name"; - private static final String CHAPTER_ATTRIBUTE_LINK = "url"; - - private List<Chapter> chapters; - - public VorbisCommentChapterReader() { - } - - @Override - public void onVorbisCommentFound() { - System.out.println("Vorbis comment found"); - } - - @Override - public void onVorbisCommentHeaderFound(VorbisCommentHeader header) { - chapters = new ArrayList<Chapter>(); - System.out.println(header.toString()); - } - - @Override - public boolean onContentVectorKey(String content) { - return content.matches(CHAPTER_KEY); - } - - @Override - public void onContentVectorValue(String key, String value) - throws VorbisCommentReaderException { - if (BuildConfig.DEBUG) - Log.d(TAG, "Key: " + key + ", value: " + value); - String attribute = VorbisCommentChapter.getAttributeTypeFromKey(key); - int id = VorbisCommentChapter.getIDFromKey(key); - Chapter chapter = getChapterById(id); - if (attribute == null) { - if (getChapterById(id) == null) { - // new chapter - long start = VorbisCommentChapter.getStartTimeFromValue(value); - chapter = new VorbisCommentChapter(id); - chapter.setStart(start); - chapters.add(chapter); - } else { - throw new VorbisCommentReaderException( - "Found chapter with duplicate ID (" + key + ", " - + value + ")"); - } - } else if (attribute.equals(CHAPTER_ATTRIBUTE_TITLE)) { - if (chapter != null) { - chapter.setTitle(value); - } - } else if (attribute.equals(CHAPTER_ATTRIBUTE_LINK)) { - if (chapter != null) { - chapter.setLink(value); - } - } - } - - @Override - public void onNoVorbisCommentFound() { - System.out.println("No vorbis comment found"); - } - - @Override - public void onEndOfComment() { - System.out.println("End of comment"); - for (Chapter c : chapters) { - System.out.println(c.toString()); - } - } - - @Override - public void onError(VorbisCommentReaderException exception) { - exception.printStackTrace(); - } - - private Chapter getChapterById(long id) { - for (Chapter c : chapters) { - if (((VorbisCommentChapter) c).getVorbisCommentId() == id) { - return c; - } - } - return null; - } - - public List<Chapter> getChapters() { - return chapters; - } - -} diff --git a/src/de/danoeh/antennapod/util/vorbiscommentreader/VorbisCommentHeader.java b/src/de/danoeh/antennapod/util/vorbiscommentreader/VorbisCommentHeader.java deleted file mode 100644 index 8c47393c9..000000000 --- a/src/de/danoeh/antennapod/util/vorbiscommentreader/VorbisCommentHeader.java +++ /dev/null @@ -1,26 +0,0 @@ -package de.danoeh.antennapod.util.vorbiscommentreader; -public class VorbisCommentHeader { - private String vendorString; - private long userCommentLength; - - public VorbisCommentHeader(String vendorString, long userCommentLength) { - super(); - this.vendorString = vendorString; - this.userCommentLength = userCommentLength; - } - - @Override - public String toString() { - return "VorbisCommentHeader [vendorString=" + vendorString - + ", userCommentLength=" + userCommentLength + "]"; - } - - public String getVendorString() { - return vendorString; - } - - public long getUserCommentLength() { - return userCommentLength; - } - -} diff --git a/src/de/danoeh/antennapod/util/vorbiscommentreader/VorbisCommentReader.java b/src/de/danoeh/antennapod/util/vorbiscommentreader/VorbisCommentReader.java deleted file mode 100644 index 718a4f30f..000000000 --- a/src/de/danoeh/antennapod/util/vorbiscommentreader/VorbisCommentReader.java +++ /dev/null @@ -1,194 +0,0 @@ -package de.danoeh.antennapod.util.vorbiscommentreader; - -import org.apache.commons.io.EndianUtils; -import org.apache.commons.io.IOUtils; - -import java.io.IOException; -import java.io.InputStream; -import java.io.UnsupportedEncodingException; -import java.nio.ByteBuffer; -import java.nio.charset.Charset; -import java.util.Arrays; - - -public abstract class VorbisCommentReader { - /** Length of first page in an ogg file in bytes. */ - private static final int FIRST_PAGE_LENGTH = 58; - private static final int SECOND_PAGE_MAX_LENGTH = 64 * 1024 * 1024; - private static final int PACKET_TYPE_IDENTIFICATION = 1; - private static final int PACKET_TYPE_COMMENT = 3; - - /** Called when Reader finds identification header. */ - public abstract void onVorbisCommentFound(); - - public abstract void onVorbisCommentHeaderFound(VorbisCommentHeader header); - - /** - * Is called every time the Reader finds a content vector. The handler - * should return true if it wants to handle the content vector. - */ - public abstract boolean onContentVectorKey(String content); - - /** - * Is called if onContentVectorKey returned true for the key. - * - * @throws VorbisCommentReaderException - */ - public abstract void onContentVectorValue(String key, String value) - throws VorbisCommentReaderException; - - public abstract void onNoVorbisCommentFound(); - - public abstract void onEndOfComment(); - - public abstract void onError(VorbisCommentReaderException exception); - - public void readInputStream(InputStream input) - throws VorbisCommentReaderException { - try { - // look for identification header - if (findIdentificationHeader(input)) { - - onVorbisCommentFound(); - input = new OggInputStream(input); - if (findCommentHeader(input)) { - VorbisCommentHeader commentHeader = readCommentHeader(input); - if (commentHeader != null) { - onVorbisCommentHeaderFound(commentHeader); - for (int i = 0; i < commentHeader - .getUserCommentLength(); i++) { - try { - long vectorLength = EndianUtils - .readSwappedUnsignedInteger(input); - String key = readContentVectorKey(input, - vectorLength).toLowerCase(); - boolean readValue = onContentVectorKey(key); - if (readValue) { - String value = readUTF8String( - input, - (int) (vectorLength - key.length() - 1)); - onContentVectorValue(key, value); - } else { - IOUtils.skipFully(input, - vectorLength - key.length() - 1); - } - } catch (IOException e) { - e.printStackTrace(); - } - } - onEndOfComment(); - } - - } else { - onError(new VorbisCommentReaderException( - "No comment header found")); - } - } else { - onNoVorbisCommentFound(); - } - } catch (IOException e) { - onError(new VorbisCommentReaderException(e)); - } - } - - private String readUTF8String(InputStream input, long length) - throws IOException { - byte[] buffer = new byte[(int) length]; - - IOUtils.readFully(input, buffer); - Charset charset = Charset.forName("UTF-8"); - return charset.newDecoder().decode(ByteBuffer.wrap(buffer)).toString(); - } - - /** - * Looks for an identification header in the first page of the file. If an - * identification header is found, it will be skipped completely and the - * method will return true, otherwise false. - * - * @throws IOException - */ - private boolean findIdentificationHeader(InputStream input) - throws IOException { - byte[] buffer = new byte[FIRST_PAGE_LENGTH]; - IOUtils.readFully(input, buffer); - int i; - for (i = 6; i < buffer.length; i++) { - if (buffer[i - 5] == 'v' && buffer[i - 4] == 'o' - && buffer[i - 3] == 'r' && buffer[i - 2] == 'b' - && buffer[i - 1] == 'i' && buffer[i] == 's' - && buffer[i - 6] == PACKET_TYPE_IDENTIFICATION) { - return true; - } - } - return false; - } - - private boolean findCommentHeader(InputStream input) throws IOException { - char[] buffer = new char["vorbis".length() + 1]; - for (int bytesRead = 0; bytesRead < SECOND_PAGE_MAX_LENGTH; bytesRead++) { - char c = (char) input.read(); - int dest = -1; - switch (c) { - case PACKET_TYPE_COMMENT: - dest = 0; - break; - case 'v': - dest = 1; - break; - case 'o': - dest = 2; - break; - case 'r': - dest = 3; - break; - case 'b': - dest = 4; - break; - case 'i': - dest = 5; - break; - case 's': - dest = 6; - break; - } - if (dest >= 0) { - buffer[dest] = c; - if (buffer[1] == 'v' && buffer[2] == 'o' && buffer[3] == 'r' - && buffer[4] == 'b' && buffer[5] == 'i' - && buffer[6] == 's' && buffer[0] == PACKET_TYPE_COMMENT) { - return true; - } - } else { - Arrays.fill(buffer, (char) 0); - } - } - return false; - } - - private VorbisCommentHeader readCommentHeader(InputStream input) - throws IOException, VorbisCommentReaderException { - try { - long vendorLength = EndianUtils.readSwappedUnsignedInteger(input); - String vendorName = readUTF8String(input, vendorLength); - long userCommentLength = EndianUtils - .readSwappedUnsignedInteger(input); - return new VorbisCommentHeader(vendorName, userCommentLength); - } catch (UnsupportedEncodingException e) { - throw new VorbisCommentReaderException(e); - } - } - - private String readContentVectorKey(InputStream input, long vectorLength) - throws IOException { - StringBuffer buffer = new StringBuffer(); - for (int i = 0; i < vectorLength; i++) { - char c = (char) input.read(); - if (c == '=') { - return buffer.toString(); - } else { - buffer.append(c); - } - } - return null; // no key found - } -} diff --git a/src/de/danoeh/antennapod/util/vorbiscommentreader/VorbisCommentReaderException.java b/src/de/danoeh/antennapod/util/vorbiscommentreader/VorbisCommentReaderException.java deleted file mode 100644 index 574373241..000000000 --- a/src/de/danoeh/antennapod/util/vorbiscommentreader/VorbisCommentReaderException.java +++ /dev/null @@ -1,24 +0,0 @@ -package de.danoeh.antennapod.util.vorbiscommentreader; -public class VorbisCommentReaderException extends Exception { - - public VorbisCommentReaderException() { - super(); - // TODO Auto-generated constructor stub - } - - public VorbisCommentReaderException(String arg0, Throwable arg1) { - super(arg0, arg1); - // TODO Auto-generated constructor stub - } - - public VorbisCommentReaderException(String arg0) { - super(arg0); - // TODO Auto-generated constructor stub - } - - public VorbisCommentReaderException(Throwable arg0) { - super(arg0); - // TODO Auto-generated constructor stub - } - -} |