summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Hennen <TomHennen@users.noreply.github.com>2015-09-20 14:15:46 -0400
committerTom Hennen <TomHennen@users.noreply.github.com>2015-09-20 14:15:46 -0400
commita89edfcad4f69a7f8ddbce62ca33d4ba80d4a9ad (patch)
tree9c9e094567c5845cf6217c7fcb84ef9174011bb1
parent7a69147a9ef21cea6aad096f628cc4a84f054ef4 (diff)
parentff9cc13b6a92ac1855ad1e9c36a71d195f4ec3e2 (diff)
downloadAntennaPod-a89edfcad4f69a7f8ddbce62ca33d4ba80d4a9ad.zip
Merge pull request #1212 from mfietz/ext_audioplayers_lib
Alternative to Prestissimo [4.1+] and other annoyances
-rw-r--r--app/build.gradle2
-rw-r--r--app/src/androidTest/java/de/test/antennapod/ui/PlaybackSonicTest.java363
-rw-r--r--app/src/main/assets/LICENSE_ANTENNAPOD_AUDIOPLAYER.txt201
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/AboutActivity.java14
-rw-r--r--app/src/main/java/de/danoeh/antennapod/dialog/VariableSpeedDialog.java7
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java109
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java92
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/DownloadLogFragment.java72
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/ItemlistFragment.java90
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/NewEpisodesFragment.java6
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java84
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java95
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/SearchFragment.java92
-rw-r--r--app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java7
-rw-r--r--app/src/main/res/xml/preferences.xml8
-rw-r--r--app/src/main/templates/about.html6
-rw-r--r--core/build.gradle8
-rw-r--r--core/src/main/aidl/com/aocate/presto/service/IDeathCallback_0_8.aidl18
-rw-r--r--core/src/main/aidl/com/aocate/presto/service/IOnBufferingUpdateListenerCallback_0_8.aidl19
-rw-r--r--core/src/main/aidl/com/aocate/presto/service/IOnCompletionListenerCallback_0_8.aidl19
-rw-r--r--core/src/main/aidl/com/aocate/presto/service/IOnErrorListenerCallback_0_8.aidl19
-rw-r--r--core/src/main/aidl/com/aocate/presto/service/IOnInfoListenerCallback_0_8.aidl19
-rw-r--r--core/src/main/aidl/com/aocate/presto/service/IOnPitchAdjustmentAvailableChangedListenerCallback_0_8.aidl19
-rw-r--r--core/src/main/aidl/com/aocate/presto/service/IOnPreparedListenerCallback_0_8.aidl19
-rw-r--r--core/src/main/aidl/com/aocate/presto/service/IOnSeekCompleteListenerCallback_0_8.aidl19
-rw-r--r--core/src/main/aidl/com/aocate/presto/service/IOnSpeedAdjustmentAvailableChangedListenerCallback_0_8.aidl19
-rw-r--r--core/src/main/aidl/com/aocate/presto/service/IPlayMedia_0_8.aidl75
-rw-r--r--core/src/main/java/com/aocate/media/AndroidMediaPlayer.java470
-rw-r--r--core/src/main/java/com/aocate/media/MediaPlayer.java1310
-rw-r--r--core/src/main/java/com/aocate/media/MediaPlayerImpl.java118
-rw-r--r--core/src/main/java/com/aocate/media/ServiceBackedMediaPlayer.java1203
-rw-r--r--core/src/main/java/com/aocate/media/SpeedAdjustmentAlgorithm.java31
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/feed/FeedItemFilter.java2
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/preferences/UserPreferences.java7
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceMediaPlayer.java20
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java6
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/playback/AudioPlayer.java10
-rw-r--r--core/src/main/res/values/strings.xml3
38 files changed, 923 insertions, 3758 deletions
diff --git a/app/build.gradle b/app/build.gradle
index e18708878..3415189aa 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -4,6 +4,7 @@ apply plugin: 'com.android.application'
apply plugin: 'me.tatarka.retrolambda'
repositories {
+ maven { url "https://jitpack.io" }
mavenCentral()
}
@@ -28,6 +29,7 @@ dependencies {
compile 'com.joanzapata.iconify:android-iconify-fontawesome:2.0.3'
compile 'com.afollestad:material-dialogs:0.7.8.0'
+ compile 'com.github.AntennaPod:AntennaPod-AudioPlayer:v1.0'
compile project(':core')
compile project(':library:drag-sort-listview')
diff --git a/app/src/androidTest/java/de/test/antennapod/ui/PlaybackSonicTest.java b/app/src/androidTest/java/de/test/antennapod/ui/PlaybackSonicTest.java
new file mode 100644
index 000000000..17ec87aa3
--- /dev/null
+++ b/app/src/androidTest/java/de/test/antennapod/ui/PlaybackSonicTest.java
@@ -0,0 +1,363 @@
+package de.test.antennapod.ui;
+
+import android.annotation.TargetApi;
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.Build;
+import android.preference.PreferenceManager;
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.FlakyTest;
+import android.view.View;
+import android.widget.ImageButton;
+import android.widget.ListView;
+
+import com.robotium.solo.Solo;
+import com.robotium.solo.Timeout;
+
+import java.util.List;
+
+import de.danoeh.antennapod.R;
+import de.danoeh.antennapod.activity.MainActivity;
+import de.danoeh.antennapod.core.feed.FeedItem;
+import de.danoeh.antennapod.core.feed.FeedMedia;
+import de.danoeh.antennapod.core.preferences.UserPreferences;
+import de.danoeh.antennapod.core.service.playback.PlaybackService;
+import de.danoeh.antennapod.core.service.playback.PlayerStatus;
+import de.danoeh.antennapod.core.storage.DBReader;
+import de.danoeh.antennapod.core.storage.DBWriter;
+import de.danoeh.antennapod.core.storage.PodDBAdapter;
+import de.danoeh.antennapod.core.util.playback.Playable;
+import de.danoeh.antennapod.core.util.playback.PlaybackController;
+
+/**
+ * test cases for starting and ending playback from the MainActivity and AudioPlayerActivity
+ */
+@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
+public class PlaybackSonicTest extends ActivityInstrumentationTestCase2<MainActivity> {
+
+ private static final String TAG = PlaybackTest.class.getSimpleName();
+ public static final int EPISODES_DRAWER_LIST_INDEX = 1;
+ public static final int QUEUE_DRAWER_LIST_INDEX = 0;
+
+ private Solo solo;
+ private UITestUtils uiTestUtils;
+
+ private Context context;
+
+ private PlaybackController controller;
+ protected FeedMedia currentMedia;
+
+ private PlaybackController createController(Activity activity) {
+ return new PlaybackController(activity, false) {
+
+ @Override
+ public void setupGUI() {
+ }
+
+ @Override
+ public void onPositionObserverUpdate() {
+ }
+
+ @Override
+ public void onBufferStart() {
+ }
+
+ @Override
+ public void onBufferEnd() {
+ }
+
+ @Override
+ public void onBufferUpdate(float progress) {
+ }
+
+ @Override
+ public void handleError(int code) {
+ }
+
+ @Override
+ public void onReloadNotification(int code) {
+ }
+
+ @Override
+ public void onSleepTimerUpdate() {
+ }
+
+ @Override
+ public ImageButton getPlayButton() {
+ return null;
+ }
+
+ @Override
+ public void postStatusMsg(int msg) {
+ }
+
+ @Override
+ public void clearStatusMsg() {
+ }
+
+ @Override
+ public boolean loadMediaInfo() {
+ Playable playable = controller.getMedia();
+ if(playable == null) {
+ currentMedia = null;
+ return true;
+ } else if(playable instanceof FeedMedia) {
+ currentMedia = (FeedMedia) playable;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public void onAwaitingVideoSurface() {
+ }
+
+ @Override
+ public void onServiceQueried() {
+ }
+
+ @Override
+ public void onShutdownNotification() {
+ }
+
+ @Override
+ public void onPlaybackEnd() {
+ currentMedia = null;
+ }
+
+ @Override
+ public void onPlaybackSpeedChange() {
+ }
+
+ @Override
+ protected void setScreenOn(boolean enable) {
+ }
+ };
+ }
+
+ public PlaybackSonicTest() {
+ super(MainActivity.class);
+ }
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+
+ PodDBAdapter.deleteDatabase();
+
+ context = getInstrumentation().getTargetContext();
+
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
+ prefs.edit()
+ .clear()
+ .putBoolean(UserPreferences.PREF_UNPAUSE_ON_HEADSET_RECONNECT, false)
+ .putBoolean(UserPreferences.PREF_PAUSE_ON_HEADSET_DISCONNECT, false)
+ .putBoolean(UserPreferences.PREF_SONIC, true)
+ .commit();
+
+ controller = createController(getActivity());
+ controller.init();
+
+ solo = new Solo(getInstrumentation(), getActivity());
+
+ uiTestUtils = new UITestUtils(context);
+ uiTestUtils.setup();
+
+ // create database
+ PodDBAdapter adapter = PodDBAdapter.getInstance();
+ adapter.open();
+ adapter.close();
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ controller.release();
+ solo.finishOpenedActivities();
+ uiTestUtils.tearDown();
+
+ // shut down playback service
+ skipEpisode();
+ context.sendBroadcast(new Intent(PlaybackService.ACTION_SHUTDOWN_PLAYBACK_SERVICE));
+
+ super.tearDown();
+ }
+
+ private void openNavDrawer() {
+ solo.clickOnScreen(50, 50);
+ }
+
+ private void setContinuousPlaybackPreference(boolean value) {
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
+ prefs.edit().putBoolean(UserPreferences.PREF_FOLLOW_QUEUE, value).commit();
+ }
+
+ private void skipEpisode() {
+ Intent skipIntent = new Intent(PlaybackService.ACTION_SKIP_CURRENT_EPISODE);
+ context.sendBroadcast(skipIntent);
+ }
+
+ private void startLocalPlayback() {
+ openNavDrawer();
+ // if we try to just click on plain old text then
+ // we might wind up clicking on the fragment title and not
+ // the drawer element like we want.
+ ListView drawerView = (ListView)solo.getView(R.id.nav_list);
+ // this should be 'Episodes'
+ View targetView = drawerView.getChildAt(EPISODES_DRAWER_LIST_INDEX);
+ solo.waitForView(targetView);
+ solo.clickOnView(targetView);
+ solo.waitForText(solo.getString(R.string.all_episodes_short_label));
+ solo.clickOnText(solo.getString(R.string.all_episodes_short_label));
+
+ final List<FeedItem> episodes = DBReader.getRecentlyPublishedEpisodes(10);
+ assertTrue(solo.waitForView(solo.getView(R.id.butSecondaryAction)));
+
+ solo.clickOnView(solo.getView(R.id.butSecondaryAction));
+ long mediaId = episodes.get(0).getMedia().getId();
+ boolean playing = solo.waitForCondition(() -> {
+ if (currentMedia != null) {
+ return currentMedia.getId() == mediaId;
+ } else {
+ return false;
+ }
+ }, Timeout.getSmallTimeout());
+ assertTrue(playing);
+ }
+
+ private void startLocalPlaybackFromQueue() {
+ openNavDrawer();
+
+ // if we try to just click on plain old text then
+ // we might wind up clicking on the fragment title and not
+ // the drawer element like we want.
+ ListView drawerView = (ListView)solo.getView(R.id.nav_list);
+ // this should be 'Queue'
+ View targetView = drawerView.getChildAt(QUEUE_DRAWER_LIST_INDEX);
+ solo.waitForView(targetView);
+ solo.clickOnView(targetView);
+
+ assertTrue(solo.waitForView(solo.getView(R.id.butSecondaryAction)));
+ final List<FeedItem> queue = DBReader.getQueue();
+ solo.clickOnImageButton(1);
+ assertTrue(solo.waitForView(solo.getView(R.id.butPlay)));
+ long mediaId = queue.get(0).getMedia().getId();
+ boolean playing = solo.waitForCondition(() -> {
+ if(currentMedia != null) {
+ return currentMedia.getId() == mediaId;
+ } else {
+ return false;
+ }
+ }, Timeout.getSmallTimeout());
+ assertTrue(playing);
+ }
+
+ public void testStartLocal() throws Exception {
+ uiTestUtils.addLocalFeedData(true);
+ DBWriter.clearQueue().get();
+ startLocalPlayback();
+ }
+
+ public void testContinousPlaybackOffSingleEpisode() throws Exception {
+ setContinuousPlaybackPreference(false);
+ uiTestUtils.addLocalFeedData(true);
+ DBWriter.clearQueue().get();
+ startLocalPlayback();
+ }
+
+ @FlakyTest(tolerance = 3)
+ public void testContinousPlaybackOffMultipleEpisodes() throws Exception {
+ setContinuousPlaybackPreference(false);
+ uiTestUtils.addLocalFeedData(true);
+ List<FeedItem> queue = DBReader.getQueue();
+ final FeedItem first = queue.get(0);
+
+ startLocalPlaybackFromQueue();
+ boolean stopped = solo.waitForCondition(() -> {
+ if (currentMedia != null) {
+ return currentMedia.getId() != first.getMedia().getId();
+ } else {
+ return false;
+ }
+ }, Timeout.getSmallTimeout());
+ assertTrue(stopped);
+ Thread.sleep(1000);
+ PlayerStatus status = controller.getStatus();
+ assertFalse(status.equals(PlayerStatus.PLAYING));
+ }
+
+ @FlakyTest(tolerance = 3)
+ public void testContinuousPlaybackOnMultipleEpisodes() throws Exception {
+ setContinuousPlaybackPreference(true);
+ uiTestUtils.addLocalFeedData(true);
+ List<FeedItem> queue = DBReader.getQueue();
+ final FeedItem first = queue.get(0);
+ final FeedItem second = queue.get(1);
+
+ startLocalPlaybackFromQueue();
+ boolean firstPlaying = solo.waitForCondition(() -> {
+ if (currentMedia != null) {
+ return currentMedia.getId() == first.getMedia().getId();
+ } else {
+ return false;
+ }
+ }, Timeout.getSmallTimeout());
+ assertTrue(firstPlaying);
+ boolean secondPlaying = solo.waitForCondition(() -> {
+ if (currentMedia != null) {
+ return currentMedia.getId() == second.getMedia().getId();
+ } else {
+ return false;
+ }
+ }, Timeout.getLargeTimeout());
+ assertTrue(secondPlaying);
+ }
+
+ /**
+ * Check if an episode can be played twice without problems.
+ */
+ private void replayEpisodeCheck(boolean followQueue) throws Exception {
+ setContinuousPlaybackPreference(followQueue);
+ uiTestUtils.addLocalFeedData(true);
+ DBWriter.clearQueue().get();
+ final List<FeedItem> episodes = DBReader.getRecentlyPublishedEpisodes(10);
+
+ startLocalPlayback();
+ long mediaId = episodes.get(0).getMedia().getId();
+ boolean startedPlaying = solo.waitForCondition(() -> {
+ if (currentMedia != null) {
+ return currentMedia.getId() == mediaId;
+ } else {
+ return false;
+ }
+ }, Timeout.getSmallTimeout());
+ assertTrue(startedPlaying);
+
+ boolean stoppedPlaying = solo.waitForCondition(() -> {
+ return currentMedia == null || currentMedia.getId() != mediaId;
+ }, Timeout.getLargeTimeout());
+ assertTrue(stoppedPlaying);
+
+ startLocalPlayback();
+ boolean startedReplay = solo.waitForCondition(() -> {
+ if(currentMedia != null) {
+ return currentMedia.getId() == mediaId;
+ } else {
+ return false;
+ }
+ }, Timeout.getLargeTimeout());
+ assertTrue(startedReplay);
+ }
+
+ public void testReplayEpisodeContinuousPlaybackOn() throws Exception {
+ replayEpisodeCheck(true);
+ }
+
+ public void testReplayEpisodeContinuousPlaybackOff() throws Exception {
+ replayEpisodeCheck(false);
+ }
+
+
+}
diff --git a/app/src/main/assets/LICENSE_ANTENNAPOD_AUDIOPLAYER.txt b/app/src/main/assets/LICENSE_ANTENNAPOD_AUDIOPLAYER.txt
new file mode 100644
index 000000000..8dada3eda
--- /dev/null
+++ b/app/src/main/assets/LICENSE_ANTENNAPOD_AUDIOPLAYER.txt
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "{}"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright {yyyy} {name of copyright owner}
+
+ 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.
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/AboutActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/AboutActivity.java
index df764e829..fe31ccda8 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/AboutActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/AboutActivity.java
@@ -57,9 +57,13 @@ public class AboutActivity extends ActionBarActivity {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
- url = url.replace("file:///android_asset/", "");
- loadAsset(url);
- return true;
+ if(url.startsWith("http")) {
+ return false;
+ } else {
+ url = url.replace("file:///android_asset/", "");
+ loadAsset(url);
+ return true;
+ }
}
});
@@ -126,8 +130,10 @@ public class AboutActivity extends ActionBarActivity {
@Override
public void onBackPressed() {
- if(showingLicense) {
+ if(showingLicense || webview.canGoBack()) {
loadAsset("about.html");
+ } else if(webview.canGoBack()) {
+ webview.goBack();
} else {
super.onBackPressed();
}
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/VariableSpeedDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/VariableSpeedDialog.java
index 8eba51540..b01b13492 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/VariableSpeedDialog.java
+++ b/app/src/main/java/de/danoeh/antennapod/dialog/VariableSpeedDialog.java
@@ -6,18 +6,19 @@ import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
-import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.core.preferences.UserPreferences;
import java.util.Arrays;
import java.util.List;
+import de.danoeh.antennapod.R;
+import de.danoeh.antennapod.core.preferences.UserPreferences;
+
public class VariableSpeedDialog {
private VariableSpeedDialog() {
}
public static void showDialog(final Context context) {
- if (com.aocate.media.MediaPlayer.isPrestoLibraryInstalled(context)) {
+ if (org.antennapod.audio.MediaPlayer.isPrestoLibraryInstalled(context)) {
showSpeedSelectorDialog(context);
} else {
showGetPluginDialog(context);
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java
index 5d0edb638..5aed66013 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java
@@ -4,10 +4,10 @@ import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
-import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.Fragment;
+import android.support.v4.util.Pair;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.widget.SearchView;
import android.util.Log;
@@ -38,7 +38,6 @@ import de.danoeh.antennapod.core.feed.EventDistributor;
import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
-import de.danoeh.antennapod.core.feed.QueueEvent;
import de.danoeh.antennapod.core.service.download.DownloadService;
import de.danoeh.antennapod.core.service.download.Downloader;
import de.danoeh.antennapod.core.storage.DBReader;
@@ -49,6 +48,10 @@ import de.danoeh.antennapod.core.storage.DownloadRequester;
import de.danoeh.antennapod.core.util.LongList;
import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler;
import de.danoeh.antennapod.menuhandler.MenuItemUtils;
+import rx.Observable;
+import rx.Subscription;
+import rx.android.schedulers.AndroidSchedulers;
+import rx.schedulers.Schedulers;
/**
* Shows unread or recently published episodes
@@ -90,6 +93,8 @@ public class AllEpisodesFragment extends Fragment {
private boolean isUpdatingFeeds;
+ protected Subscription subscription;
+
public AllEpisodesFragment() {
// by default we show all the episodes
this(false, DEFAULT_PREF_NAME);
@@ -113,7 +118,7 @@ public class AllEpisodesFragment extends Fragment {
@Override
public void onResume() {
super.onResume();
- startItemLoader();
+ loadItems();
}
@Override
@@ -140,7 +145,9 @@ public class AllEpisodesFragment extends Fragment {
public void onStop() {
super.onStop();
EventDistributor.getInstance().unregister(contentUpdate);
- stopItemLoader();
+ if(subscription != null) {
+ subscription.unsubscribe();
+ }
}
@Override
@@ -436,7 +443,7 @@ public class AllEpisodesFragment extends Fragment {
@Override
public void update(EventDistributor eventDistributor, Integer arg) {
if ((arg & EVENTS) != 0) {
- startItemLoader();
+ loadItems();
if (isUpdatingFeeds != updateRefreshMenuItemChecker.isRefreshing()) {
getActivity().supportInvalidateOptionsMenu();
}
@@ -453,69 +460,43 @@ public class AllEpisodesFragment extends Fragment {
}
}
- private ItemLoader itemLoader;
-
- protected void startItemLoader() {
- if (itemLoader != null) {
- itemLoader.cancel(true);
+ protected void loadItems() {
+ if(subscription != null) {
+ subscription.unsubscribe();
}
- itemLoader = new ItemLoader();
- itemLoader.execute();
- }
-
- protected void stopItemLoader() {
- if (itemLoader != null) {
- itemLoader.cancel(true);
+ if (viewsCreated && !itemsLoaded) {
+ listView.setVisibility(View.GONE);
+ txtvEmpty.setVisibility(View.GONE);
+ progLoading.setVisibility(View.VISIBLE);
}
+ subscription = Observable.defer(() -> Observable.just(loadData()))
+ .subscribeOn(Schedulers.newThread())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(data -> {
+ listView.setVisibility(View.VISIBLE);
+ progLoading.setVisibility(View.GONE);
+ if (data != null) {
+ episodes = data.first;
+ queuedItemsIds = data.second;
+ itemsLoaded = true;
+ if (viewsCreated && activity.get() != null) {
+ onFragmentLoaded();
+ }
+ }
+ }, error -> {
+ Log.e(TAG, Log.getStackTraceString(error));
+ });
}
- private class ItemLoader extends AsyncTask<Void, Void, Object[]> {
-
- @Override
- protected void onPreExecute() {
- super.onPreExecute();
- if (viewsCreated && !itemsLoaded) {
- listView.setVisibility(View.GONE);
- txtvEmpty.setVisibility(View.GONE);
- progLoading.setVisibility(View.VISIBLE);
- }
- }
-
- @Override
- protected Object[] doInBackground(Void... params) {
- Context context = activity.get();
- if (context != null) {
- if(showOnlyNewEpisodes) {
- return new Object[] {
- DBReader.getNewItemsList(),
- DBReader.getQueueIDList(),
- null // see ItemAccess.isNew
- };
- } else {
- return new Object[]{
- DBReader.getRecentlyPublishedEpisodes(RECENT_EPISODES_LIMIT),
- DBReader.getQueueIDList()
- };
- }
- } else {
- return null;
- }
- }
-
- @Override
- protected void onPostExecute(Object[] lists) {
- super.onPostExecute(lists);
- listView.setVisibility(View.VISIBLE);
- progLoading.setVisibility(View.GONE);
-
- if (lists != null) {
- episodes = (List<FeedItem>) lists[0];
- queuedItemsIds = (LongList) lists[1];
- itemsLoaded = true;
- if (viewsCreated && activity.get() != null) {
- onFragmentLoaded();
- }
- }
+ private Pair<List<FeedItem>,LongList> loadData() {
+ List<FeedItem> items;
+ if(showOnlyNewEpisodes) {
+ items = DBReader.getNewItemsList();
+ } else {
+ items = DBReader.getRecentlyPublishedEpisodes(RECENT_EPISODES_LIMIT);
}
+ LongList queuedIds = DBReader.getQueueIDList();
+ return Pair.create(items, queuedIds);
}
+
}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java
index 278928f3d..c5b582d3a 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java
@@ -1,14 +1,12 @@
package de.danoeh.antennapod.fragment;
import android.app.Activity;
-import android.content.Context;
-import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
+import android.util.Log;
import android.view.View;
import android.widget.ListView;
-import java.util.Collections;
import java.util.List;
import de.danoeh.antennapod.R;
@@ -18,11 +16,18 @@ import de.danoeh.antennapod.core.feed.EventDistributor;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBWriter;
+import rx.Observable;
+import rx.Subscription;
+import rx.android.schedulers.AndroidSchedulers;
+import rx.schedulers.Schedulers;
/**
* Displays all running downloads and provides a button to delete them
*/
public class CompletedDownloadsFragment extends ListFragment {
+
+ private static final String TAG = CompletedDownloadsFragment.class.getSimpleName();
+
private static final int EVENTS =
EventDistributor.DOWNLOAD_HANDLED |
EventDistributor.DOWNLOADLOG_UPDATE |
@@ -34,11 +39,12 @@ public class CompletedDownloadsFragment extends ListFragment {
private boolean viewCreated = false;
private boolean itemsLoaded = false;
+ private Subscription subscription;
+
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
-
- startItemLoader();
+ loadItems();
}
@Override
@@ -51,13 +57,17 @@ public class CompletedDownloadsFragment extends ListFragment {
public void onStop() {
super.onStop();
EventDistributor.getInstance().unregister(contentUpdate);
- stopItemLoader();
+ if(subscription != null) {
+ subscription.unsubscribe();
+ }
}
@Override
public void onDetach() {
super.onDetach();
- stopItemLoader();
+ if(subscription != null) {
+ subscription.unsubscribe();
+ }
}
@Override
@@ -65,7 +75,9 @@ public class CompletedDownloadsFragment extends ListFragment {
super.onDestroyView();
listAdapter = null;
viewCreated = false;
- stopItemLoader();
+ if(subscription != null) {
+ subscription.unsubscribe();
+ }
}
@Override
@@ -132,56 +144,32 @@ public class CompletedDownloadsFragment extends ListFragment {
@Override
public void update(EventDistributor eventDistributor, Integer arg) {
if ((arg & EVENTS) != 0) {
- startItemLoader();
+ loadItems();
}
}
};
- private ItemLoader itemLoader;
-
- private void startItemLoader() {
- if (itemLoader != null) {
- itemLoader.cancel(true);
+ private void loadItems() {
+ if(subscription != null) {
+ subscription.unsubscribe();
}
- itemLoader = new ItemLoader();
- itemLoader.execute();
- }
-
- private void stopItemLoader() {
- if (itemLoader != null) {
- itemLoader.cancel(true);
+ if (!itemsLoaded && viewCreated) {
+ setListShown(false);
}
+ subscription = Observable.defer(() -> Observable.just(DBReader.getDownloadedItems()))
+ .subscribeOn(Schedulers.newThread())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(result -> {
+ if (result != null) {
+ items = result;
+ itemsLoaded = true;
+ if (viewCreated && getActivity() != null) {
+ onFragmentLoaded();
+ }
+ }
+ }, error -> {
+ Log.e(TAG, Log.getStackTraceString(error));
+ });
}
- private class ItemLoader extends AsyncTask<Void, Void, List<FeedItem>> {
-
- @Override
- protected void onPreExecute() {
- super.onPreExecute();
- if (!itemsLoaded && viewCreated) {
- setListShown(false);
- }
- }
-
- @Override
- protected void onPostExecute(List<FeedItem> results) {
- super.onPostExecute(results);
- if (results != null) {
- items = results;
- itemsLoaded = true;
- if (viewCreated && getActivity() != null) {
- onFragmentLoaded();
- }
- }
- }
-
- @Override
- protected List<FeedItem> doInBackground(Void... params) {
- Context context = getActivity();
- if (context != null) {
- return DBReader.getDownloadedItems();
- }
- return Collections.emptyList();
- }
- }
}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/DownloadLogFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/DownloadLogFragment.java
index da2c05a69..669c6ac49 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/DownloadLogFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/DownloadLogFragment.java
@@ -1,11 +1,10 @@
package de.danoeh.antennapod.fragment;
-import android.content.Context;
import android.content.res.TypedArray;
-import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.support.v4.view.MenuItemCompat;
+import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
@@ -20,6 +19,10 @@ import de.danoeh.antennapod.core.feed.EventDistributor;
import de.danoeh.antennapod.core.service.download.DownloadStatus;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBWriter;
+import rx.Observable;
+import rx.Subscription;
+import rx.android.schedulers.AndroidSchedulers;
+import rx.schedulers.Schedulers;
/**
* Shows the download log
@@ -34,19 +37,23 @@ public class DownloadLogFragment extends ListFragment {
private boolean viewsCreated = false;
private boolean itemsLoaded = false;
+ private Subscription subscription;
+
@Override
public void onStart() {
super.onStart();
setHasOptionsMenu(true);
EventDistributor.getInstance().register(contentUpdate);
- startItemLoader();
+ loadItems();
}
@Override
public void onStop() {
super.onStop();
EventDistributor.getInstance().unregister(contentUpdate);
- stopItemLoader();
+ if(subscription != null) {
+ subscription.unsubscribe();
+ }
}
@Override
@@ -93,27 +100,11 @@ public class DownloadLogFragment extends ListFragment {
@Override
public void update(EventDistributor eventDistributor, Integer arg) {
if ((arg & EventDistributor.DOWNLOADLOG_UPDATE) != 0) {
- startItemLoader();
+ loadItems();
}
}
};
- private ItemLoader itemLoader;
-
- private void startItemLoader() {
- if (itemLoader != null) {
- itemLoader.cancel(true);
- }
- itemLoader = new ItemLoader();
- itemLoader.execute();
- }
-
- private void stopItemLoader() {
- if (itemLoader != null) {
- itemLoader.cancel(true);
- }
- }
-
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
@@ -152,27 +143,24 @@ public class DownloadLogFragment extends ListFragment {
}
}
- private class ItemLoader extends AsyncTask<Void, Void, List<DownloadStatus>> {
-
- @Override
- protected void onPostExecute(List<DownloadStatus> downloadStatuses) {
- super.onPostExecute(downloadStatuses);
- if (downloadStatuses != null) {
- downloadLog = downloadStatuses;
- itemsLoaded = true;
- if (viewsCreated) {
- onFragmentLoaded();
- }
- }
- }
-
- @Override
- protected List<DownloadStatus> doInBackground(Void... params) {
- Context context = getActivity();
- if (context != null) {
- return DBReader.getDownloadLog();
- }
- return null;
+ private void loadItems() {
+ if(subscription != null) {
+ subscription.unsubscribe();
}
+ subscription = Observable.defer(() -> Observable.just(DBReader.getDownloadLog()))
+ .subscribeOn(Schedulers.newThread())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(result -> {
+ if (result != null) {
+ downloadLog = result;
+ itemsLoaded = true;
+ if (viewsCreated) {
+ onFragmentLoaded();
+ }
+ }
+ }, error -> {
+ Log.e(TAG, Log.getStackTraceString(error));
+ });
}
+
}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ItemlistFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ItemlistFragment.java
index 38c9b645a..3d0ff66f7 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/ItemlistFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/ItemlistFragment.java
@@ -7,12 +7,12 @@ import android.content.Intent;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.LightingColorFilter;
-import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.Fragment;
import android.support.v4.app.ListFragment;
+import android.support.v4.util.Pair;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.widget.SearchView;
@@ -73,6 +73,10 @@ import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler;
import de.danoeh.antennapod.menuhandler.FeedMenuHandler;
import de.danoeh.antennapod.menuhandler.MenuItemUtils;
import de.greenrobot.event.EventBus;
+import rx.Observable;
+import rx.Subscription;
+import rx.android.schedulers.AndroidSchedulers;
+import rx.schedulers.Schedulers;
/**
* Displays a list of FeedItems.
@@ -111,6 +115,8 @@ public class ItemlistFragment extends ListFragment {
private TextView txtvInformation;
+ private Subscription subscription;
+
/**
* Creates new ItemlistFragment which shows the Feeditems of a specific
* feed. Sets 'showFeedtitle' to false
@@ -156,7 +162,9 @@ public class ItemlistFragment extends ListFragment {
super.onStop();
EventDistributor.getInstance().unregister(contentUpdate);
EventBus.getDefault().unregister(this);
- stopItemLoader();
+ if(subscription != null) {
+ subscription.unsubscribe();
+ }
}
@Override
@@ -164,13 +172,15 @@ public class ItemlistFragment extends ListFragment {
super.onResume();
Log.d(TAG, "onResume()");
updateProgressBarVisibility();
- startItemLoader();
+ loadItems();
}
@Override
public void onDetach() {
super.onDetach();
- stopItemLoader();
+ if(subscription != null) {
+ subscription.unsubscribe();
+ }
}
@Override
@@ -385,13 +395,13 @@ public class ItemlistFragment extends ListFragment {
public void onEvent(QueueEvent event) {
Log.d(TAG, "onEvent(" + event + ")");
- startItemLoader();
+ loadItems();
}
public void onEvent(FeedEvent event) {
Log.d(TAG, "onEvent(" + event + ")");
if(event.feedId == feedID) {
- startItemLoader();
+ loadItems();
}
}
@@ -404,7 +414,7 @@ public class ItemlistFragment extends ListFragment {
if ((EventDistributor.DOWNLOAD_QUEUED & arg) != 0) {
updateProgressBarVisibility();
} else {
- startItemLoader();
+ loadItems();
updateProgressBarVisibility();
}
}
@@ -608,51 +618,37 @@ public class ItemlistFragment extends ListFragment {
}
};
- private ItemLoader itemLoader;
- private void startItemLoader() {
- if (itemLoader != null) {
- itemLoader.cancel(true);
+ private void loadItems() {
+ if(subscription != null) {
+ subscription.unsubscribe();
}
- itemLoader = new ItemLoader();
- itemLoader.execute(feedID);
- }
- private void stopItemLoader() {
- if (itemLoader != null) {
- itemLoader.cancel(true);
- }
+ subscription = Observable.defer(() -> Observable.just(loadData()))
+ .subscribeOn(Schedulers.newThread())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(result -> {
+ if (result != null) {
+ feed = result.first;
+ queuedItemsIds = result.second;
+ itemsLoaded = true;
+ if (viewsCreated) {
+ onFragmentLoaded();
+ }
+ }
+ }, error -> {
+ Log.e(TAG, Log.getStackTraceString(error));
+ });
}
- private class ItemLoader extends AsyncTask<Long, Void, Object[]> {
- @Override
- protected Object[] doInBackground(Long... params) {
- long feedID = params[0];
- Context context = getActivity();
- if (context != null) {
- Feed feed = DBReader.getFeed(feedID);
- if(feed != null && feed.getItemFilter() != null) {
- FeedItemFilter filter = feed.getItemFilter();
- feed.setItems(filter.filter(context, feed.getItems()));
- }
- LongList queuedItemsIds = DBReader.getQueueIDList();
- return new Object[] { feed, queuedItemsIds };
- } else {
- return null;
- }
- }
-
- @Override
- protected void onPostExecute(Object[] res) {
- super.onPostExecute(res);
- if (res != null) {
- feed = (Feed) res[0];
- queuedItemsIds = (LongList) res[1];
- itemsLoaded = true;
- if (viewsCreated) {
- onFragmentLoaded();
- }
- }
+ private Pair<Feed, LongList> loadData() {
+ Feed feed = DBReader.getFeed(feedID);
+ if(feed != null && feed.getItemFilter() != null) {
+ FeedItemFilter filter = feed.getItemFilter();
+ feed.setItems(filter.filter(feed.getItems()));
}
+ LongList queuedItemsIds = DBReader.getQueueIDList();
+ return Pair.create(feed, queuedItemsIds);
}
+
}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/NewEpisodesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/NewEpisodesFragment.java
index 6177f2a50..d454208c1 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/NewEpisodesFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/NewEpisodesFragment.java
@@ -39,7 +39,7 @@ public class NewEpisodesFragment extends AllEpisodesFragment {
public void onEvent(QueueEvent event) {
Log.d(TAG, "onEvent(" + event + ")");
- startItemLoader();
+ loadItems();
}
@Override
@@ -69,7 +69,9 @@ public class NewEpisodesFragment extends AllEpisodesFragment {
@Override
public void remove(int which) {
Log.d(TAG, "remove(" + which + ")");
- stopItemLoader();
+ if(subscription != null) {
+ subscription.unsubscribe();
+ }
FeedItem item = (FeedItem) listView.getAdapter().getItem(which);
// we're marking it as unplayed since the user didn't actually play it
// but they don't want it considered 'NEW' anymore
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java
index 530883667..e6460309b 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java
@@ -1,9 +1,7 @@
package de.danoeh.antennapod.fragment;
import android.app.Activity;
-import android.content.Context;
import android.content.res.TypedArray;
-import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.ListFragment;
@@ -33,6 +31,10 @@ import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBWriter;
import de.danoeh.antennapod.core.util.LongList;
import de.greenrobot.event.EventBus;
+import rx.Observable;
+import rx.Subscription;
+import rx.android.schedulers.AndroidSchedulers;
+import rx.schedulers.Schedulers;
public class PlaybackHistoryFragment extends ListFragment {
@@ -53,6 +55,8 @@ public class PlaybackHistoryFragment extends ListFragment {
private DownloadObserver downloadObserver;
private List<Downloader> downloaderList;
+ private Subscription subscription;
+
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -63,7 +67,7 @@ public class PlaybackHistoryFragment extends ListFragment {
@Override
public void onResume() {
super.onResume();
- startItemLoader();
+ loadItems();
}
@Override
@@ -78,13 +82,17 @@ public class PlaybackHistoryFragment extends ListFragment {
super.onStop();
EventDistributor.getInstance().unregister(contentUpdate);
EventBus.getDefault().unregister(this);
- stopItemLoader();
+ if(subscription != null) {
+ subscription.unsubscribe();
+ }
}
@Override
public void onDetach() {
super.onDetach();
- stopItemLoader();
+ if(subscription != null) {
+ subscription.unsubscribe();
+ }
activity.set(null);
}
@@ -176,7 +184,7 @@ public class PlaybackHistoryFragment extends ListFragment {
public void onEvent(QueueEvent event) {
Log.d(TAG, "onEvent(" + event + ")");
- startItemLoader();
+ loadItems();
}
private EventDistributor.EventListener contentUpdate = new EventDistributor.EventListener() {
@@ -184,7 +192,7 @@ public class PlaybackHistoryFragment extends ListFragment {
@Override
public void update(EventDistributor eventDistributor, Integer arg) {
if ((arg & EVENTS) != 0) {
- startItemLoader();
+ loadItems();
getActivity().supportInvalidateOptionsMenu();
}
}
@@ -245,48 +253,32 @@ public class PlaybackHistoryFragment extends ListFragment {
}
};
- private ItemLoader itemLoader;
-
- private void startItemLoader() {
- if (itemLoader != null) {
- itemLoader.cancel(true);
+ private void loadItems() {
+ if(subscription != null) {
+ subscription.unsubscribe();
}
- itemLoader = new ItemLoader();
- itemLoader.execute();
+ subscription = Observable.defer(() -> Observable.just(loadData()))
+ .subscribeOn(Schedulers.newThread())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(result -> {
+ if (result != null) {
+ playbackHistory = result.first;
+ queue = result.second;
+ itemsLoaded = true;
+ if (viewsCreated) {
+ onFragmentLoaded();
+ }
+ }
+ }, error -> {
+ Log.e(TAG, Log.getStackTraceString(error));
+ });
}
- private void stopItemLoader() {
- if (itemLoader != null) {
- itemLoader.cancel(true);
- }
+ private Pair<List<FeedItem>, LongList> loadData() {
+ List<FeedItem> history = DBReader.getPlaybackHistory();
+ LongList queue = DBReader.getQueueIDList();
+ DBReader.loadFeedDataOfFeedItemlist(history);
+ return Pair.create(history, queue);
}
- private class ItemLoader extends AsyncTask<Void, Void, Pair<List<FeedItem>,LongList>> {
-
- @Override
- protected Pair<List<FeedItem>,LongList> doInBackground(Void... params) {
- Context context = activity.get();
- if (context != null) {
- List<FeedItem> history = DBReader.getPlaybackHistory();
- LongList queue = DBReader.getQueueIDList();
- DBReader.loadFeedDataOfFeedItemlist(history);
- return Pair.create(history, queue);
- } else {
- return null;
- }
- }
-
- @Override
- protected void onPostExecute(Pair<List<FeedItem>,LongList> res) {
- super.onPostExecute(res);
- if (res != null) {
- playbackHistory = res.first;
- queue = res.second;
- itemsLoaded = true;
- if (viewsCreated) {
- onFragmentLoaded();
- }
- }
- }
- }
}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java
index 63c319e03..7bcd98dc8 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java
@@ -4,7 +4,6 @@ import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
-import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.Fragment;
@@ -55,6 +54,10 @@ import de.danoeh.antennapod.core.util.gui.UndoBarController;
import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler;
import de.danoeh.antennapod.menuhandler.MenuItemUtils;
import de.greenrobot.event.EventBus;
+import rx.Observable;
+import rx.Subscription;
+import rx.android.schedulers.AndroidSchedulers;
+import rx.schedulers.Schedulers;
/**
* Shows all items in the queue
@@ -98,6 +101,8 @@ public class QueueFragment extends Fragment {
*/
private boolean blockDownloadObserverUpdate = false;
+ private Subscription subscription;
+
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -109,7 +114,7 @@ public class QueueFragment extends Fragment {
@Override
public void onResume() {
super.onResume();
- startItemLoader();
+ loadItems();
}
@Override
@@ -138,7 +143,9 @@ public class QueueFragment extends Fragment {
super.onStop();
EventDistributor.getInstance().unregister(contentUpdate);
EventBus.getDefault().unregister(this);
- stopItemLoader();
+ if(subscription != null) {
+ subscription.unsubscribe();
+ }
if(undoBarController.isShowing()) {
undoBarController.close();
}
@@ -156,7 +163,7 @@ public class QueueFragment extends Fragment {
undoBarController.showUndoBar(false, getString(R.string.removed_from_queue),
new FeedItemUndoToken(event.item, event.position));
}
- startItemLoader();
+ loadItems();
}
private void saveScrollPosition() {
@@ -398,7 +405,9 @@ public class QueueFragment extends Fragment {
public void drop(int from, int to) {
Log.d(TAG, "drop");
blockDownloadObserverUpdate = false;
- stopItemLoader();
+ if(subscription != null) {
+ subscription.unsubscribe();
+ }
final FeedItem item = queue.remove(from);
queue.add(to, item);
listAdapter.notifyDataSetChanged();
@@ -408,7 +417,9 @@ public class QueueFragment extends Fragment {
@Override
public void remove(int which) {
Log.d(TAG, "remove(" + which + ")");
- stopItemLoader();
+ if(subscription != null) {
+ subscription.unsubscribe();
+ }
FeedItem item = (FeedItem) listView.getAdapter().getItem(which);
DBWriter.removeQueueItem(getActivity(), item, true);
}
@@ -556,7 +567,7 @@ public class QueueFragment extends Fragment {
@Override
public void update(EventDistributor eventDistributor, Integer arg) {
if ((arg & EVENTS) != 0) {
- startItemLoader();
+ loadItems();
if (isUpdatingFeeds != updateRefreshMenuItemChecker.isRefreshing()) {
getActivity().supportInvalidateOptionsMenu();
}
@@ -564,55 +575,31 @@ public class QueueFragment extends Fragment {
}
};
- private ItemLoader itemLoader;
-
- private void startItemLoader() {
- if (itemLoader != null) {
- itemLoader.cancel(true);
+ private void loadItems() {
+ if(subscription != null) {
+ subscription.unsubscribe();
}
- itemLoader = new ItemLoader();
- itemLoader.execute();
- }
-
- private void stopItemLoader() {
- if (itemLoader != null) {
- itemLoader.cancel(true);
+ if (viewsCreated && !itemsLoaded) {
+ listView.setVisibility(View.GONE);
+ txtvEmpty.setVisibility(View.GONE);
+ progLoading.setVisibility(View.VISIBLE);
}
+ subscription = Observable.defer(() -> Observable.just(DBReader.getQueue()))
+ .subscribeOn(Schedulers.newThread())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(result -> {
+ listView.setVisibility(View.VISIBLE);
+ progLoading.setVisibility(View.GONE);
+ if(result != null) {
+ queue = result;
+ itemsLoaded = true;
+ if (viewsCreated && activity.get() != null) {
+ onFragmentLoaded();
+ }
+ }
+ }, error -> {
+ Log.e(TAG, Log.getStackTraceString(error));
+ });
}
- private class ItemLoader extends AsyncTask<Void, Void, List<FeedItem>> {
- @Override
- protected void onPreExecute() {
- super.onPreExecute();
- if (viewsCreated && !itemsLoaded) {
- listView.setVisibility(View.GONE);
- txtvEmpty.setVisibility(View.GONE);
- progLoading.setVisibility(View.VISIBLE);
- }
- }
-
- @Override
- protected void onPostExecute(List<FeedItem> feedItems) {
- super.onPostExecute(feedItems);
- listView.setVisibility(View.VISIBLE);
- progLoading.setVisibility(View.GONE);
-
- if (feedItems != null) {
- queue = feedItems;
- itemsLoaded = true;
- if (viewsCreated && activity.get() != null) {
- onFragmentLoaded();
- }
- }
- }
-
- @Override
- protected List<FeedItem> doInBackground(Void... params) {
- Context context = activity.get();
- if (context != null) {
- return DBReader.getQueue();
- }
- return null;
- }
- }
}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/SearchFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/SearchFragment.java
index 975493ce9..edd8cdd1a 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/SearchFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/SearchFragment.java
@@ -1,19 +1,18 @@
package de.danoeh.antennapod.fragment;
import android.content.Context;
-import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.widget.SearchView;
+import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.ListView;
-import java.util.Collections;
import java.util.List;
import de.danoeh.antennapod.R;
@@ -25,6 +24,10 @@ import de.danoeh.antennapod.core.feed.FeedComponent;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.SearchResult;
import de.danoeh.antennapod.core.storage.FeedSearcher;
+import rx.Observable;
+import rx.Subscription;
+import rx.android.schedulers.AndroidSchedulers;
+import rx.schedulers.Schedulers;
/**
* Performs a search operation on all feeds or one specific feed and displays the search result.
@@ -41,6 +44,8 @@ public class SearchFragment extends ListFragment {
private boolean viewCreated = false;
private boolean itemsLoaded = false;
+ private Subscription subscription;
+
/**
* Create a new SearchFragment that searches all feeds.
*/
@@ -68,7 +73,7 @@ public class SearchFragment extends ListFragment {
super.onCreate(savedInstanceState);
setRetainInstance(true);
setHasOptionsMenu(true);
- startSearchTask();
+ search();
}
@Override
@@ -80,14 +85,18 @@ public class SearchFragment extends ListFragment {
@Override
public void onStop() {
super.onStop();
- stopSearchTask();
+ if(subscription != null) {
+ subscription.unsubscribe();
+ }
EventDistributor.getInstance().unregister(contentUpdate);
}
@Override
public void onDetach() {
super.onDetach();
- stopSearchTask();
+ if(subscription != null) {
+ subscription.unsubscribe();
+ }
}
@Override
@@ -143,7 +152,7 @@ public class SearchFragment extends ListFragment {
public boolean onQueryTextSubmit(String s) {
getArguments().putString(ARG_QUERY, s);
itemsLoaded = false;
- startSearchTask();
+ search();
return true;
}
@@ -161,7 +170,7 @@ public class SearchFragment extends ListFragment {
public void update(EventDistributor eventDistributor, Integer arg) {
if ((arg & (EventDistributor.UNREAD_ITEMS_UPDATE
| EventDistributor.DOWNLOAD_HANDLED)) != 0) {
- startSearchTask();
+ search();
}
}
};
@@ -187,53 +196,36 @@ public class SearchFragment extends ListFragment {
}
};
- private SearchTask searchTask;
- private void startSearchTask() {
- if (searchTask != null) {
- searchTask.cancel(true);
+ private void search() {
+ if(subscription != null) {
+ subscription.unsubscribe();
}
- searchTask = new SearchTask();
- searchTask.execute(getArguments());
- }
-
- private void stopSearchTask() {
- if (searchTask != null) {
- searchTask.cancel(true);
+ if (viewCreated && !itemsLoaded) {
+ setListShown(false);
}
+ subscription = Observable.defer(() -> Observable.just(performSearch()))
+ .subscribeOn(Schedulers.newThread())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(result -> {
+ if (result != null) {
+ itemsLoaded = true;
+ searchResults = result;
+ if (viewCreated) {
+ onFragmentLoaded();
+ }
+ }
+ }, error -> {
+ Log.e(TAG, Log.getStackTraceString(error));
+ });
}
- private class SearchTask extends AsyncTask<Bundle, Void, List<SearchResult>> {
- @Override
- protected List<SearchResult> doInBackground(Bundle... params) {
- String query = params[0].getString(ARG_QUERY);
- long feed = params[0].getLong(ARG_FEED);
- Context context = getActivity();
- if (context != null) {
- return FeedSearcher.performSearch(context, query, feed);
- } else {
- return Collections.emptyList();
- }
- }
-
- @Override
- protected void onPreExecute() {
- super.onPreExecute();
- if (viewCreated && !itemsLoaded) {
- setListShown(false);
- }
- }
-
- @Override
- protected void onPostExecute(List<SearchResult> results) {
- super.onPostExecute(results);
- if (results != null) {
- itemsLoaded = true;
- searchResults = results;
- if (viewCreated) {
- onFragmentLoaded();
- }
- }
- }
+ private List<SearchResult> performSearch() {
+ Bundle args = getArguments();
+ String query = args.getString(ARG_QUERY);
+ long feed = args.getLong(ARG_FEED);
+ Context context = getActivity();
+ return FeedSearcher.performSearch(context, query, feed);
}
+
}
diff --git a/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java b/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java
index 3c9bf464c..1630898ec 100644
--- a/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java
+++ b/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java
@@ -460,6 +460,13 @@ public class PreferenceController {
ui.findPreference(UserPreferences.PREF_ENABLE_AUTODL_ON_BATTERY)
.setEnabled(UserPreferences.isEnableAutodownload());
+
+ if (Build.VERSION.SDK_INT >= 16) {
+ ui.findPreference(UserPreferences.PREF_SONIC).setEnabled(true);
+ } else {
+ Preference prefSonic = ui.findPreference(UserPreferences.PREF_SONIC);
+ prefSonic.setSummary("[Android 4.1+]\n" + prefSonic.getSummary());
+ }
}
private void setParallelDownloadsText(int downloads) {
diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml
index c9be65f2b..af20eddfd 100644
--- a/app/src/main/res/xml/preferences.xml
+++ b/app/src/main/res/xml/preferences.xml
@@ -223,7 +223,15 @@
<Preference
android:key="prefAbout"
android:title="@string/about_pref"/>
+ </PreferenceCategory>
+ <PreferenceCategory android:title="@string/experimental_pref">
+ <CheckBoxPreference
+ android:defaultValue="false"
+ android:enabled="false"
+ android:key="prefSonic"
+ android:summary="@string/pref_sonic_message"
+ android:title="@string/pref_sonic_title"/>
</PreferenceCategory>
</PreferenceScreen>
diff --git a/app/src/main/templates/about.html b/app/src/main/templates/about.html
index 3f26c2366..6ed5fc41d 100644
--- a/app/src/main/templates/about.html
+++ b/app/src/main/templates/about.html
@@ -59,8 +59,7 @@
<h1>Used libraries</h1>
<h2>Apache Commons <a href="http://commons.apache.org/">(Link)</a></h2>
-by The Apache Software Foundation, licensed under the Apache 2.0 license <a
- href="LICENSE_APACHE_COMMONS.txt">(View)</a>
+by The Apache Software Foundation, licensed under the Apache 2.0 license <a href="LICENSE_APACHE_COMMONS.txt">(View)</a>
<h2>DragSortListView <a href="https://github.com/bauerca/drag-sort-listview">(Link)</a></h2>
by Carl Bauer, licensed under the Apache 2.0 license <a href="LICENSE_DSLV.txt">(View)</a>
@@ -101,5 +100,8 @@ licensed under the Apache 2.0 license <a href="LICENSE_RX_ANDROID.txt">(View)</a
<h2>StackBlur <a href="https://github.com/kikoso/android-stackblur">(Link)</a></h2>
by Enrique L&oacute;pez Ma&ntilde;as, licensed under the Apache 2.0 license <a href="LICENSE_STACKBLUR.txt">(View)</a>
+<h2>AntennaPod-AudioPlayer <a href="https://github.com/AntennaPod/AntennaPod-AudioPlayer/">(Link)</a></h2>
+by the AntennaPod team, licensed under the Apache 2.0 license <a href="LICENSE_ANTENNAPOD_AUDIOPLAYER.txt">(View)</a>
+
</body>
</html>
diff --git a/core/build.gradle b/core/build.gradle
index 4b1ab98a6..85891b999 100644
--- a/core/build.gradle
+++ b/core/build.gradle
@@ -32,8 +32,12 @@ android {
}
+repositories {
+ maven { url "https://jitpack.io" }
+ mavenCentral()
+}
+
dependencies {
- compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:support-v4:22.2.1'
compile 'com.android.support:appcompat-v7:22.2.1'
compile 'com.android.support:design:22.2.1'
@@ -52,4 +56,6 @@ dependencies {
compile 'com.nineoldandroids:library:2.4.0'
compile 'de.greenrobot:eventbus:2.4.0'
compile 'io.reactivex:rxandroid:1.0.1'
+
+ compile 'com.github.AntennaPod:AntennaPod-AudioPlayer:v1.0'
}
diff --git a/core/src/main/aidl/com/aocate/presto/service/IDeathCallback_0_8.aidl b/core/src/main/aidl/com/aocate/presto/service/IDeathCallback_0_8.aidl
deleted file mode 100644
index 6bdc76801..000000000
--- a/core/src/main/aidl/com/aocate/presto/service/IDeathCallback_0_8.aidl
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2011, Aocate, Inc.
-//
-// 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 com.aocate.presto.service;
-
-oneway interface IDeathCallback_0_8 {
-} \ No newline at end of file
diff --git a/core/src/main/aidl/com/aocate/presto/service/IOnBufferingUpdateListenerCallback_0_8.aidl b/core/src/main/aidl/com/aocate/presto/service/IOnBufferingUpdateListenerCallback_0_8.aidl
deleted file mode 100644
index 7357e402e..000000000
--- a/core/src/main/aidl/com/aocate/presto/service/IOnBufferingUpdateListenerCallback_0_8.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2011, Aocate, Inc.
-//
-// 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 com.aocate.presto.service;
-
-interface IOnBufferingUpdateListenerCallback_0_8 {
- void onBufferingUpdate(int percent);
-} \ No newline at end of file
diff --git a/core/src/main/aidl/com/aocate/presto/service/IOnCompletionListenerCallback_0_8.aidl b/core/src/main/aidl/com/aocate/presto/service/IOnCompletionListenerCallback_0_8.aidl
deleted file mode 100644
index d5edea729..000000000
--- a/core/src/main/aidl/com/aocate/presto/service/IOnCompletionListenerCallback_0_8.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2011, Aocate, Inc.
-//
-// 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 com.aocate.presto.service;
-
-interface IOnCompletionListenerCallback_0_8 {
- void onCompletion();
-} \ No newline at end of file
diff --git a/core/src/main/aidl/com/aocate/presto/service/IOnErrorListenerCallback_0_8.aidl b/core/src/main/aidl/com/aocate/presto/service/IOnErrorListenerCallback_0_8.aidl
deleted file mode 100644
index 2c4f2df3e..000000000
--- a/core/src/main/aidl/com/aocate/presto/service/IOnErrorListenerCallback_0_8.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2011, Aocate, Inc.
-//
-// 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 com.aocate.presto.service;
-
-interface IOnErrorListenerCallback_0_8 {
- boolean onError(int what, int extra);
-}
diff --git a/core/src/main/aidl/com/aocate/presto/service/IOnInfoListenerCallback_0_8.aidl b/core/src/main/aidl/com/aocate/presto/service/IOnInfoListenerCallback_0_8.aidl
deleted file mode 100644
index 9dbd1d260..000000000
--- a/core/src/main/aidl/com/aocate/presto/service/IOnInfoListenerCallback_0_8.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2011, Aocate, Inc.
-//
-// 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 com.aocate.presto.service;
-
-interface IOnInfoListenerCallback_0_8 {
- boolean onInfo(int what, int extra);
-} \ No newline at end of file
diff --git a/core/src/main/aidl/com/aocate/presto/service/IOnPitchAdjustmentAvailableChangedListenerCallback_0_8.aidl b/core/src/main/aidl/com/aocate/presto/service/IOnPitchAdjustmentAvailableChangedListenerCallback_0_8.aidl
deleted file mode 100644
index 41223a97b..000000000
--- a/core/src/main/aidl/com/aocate/presto/service/IOnPitchAdjustmentAvailableChangedListenerCallback_0_8.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2011, Aocate, Inc.
-//
-// 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 com.aocate.presto.service;
-
-interface IOnPitchAdjustmentAvailableChangedListenerCallback_0_8 {
- void onPitchAdjustmentAvailableChanged(boolean pitchAdjustmentAvailable);
-} \ No newline at end of file
diff --git a/core/src/main/aidl/com/aocate/presto/service/IOnPreparedListenerCallback_0_8.aidl b/core/src/main/aidl/com/aocate/presto/service/IOnPreparedListenerCallback_0_8.aidl
deleted file mode 100644
index 7be8f1237..000000000
--- a/core/src/main/aidl/com/aocate/presto/service/IOnPreparedListenerCallback_0_8.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2011, Aocate, Inc.
-//
-// 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 com.aocate.presto.service;
-
-interface IOnPreparedListenerCallback_0_8 {
- void onPrepared();
-} \ No newline at end of file
diff --git a/core/src/main/aidl/com/aocate/presto/service/IOnSeekCompleteListenerCallback_0_8.aidl b/core/src/main/aidl/com/aocate/presto/service/IOnSeekCompleteListenerCallback_0_8.aidl
deleted file mode 100644
index 5bdda98b6..000000000
--- a/core/src/main/aidl/com/aocate/presto/service/IOnSeekCompleteListenerCallback_0_8.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2011, Aocate, Inc.
-//
-// 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 com.aocate.presto.service;
-
-interface IOnSeekCompleteListenerCallback_0_8 {
- void onSeekComplete();
-} \ No newline at end of file
diff --git a/core/src/main/aidl/com/aocate/presto/service/IOnSpeedAdjustmentAvailableChangedListenerCallback_0_8.aidl b/core/src/main/aidl/com/aocate/presto/service/IOnSpeedAdjustmentAvailableChangedListenerCallback_0_8.aidl
deleted file mode 100644
index a69c1cf34..000000000
--- a/core/src/main/aidl/com/aocate/presto/service/IOnSpeedAdjustmentAvailableChangedListenerCallback_0_8.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2011, Aocate, Inc.
-//
-// 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 com.aocate.presto.service;
-
-interface IOnSpeedAdjustmentAvailableChangedListenerCallback_0_8 {
- void onSpeedAdjustmentAvailableChanged(boolean speedAdjustmentAvailable);
-} \ No newline at end of file
diff --git a/core/src/main/aidl/com/aocate/presto/service/IPlayMedia_0_8.aidl b/core/src/main/aidl/com/aocate/presto/service/IPlayMedia_0_8.aidl
deleted file mode 100644
index 12a6047de..000000000
--- a/core/src/main/aidl/com/aocate/presto/service/IPlayMedia_0_8.aidl
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2011, Aocate, Inc.
-//
-// 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 com.aocate.presto.service;
-
-import com.aocate.presto.service.IDeathCallback_0_8;
-import com.aocate.presto.service.IOnBufferingUpdateListenerCallback_0_8;
-import com.aocate.presto.service.IOnCompletionListenerCallback_0_8;
-import com.aocate.presto.service.IOnErrorListenerCallback_0_8;
-import com.aocate.presto.service.IOnPitchAdjustmentAvailableChangedListenerCallback_0_8;
-import com.aocate.presto.service.IOnPreparedListenerCallback_0_8;
-import com.aocate.presto.service.IOnSeekCompleteListenerCallback_0_8;
-import com.aocate.presto.service.IOnSpeedAdjustmentAvailableChangedListenerCallback_0_8;
-import com.aocate.presto.service.IOnInfoListenerCallback_0_8;
-
-interface IPlayMedia_0_8 {
- boolean canSetPitch(long sessionId);
- boolean canSetSpeed(long sessionId);
- float getCurrentPitchStepsAdjustment(long sessionId);
- int getCurrentPosition(long sessionId);
- float getCurrentSpeedMultiplier(long sessionId);
- int getDuration(long sessionId);
- float getMaxSpeedMultiplier(long sessionId);
- float getMinSpeedMultiplier(long sessionId);
- int getVersionCode();
- String getVersionName();
- boolean isLooping(long sessionId);
- boolean isPlaying(long sessionId);
- void pause(long sessionId);
- void prepare(long sessionId);
- void prepareAsync(long sessionId);
- void registerOnBufferingUpdateCallback(long sessionId, IOnBufferingUpdateListenerCallback_0_8 cb);
- void registerOnCompletionCallback(long sessionId, IOnCompletionListenerCallback_0_8 cb);
- void registerOnErrorCallback(long sessionId, IOnErrorListenerCallback_0_8 cb);
- void registerOnInfoCallback(long sessionId, IOnInfoListenerCallback_0_8 cb);
- void registerOnPitchAdjustmentAvailableChangedCallback(long sessionId, IOnPitchAdjustmentAvailableChangedListenerCallback_0_8 cb);
- void registerOnPreparedCallback(long sessionId, IOnPreparedListenerCallback_0_8 cb);
- void registerOnSeekCompleteCallback(long sessionId, IOnSeekCompleteListenerCallback_0_8 cb);
- void registerOnSpeedAdjustmentAvailableChangedCallback(long sessionId, IOnSpeedAdjustmentAvailableChangedListenerCallback_0_8 cb);
- void release(long sessionId);
- void reset(long sessionId);
- void seekTo(long sessionId, int msec);
- void setAudioStreamType(long sessionId, int streamtype);
- void setDataSourceString(long sessionId, String path);
- void setDataSourceUri(long sessionId, in Uri uri);
- void setEnableSpeedAdjustment(long sessionId, boolean enableSpeedAdjustment);
- void setLooping(long sessionId, boolean looping);
- void setPitchStepsAdjustment(long sessionId, float pitchSteps);
- void setPlaybackPitch(long sessionId, float f);
- void setPlaybackSpeed(long sessionId, float f);
- void setSpeedAdjustmentAlgorithm(long sessionId, int algorithm);
- void setVolume(long sessionId, float left, float right);
- void start(long sessionId);
- long startSession(IDeathCallback_0_8 cb);
- void stop(long sessionId);
- void unregisterOnBufferingUpdateCallback(long sessionId, IOnBufferingUpdateListenerCallback_0_8 cb);
- void unregisterOnCompletionCallback(long sessionId, IOnCompletionListenerCallback_0_8 cb);
- void unregisterOnErrorCallback(long sessionId, IOnErrorListenerCallback_0_8 cb);
- void unregisterOnInfoCallback(long sessionId, IOnInfoListenerCallback_0_8 cb);
- void unregisterOnPitchAdjustmentAvailableChangedCallback(long sessionId, IOnPitchAdjustmentAvailableChangedListenerCallback_0_8 cb);
- void unregisterOnPreparedCallback(long sessionId, IOnPreparedListenerCallback_0_8 cb);
- void unregisterOnSeekCompleteCallback(long sessionId, IOnSeekCompleteListenerCallback_0_8 cb);
- void unregisterOnSpeedAdjustmentAvailableChangedCallback(long sessionId, IOnSpeedAdjustmentAvailableChangedListenerCallback_0_8 cb);
-} \ No newline at end of file
diff --git a/core/src/main/java/com/aocate/media/AndroidMediaPlayer.java b/core/src/main/java/com/aocate/media/AndroidMediaPlayer.java
deleted file mode 100644
index 7c2ea3d61..000000000
--- a/core/src/main/java/com/aocate/media/AndroidMediaPlayer.java
+++ /dev/null
@@ -1,470 +0,0 @@
-// Copyright 2011, Aocate, Inc.
-//
-// 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 com.aocate.media;
-
-import android.content.Context;
-import android.media.MediaPlayer;
-import android.net.Uri;
-import android.util.Log;
-
-import java.io.IOException;
-
-public class AndroidMediaPlayer extends MediaPlayerImpl {
- private final static String AMP_TAG = "AocateAndroidMediaPlayer";
-
- // private static final long TIMEOUT_DURATION_MS = 500;
-
- android.media.MediaPlayer mp = null;
-
- private android.media.MediaPlayer.OnBufferingUpdateListener onBufferingUpdateListener = new android.media.MediaPlayer.OnBufferingUpdateListener() {
- public void onBufferingUpdate(android.media.MediaPlayer mp, int percent) {
- if (owningMediaPlayer != null) {
- owningMediaPlayer.lock.lock();
- try {
- if ((owningMediaPlayer.onBufferingUpdateListener != null)
- && (owningMediaPlayer.mpi == AndroidMediaPlayer.this)) {
- owningMediaPlayer.onBufferingUpdateListener.onBufferingUpdate(owningMediaPlayer, percent);
- }
- }
- finally {
- owningMediaPlayer.lock.unlock();
- }
- }
-
- }
- };
-
- private android.media.MediaPlayer.OnCompletionListener onCompletionListener = new android.media.MediaPlayer.OnCompletionListener() {
- public void onCompletion(android.media.MediaPlayer mp) {
- Log.d(AMP_TAG, "onCompletionListener being called");
- if (owningMediaPlayer != null) {
- owningMediaPlayer.lock.lock();
- try {
- if (owningMediaPlayer.onCompletionListener != null) {
- owningMediaPlayer.onCompletionListener.onCompletion(owningMediaPlayer);
- }
- }
- finally {
- owningMediaPlayer.lock.unlock();
- }
- }
- }
- };
-
- private android.media.MediaPlayer.OnErrorListener onErrorListener = new android.media.MediaPlayer.OnErrorListener() {
- public boolean onError(android.media.MediaPlayer mp, int what, int extra) {
- // Once we're in errored state, any received messages are going to be junked
- if (owningMediaPlayer != null) {
- owningMediaPlayer.lock.lock();
- try {
- if (owningMediaPlayer.onErrorListener != null) {
- return owningMediaPlayer.onErrorListener.onError(owningMediaPlayer, what, extra);
- }
- }
- finally {
- owningMediaPlayer.lock.unlock();
- }
- }
- return false;
- }
- };
-
- private android.media.MediaPlayer.OnInfoListener onInfoListener = new android.media.MediaPlayer.OnInfoListener() {
- public boolean onInfo(android.media.MediaPlayer mp, int what, int extra) {
- if (owningMediaPlayer != null) {
- owningMediaPlayer.lock.lock();
- try {
- if ((owningMediaPlayer.onInfoListener != null)
- && (owningMediaPlayer.mpi == AndroidMediaPlayer.this)) {
- return owningMediaPlayer.onInfoListener.onInfo(owningMediaPlayer, what, extra);
- }
- }
- finally {
- owningMediaPlayer.lock.unlock();
- }
- }
- return false;
- }
- };
-
- // We have to assign this.onPreparedListener because the
- // onPreparedListener in owningMediaPlayer sets the state
- // to PREPARED. Due to prepareAsync, that's the only
- // reasonable place to do it
- // The others it just didn't make sense to have a setOnXListener that didn't use the parameter
- private android.media.MediaPlayer.OnPreparedListener onPreparedListener = new android.media.MediaPlayer.OnPreparedListener() {
- public void onPrepared(android.media.MediaPlayer mp) {
- Log.d(AMP_TAG, "Calling onPreparedListener.onPrepared()");
- if (AndroidMediaPlayer.this.owningMediaPlayer != null) {
- AndroidMediaPlayer.this.lockMuteOnPreparedCount.lock();
- try {
- if (AndroidMediaPlayer.this.muteOnPreparedCount > 0) {
- AndroidMediaPlayer.this.muteOnPreparedCount--;
- }
- else {
- AndroidMediaPlayer.this.muteOnPreparedCount = 0;
- if (AndroidMediaPlayer.this.owningMediaPlayer.onPreparedListener != null) {
- Log.d(AMP_TAG, "Invoking AndroidMediaPlayer.this.owningMediaPlayer.onPreparedListener.onPrepared");
- AndroidMediaPlayer.this.owningMediaPlayer.onPreparedListener.onPrepared(AndroidMediaPlayer.this.owningMediaPlayer);
- }
- }
- }
- finally {
- AndroidMediaPlayer.this.lockMuteOnPreparedCount.unlock();
- }
- if (owningMediaPlayer.mpi != AndroidMediaPlayer.this) {
- Log.d(AMP_TAG, "owningMediaPlayer has changed implementation");
- }
- }
- }
- };
-
- private android.media.MediaPlayer.OnSeekCompleteListener onSeekCompleteListener = new android.media.MediaPlayer.OnSeekCompleteListener() {
- public void onSeekComplete(android.media.MediaPlayer mp) {
- if (owningMediaPlayer != null) {
- owningMediaPlayer.lock.lock();
- try {
- lockMuteOnSeekCount.lock();
- try {
- if (AndroidMediaPlayer.this.muteOnSeekCount > 0) {
- AndroidMediaPlayer.this.muteOnSeekCount--;
- }
- else {
- AndroidMediaPlayer.this.muteOnSeekCount = 0;
- if (AndroidMediaPlayer.this.owningMediaPlayer.onSeekCompleteListener != null) {
- owningMediaPlayer.onSeekCompleteListener.onSeekComplete(owningMediaPlayer);
- }
- }
- }
- finally {
- lockMuteOnSeekCount.unlock();
- }
- }
- finally {
- owningMediaPlayer.lock.unlock();
- }
- }
- }
- };
-
- public AndroidMediaPlayer(com.aocate.media.MediaPlayer owningMediaPlayer, Context context) {
- super(owningMediaPlayer, context);
-
- mp = new MediaPlayer();
-
-// final ReentrantLock lock = new ReentrantLock();
-// Handler handler = new Handler(Looper.getMainLooper()) {
-// @Override
-// public void handleMessage(Message msg) {
-// Log.d(AMP_TAG, "Instantiating new AndroidMediaPlayer from Handler");
-// lock.lock();
-// if (mp == null) {
-// mp = new MediaPlayer();
-// }
-// lock.unlock();
-// }
-// };
-//
-// long endTime = System.currentTimeMillis() + TIMEOUT_DURATION_MS;
-//
-// while (true) {
-// // Retry messages until mp isn't null or it's time to give up
-// handler.sendMessage(handler.obtainMessage());
-// if ((mp != null)
-// || (endTime < System.currentTimeMillis())) {
-// break;
-// }
-// try {
-// Thread.sleep(50);
-// } catch (InterruptedException e) {
-// // TODO Auto-generated catch block
-// e.printStackTrace();
-// }
-// }
-
- if (mp == null) {
- throw new IllegalStateException("Did not instantiate android.media.MediaPlayer successfully");
- }
-
- mp.setOnBufferingUpdateListener(this.onBufferingUpdateListener);
- mp.setOnCompletionListener(this.onCompletionListener);
- mp.setOnErrorListener(this.onErrorListener);
- mp.setOnInfoListener(this.onInfoListener);
- Log.d(AMP_TAG, " ++++++++++++++++++++++++++++++++ Setting prepared listener to this.onPreparedListener");
- mp.setOnPreparedListener(this.onPreparedListener);
- mp.setOnSeekCompleteListener(this.onSeekCompleteListener);
- }
-
- @Override
- public boolean canSetPitch() {
- return false;
- }
-
- @Override
- public boolean canSetSpeed() {
- return false;
- }
-
- @Override
- public float getCurrentPitchStepsAdjustment() {
- return 0;
- }
-
- @Override
- public int getCurrentPosition() {
- owningMediaPlayer.lock.lock();
- try {
- return mp.getCurrentPosition();
- }
- finally {
- owningMediaPlayer.lock.unlock();
- }
- }
-
- @Override
- public float getCurrentSpeedMultiplier() {
- return 1f;
- }
-
- @Override
- public int getDuration() {
- owningMediaPlayer.lock.lock();
- try {
- return mp.getDuration();
- }
- finally {
- owningMediaPlayer.lock.unlock();
- }
- }
-
- @Override
- public float getMaxSpeedMultiplier() {
- return 1f;
- }
-
- @Override
- public float getMinSpeedMultiplier() {
- return 1f;
- }
-
- @Override
- public boolean isLooping() {
- owningMediaPlayer.lock.lock();
- try {
- return mp.isLooping();
- }
- finally {
- owningMediaPlayer.lock.unlock();
- }
- }
-
- @Override
- public boolean isPlaying() {
- owningMediaPlayer.lock.lock();
- try {
- return mp.isPlaying();
- }
- finally {
- owningMediaPlayer.lock.unlock();
- }
- }
-
- @Override
- public void pause() {
- owningMediaPlayer.lock.lock();
- try {
- mp.pause();
- }
- finally {
- owningMediaPlayer.lock.unlock();
- }
- }
-
- @Override
- public void prepare() throws IllegalStateException, IOException {
- owningMediaPlayer.lock.lock();
- Log.d(AMP_TAG, "prepare()");
- try {
- mp.prepare();
- Log.d(AMP_TAG, "Finish prepare()");
- }
- finally {
- owningMediaPlayer.lock.unlock();
- }
- }
-
- @Override
- public void prepareAsync() {
- mp.prepareAsync();
- }
-
- @Override
- public void release() {
- owningMediaPlayer.lock.lock();
- try {
- if (mp != null) {
- Log.d(AMP_TAG, "mp.release()");
- mp.release();
- }
- }
- finally {
- owningMediaPlayer.lock.unlock();
- }
- }
-
- @Override
- public void reset() {
- owningMediaPlayer.lock.lock();
- try {
- mp.reset();
- }
- finally {
- owningMediaPlayer.lock.unlock();
- }
- }
-
- @Override
- public void seekTo(int msec) throws IllegalStateException {
- owningMediaPlayer.lock.lock();
- try {
- mp.setOnSeekCompleteListener(this.onSeekCompleteListener);
- mp.seekTo(msec);
- }
- finally {
- owningMediaPlayer.lock.unlock();
- }
- }
-
- @Override
- public void setAudioStreamType(int streamtype) {
- owningMediaPlayer.lock.lock();
- try {
- mp.setAudioStreamType(streamtype);
- }
- finally {
- owningMediaPlayer.lock.unlock();
- }
- }
-
- @Override
- public void setDataSource(Context context, Uri uri)
- throws IllegalArgumentException, IllegalStateException, IOException {
- owningMediaPlayer.lock.lock();
- try {
- Log.d(AMP_TAG, "setDataSource(context, " + uri.toString() + ")");
- mp.setDataSource(context, uri);
- }
- finally {
- owningMediaPlayer.lock.unlock();
- }
- }
-
- @Override
- public void setDataSource(String path) throws IllegalArgumentException,
- IllegalStateException, IOException {
- owningMediaPlayer.lock.lock();
- try {
- Log.d(AMP_TAG, "setDataSource(" + path + ")");
- mp.setDataSource(path);
- }
- finally {
- owningMediaPlayer.lock.unlock();
- }
- }
-
- @Override
- public void setEnableSpeedAdjustment(boolean enableSpeedAdjustment) {
- // Can't!
- }
-
- @Override
- public void setLooping(boolean loop) {
- owningMediaPlayer.lock.lock();
- try {
- mp.setLooping(loop);
- }
- finally {
- owningMediaPlayer.lock.unlock();
- }
- }
-
- @Override
- public void setPitchStepsAdjustment(float pitchSteps) {
- // Can't!
- }
-
- @Override
- public void setPlaybackPitch(float f) {
- // Can't!
- }
-
- @Override
- public void setPlaybackSpeed(float f) {
- // Can't!
- Log.d(AMP_TAG, "setPlaybackSpeed(" + f + ")");
- }
-
- @Override
- public void setSpeedAdjustmentAlgorithm(int algorithm) {
- // Can't!
- Log.d(AMP_TAG, "setSpeedAdjustmentAlgorithm(" + algorithm + ")");
- }
-
- @Override
- public void setVolume(float leftVolume, float rightVolume) {
- owningMediaPlayer.lock.lock();
- try {
- mp.setVolume(leftVolume, rightVolume);
- }
- finally {
- owningMediaPlayer.lock.unlock();
- }
- }
-
- @Override
- public void setWakeMode(Context context, int mode) {
- owningMediaPlayer.lock.lock();
- try {
- if (mode != 0) {
- mp.setWakeMode(context, mode);
- }
- }
- finally {
- owningMediaPlayer.lock.unlock();
- }
- }
-
- @Override
- public void start() {
- owningMediaPlayer.lock.lock();
- try {
- mp.start();
- }
- finally {
- owningMediaPlayer.lock.unlock();
- }
- }
-
- @Override
- public void stop() {
- owningMediaPlayer.lock.lock();
- try {
- mp.stop();
- }
- finally {
- owningMediaPlayer.lock.unlock();
- }
- }
-}
diff --git a/core/src/main/java/com/aocate/media/MediaPlayer.java b/core/src/main/java/com/aocate/media/MediaPlayer.java
deleted file mode 100644
index 79e63d03d..000000000
--- a/core/src/main/java/com/aocate/media/MediaPlayer.java
+++ /dev/null
@@ -1,1310 +0,0 @@
-// Copyright 2011, Aocate, Inc.
-//
-// 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 com.aocate.media;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.media.AudioManager;
-import android.net.Uri;
-import android.os.Handler;
-import android.os.Handler.Callback;
-import android.os.IBinder;
-import android.os.Message;
-import android.util.Log;
-
-import java.io.IOException;
-import java.util.List;
-import java.util.concurrent.locks.ReentrantLock;
-
-import de.danoeh.antennapod.core.BuildConfig;
-
-public class MediaPlayer {
- public static final String TAG = "com.aocate.media.MediaPlayer";
-
- public interface OnBufferingUpdateListener {
- public abstract void onBufferingUpdate(MediaPlayer arg0, int percent);
- }
-
- public interface OnCompletionListener {
- public abstract void onCompletion(MediaPlayer arg0);
- }
-
- public interface OnErrorListener {
- public abstract boolean onError(MediaPlayer arg0, int what, int extra);
- }
-
- public interface OnInfoListener {
- public abstract boolean onInfo(MediaPlayer arg0, int what, int extra);
- }
-
- public interface OnPitchAdjustmentAvailableChangedListener {
- /**
- * @param arg0 The owning media player
- * @param pitchAdjustmentAvailable True if pitch adjustment is available, false if not
- */
- public abstract void onPitchAdjustmentAvailableChanged(
- MediaPlayer arg0, boolean pitchAdjustmentAvailable);
- }
-
- public interface OnPreparedListener {
- public abstract void onPrepared(MediaPlayer arg0);
- }
-
- public interface OnSeekCompleteListener {
- public abstract void onSeekComplete(MediaPlayer arg0);
- }
-
- public interface OnSpeedAdjustmentAvailableChangedListener {
- /**
- * @param arg0 The owning media player
- * @param speedAdjustmentAvailable True if speed adjustment is available, false if not
- */
- public abstract void onSpeedAdjustmentAvailableChanged(
- MediaPlayer arg0, boolean speedAdjustmentAvailable);
- }
-
- public enum State {
- IDLE, INITIALIZED, PREPARED, STARTED, PAUSED, STOPPED, PREPARING, PLAYBACK_COMPLETED, END, ERROR
- }
-
- private static Uri SPEED_ADJUSTMENT_MARKET_URI = Uri
- .parse("market://details?id=com.aocate.presto");
-
- private static Intent prestoMarketIntent = null;
-
- public static final int MEDIA_ERROR_SERVER_DIED = android.media.MediaPlayer.MEDIA_ERROR_SERVER_DIED;
- public static final int MEDIA_ERROR_UNKNOWN = android.media.MediaPlayer.MEDIA_ERROR_UNKNOWN;
- public static final int MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK = android.media.MediaPlayer.MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK;
-
- /**
- * Indicates whether the specified action can be used as an intent. This
- * method queries the package manager for installed packages that can
- * respond to an intent with the specified action. If no suitable package is
- * found, this method returns false.
- *
- * @param context The application's environment.
- * @param action The Intent action to check for availability.
- * @return True if an Intent with the specified action can be sent and
- * responded to, false otherwise.
- */
- public static boolean isIntentAvailable(Context context, String action) {
- final PackageManager packageManager = context.getPackageManager();
- final Intent intent = new Intent(action);
- List<ResolveInfo> list = packageManager.queryIntentServices(intent,
- PackageManager.MATCH_DEFAULT_ONLY);
- return list.size() > 0;
- }
-
- /**
- * Returns an explicit Intent for a service that accepts the given Intent
- * or null if no such service was found.
- *
- * @param context The application's environment.
- * @param action The Intent action to check for availability.
- * @return The explicit service Intent or null if no service was found.
- */
- public static Intent getPrestoServiceIntent(Context context, String action) {
- final PackageManager packageManager = context.getPackageManager();
- final Intent actionIntent = new Intent(action);
- List<ResolveInfo> list = packageManager.queryIntentServices(actionIntent,
- PackageManager.MATCH_DEFAULT_ONLY);
- if (list.size() > 0) {
- ResolveInfo first = list.get(0);
- if (first.serviceInfo != null) {
- Intent intent = new Intent();
- intent.setComponent(new ComponentName(first.serviceInfo.packageName,
- first.serviceInfo.name));
- Log.i(TAG, "Returning intent:" + intent.toString());
- return intent;
- } else {
- Log.e(TAG, "Found service that accepts " + action + ", but serviceInfo was null");
- return null;
- }
- } else {
- return null;
- }
- }
-
- /**
- * Indicates whether the Presto library is installed
- *
- * @param context The context to use to query the package manager.
- * @return True if the Presto library is installed, false if not.
- */
- public static boolean isPrestoLibraryInstalled(Context context) {
- return isIntentAvailable(context, ServiceBackedMediaPlayer.INTENT_NAME);
- }
-
- /**
- * Return an Intent that opens the Android Market page for the speed
- * alteration library
- *
- * @return The Intent for the Presto library on the Android Market
- */
- public static Intent getPrestoMarketIntent() {
- if (prestoMarketIntent == null) {
- prestoMarketIntent = new Intent(Intent.ACTION_VIEW,
- SPEED_ADJUSTMENT_MARKET_URI);
- }
- return prestoMarketIntent;
- }
-
- /**
- * Open the Android Market page for the Presto library
- *
- * @param context The context from which to open the Android Market page
- */
- public static void openPrestoMarketIntent(Context context) {
- context.startActivity(getPrestoMarketIntent());
- }
-
- private static final String MP_TAG = "AocateReplacementMediaPlayer";
-
- private static final double PITCH_STEP_CONSTANT = 1.0594630943593;
-
- private AndroidMediaPlayer amp = null;
- // This is whether speed adjustment should be enabled (by the Service)
- // To avoid the Service entirely, set useService to false
- protected boolean enableSpeedAdjustment = true;
- private int lastKnownPosition = 0;
- // In some cases, we're going to have to replace the
- // android.media.MediaPlayer on the fly, and we don't want to touch the
- // wrong media player, so lock it way too much.
- ReentrantLock lock = new ReentrantLock();
- private int mAudioStreamType = AudioManager.STREAM_MUSIC;
- private Context mContext;
- private boolean mIsLooping = false;
- private float mLeftVolume = 1f;
- private float mPitchStepsAdjustment = 0f;
- private float mRightVolume = 1f;
- private float mSpeedMultiplier = 1f;
- private int mWakeMode = 0;
- MediaPlayerImpl mpi = null;
- protected boolean pitchAdjustmentAvailable = false;
- private ServiceBackedMediaPlayer sbmp = null;
- protected boolean speedAdjustmentAvailable = false;
-
- private Handler mServiceDisconnectedHandler = null;
-
- // Some parts of state cannot be found by calling MediaPlayerImpl functions,
- // so store our own state. This also helps copy state when changing
- // implementations
- State state = State.INITIALIZED;
- String stringDataSource = null;
- Uri uriDataSource = null;
- private boolean useService = false;
-
- // Naming Convention for Listeners
- // Most listeners can both be set by clients and called by MediaPlayImpls
- // There are a few that have to do things in this class as well as calling
- // the function. In all cases, onX is what is called by MediaPlayerImpl
- // If there is work to be done in this class, then the listener that is
- // set by setX is X (with the first letter lowercase).
- OnBufferingUpdateListener onBufferingUpdateListener = null;
- OnCompletionListener onCompletionListener = null;
- OnErrorListener onErrorListener = null;
- OnInfoListener onInfoListener = null;
-
- // Special case. Pitch adjustment ceases to be available when we switch
- // to the android.media.MediaPlayer (though it is not guaranteed to be
- // available when using the ServiceBackedMediaPlayer)
- OnPitchAdjustmentAvailableChangedListener onPitchAdjustmentAvailableChangedListener = new OnPitchAdjustmentAvailableChangedListener() {
- public void onPitchAdjustmentAvailableChanged(MediaPlayer arg0,
- boolean pitchAdjustmentAvailable) {
- lock.lock();
- try {
- Log
- .d(
- MP_TAG,
- "onPitchAdjustmentAvailableChangedListener.onPitchAdjustmentAvailableChanged being called");
- if (MediaPlayer.this.pitchAdjustmentAvailable != pitchAdjustmentAvailable) {
- Log.d(MP_TAG, "Pitch adjustment state has changed from "
- + MediaPlayer.this.pitchAdjustmentAvailable
- + " to " + pitchAdjustmentAvailable);
- MediaPlayer.this.pitchAdjustmentAvailable = pitchAdjustmentAvailable;
- if (MediaPlayer.this.pitchAdjustmentAvailableChangedListener != null) {
- MediaPlayer.this.pitchAdjustmentAvailableChangedListener
- .onPitchAdjustmentAvailableChanged(arg0,
- pitchAdjustmentAvailable);
- }
- }
- } finally {
- lock.unlock();
- }
- }
- };
- OnPitchAdjustmentAvailableChangedListener pitchAdjustmentAvailableChangedListener = null;
-
- MediaPlayer.OnPreparedListener onPreparedListener = new MediaPlayer.OnPreparedListener() {
- public void onPrepared(MediaPlayer arg0) {
- Log.d(MP_TAG, "onPreparedListener 242 setting state to PREPARED");
- MediaPlayer.this.state = State.PREPARED;
- if (MediaPlayer.this.preparedListener != null) {
- Log.d(MP_TAG, "Calling preparedListener");
- MediaPlayer.this.preparedListener.onPrepared(arg0);
- }
- Log.d(MP_TAG, "Wrap up onPreparedListener");
- }
- };
-
- OnPreparedListener preparedListener = null;
- OnSeekCompleteListener onSeekCompleteListener = null;
-
- // Special case. Speed adjustment ceases to be available when we switch
- // to the android.media.MediaPlayer (though it is not guaranteed to be
- // available when using the ServiceBackedMediaPlayer)
- OnSpeedAdjustmentAvailableChangedListener onSpeedAdjustmentAvailableChangedListener = new OnSpeedAdjustmentAvailableChangedListener() {
- public void onSpeedAdjustmentAvailableChanged(MediaPlayer arg0,
- boolean speedAdjustmentAvailable) {
- lock.lock();
- try {
- Log
- .d(
- MP_TAG,
- "onSpeedAdjustmentAvailableChangedListener.onSpeedAdjustmentAvailableChanged being called");
- if (MediaPlayer.this.speedAdjustmentAvailable != speedAdjustmentAvailable) {
- Log.d(MP_TAG, "Speed adjustment state has changed from "
- + MediaPlayer.this.speedAdjustmentAvailable
- + " to " + speedAdjustmentAvailable);
- MediaPlayer.this.speedAdjustmentAvailable = speedAdjustmentAvailable;
- if (MediaPlayer.this.speedAdjustmentAvailableChangedListener != null) {
- MediaPlayer.this.speedAdjustmentAvailableChangedListener
- .onSpeedAdjustmentAvailableChanged(arg0,
- speedAdjustmentAvailable);
- }
- }
- } finally {
- lock.unlock();
- }
- }
- };
- OnSpeedAdjustmentAvailableChangedListener speedAdjustmentAvailableChangedListener = null;
-
- private int speedAdjustmentAlgorithm = SpeedAdjustmentAlgorithm.SONIC;
-
- public MediaPlayer(final Context context) {
- this(context, true);
- }
-
- public MediaPlayer(final Context context, boolean useService) {
- this.mContext = context;
- this.useService = useService;
-
- // So here's the major problem
- // Sometimes the service won't exist or won't be connected,
- // so start with an android.media.MediaPlayer, and when
- // the service is connected, use that from then on
- this.mpi = this.amp = new AndroidMediaPlayer(this, context);
-
- // setupMpi will go get the Service, if it can, then bring that
- // implementation into sync
- Log.d(MP_TAG, "setupMpi");
- setupMpi(context);
- }
-
- private boolean invalidServiceConnectionConfiguration() {
- if (!(this.mpi instanceof ServiceBackedMediaPlayer)) {
- if (this.useService && isPrestoLibraryInstalled()) {
- // In this case, the Presto library has been installed
- // or something while playing sound
- // We could be using the service, but we're not
- Log.d(MP_TAG, "We could be using the service, but we're not 316");
- return true;
- }
- // If useService is false, then we shouldn't be using the SBMP
- // If the Presto library isn't installed, ditto
- Log.d(MP_TAG, "this.mpi is not a ServiceBackedMediaPlayer, but we couldn't use it anyway 321");
- return false;
- } else {
- if (BuildConfig.DEBUG && !(this.mpi instanceof ServiceBackedMediaPlayer))
- throw new AssertionError();
- if (this.useService && isPrestoLibraryInstalled()) {
- // We should be using the service, and we are. Great!
- Log.d(MP_TAG, "We could be using a ServiceBackedMediaPlayer and we are 327");
- return false;
- }
- // We're trying to use the service when we shouldn't,
- // that's an invalid configuration
- Log.d(MP_TAG, "We're trying to use a ServiceBackedMediaPlayer but we shouldn't be 332");
- return true;
- }
- }
-
- private void setupMpi(final Context context) {
- lock.lock();
- try {
- Log.d(MP_TAG, "setupMpi 336");
- // Check if the client wants to use the service at all,
- // then if we're already using the right kind of media player
- if (this.useService && isPrestoLibraryInstalled()) {
- if ((this.mpi != null)
- && (this.mpi instanceof ServiceBackedMediaPlayer)) {
- Log.d(MP_TAG, "Already using ServiceBackedMediaPlayer");
- return;
- }
- if (this.sbmp == null) {
- Log.d(MP_TAG, "Instantiating new ServiceBackedMediaPlayer 346");
- this.sbmp = new ServiceBackedMediaPlayer(this, context,
- new ServiceConnection() {
- public void onServiceConnected(
- ComponentName className,
- final IBinder service) {
- Thread t = new Thread(new Runnable() {
- public void run() {
- // This lock probably isn't granular
- // enough
- MediaPlayer.this.lock.lock();
- Log.d(MP_TAG,
- "onServiceConnected 257");
- try {
- MediaPlayer.this
- .switchMediaPlayerImpl(
- MediaPlayer.this.amp,
- MediaPlayer.this.sbmp);
- Log.d(MP_TAG, "End onServiceConnected 362");
- } finally {
- MediaPlayer.this.lock.unlock();
- }
- }
- });
- t.start();
- }
-
- public void onServiceDisconnected(
- ComponentName className) {
- MediaPlayer.this.lock.lock();
- try {
- // Can't get any more useful information
- // out of sbmp
- if (MediaPlayer.this.sbmp != null) {
- MediaPlayer.this.sbmp.release();
- }
- // Unlike most other cases, sbmp gets set
- // to null since there's nothing useful
- // backing it now
- MediaPlayer.this.sbmp = null;
-
- if (mServiceDisconnectedHandler == null) {
- mServiceDisconnectedHandler = new Handler(new Callback() {
- public boolean handleMessage(Message msg) {
- // switchMediaPlayerImpl won't try to
- // clone anything from null
- lock.lock();
- try {
- if (MediaPlayer.this.amp == null) {
- // This should never be in this state
- MediaPlayer.this.amp = new AndroidMediaPlayer(
- MediaPlayer.this,
- MediaPlayer.this.mContext);
- }
- // Use sbmp instead of null in case by some miracle it's
- // been restored in the meantime
- MediaPlayer.this.switchMediaPlayerImpl(
- MediaPlayer.this.sbmp,
- MediaPlayer.this.amp);
- return true;
- } finally {
- lock.unlock();
- }
- }
- });
- }
-
- // This code needs to execute on the
- // original thread to instantiate
- // the new object in the right place
- mServiceDisconnectedHandler
- .sendMessage(
- mServiceDisconnectedHandler
- .obtainMessage());
- // Note that we do NOT want to set
- // useService. useService is about
- // what the user wants, not what they
- // get
- } finally {
- MediaPlayer.this.lock.unlock();
- }
- }
- }
- );
- }
- switchMediaPlayerImpl(this.amp, this.sbmp);
- } else {
- if ((this.mpi != null)
- && (this.mpi instanceof AndroidMediaPlayer)) {
- Log.d(MP_TAG, "Already using AndroidMediaPlayer");
- return;
- }
- if (this.amp == null) {
- Log.d(MP_TAG, "Instantiating new AndroidMediaPlayer (this should be impossible)");
- this.amp = new AndroidMediaPlayer(this, context);
- }
- switchMediaPlayerImpl(this.sbmp, this.amp);
- }
- } finally {
- lock.unlock();
- }
- }
-
- private void switchMediaPlayerImpl(MediaPlayerImpl from, MediaPlayerImpl to) {
- lock.lock();
- try {
- Log.d(MP_TAG, "switchMediaPlayerImpl");
- if ((from == to)
- // Same object, nothing to synchronize
- || (to == null)
- // Nothing to copy to (maybe this should throw an error?)
- || ((to instanceof ServiceBackedMediaPlayer) && !((ServiceBackedMediaPlayer) to).isConnected())
- // ServiceBackedMediaPlayer hasn't yet connected, onServiceConnected will take care of the transition
- || (MediaPlayer.this.state == State.END)) {
- // State.END is after a release(), no further functions should
- // be called on this class and from is likely to have problems
- // retrieving state that won't be used anyway
- return;
- }
- // Extract all that we can from the existing implementation
- // and copy it to the new implementation
-
- Log.d(MP_TAG, "switchMediaPlayerImpl(), current state is "
- + this.state.toString());
-
- to.reset();
-
- // Do this first so we don't have to prepare the same
- // data file twice
- to.setEnableSpeedAdjustment(MediaPlayer.this.enableSpeedAdjustment);
-
- // This is a reasonable place to set all of these,
- // none of them require prepare() or the like first
- to.setAudioStreamType(this.mAudioStreamType);
- to.setSpeedAdjustmentAlgorithm(this.speedAdjustmentAlgorithm);
- to.setLooping(this.mIsLooping);
- to.setPitchStepsAdjustment(this.mPitchStepsAdjustment);
- Log.d(MP_TAG, "Setting playback speed to " + this.mSpeedMultiplier);
- to.setPlaybackSpeed(this.mSpeedMultiplier);
- to.setVolume(MediaPlayer.this.mLeftVolume,
- MediaPlayer.this.mRightVolume);
- to.setWakeMode(this.mContext, this.mWakeMode);
-
- Log.d(MP_TAG, "asserting at least one data source is null");
- assert ((MediaPlayer.this.stringDataSource == null) || (MediaPlayer.this.uriDataSource == null));
-
- if (uriDataSource != null) {
- Log.d(MP_TAG, "switchMediaPlayerImpl(): uriDataSource != null");
- try {
- to.setDataSource(this.mContext, uriDataSource);
- } catch (IllegalArgumentException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (IllegalStateException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- if (stringDataSource != null) {
- Log.d(MP_TAG,
- "switchMediaPlayerImpl(): stringDataSource != null");
- try {
- to.setDataSource(stringDataSource);
- } catch (IllegalArgumentException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (IllegalStateException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- if ((this.state == State.PREPARED)
- || (this.state == State.PREPARING)
- || (this.state == State.PAUSED)
- || (this.state == State.STOPPED)
- || (this.state == State.STARTED)
- || (this.state == State.PLAYBACK_COMPLETED)) {
- Log.d(MP_TAG, "switchMediaPlayerImpl(): prepare and seek");
- // Use prepare here instead of prepareAsync so that
- // we wait for it to be ready before we try to use it
- try {
- to.muteNextOnPrepare();
- to.prepare();
- } catch (IllegalStateException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
-
- int seekPos = 0;
- if (from != null) {
- seekPos = from.getCurrentPosition();
- } else if (this.lastKnownPosition < to.getDuration()) {
- // This can happen if the Service unexpectedly
- // disconnected. Because it would result in too much
- // information being passed around, we don't constantly
- // poll for the lastKnownPosition, but we'll save it
- // when getCurrentPosition is called
- seekPos = this.lastKnownPosition;
- }
- to.muteNextSeek();
- to.seekTo(seekPos);
- }
- if ((from != null)
- && from.isPlaying()) {
- from.pause();
- }
- if ((this.state == State.STARTED)
- || (this.state == State.PAUSED)
- || (this.state == State.STOPPED)) {
- Log.d(MP_TAG, "switchMediaPlayerImpl(): start");
- if (to != null) {
- to.start();
- }
- }
-
- if (this.state == State.PAUSED) {
- Log.d(MP_TAG, "switchMediaPlayerImpl(): paused");
- if (to != null) {
- to.pause();
- }
- } else if (this.state == State.STOPPED) {
- Log.d(MP_TAG, "switchMediaPlayerImpl(): stopped");
- if (to != null) {
- to.stop();
- }
- }
-
- this.mpi = to;
-
- // Cheating here by relying on the side effect in
- // on(Pitch|Speed)AdjustmentAvailableChanged
- if ((to.canSetPitch() != this.pitchAdjustmentAvailable)
- && (this.onPitchAdjustmentAvailableChangedListener != null)) {
- this.onPitchAdjustmentAvailableChangedListener
- .onPitchAdjustmentAvailableChanged(this, to
- .canSetPitch());
- }
- if ((to.canSetSpeed() != this.speedAdjustmentAvailable)
- && (this.onSpeedAdjustmentAvailableChangedListener != null)) {
- this.onSpeedAdjustmentAvailableChangedListener
- .onSpeedAdjustmentAvailableChanged(this, to
- .canSetSpeed());
- }
- Log.d(MP_TAG, "switchMediaPlayerImpl() 625 " + this.state.toString());
- } finally {
- lock.unlock();
- }
- }
-
- /**
- * Returns true if pitch can be changed at this moment
- *
- * @return True if pitch can be changed
- */
- public boolean canSetPitch() {
- lock.lock();
- try {
- return this.mpi.canSetPitch();
- } finally {
- lock.unlock();
- }
- }
-
- /**
- * Returns true if speed can be changed at this moment
- *
- * @return True if speed can be changed
- */
- public boolean canSetSpeed() {
- lock.lock();
- try {
- return this.mpi.canSetSpeed();
- } finally {
- lock.unlock();
- }
- }
-
- protected void finalize() throws Throwable {
- lock.lock();
- try {
- Log.d(MP_TAG, "finalize() 626");
- this.release();
- } finally {
- lock.unlock();
- }
- }
-
- /**
- * Returns the number of steps (in a musical scale) by which playback is
- * currently shifted. When greater than zero, pitch is shifted up. When less
- * than zero, pitch is shifted down.
- *
- * @return The number of steps pitch is currently shifted by
- */
- public float getCurrentPitchStepsAdjustment() {
- lock.lock();
- try {
- return this.mpi.getCurrentPitchStepsAdjustment();
- } finally {
- lock.unlock();
- }
- }
-
- /**
- * Functions identically to android.media.MediaPlayer.getCurrentPosition()
- * Accurate only to frame size of encoded data (26 ms for MP3s)
- *
- * @return Current position (in milliseconds)
- */
- public int getCurrentPosition() {
- lock.lock();
- try {
- return (this.lastKnownPosition = this.mpi.getCurrentPosition());
- } finally {
- lock.unlock();
- }
- }
-
- /**
- * Returns the current speed multiplier. Defaults to 1.0 (normal speed)
- *
- * @return The current speed multiplier
- */
- public float getCurrentSpeedMultiplier() {
- lock.lock();
- try {
- return this.mpi.getCurrentSpeedMultiplier();
- } finally {
- lock.unlock();
- }
- }
-
- /**
- * Functions identically to android.media.MediaPlayer.getDuration()
- *
- * @return Length of the track (in milliseconds)
- */
- public int getDuration() {
- lock.lock();
- try {
- return this.mpi.getDuration();
- } finally {
- lock.unlock();
- }
- }
-
- /**
- * Get the maximum value that can be passed to setPlaybackSpeed
- *
- * @return The maximum speed multiplier
- */
- public float getMaxSpeedMultiplier() {
- lock.lock();
- try {
- return this.mpi.getMaxSpeedMultiplier();
- } finally {
- lock.unlock();
- }
- }
-
- /**
- * Get the minimum value that can be passed to setPlaybackSpeed
- *
- * @return The minimum speed multiplier
- */
- public float getMinSpeedMultiplier() {
- lock.lock();
- try {
- return this.mpi.getMinSpeedMultiplier();
- } finally {
- lock.unlock();
- }
- }
-
- /**
- * Gets the version code of the backing service
- *
- * @return -1 if ServiceBackedMediaPlayer is not used, 0 if the service is not
- * connected, otherwise the version code retrieved from the service
- */
- public int getServiceVersionCode() {
- lock.lock();
- try {
- if (this.mpi instanceof ServiceBackedMediaPlayer) {
- return ((ServiceBackedMediaPlayer) this.mpi).getServiceVersionCode();
- } else {
- return -1;
- }
- } finally {
- lock.unlock();
- }
- }
-
- /**
- * Gets the version name of the backing service
- *
- * @return null if ServiceBackedMediaPlayer is not used, empty string if
- * the service is not connected, otherwise the version name retrieved from
- * the service
- */
- public String getServiceVersionName() {
- lock.lock();
- try {
- if (this.mpi instanceof ServiceBackedMediaPlayer) {
- return ((ServiceBackedMediaPlayer) this.mpi).getServiceVersionName();
- } else {
- return null;
- }
- } finally {
- lock.unlock();
- }
- }
-
- /**
- * Functions identically to android.media.MediaPlayer.isLooping()
- *
- * @return True if the track is looping
- */
- public boolean isLooping() {
- lock.lock();
- try {
- return this.mpi.isLooping();
- } finally {
- lock.unlock();
- }
- }
-
- /**
- * Functions identically to android.media.MediaPlayer.isPlaying()
- *
- * @return True if the track is playing
- */
- public boolean isPlaying() {
- lock.lock();
- try {
- return this.mpi.isPlaying();
- } finally {
- lock.unlock();
- }
- }
-
- /**
- * Returns true if this MediaPlayer has access to the Presto
- * library
- *
- * @return True if the Presto library is installed
- */
- public boolean isPrestoLibraryInstalled() {
- if ((this.mpi == null) || (this.mpi.mContext == null)) {
- return false;
- }
- return isPrestoLibraryInstalled(this.mpi.mContext);
- }
-
- /**
- * Open the Android Market page in the same context as this MediaPlayer
- */
- public void openPrestoMarketIntent() {
- if ((this.mpi != null) && (this.mpi.mContext != null)) {
- openPrestoMarketIntent(this.mpi.mContext);
- }
- }
-
- /**
- * Functions identically to android.media.MediaPlayer.pause() Pauses the
- * track
- */
- public void pause() {
- lock.lock();
- try {
- if (invalidServiceConnectionConfiguration()) {
- setupMpi(this.mpi.mContext);
- }
- this.state = State.PAUSED;
- this.mpi.pause();
- } finally {
- lock.unlock();
- }
- }
-
- /**
- * Functions identically to android.media.MediaPlayer.prepare() Prepares the
- * track. This or prepareAsync must be called before start()
- */
- public void prepare() throws IllegalStateException, IOException {
- lock.lock();
- try {
- Log.d(MP_TAG, "prepare() 746 using " + ((this.mpi == null) ? "null (this shouldn't happen)" : this.mpi.getClass().toString()) + " state " + this.state.toString());
- Log.d(MP_TAG, "onPreparedListener is: " + ((this.onPreparedListener == null) ? "null" : "non-null"));
- Log.d(MP_TAG, "preparedListener is: " + ((this.preparedListener == null) ? "null" : "non-null"));
- if (invalidServiceConnectionConfiguration()) {
- setupMpi(this.mpi.mContext);
- }
- this.mpi.prepare();
- this.state = State.PREPARED;
- Log.d(MP_TAG, "prepare() finished 778");
- } finally {
- lock.unlock();
- }
- }
-
- /**
- * Functions identically to android.media.MediaPlayer.prepareAsync()
- * Prepares the track. This or prepare must be called before start()
- */
- public void prepareAsync() {
- lock.lock();
- try {
- Log.d(MP_TAG, "prepareAsync() 779");
- if (invalidServiceConnectionConfiguration()) {
- setupMpi(this.mpi.mContext);
- }
- this.state = State.PREPARING;
- this.mpi.prepareAsync();
- } finally {
- lock.unlock();
- }
- }
-
- /**
- * Functions identically to android.media.MediaPlayer.release() Releases the
- * underlying resources used by the media player.
- */
- public void release() {
- lock.lock();
- try {
- Log.d(MP_TAG, "Releasing MediaPlayer 791");
-
- this.state = State.END;
- if (this.amp != null) {
- this.amp.release();
- }
- if (this.sbmp != null) {
- this.sbmp.release();
- }
-
- this.onBufferingUpdateListener = null;
- this.onCompletionListener = null;
- this.onErrorListener = null;
- this.onInfoListener = null;
- this.preparedListener = null;
- this.onPitchAdjustmentAvailableChangedListener = null;
- this.pitchAdjustmentAvailableChangedListener = null;
- Log.d(MP_TAG, "Setting onSeekCompleteListener to null 871");
- this.onSeekCompleteListener = null;
- this.onSpeedAdjustmentAvailableChangedListener = null;
- this.speedAdjustmentAvailableChangedListener = null;
- } finally {
- lock.unlock();
- }
- }
-
- /**
- * Functions identically to android.media.MediaPlayer.reset() Resets the
- * track to idle state
- */
- public void reset() {
- lock.lock();
- try {
- this.state = State.IDLE;
- this.stringDataSource = null;
- this.uriDataSource = null;
- this.mpi.reset();
- } finally {
- lock.unlock();
- }
- }
-
- /**
- * Functions identically to android.media.MediaPlayer.seekTo(int msec) Seeks
- * to msec in the track
- */
- public void seekTo(int msec) throws IllegalStateException {
- lock.lock();
- try {
- this.mpi.seekTo(msec);
- } finally {
- lock.unlock();
- }
- }
-
- /**
- * Functions identically to android.media.MediaPlayer.setAudioStreamType(int
- * streamtype) Sets the audio stream type.
- */
- public void setAudioStreamType(int streamtype) {
- lock.lock();
- try {
- this.mAudioStreamType = streamtype;
- this.mpi.setAudioStreamType(streamtype);
- } finally {
- lock.unlock();
- }
- }
-
- /**
- * Functions identically to android.media.MediaPlayer.setDataSource(Context
- * context, Uri uri) Sets uri as data source in the context given
- */
- public void setDataSource(Context context, Uri uri)
- throws IllegalArgumentException, IllegalStateException, IOException {
- lock.lock();
- try {
- Log.d(MP_TAG, "In setDataSource(context, " + uri.toString() + "), using " + this.mpi.getClass().toString());
- if (invalidServiceConnectionConfiguration()) {
- setupMpi(this.mpi.mContext);
- }
- this.state = State.INITIALIZED;
- this.stringDataSource = null;
- this.uriDataSource = uri;
- this.mpi.setDataSource(context, uri);
- } finally {
- lock.unlock();
- }
- }
-
- /**
- * Functions identically to android.media.MediaPlayer.setDataSource(String
- * path) Sets the data source of the track to a file given.
- */
- public void setDataSource(String path) throws IllegalArgumentException,
- IllegalStateException, IOException {
- lock.lock();
- try {
- Log.d(MP_TAG, "In setDataSource(context, " + path + ")");
- if (invalidServiceConnectionConfiguration()) {
- setupMpi(this.mpi.mContext);
- }
- this.state = State.INITIALIZED;
- this.stringDataSource = path;
- this.uriDataSource = null;
- this.mpi.setDataSource(path);
- } finally {
- lock.unlock();
- }
- }
-
- /**
- * Sets whether to use speed adjustment or not. Speed adjustment on is more
- * computation-intensive than with it off.
- *
- * @param enableSpeedAdjustment Whether speed adjustment should be supported.
- */
- public void setEnableSpeedAdjustment(boolean enableSpeedAdjustment) {
- lock.lock();
- try {
- this.enableSpeedAdjustment = enableSpeedAdjustment;
- this.mpi.setEnableSpeedAdjustment(enableSpeedAdjustment);
- } finally {
- lock.unlock();
- }
- }
-
- /**
- * Functions identically to android.media.MediaPlayer.setLooping(boolean
- * loop) Sets the track to loop infinitely if loop is true, play once if
- * loop is false
- */
- public void setLooping(boolean loop) {
- lock.lock();
- try {
- this.mIsLooping = loop;
- this.mpi.setLooping(loop);
- } finally {
- lock.unlock();
- }
- }
-
- /**
- * Sets the number of steps (in a musical scale) by which playback is
- * currently shifted. When greater than zero, pitch is shifted up. When less
- * than zero, pitch is shifted down.
- *
- * @param pitchSteps The number of steps by which to shift playback
- */
- public void setPitchStepsAdjustment(float pitchSteps) {
- lock.lock();
- try {
- this.mPitchStepsAdjustment = pitchSteps;
- this.mpi.setPitchStepsAdjustment(pitchSteps);
- } finally {
- lock.unlock();
- }
- }
-
- /**
- * Set the algorithm to use for changing the speed and pitch of audio
- * See SpeedAdjustmentAlgorithm constants for more details
- *
- * @param algorithm The algorithm to use.
- */
- public void setSpeedAdjustmentAlgorithm(int algorithm) {
- lock.lock();
- try {
- this.speedAdjustmentAlgorithm = algorithm;
- if (this.mpi != null) {
- this.mpi.setSpeedAdjustmentAlgorithm(algorithm);
- }
- } finally {
- lock.unlock();
- }
- }
-
- private static float getPitchStepsAdjustment(float pitch) {
- return (float) (Math.log(pitch) / (2 * Math.log(PITCH_STEP_CONSTANT)));
- }
-
- /**
- * Sets the percentage by which pitch is currently shifted. When greater
- * than zero, pitch is shifted up. When less than zero, pitch is shifted
- * down
- *
- * @param f The percentage to shift pitch
- */
- public void setPlaybackPitch(float pitch) {
- lock.lock();
- try {
- this.mPitchStepsAdjustment = getPitchStepsAdjustment(pitch);
- this.mpi.setPlaybackPitch(pitch);
- } finally {
- lock.unlock();
- }
- }
-
- /**
- * Set playback speed. 1.0 is normal speed, 2.0 is double speed, and so on.
- * Speed should never be set to 0 or below.
- *
- * @param f The speed multiplier to use for further playback
- */
- public void setPlaybackSpeed(float f) {
- lock.lock();
- try {
- this.mSpeedMultiplier = f;
- this.mpi.setPlaybackSpeed(f);
- } finally {
- lock.unlock();
- }
- }
-
- /**
- * Sets whether to use speed adjustment or not. Speed adjustment on is more
- * computation-intensive than with it off.
- *
- * @param enableSpeedAdjustment Whether speed adjustment should be supported.
- */
- public void setUseService(boolean useService) {
- lock.lock();
- try {
- this.useService = useService;
- setupMpi(this.mpi.mContext);
- } finally {
- lock.unlock();
- }
- }
-
- /**
- * Functions identically to android.media.MediaPlayer.setVolume(float
- * leftVolume, float rightVolume) Sets the stereo volume
- */
- public void setVolume(float leftVolume, float rightVolume) {
- lock.lock();
- try {
- this.mLeftVolume = leftVolume;
- this.mRightVolume = rightVolume;
- this.mpi.setVolume(leftVolume, rightVolume);
- } finally {
- lock.unlock();
- }
- }
-
- /**
- * Functions identically to android.media.MediaPlayer.setWakeMode(Context
- * context, int mode) Acquires a wake lock in the context given. You must
- * request the appropriate permissions in your AndroidManifest.xml file.
- */
- public void setWakeMode(Context context, int mode) {
- lock.lock();
- try {
- this.mWakeMode = mode;
- this.mpi.setWakeMode(context, mode);
- } finally {
- lock.unlock();
- }
- }
-
- /**
- * Functions identically to
- * android.media.MediaPlayer.setOnCompletionListener(OnCompletionListener
- * listener) Sets a listener to be used when a track completes playing.
- */
- public void setOnBufferingUpdateListener(OnBufferingUpdateListener listener) {
- lock.lock();
- try {
- this.onBufferingUpdateListener = listener;
- } finally {
- lock.unlock();
- }
- }
-
- /**
- * Functions identically to
- * android.media.MediaPlayer.setOnCompletionListener(OnCompletionListener
- * listener) Sets a listener to be used when a track completes playing.
- */
- public void setOnCompletionListener(OnCompletionListener listener) {
- lock.lock();
- try {
- this.onCompletionListener = listener;
- } finally {
- lock.unlock();
- }
- }
-
- /**
- * Functions identically to
- * android.media.MediaPlayer.setOnErrorListener(OnErrorListener listener)
- * Sets a listener to be used when a track encounters an error.
- */
- public void setOnErrorListener(OnErrorListener listener) {
- lock.lock();
- try {
- this.onErrorListener = listener;
- } finally {
- lock.unlock();
- }
- }
-
- /**
- * Functions identically to
- * android.media.MediaPlayer.setOnInfoListener(OnInfoListener listener) Sets
- * a listener to be used when a track has info.
- */
- public void setOnInfoListener(OnInfoListener listener) {
- lock.lock();
- try {
- this.onInfoListener = listener;
- } finally {
- lock.unlock();
- }
- }
-
- /**
- * Sets a listener that will fire when pitch adjustment becomes available or
- * stops being available
- */
- public void setOnPitchAdjustmentAvailableChangedListener(
- OnPitchAdjustmentAvailableChangedListener listener) {
- lock.lock();
- try {
- this.pitchAdjustmentAvailableChangedListener = listener;
- } finally {
- lock.unlock();
- }
- }
-
- /**
- * Functions identically to
- * android.media.MediaPlayer.setOnPreparedListener(OnPreparedListener
- * listener) Sets a listener to be used when a track finishes preparing.
- */
- public void setOnPreparedListener(OnPreparedListener listener) {
- lock.lock();
- Log.d(MP_TAG, " ++++++++++++++++++++++++++++++++++++++++++++ setOnPreparedListener");
- try {
- this.preparedListener = listener;
- // For this one, we do not explicitly set the MediaPlayer or the
- // Service listener. This is because in addition to calling the
- // listener provided by the client, it's necessary to change
- // state to PREPARED. See prepareAsync for implementation details
- } finally {
- lock.unlock();
- }
- }
-
- /**
- * Functions identically to
- * android.media.MediaPlayer.setOnSeekCompleteListener
- * (OnSeekCompleteListener listener) Sets a listener to be used when a track
- * finishes seeking.
- */
- public void setOnSeekCompleteListener(OnSeekCompleteListener listener) {
- lock.lock();
- try {
- this.onSeekCompleteListener = listener;
- } finally {
- lock.unlock();
- }
- }
-
- /**
- * Sets a listener that will fire when speed adjustment becomes available or
- * stops being available
- */
- public void setOnSpeedAdjustmentAvailableChangedListener(
- OnSpeedAdjustmentAvailableChangedListener listener) {
- lock.lock();
- try {
- this.speedAdjustmentAvailableChangedListener = listener;
- } finally {
- lock.unlock();
- }
- }
-
- /**
- * Functions identically to android.media.MediaPlayer.start() Starts a track
- * playing
- */
- public void start() {
- lock.lock();
- try {
- Log.d(MP_TAG, "start() 1149");
- if (invalidServiceConnectionConfiguration()) {
- setupMpi(this.mpi.mContext);
- }
- this.state = State.STARTED;
- Log.d(MP_TAG, "start() 1154");
- this.mpi.start();
- } finally {
- lock.unlock();
- }
- }
-
- /**
- * Functions identically to android.media.MediaPlayer.stop() Stops a track
- * playing and resets its position to the start.
- */
- public void stop() {
- lock.lock();
- try {
- if (invalidServiceConnectionConfiguration()) {
- setupMpi(this.mpi.mContext);
- }
- this.state = State.STOPPED;
- this.mpi.stop();
- } finally {
- lock.unlock();
- }
- }
-} \ No newline at end of file
diff --git a/core/src/main/java/com/aocate/media/MediaPlayerImpl.java b/core/src/main/java/com/aocate/media/MediaPlayerImpl.java
deleted file mode 100644
index 856ab47ce..000000000
--- a/core/src/main/java/com/aocate/media/MediaPlayerImpl.java
+++ /dev/null
@@ -1,118 +0,0 @@
-// Copyright 2011, Aocate, Inc.
-//
-// 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 com.aocate.media;
-
-import java.io.IOException;
-import java.util.concurrent.locks.ReentrantLock;
-
-import android.content.Context;
-import android.net.Uri;
-import android.util.Log;
-
-public abstract class MediaPlayerImpl {
- private static final String MPI_TAG = "AocateMediaPlayerImpl";
- protected final MediaPlayer owningMediaPlayer;
- protected final Context mContext;
- protected int muteOnPreparedCount = 0;
- protected int muteOnSeekCount = 0;
-
- public MediaPlayerImpl(MediaPlayer owningMediaPlayer, Context context) {
- this.owningMediaPlayer = owningMediaPlayer;
-
- this.mContext = context;
- }
-
- public abstract boolean canSetPitch();
-
- public abstract boolean canSetSpeed();
-
- public abstract float getCurrentPitchStepsAdjustment();
-
- public abstract int getCurrentPosition();
-
- public abstract float getCurrentSpeedMultiplier();
-
- public abstract int getDuration();
-
- public abstract float getMaxSpeedMultiplier();
-
- public abstract float getMinSpeedMultiplier();
-
- public abstract boolean isLooping();
-
- public abstract boolean isPlaying();
-
- public abstract void pause();
-
- public abstract void prepare() throws IllegalStateException, IOException;
-
- public abstract void prepareAsync();
-
- public abstract void release();
-
- public abstract void reset();
-
- public abstract void seekTo(int msec) throws IllegalStateException;
-
- public abstract void setAudioStreamType(int streamtype);
-
- public abstract void setDataSource(Context context, Uri uri) throws IllegalArgumentException, IllegalStateException, IOException;
-
- public abstract void setDataSource(String path) throws IllegalArgumentException, IllegalStateException, IOException;
-
- public abstract void setEnableSpeedAdjustment(boolean enableSpeedAdjustment);
-
- public abstract void setLooping(boolean loop);
-
- public abstract void setPitchStepsAdjustment(float pitchSteps);
-
- public abstract void setPlaybackPitch(float f);
-
- public abstract void setPlaybackSpeed(float f);
-
- public abstract void setSpeedAdjustmentAlgorithm(int algorithm);
-
- public abstract void setVolume(float leftVolume, float rightVolume);
-
- public abstract void setWakeMode(Context context, int mode);
-
- public abstract void start();
-
- public abstract void stop();
-
- protected ReentrantLock lockMuteOnPreparedCount = new ReentrantLock();
- public void muteNextOnPrepare() {
- lockMuteOnPreparedCount.lock();
- Log.d(MPI_TAG, "muteNextOnPrepare()");
- try {
- this.muteOnPreparedCount++;
- }
- finally {
- lockMuteOnPreparedCount.unlock();
- }
- }
-
- protected ReentrantLock lockMuteOnSeekCount = new ReentrantLock();
- public void muteNextSeek() {
- lockMuteOnSeekCount.lock();
- Log.d(MPI_TAG, "muteNextOnSeek()");
- try {
- this.muteOnSeekCount++;
- }
- finally {
- lockMuteOnSeekCount.unlock();
- }
- }
-}
diff --git a/core/src/main/java/com/aocate/media/ServiceBackedMediaPlayer.java b/core/src/main/java/com/aocate/media/ServiceBackedMediaPlayer.java
deleted file mode 100644
index 0e27a8014..000000000
--- a/core/src/main/java/com/aocate/media/ServiceBackedMediaPlayer.java
+++ /dev/null
@@ -1,1203 +0,0 @@
-// Copyright 2011, Aocate, Inc.
-//
-// 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.
-//
-// -----------------------------------------------------------------------
-// Compared to the original version, this class been slightly modified so
-// that any acquired WakeLocks are only held while the MediaPlayer is
-// playing (see the stayAwake method for more details).
-
-
-package com.aocate.media;
-
-import java.io.IOException;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.media.AudioManager;
-import android.net.Uri;
-import android.os.IBinder;
-import android.os.PowerManager;
-import android.os.RemoteException;
-import android.os.PowerManager.WakeLock;
-import android.util.Log;
-
-import com.aocate.media.MediaPlayer.State;
-import com.aocate.presto.service.IDeathCallback_0_8;
-import com.aocate.presto.service.IOnBufferingUpdateListenerCallback_0_8;
-import com.aocate.presto.service.IOnCompletionListenerCallback_0_8;
-import com.aocate.presto.service.IOnErrorListenerCallback_0_8;
-import com.aocate.presto.service.IOnInfoListenerCallback_0_8;
-import com.aocate.presto.service.IOnPitchAdjustmentAvailableChangedListenerCallback_0_8;
-import com.aocate.presto.service.IOnPreparedListenerCallback_0_8;
-import com.aocate.presto.service.IOnSeekCompleteListenerCallback_0_8;
-import com.aocate.presto.service.IOnSpeedAdjustmentAvailableChangedListenerCallback_0_8;
-import com.aocate.presto.service.IPlayMedia_0_8;
-
-import de.danoeh.antennapod.core.BuildConfig;
-
-/**
- * Class for connecting to remote speed-altering, media playing Service
- * Note that there is unusually high coupling between MediaPlayer and this
- * class. This is an unfortunate compromise, since the alternative was to
- * track state in two different places in this code (plus the internal state
- * of the remote media player).
- * @author aocate
- *
- */
-public class ServiceBackedMediaPlayer extends MediaPlayerImpl {
- static final String INTENT_NAME = "com.aocate.intent.PLAY_AUDIO_ADJUST_SPEED_0_8";
-
- private static final String SBMP_TAG = "AocateServiceBackedMediaPlayer";
-
- private ServiceConnection mPlayMediaServiceConnection = null;
- protected IPlayMedia_0_8 pmInterface = null;
- private Intent playMediaServiceIntent = null;
- // In some cases, we're going to have to replace the
- // android.media.MediaPlayer on the fly, and we don't want to touch the
- // wrong media player.
-
- private long sessionId = 0;
- private boolean isErroring = false;
- private int mAudioStreamType = AudioManager.STREAM_MUSIC;
-
- private WakeLock mWakeLock = null;
-
- // So here's the major problem
- // Sometimes the service won't exist or won't be connected,
- // so start with an android.media.MediaPlayer, and when
- // the service is connected, use that from then on
- public ServiceBackedMediaPlayer(MediaPlayer owningMediaPlayer, final Context context, final ServiceConnection serviceConnection) {
- super(owningMediaPlayer, context);
- Log.d(SBMP_TAG, "Instantiating ServiceBackedMediaPlayer 87");
- this.playMediaServiceIntent =
- MediaPlayer.getPrestoServiceIntent(context, INTENT_NAME);
- this.mPlayMediaServiceConnection = new ServiceConnection() {
- public void onServiceConnected(ComponentName name, IBinder service) {
- IPlayMedia_0_8 tmpPlayMediaInterface = IPlayMedia_0_8.Stub.asInterface((IBinder) service);
-
- Log.d(SBMP_TAG, "Setting up pmInterface 94");
- if (ServiceBackedMediaPlayer.this.sessionId == 0) {
- try {
- // The IDeathCallback isn't a conventional callback.
- // It exists so that if the client ceases to exist,
- // the Service becomes aware of that and can shut
- // down whatever it needs to shut down
- ServiceBackedMediaPlayer.this.sessionId = tmpPlayMediaInterface.startSession(new IDeathCallback_0_8.Stub() {
- });
- // This is really bad if this fails
- } catch (RemoteException e) {
- e.printStackTrace();
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
-
- Log.d(SBMP_TAG, "Assigning pmInterface");
-
- ServiceBackedMediaPlayer.this.setOnBufferingUpdateCallback(tmpPlayMediaInterface);
- ServiceBackedMediaPlayer.this.setOnCompletionCallback(tmpPlayMediaInterface);
- ServiceBackedMediaPlayer.this.setOnErrorCallback(tmpPlayMediaInterface);
- ServiceBackedMediaPlayer.this.setOnInfoCallback(tmpPlayMediaInterface);
- ServiceBackedMediaPlayer.this.setOnPitchAdjustmentAvailableChangedListener(tmpPlayMediaInterface);
- ServiceBackedMediaPlayer.this.setOnPreparedCallback(tmpPlayMediaInterface);
- ServiceBackedMediaPlayer.this.setOnSeekCompleteCallback(tmpPlayMediaInterface);
- ServiceBackedMediaPlayer.this.setOnSpeedAdjustmentAvailableChangedCallback(tmpPlayMediaInterface);
-
- // In order to avoid race conditions from the sessionId or listener not being assigned
- pmInterface = tmpPlayMediaInterface;
-
- Log.d(SBMP_TAG, "Invoking onServiceConnected");
- serviceConnection.onServiceConnected(name, service);
- }
-
- public void onServiceDisconnected(ComponentName name) {
- Log.d(SBMP_TAG, "onServiceDisconnected 114");
-
- pmInterface = null;
-
- sessionId = 0;
-
- serviceConnection.onServiceDisconnected(name);
- }
- };
-
- Log.d(SBMP_TAG, "Connecting PlayMediaService 124");
- if (!ConnectPlayMediaService()) {
- Log.e(SBMP_TAG, "bindService failed");
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
-
- private boolean ConnectPlayMediaService() {
- Log.d(SBMP_TAG, "ConnectPlayMediaService()");
-
- if (MediaPlayer.isIntentAvailable(mContext, INTENT_NAME)) {
- Log.d(SBMP_TAG, INTENT_NAME + " is available");
- if (pmInterface == null) {
- try {
- Log.d(SBMP_TAG, "Binding service");
- return mContext.bindService(playMediaServiceIntent, mPlayMediaServiceConnection, Context.BIND_AUTO_CREATE);
- } catch (Exception e) {
- Log.e(SBMP_TAG, "Could not bind with service", e);
- return false;
- }
- } else {
- Log.d(SBMP_TAG, "Service already bound");
- return true;
- }
- }
- else {
- Log.d(SBMP_TAG, INTENT_NAME + " is not available");
- return false;
- }
- }
-
- /**
- * Returns true if pitch can be changed at this moment
- * @return True if pitch can be changed
- */
- @Override
- public boolean canSetPitch() {
- Log.d(SBMP_TAG, "canSetPitch() 155");
-
- if (pmInterface == null) {
- if (!ConnectPlayMediaService()) {
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
- if (pmInterface != null) {
- // Can't set pitch if the service isn't connected
- try {
- return pmInterface.canSetPitch(ServiceBackedMediaPlayer.this.sessionId);
- } catch (RemoteException e) {
- e.printStackTrace();
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
- return false;
- }
-
- /**
- * Returns true if speed can be changed at this moment
- * @return True if speed can be changed
- */
- @Override
- public boolean canSetSpeed() {
- Log.d(SBMP_TAG, "canSetSpeed() 180");
- if (pmInterface == null) {
- if (!ConnectPlayMediaService()) {
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
- if (pmInterface != null) {
- // Can't set speed if the service isn't connected
- try {
- return pmInterface.canSetSpeed(ServiceBackedMediaPlayer.this.sessionId);
- } catch (RemoteException e) {
- e.printStackTrace();
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
- return false;
- }
-
- void error(int what, int extra) {
- owningMediaPlayer.lock.lock();
- Log.e(SBMP_TAG, "error(" + what + ", " + extra + ")");
- stayAwake(false);
- try {
- if (!this.isErroring) {
- this.isErroring = true;
- owningMediaPlayer.state = State.ERROR;
- if (owningMediaPlayer.onErrorListener != null) {
- if (owningMediaPlayer.onErrorListener.onError(owningMediaPlayer, what, extra)) {
- return;
- }
- }
- if (owningMediaPlayer.onCompletionListener != null) {
- owningMediaPlayer.onCompletionListener.onCompletion(owningMediaPlayer);
- }
- }
- }
- finally {
- this.isErroring = false;
- owningMediaPlayer.lock.unlock();
- }
- }
-
- protected void finalize() throws Throwable {
- owningMediaPlayer.lock.lock();
- try {
- Log.d(SBMP_TAG, "finalize() 224");
- this.release();
- }
- finally {
- owningMediaPlayer.lock.unlock();
- }
- }
-
- /**
- * Returns the number of steps (in a musical scale) by which playback is
- * currently shifted. When greater than zero, pitch is shifted up.
- * When less than zero, pitch is shifted down.
- * @return The number of steps pitch is currently shifted by
- */
- @Override
- public float getCurrentPitchStepsAdjustment() {
- Log.d(SBMP_TAG, "getCurrentPitchStepsAdjustment() 240");
- if (pmInterface == null) {
- if (!ConnectPlayMediaService()) {
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
- if (pmInterface != null) {
- // Can't set pitch if the service isn't connected
- try {
- return pmInterface.getCurrentPitchStepsAdjustment(
- ServiceBackedMediaPlayer.this.sessionId);
- } catch (RemoteException e) {
- e.printStackTrace();
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
- return 0f;
- }
-
- /**
- * Functions identically to android.media.MediaPlayer.getCurrentPosition()
- * @return Current position (in milliseconds)
- */
- @Override
- public int getCurrentPosition() {
- if (pmInterface == null) {
- if (!ConnectPlayMediaService()) {
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
- try {
- return pmInterface.getCurrentPosition(
- ServiceBackedMediaPlayer.this.sessionId);
- } catch (RemoteException e) {
- e.printStackTrace();
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- return 0;
- }
-
- /**
- * Returns the current speed multiplier. Defaults to 1.0 (normal speed)
- * @return The current speed multiplier
- */
- @Override
- public float getCurrentSpeedMultiplier() {
- Log.d(SBMP_TAG, "getCurrentSpeedMultiplier() 286");
- if (pmInterface == null) {
- if (!ConnectPlayMediaService()) {
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
- if (pmInterface != null) {
- // Can't set speed if the service isn't connected
- try {
- return pmInterface.getCurrentSpeedMultiplier(
- ServiceBackedMediaPlayer.this.sessionId);
- } catch (RemoteException e) {
- e.printStackTrace();
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
- return 1;
- }
-
- /**
- * Functions identically to android.media.MediaPlayer.getDuration()
- * @return Length of the track (in milliseconds)
- */
- @Override
- public int getDuration() {
- Log.d(SBMP_TAG, "getDuration() 311");
- if (pmInterface == null) {
- if (!ConnectPlayMediaService()) {
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
- try {
- return pmInterface.getDuration(ServiceBackedMediaPlayer.this.sessionId);
- } catch (RemoteException e) {
- e.printStackTrace();
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- return 0;
- }
-
- /**
- * Get the maximum value that can be passed to setPlaybackSpeed
- * @return The maximum speed multiplier
- */
- @Override
- public float getMaxSpeedMultiplier() {
- Log.d(SBMP_TAG, "getMaxSpeedMultiplier() 332");
- if (pmInterface == null) {
- if (!ConnectPlayMediaService()) {
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
- if (pmInterface != null) {
- // Can't set speed if the Service isn't connected
- try {
- return pmInterface.getMaxSpeedMultiplier(
- ServiceBackedMediaPlayer.this.sessionId);
- } catch (RemoteException e) {
- e.printStackTrace();
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
- return 1f;
- }
-
- /**
- * Get the minimum value that can be passed to setPlaybackSpeed
- * @return The minimum speed multiplier
- */
- @Override
- public float getMinSpeedMultiplier() {
- Log.d(SBMP_TAG, "getMinSpeedMultiplier() 357");
- if (pmInterface == null) {
- if (!ConnectPlayMediaService()) {
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
- if (pmInterface != null) {
- // Can't set speed if the Service isn't connected
- try {
- return pmInterface.getMinSpeedMultiplier(
- ServiceBackedMediaPlayer.this.sessionId);
- } catch (RemoteException e) {
- e.printStackTrace();
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
- return 1f;
- }
-
- public int getServiceVersionCode() {
- Log.d(SBMP_TAG, "getVersionCode");
- if (pmInterface == null) {
- if (!ConnectPlayMediaService()) {
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
- try {
- return pmInterface.getVersionCode();
- } catch (RemoteException e) {
- e.printStackTrace();
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- return 0;
- }
-
- public String getServiceVersionName() {
- Log.d(SBMP_TAG, "getVersionName");
- if (pmInterface == null) {
- if (!ConnectPlayMediaService()) {
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
- try {
- return pmInterface.getVersionName();
- } catch (RemoteException e) {
- e.printStackTrace();
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- return "";
- }
-
- public boolean isConnected() {
- return (pmInterface != null);
- }
-
- /**
- * Functions identically to android.media.MediaPlayer.isLooping()
- * @return True if the track is looping
- */
- @Override
- public boolean isLooping() {
- Log.d(SBMP_TAG, "isLooping() 382");
- if (pmInterface == null) {
- if (!ConnectPlayMediaService()) {
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
- try {
- return pmInterface.isLooping(ServiceBackedMediaPlayer.this.sessionId);
- } catch (RemoteException e) {
- e.printStackTrace();
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- return false;
- }
-
- /**
- * Functions identically to android.media.MediaPlayer.isPlaying()
- * @return True if the track is playing
- */
- @Override
- public boolean isPlaying() {
- if (pmInterface == null) {
- if (!ConnectPlayMediaService()) {
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
- if (pmInterface != null) {
- try {
- return pmInterface.isPlaying(ServiceBackedMediaPlayer.this.sessionId);
- } catch (RemoteException e) {
- e.printStackTrace();
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
- return false;
- }
-
- /**
- * Functions identically to android.media.MediaPlayer.pause()
- * Pauses the track
- */
- @Override
- public void pause() {
- Log.d(SBMP_TAG, "pause() 424");
- if (pmInterface == null) {
- if (!ConnectPlayMediaService()) {
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
- try {
- pmInterface.pause(ServiceBackedMediaPlayer.this.sessionId);
- } catch (RemoteException e) {
- e.printStackTrace();
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- stayAwake(false);
- }
-
- /**
- * Functions identically to android.media.MediaPlayer.prepare()
- * Prepares the track. This or prepareAsync must be called before start()
- */
- @Override
- public void prepare() throws IllegalStateException, IOException {
- Log.d(SBMP_TAG, "prepare() 444");
- Log.d(SBMP_TAG, "onPreparedCallback is: " + ((this.mOnPreparedCallback == null) ? "null" : "non-null"));
- if (pmInterface == null) {
- Log.d(SBMP_TAG, "prepare: pmInterface is null");
- if (!ConnectPlayMediaService()) {
- Log.d(SBMP_TAG, "prepare: Failed to connect play media service");
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
- if (pmInterface != null) {
- Log.d(SBMP_TAG, "prepare: pmInterface isn't null");
- try {
- Log.d(SBMP_TAG, "prepare: Remote invoke pmInterface.prepare(" + ServiceBackedMediaPlayer.this.sessionId + ")");
- pmInterface.prepare(ServiceBackedMediaPlayer.this.sessionId);
- Log.d(SBMP_TAG, "prepare: prepared");
- } catch (RemoteException e) {
- Log.d(SBMP_TAG, "prepare: RemoteException");
- e.printStackTrace();
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
- Log.d(SBMP_TAG, "Done with prepare()");
- }
-
- /**
- * Functions identically to android.media.MediaPlayer.prepareAsync()
- * Prepares the track. This or prepare must be called before start()
- */
- @Override
- public void prepareAsync() {
- Log.d(SBMP_TAG, "prepareAsync() 469");
- if (pmInterface == null) {
- if (!ConnectPlayMediaService()) {
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
- try {
- pmInterface.prepareAsync(ServiceBackedMediaPlayer.this.sessionId);
- } catch (RemoteException e) {
- e.printStackTrace();
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
-
- /**
- * Functions identically to android.media.MediaPlayer.release()
- * Releases the underlying resources used by the media player.
- */
- @Override
- public void release() {
- Log.d(SBMP_TAG, "release() 492");
- if (pmInterface == null) {
- if (!ConnectPlayMediaService()) {
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
- if (pmInterface != null) {
- Log.d(SBMP_TAG, "release() 500");
- try {
- pmInterface.release(ServiceBackedMediaPlayer.this.sessionId);
- } catch (RemoteException e) {
- e.printStackTrace();
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- mContext.unbindService(this.mPlayMediaServiceConnection);
- // Don't try to keep awake (if we were)
- this.setWakeMode(mContext, 0);
- pmInterface = null;
- this.sessionId = 0;
- }
-
- if ((this.mWakeLock != null) && this.mWakeLock.isHeld()) {
- Log.d(SBMP_TAG, "Releasing wakelock");
- this.mWakeLock.release();
- }
- }
-
- /**
- * Functions identically to android.media.MediaPlayer.reset()
- * Resets the track to idle state
- */
- @Override
- public void reset() {
- Log.d(SBMP_TAG, "reset() 523");
- if (pmInterface == null) {
- if (!ConnectPlayMediaService()) {
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
- try {
- pmInterface.reset(ServiceBackedMediaPlayer.this.sessionId);
- } catch (RemoteException e) {
- e.printStackTrace();
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- stayAwake(false);
- }
-
- /**
- * Functions identically to android.media.MediaPlayer.seekTo(int msec)
- * Seeks to msec in the track
- */
- @Override
- public void seekTo(int msec) throws IllegalStateException {
- Log.d(SBMP_TAG, "seekTo(" + msec + ")");
- if (pmInterface == null) {
- if (!ConnectPlayMediaService()) {
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
- try {
- pmInterface.seekTo(ServiceBackedMediaPlayer.this.sessionId, msec);
- } catch (RemoteException e) {
- e.printStackTrace();
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
-
- /**
- * Functions identically to android.media.MediaPlayer.setAudioStreamType(int streamtype)
- * Sets the audio stream type.
- */
- @Override
- public void setAudioStreamType(int streamtype) {
- Log.d(SBMP_TAG, "setAudioStreamType(" + streamtype + ")");
- if (pmInterface == null) {
- if (!ConnectPlayMediaService()) {
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
- try {
- pmInterface.setAudioStreamType(
- ServiceBackedMediaPlayer.this.sessionId,
- this.mAudioStreamType);
- } catch (RemoteException e) {
- e.printStackTrace();
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
-
-
- /**
- * Functions identically to android.media.MediaPlayer.setDataSource(Context context, Uri uri)
- * Sets uri as data source in the context given
- */
- @Override
- public void setDataSource(Context context, Uri uri) throws IllegalArgumentException, IllegalStateException, IOException {
- Log.d(SBMP_TAG, "setDataSource(context, uri)");
- if (pmInterface == null) {
- if (!ConnectPlayMediaService()) {
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
- try {
- pmInterface.setDataSourceUri(
- ServiceBackedMediaPlayer.this.sessionId,
- uri);
- } catch (RemoteException e) {
- e.printStackTrace();
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
-
- /**
- * Functions identically to android.media.MediaPlayer.setDataSource(String path)
- * Sets the data source of the track to a file given.
- */
- @Override
- public void setDataSource(String path) throws IllegalArgumentException, IllegalStateException, IOException {
- Log.d(SBMP_TAG, "setDataSource(path)");
- if (pmInterface == null) {
- if (!ConnectPlayMediaService()) {
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
- if (pmInterface == null) {
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- else {
- try {
- pmInterface.setDataSourceString(
- ServiceBackedMediaPlayer.this.sessionId,
- path);
- } catch (RemoteException e) {
- e.printStackTrace();
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
- }
-
- /**
- * Sets whether to use speed adjustment or not. Speed adjustment on is
- * more computation-intensive than with it off.
- * @param enableSpeedAdjustment Whether speed adjustment should be supported.
- */
- @Override
- public void setEnableSpeedAdjustment(boolean enableSpeedAdjustment) {
- // TODO: This has no business being here, I think
- owningMediaPlayer.lock.lock();
- Log.d(SBMP_TAG, "setEnableSpeedAdjustment(enableSpeedAdjustment)");
- try {
- if (pmInterface == null) {
- if (!ConnectPlayMediaService()) {
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
- if (pmInterface != null) {
- // Can't set speed if the Service isn't connected
- try {
- pmInterface.setEnableSpeedAdjustment(
- ServiceBackedMediaPlayer.this.sessionId,
- enableSpeedAdjustment);
- } catch (RemoteException e) {
- e.printStackTrace();
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
- }
- finally {
- owningMediaPlayer.lock.unlock();
- }
- }
-
-
- /**
- * Functions identically to android.media.MediaPlayer.setLooping(boolean loop)
- * Sets the track to loop infinitely if loop is true, play once if loop is false
- */
- @Override
- public void setLooping(boolean loop) {
- Log.d(SBMP_TAG, "setLooping(" + loop + ")");
- if (pmInterface == null) {
- if (!ConnectPlayMediaService()) {
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
- try {
- pmInterface.setLooping(ServiceBackedMediaPlayer.this.sessionId, loop);
- } catch (RemoteException e) {
- e.printStackTrace();
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
-
- /**
- * Sets the number of steps (in a musical scale) by which playback is
- * currently shifted. When greater than zero, pitch is shifted up.
- * When less than zero, pitch is shifted down.
- *
- * @param pitchSteps The number of steps by which to shift playback
- */
- @Override
- public void setPitchStepsAdjustment(float pitchSteps) {
- Log.d(SBMP_TAG, "setPitchStepsAdjustment(" + pitchSteps + ")");
- if (pmInterface == null) {
- if (!ConnectPlayMediaService()) {
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
- if (pmInterface != null) {
- // Can't set speed if the Service isn't connected
- try {
- pmInterface.setPitchStepsAdjustment(
- ServiceBackedMediaPlayer.this.sessionId,
- pitchSteps);
- } catch (RemoteException e) {
- e.printStackTrace();
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
- }
-
- /**
- * Sets the percentage by which pitch is currently shifted. When
- * greater than zero, pitch is shifted up. When less than zero, pitch
- * is shifted down
- * @param f The percentage to shift pitch
- */
- @Override
- public void setPlaybackPitch(float f) {
- Log.d(SBMP_TAG, "setPlaybackPitch(" + f + ")");
- if (pmInterface == null) {
- if (!ConnectPlayMediaService()) {
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
- if (pmInterface != null) {
- // Can't set speed if the Service isn't connected
- try {
- pmInterface.setPlaybackPitch(
- ServiceBackedMediaPlayer.this.sessionId,
- f);
- } catch (RemoteException e) {
- e.printStackTrace();
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
- }
-
- /**
- * Set playback speed. 1.0 is normal speed, 2.0 is double speed, and so
- * on. Speed should never be set to 0 or below.
- * @param f The speed multiplier to use for further playback
- */
- @Override
- public void setPlaybackSpeed(float f) {
- Log.d(SBMP_TAG, "setPlaybackSpeed(" + f + ")");
- if (pmInterface == null) {
- if (!ConnectPlayMediaService()) {
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
- if (pmInterface != null) {
- // Can't set speed if the Service isn't connected
- try {
- pmInterface.setPlaybackSpeed(
- ServiceBackedMediaPlayer.this.sessionId,
- f);
- } catch (RemoteException e) {
- e.printStackTrace();
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
- }
-
- @Override
- public void setSpeedAdjustmentAlgorithm(int algorithm) {
- if (pmInterface == null) {
- if (!ConnectPlayMediaService()) {
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
- try {
- pmInterface.setSpeedAdjustmentAlgorithm(
- ServiceBackedMediaPlayer.this.sessionId,
- algorithm);
- } catch (RemoteException e) {
- e.printStackTrace();
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
-
- /**
- * Functions identically to android.media.MediaPlayer.setVolume(float leftVolume, float rightVolume)
- * Sets the stereo volume
- */
- @Override
- public void setVolume(float leftVolume, float rightVolume) {
- Log.d(SBMP_TAG, "setVolume(" + leftVolume + ", " + rightVolume + ")");
- if (pmInterface == null) {
- if (!ConnectPlayMediaService()) {
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
- try {
- pmInterface.setVolume(
- ServiceBackedMediaPlayer.this.sessionId,
- leftVolume,
- rightVolume);
- } catch (RemoteException e) {
- e.printStackTrace();
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
-
- /**
- * Functions identically to android.media.MediaPlayer.setWakeMode(Context context, int mode)
- * Acquires a wake lock in the context given. You must request the appropriate permissions
- * in your AndroidManifest.xml file.
- */
- @Override
- // This does not just call .setWakeMode() in the Service because doing so
- // would add a permission requirement to the Service. Do it here, and it's
- // the client app's responsibility to request that permission
- public void setWakeMode(Context context, int mode) {
- Log.d(SBMP_TAG, "setWakeMode(context, " + mode + ")");
- if ((this.mWakeLock != null)
- && (this.mWakeLock.isHeld())) {
- this.mWakeLock.release();
- }
- if (mode != 0) {
- if (this.mWakeLock == null) {
- PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
- // Since mode can't be changed on the fly, we have to allocate a new one
- this.mWakeLock = pm.newWakeLock(mode, this.getClass().getName());
- this.mWakeLock.setReferenceCounted(false);
- }
-
- this.mWakeLock.acquire();
- }
- }
-
- /**
- * Changes the state of the WakeLock if it has been acquired.
- * If no WakeLock has been acquired with setWakeMode, this method does nothing.
- * */
- private void stayAwake(boolean awake) {
- if (BuildConfig.DEBUG) Log.d(SBMP_TAG, "stayAwake(" + awake + ")");
- if (mWakeLock != null) {
- if (awake && !mWakeLock.isHeld()) {
- mWakeLock.acquire();
- } else if (!awake && mWakeLock.isHeld()) {
- mWakeLock.release();
- }
- }
- }
-
- private IOnBufferingUpdateListenerCallback_0_8.Stub mOnBufferingUpdateCallback = null;
- private void setOnBufferingUpdateCallback(IPlayMedia_0_8 iface) {
- try {
- if (this.mOnBufferingUpdateCallback == null) {
- mOnBufferingUpdateCallback = new IOnBufferingUpdateListenerCallback_0_8.Stub() {
- public void onBufferingUpdate(int percent)
- throws RemoteException {
- owningMediaPlayer.lock.lock();
- try {
- if ((owningMediaPlayer.onBufferingUpdateListener != null)
- && (owningMediaPlayer.mpi == ServiceBackedMediaPlayer.this)) {
- owningMediaPlayer.onBufferingUpdateListener.onBufferingUpdate(owningMediaPlayer, percent);
- }
- }
- finally {
- owningMediaPlayer.lock.unlock();
- }
- }
- };
- }
- iface.registerOnBufferingUpdateCallback(
- ServiceBackedMediaPlayer.this.sessionId,
- mOnBufferingUpdateCallback);
- } catch (RemoteException e) {
- e.printStackTrace();
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
-
- private IOnCompletionListenerCallback_0_8.Stub mOnCompletionCallback = null;
- private void setOnCompletionCallback(IPlayMedia_0_8 iface) {
- try {
- if (this.mOnCompletionCallback == null) {
- this.mOnCompletionCallback = new IOnCompletionListenerCallback_0_8.Stub() {
- public void onCompletion() throws RemoteException {
- owningMediaPlayer.lock.lock();
- Log.d(SBMP_TAG, "onCompletionListener being called");
- stayAwake(false);
- try {
- if (owningMediaPlayer.onCompletionListener != null) {
- owningMediaPlayer.onCompletionListener.onCompletion(owningMediaPlayer);
- }
- }
- finally {
- owningMediaPlayer.lock.unlock();
- }
- }
- };
- }
- iface.registerOnCompletionCallback(
- ServiceBackedMediaPlayer.this.sessionId,
- this.mOnCompletionCallback);
- } catch (RemoteException e) {
- e.printStackTrace();
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
-
- private IOnErrorListenerCallback_0_8.Stub mOnErrorCallback = null;
- private void setOnErrorCallback(IPlayMedia_0_8 iface) {
- try {
- if (this.mOnErrorCallback == null) {
- this.mOnErrorCallback = new IOnErrorListenerCallback_0_8.Stub() {
- public boolean onError(int what, int extra) throws RemoteException {
- owningMediaPlayer.lock.lock();
- stayAwake(false);
- try {
- if (owningMediaPlayer.onErrorListener != null) {
- return owningMediaPlayer.onErrorListener.onError(owningMediaPlayer, what, extra);
- }
- return false;
- }
- finally {
- owningMediaPlayer.lock.unlock();
- }
- }
- };
- }
- iface.registerOnErrorCallback(
- ServiceBackedMediaPlayer.this.sessionId,
- this.mOnErrorCallback);
- } catch (RemoteException e) {
- e.printStackTrace();
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
-
- private IOnInfoListenerCallback_0_8.Stub mOnInfoCallback = null;
- private void setOnInfoCallback(IPlayMedia_0_8 iface) {
- try {
- if (this.mOnInfoCallback == null) {
- this.mOnInfoCallback = new IOnInfoListenerCallback_0_8.Stub() {
- public boolean onInfo(int what, int extra) throws RemoteException {
- owningMediaPlayer.lock.lock();
- try {
- if ((owningMediaPlayer.onInfoListener != null)
- && (owningMediaPlayer.mpi == ServiceBackedMediaPlayer.this)) {
- return owningMediaPlayer.onInfoListener.onInfo(owningMediaPlayer, what, extra);
- }
- }
- finally {
- owningMediaPlayer.lock.unlock();
- }
- return false;
- }
- };
- }
- iface.registerOnInfoCallback(
- ServiceBackedMediaPlayer.this.sessionId,
- this.mOnInfoCallback);
- } catch (RemoteException e) {
- e.printStackTrace();
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
-
- private IOnPitchAdjustmentAvailableChangedListenerCallback_0_8.Stub mOnPitchAdjustmentAvailableChangedCallback = null;
- private void setOnPitchAdjustmentAvailableChangedListener(IPlayMedia_0_8 iface) {
- try {
- if (this.mOnPitchAdjustmentAvailableChangedCallback == null) {
- this.mOnPitchAdjustmentAvailableChangedCallback = new IOnPitchAdjustmentAvailableChangedListenerCallback_0_8.Stub() {
- public void onPitchAdjustmentAvailableChanged(
- boolean pitchAdjustmentAvailable)
- throws RemoteException {
- owningMediaPlayer.lock.lock();
- try {
- if (owningMediaPlayer.onPitchAdjustmentAvailableChangedListener != null) {
- owningMediaPlayer.onPitchAdjustmentAvailableChangedListener.onPitchAdjustmentAvailableChanged(owningMediaPlayer, pitchAdjustmentAvailable);
- }
- }
- finally {
- owningMediaPlayer.lock.unlock();
- }
- }
- };
- }
- iface.registerOnPitchAdjustmentAvailableChangedCallback(
- ServiceBackedMediaPlayer.this.sessionId,
- this.mOnPitchAdjustmentAvailableChangedCallback);
- } catch (RemoteException e) {
- e.printStackTrace();
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
-
- private IOnPreparedListenerCallback_0_8.Stub mOnPreparedCallback = null;
- private void setOnPreparedCallback(IPlayMedia_0_8 iface) {
- try {
- if (this.mOnPreparedCallback == null) {
- this.mOnPreparedCallback = new IOnPreparedListenerCallback_0_8.Stub() {
- public void onPrepared() throws RemoteException {
- owningMediaPlayer.lock.lock();
- Log.d(SBMP_TAG, "setOnPreparedCallback.mOnPreparedCallback.onPrepared 1050");
- try {
- Log.d(SBMP_TAG, "owningMediaPlayer.onPreparedListener is " + ((owningMediaPlayer.onPreparedListener == null) ? "null" : "non-null"));
- Log.d(SBMP_TAG, "owningMediaPlayer.mpi is " + ((owningMediaPlayer.mpi == ServiceBackedMediaPlayer.this) ? "this" : "not this"));
- ServiceBackedMediaPlayer.this.lockMuteOnPreparedCount.lock();
- try {
- if (ServiceBackedMediaPlayer.this.muteOnPreparedCount > 0) {
- ServiceBackedMediaPlayer.this.muteOnPreparedCount--;
- }
- else {
- ServiceBackedMediaPlayer.this.muteOnPreparedCount = 0;
- if (ServiceBackedMediaPlayer.this.owningMediaPlayer.onPreparedListener != null) {
- owningMediaPlayer.onPreparedListener.onPrepared(owningMediaPlayer);
- }
- }
- }
- finally {
- ServiceBackedMediaPlayer.this.lockMuteOnPreparedCount.unlock();
- }
- }
- finally {
- owningMediaPlayer.lock.unlock();
- }
- }
- };
- }
- iface.registerOnPreparedCallback(
- ServiceBackedMediaPlayer.this.sessionId,
- this.mOnPreparedCallback);
- } catch (RemoteException e) {
- e.printStackTrace();
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
-
- private IOnSeekCompleteListenerCallback_0_8.Stub mOnSeekCompleteCallback = null;
- private void setOnSeekCompleteCallback(IPlayMedia_0_8 iface) {
- try {
- if (this.mOnSeekCompleteCallback == null) {
- this.mOnSeekCompleteCallback = new IOnSeekCompleteListenerCallback_0_8.Stub() {
- public void onSeekComplete() throws RemoteException {
- Log.d(SBMP_TAG, "onSeekComplete() 941");
- owningMediaPlayer.lock.lock();
- try {
- if (ServiceBackedMediaPlayer.this.muteOnSeekCount > 0) {
- Log.d(SBMP_TAG, "The next " + ServiceBackedMediaPlayer.this.muteOnSeekCount + " seek events are muted (counting this one)");
- ServiceBackedMediaPlayer.this.muteOnSeekCount--;
- }
- else {
- ServiceBackedMediaPlayer.this.muteOnSeekCount = 0;
- Log.d(SBMP_TAG, "Attempting to invoke next seek event");
- if (ServiceBackedMediaPlayer.this.owningMediaPlayer.onSeekCompleteListener != null) {
- Log.d(SBMP_TAG, "Invoking onSeekComplete");
- owningMediaPlayer.onSeekCompleteListener.onSeekComplete(owningMediaPlayer);
- }
- }
- }
- finally {
- owningMediaPlayer.lock.unlock();
- }
- }
- };
- }
- iface.registerOnSeekCompleteCallback(
- ServiceBackedMediaPlayer.this.sessionId,
- this.mOnSeekCompleteCallback);
- } catch (RemoteException e) {
- e.printStackTrace();
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
-
- private IOnSpeedAdjustmentAvailableChangedListenerCallback_0_8.Stub mOnSpeedAdjustmentAvailableChangedCallback = null;
- private void setOnSpeedAdjustmentAvailableChangedCallback(IPlayMedia_0_8 iface) {
- try {
- Log.d(SBMP_TAG, "Setting the service of on speed adjustment available changed");
- if (this.mOnSpeedAdjustmentAvailableChangedCallback == null) {
- this.mOnSpeedAdjustmentAvailableChangedCallback = new IOnSpeedAdjustmentAvailableChangedListenerCallback_0_8.Stub() {
- public void onSpeedAdjustmentAvailableChanged(
- boolean speedAdjustmentAvailable)
- throws RemoteException {
- owningMediaPlayer.lock.lock();
- try {
- if (owningMediaPlayer.onSpeedAdjustmentAvailableChangedListener != null) {
- owningMediaPlayer.onSpeedAdjustmentAvailableChangedListener.onSpeedAdjustmentAvailableChanged(owningMediaPlayer, speedAdjustmentAvailable);
- }
- }
- finally {
- owningMediaPlayer.lock.unlock();
- }
- }
- };
- }
- iface.registerOnSpeedAdjustmentAvailableChangedCallback(
- ServiceBackedMediaPlayer.this.sessionId,
- this.mOnSpeedAdjustmentAvailableChangedCallback);
- } catch (RemoteException e) {
- e.printStackTrace();
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
-
- /**
- * Functions identically to android.media.MediaPlayer.start()
- * Starts a track playing
- */
- @Override
- public void start() {
- Log.d(SBMP_TAG, "start()");
- if (pmInterface == null) {
- if (!ConnectPlayMediaService()) {
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
- try {
- pmInterface.start(ServiceBackedMediaPlayer.this.sessionId);
- } catch (RemoteException e) {
- e.printStackTrace();
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- stayAwake(true);
- }
-
- /**
- * Functions identically to android.media.MediaPlayer.stop()
- * Stops a track playing and resets its position to the start.
- */
- @Override
- public void stop() {
- Log.d(SBMP_TAG, "stop()");
- if (pmInterface == null) {
- if (!ConnectPlayMediaService()) {
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- }
- try {
- pmInterface.stop(ServiceBackedMediaPlayer.this.sessionId);
- } catch (RemoteException e) {
- e.printStackTrace();
- ServiceBackedMediaPlayer.this.error(MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
- }
- stayAwake(false);
- }
-} \ No newline at end of file
diff --git a/core/src/main/java/com/aocate/media/SpeedAdjustmentAlgorithm.java b/core/src/main/java/com/aocate/media/SpeedAdjustmentAlgorithm.java
deleted file mode 100644
index d337a0452..000000000
--- a/core/src/main/java/com/aocate/media/SpeedAdjustmentAlgorithm.java
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2011, Aocate, Inc.
-//
-// 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 com.aocate.media;
-
-public class SpeedAdjustmentAlgorithm {
- /**
- * Use this to use the user-specified algorithm
- */
- public static int DEFAULT = 0;
-
- /**
- * Better for voice audio
- */
- public static int SONIC = 1;
- /**
- * Better for music audio
- */
- public static int WSOLA = 2;
-}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/feed/FeedItemFilter.java b/core/src/main/java/de/danoeh/antennapod/core/feed/FeedItemFilter.java
index 879b28096..c1d21552e 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/feed/FeedItemFilter.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/feed/FeedItemFilter.java
@@ -55,7 +55,7 @@ public class FeedItemFilter {
}
}
- public List<FeedItem> filter(Context context, List<FeedItem> items) {
+ public List<FeedItem> filter(List<FeedItem> items) {
if(properties.length == 0) {
return items;
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/preferences/UserPreferences.java b/core/src/main/java/de/danoeh/antennapod/core/preferences/UserPreferences.java
index c0d44dff3..e6a2a2464 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/preferences/UserPreferences.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/preferences/UserPreferences.java
@@ -89,6 +89,10 @@ public class UserPreferences {
public static final String IMAGE_CACHE_DEFAULT_VALUE = "100";
public static final int IMAGE_CACHE_SIZE_MINIMUM = 20;
+ // Experimental
+ public static final String PREF_SONIC = "prefSonic";
+ public static final String PREF_NORMALIZER = "prefNormalizer";
+
// Constants
private static int EPISODE_CACHE_SIZE_UNLIMITED = -1;
public static int FEED_ORDER_COUNTER = 0;
@@ -469,6 +473,9 @@ public class UserPreferences {
return selectedSpeeds;
}
+ public static boolean useSonic() {
+ return prefs.getBoolean(PREF_SONIC, false);
+ }
/**
* Return the folder where the app stores all of its data. This method will
diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceMediaPlayer.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceMediaPlayer.java
index 757b2e980..7cf7eb622 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceMediaPlayer.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceMediaPlayer.java
@@ -1047,9 +1047,9 @@ public class PlaybackServiceMediaPlayer implements SharedPreferences.OnSharedPre
return mp;
}
- private final com.aocate.media.MediaPlayer.OnCompletionListener audioCompletionListener = new com.aocate.media.MediaPlayer.OnCompletionListener() {
+ private final org.antennapod.audio.MediaPlayer.OnCompletionListener audioCompletionListener = new org.antennapod.audio.MediaPlayer.OnCompletionListener() {
@Override
- public void onCompletion(com.aocate.media.MediaPlayer mp) {
+ public void onCompletion(org.antennapod.audio.MediaPlayer mp) {
genericOnCompletion();
}
};
@@ -1065,9 +1065,9 @@ public class PlaybackServiceMediaPlayer implements SharedPreferences.OnSharedPre
endPlayback();
}
- private final com.aocate.media.MediaPlayer.OnBufferingUpdateListener audioBufferingUpdateListener = new com.aocate.media.MediaPlayer.OnBufferingUpdateListener() {
+ private final org.antennapod.audio.MediaPlayer.OnBufferingUpdateListener audioBufferingUpdateListener = new org.antennapod.audio.MediaPlayer.OnBufferingUpdateListener() {
@Override
- public void onBufferingUpdate(com.aocate.media.MediaPlayer mp,
+ public void onBufferingUpdate(org.antennapod.audio.MediaPlayer mp,
int percent) {
genericOnBufferingUpdate(percent);
}
@@ -1084,9 +1084,9 @@ public class PlaybackServiceMediaPlayer implements SharedPreferences.OnSharedPre
callback.onBufferingUpdate(percent);
}
- private final com.aocate.media.MediaPlayer.OnInfoListener audioInfoListener = new com.aocate.media.MediaPlayer.OnInfoListener() {
+ private final org.antennapod.audio.MediaPlayer.OnInfoListener audioInfoListener = new org.antennapod.audio.MediaPlayer.OnInfoListener() {
@Override
- public boolean onInfo(com.aocate.media.MediaPlayer mp, int what,
+ public boolean onInfo(org.antennapod.audio.MediaPlayer mp, int what,
int extra) {
return genericInfoListener(what);
}
@@ -1103,9 +1103,9 @@ public class PlaybackServiceMediaPlayer implements SharedPreferences.OnSharedPre
return callback.onMediaPlayerInfo(what);
}
- private final com.aocate.media.MediaPlayer.OnErrorListener audioErrorListener = new com.aocate.media.MediaPlayer.OnErrorListener() {
+ private final org.antennapod.audio.MediaPlayer.OnErrorListener audioErrorListener = new org.antennapod.audio.MediaPlayer.OnErrorListener() {
@Override
- public boolean onError(com.aocate.media.MediaPlayer mp, int what,
+ public boolean onError(org.antennapod.audio.MediaPlayer mp, int what,
int extra) {
return genericOnError(mp, what, extra);
}
@@ -1122,9 +1122,9 @@ public class PlaybackServiceMediaPlayer implements SharedPreferences.OnSharedPre
return callback.onMediaPlayerError(inObj, what, extra);
}
- private final com.aocate.media.MediaPlayer.OnSeekCompleteListener audioSeekCompleteListener = new com.aocate.media.MediaPlayer.OnSeekCompleteListener() {
+ private final org.antennapod.audio.MediaPlayer.OnSeekCompleteListener audioSeekCompleteListener = new org.antennapod.audio.MediaPlayer.OnSeekCompleteListener() {
@Override
- public void onSeekComplete(com.aocate.media.MediaPlayer mp) {
+ public void onSeekComplete(org.antennapod.audio.MediaPlayer mp) {
genericSeekCompleteListener();
}
};
diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java b/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java
index 73037d771..fa4a5726a 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java
@@ -309,7 +309,11 @@ public class PodDBAdapter {
dbHelper.close();
dbHelper = null;
}
- return context.deleteDatabase(PodDBAdapter.DATABASE_NAME);
+ if(context != null) { // may not have been initialized
+ return context.deleteDatabase(PodDBAdapter.DATABASE_NAME);
+ } else {
+ return false;
+ }
}
/**
diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/playback/AudioPlayer.java b/core/src/main/java/de/danoeh/antennapod/core/util/playback/AudioPlayer.java
index aafcea307..b6beb5bf1 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/util/playback/AudioPlayer.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/util/playback/AudioPlayer.java
@@ -3,7 +3,9 @@ package de.danoeh.antennapod.core.util.playback;
import android.content.Context;
import android.util.Log;
import android.view.SurfaceHolder;
-import com.aocate.media.MediaPlayer;
+import org.antennapod.audio.MediaPlayer;
+
+import de.danoeh.antennapod.core.preferences.UserPreferences;
public class AudioPlayer extends MediaPlayer implements IPlayer {
private static final String TAG = "AudioPlayer";
@@ -16,7 +18,6 @@ public class AudioPlayer extends MediaPlayer implements IPlayer {
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
@@ -31,4 +32,9 @@ public class AudioPlayer extends MediaPlayer implements IPlayer {
public void setVideoScalingMode(int mode) {
throw new UnsupportedOperationException("Setting scaling mode is not supported in Audio Player");
}
+
+ @Override
+ protected boolean useSonic() {
+ return UserPreferences.useSonic();
+ }
}
diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml
index 68c5150e5..ff9891bab 100644
--- a/core/src/main/res/values/strings.xml
+++ b/core/src/main/res/values/strings.xml
@@ -344,6 +344,9 @@
<string name="pref_smart_mark_as_played_disabled">Disabled</string>
<string name="pref_image_cache_size_title">Image Cache Size</string>
<string name="pref_image_cache_size_sum">Size of the disk cache for images.</string>
+ <string name="experimental_pref">Experimental</string>
+ <string name="pref_sonic_title">Sonic media player</string>
+ <string name="pref_sonic_message">Use built-in sonic media player as a replacement for Prestissimo</string>
<!-- Auto-Flattr dialog -->
<string name="auto_flattr_enable">Enable automatic flattring</string>