Merge pull request #3248 from maxbechtold/feat/simple-adjust-volume-per-feed
Feat/simple adjust volume per feed
This commit is contained in:
commit
8dd595e0e8
|
@ -3,7 +3,8 @@ package de.test.antennapod.service.playback;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
import androidx.test.filters.MediumTest;
|
import androidx.test.filters.MediumTest;
|
||||||
import androidx.test.platform.app.InstrumentationRegistry;
|
|
||||||
|
import de.danoeh.antennapod.core.feed.VolumeAdaptionSetting;
|
||||||
import de.test.antennapod.EspressoTestUtils;
|
import de.test.antennapod.EspressoTestUtils;
|
||||||
import junit.framework.AssertionFailedError;
|
import junit.framework.AssertionFailedError;
|
||||||
|
|
||||||
|
@ -125,7 +126,7 @@ public class PlaybackServiceMediaPlayerTest {
|
||||||
private Playable writeTestPlayable(String downloadUrl, String fileUrl) {
|
private Playable writeTestPlayable(String downloadUrl, String fileUrl) {
|
||||||
final Context c = getInstrumentation().getTargetContext();
|
final Context c = getInstrumentation().getTargetContext();
|
||||||
Feed f = new Feed(0, null, "f", "l", "d", null, null, null, null, "i", null, null, "l", false);
|
Feed f = new Feed(0, null, "f", "l", "d", null, null, null, null, "i", null, null, "l", false);
|
||||||
FeedPreferences prefs = new FeedPreferences(f.getId(), false, FeedPreferences.AutoDeleteAction.NO, null, null);
|
FeedPreferences prefs = new FeedPreferences(f.getId(), false, FeedPreferences.AutoDeleteAction.NO, VolumeAdaptionSetting.OFF, null, null);
|
||||||
f.setPreferences(prefs);
|
f.setPreferences(prefs);
|
||||||
f.setItems(new ArrayList<>());
|
f.setItems(new ArrayList<>());
|
||||||
FeedItem i = new FeedItem(0, "t", "i", "l", new Date(), FeedItem.UNPLAYED, f);
|
FeedItem i = new FeedItem(0, "t", "i", "l", new Date(), FeedItem.UNPLAYED, f);
|
||||||
|
|
|
@ -14,7 +14,6 @@ import androidx.appcompat.app.AlertDialog;
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.AdapterView;
|
import android.widget.AdapterView;
|
||||||
|
@ -48,6 +47,7 @@ import de.danoeh.antennapod.core.event.DownloadEvent;
|
||||||
import de.danoeh.antennapod.core.feed.Feed;
|
import de.danoeh.antennapod.core.feed.Feed;
|
||||||
import de.danoeh.antennapod.core.feed.FeedItem;
|
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||||
import de.danoeh.antennapod.core.feed.FeedPreferences;
|
import de.danoeh.antennapod.core.feed.FeedPreferences;
|
||||||
|
import de.danoeh.antennapod.core.feed.VolumeAdaptionSetting;
|
||||||
import de.danoeh.antennapod.core.glide.ApGlideSettings;
|
import de.danoeh.antennapod.core.glide.ApGlideSettings;
|
||||||
import de.danoeh.antennapod.core.glide.FastBlurTransformation;
|
import de.danoeh.antennapod.core.glide.FastBlurTransformation;
|
||||||
import de.danoeh.antennapod.core.preferences.UserPreferences;
|
import de.danoeh.antennapod.core.preferences.UserPreferences;
|
||||||
|
@ -230,7 +230,7 @@ public class OnlineFeedViewActivity extends AppCompatActivity {
|
||||||
url = URLChecker.prepareURL(url);
|
url = URLChecker.prepareURL(url);
|
||||||
feed = new Feed(url, null);
|
feed = new Feed(url, null);
|
||||||
if (username != null && password != null) {
|
if (username != null && password != null) {
|
||||||
feed.setPreferences(new FeedPreferences(0, false, FeedPreferences.AutoDeleteAction.GLOBAL, username, password));
|
feed.setPreferences(new FeedPreferences(0, false, FeedPreferences.AutoDeleteAction.GLOBAL, VolumeAdaptionSetting.OFF, username, password));
|
||||||
}
|
}
|
||||||
String fileUrl = new File(getExternalCacheDir(),
|
String fileUrl = new File(getExternalCacheDir(),
|
||||||
FileNameGenerator.generateFileName(feed.getDownload_url())).toString();
|
FileNameGenerator.generateFileName(feed.getDownload_url())).toString();
|
||||||
|
|
|
@ -2,6 +2,7 @@ package de.danoeh.antennapod.fragment;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import androidx.preference.SwitchPreference;
|
import androidx.preference.SwitchPreference;
|
||||||
import androidx.preference.ListPreference;
|
import androidx.preference.ListPreference;
|
||||||
|
@ -10,10 +11,13 @@ import android.util.Log;
|
||||||
import de.danoeh.antennapod.R;
|
import de.danoeh.antennapod.R;
|
||||||
import de.danoeh.antennapod.activity.MainActivity;
|
import de.danoeh.antennapod.activity.MainActivity;
|
||||||
import de.danoeh.antennapod.core.dialog.ConfirmationDialog;
|
import de.danoeh.antennapod.core.dialog.ConfirmationDialog;
|
||||||
|
import de.danoeh.antennapod.core.event.settings.VolumeAdaptionChangedEvent;
|
||||||
import de.danoeh.antennapod.core.feed.Feed;
|
import de.danoeh.antennapod.core.feed.Feed;
|
||||||
import de.danoeh.antennapod.core.feed.FeedFilter;
|
import de.danoeh.antennapod.core.feed.FeedFilter;
|
||||||
import de.danoeh.antennapod.core.feed.FeedPreferences;
|
import de.danoeh.antennapod.core.feed.FeedPreferences;
|
||||||
|
import de.danoeh.antennapod.core.feed.VolumeAdaptionSetting;
|
||||||
import de.danoeh.antennapod.core.preferences.UserPreferences;
|
import de.danoeh.antennapod.core.preferences.UserPreferences;
|
||||||
|
import de.danoeh.antennapod.core.service.playback.PlaybackService;
|
||||||
import de.danoeh.antennapod.core.storage.DBReader;
|
import de.danoeh.antennapod.core.storage.DBReader;
|
||||||
import de.danoeh.antennapod.core.storage.DBWriter;
|
import de.danoeh.antennapod.core.storage.DBWriter;
|
||||||
import de.danoeh.antennapod.dialog.AuthenticationDialog;
|
import de.danoeh.antennapod.dialog.AuthenticationDialog;
|
||||||
|
@ -23,6 +27,8 @@ import io.reactivex.MaybeOnSubscribe;
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||||
import io.reactivex.disposables.Disposable;
|
import io.reactivex.disposables.Disposable;
|
||||||
import io.reactivex.schedulers.Schedulers;
|
import io.reactivex.schedulers.Schedulers;
|
||||||
|
import org.greenrobot.eventbus.EventBus;
|
||||||
|
|
||||||
import java.text.DecimalFormat;
|
import java.text.DecimalFormat;
|
||||||
import java.text.DecimalFormatSymbols;
|
import java.text.DecimalFormatSymbols;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
@ -73,11 +79,13 @@ public class FeedSettingsFragment extends PreferenceFragmentCompat {
|
||||||
setupAutoDownloadPreference();
|
setupAutoDownloadPreference();
|
||||||
setupKeepUpdatedPreference();
|
setupKeepUpdatedPreference();
|
||||||
setupAutoDeletePreference();
|
setupAutoDeletePreference();
|
||||||
|
setupVolumeReductionPreferences();
|
||||||
setupAuthentificationPreference();
|
setupAuthentificationPreference();
|
||||||
setupEpisodeFilterPreference();
|
setupEpisodeFilterPreference();
|
||||||
setupPlaybackSpeedPreference();
|
setupPlaybackSpeedPreference();
|
||||||
|
|
||||||
updateAutoDeleteSummary();
|
updateAutoDeleteSummary();
|
||||||
|
updateVolumeReductionValue();
|
||||||
updateAutoDownloadEnabled();
|
updateAutoDownloadEnabled();
|
||||||
updatePlaybackSpeedPreference();
|
updatePlaybackSpeedPreference();
|
||||||
}, error -> Log.d(TAG, Log.getStackTraceString(error)), () -> { });
|
}, error -> Log.d(TAG, Log.getStackTraceString(error)), () -> { });
|
||||||
|
@ -206,6 +214,49 @@ public class FeedSettingsFragment extends PreferenceFragmentCompat {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setupVolumeReductionPreferences() {
|
||||||
|
ListPreference volumeReductionPreference = (ListPreference) findPreference("volumeReduction");
|
||||||
|
volumeReductionPreference.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||||
|
switch ((String) newValue) {
|
||||||
|
case "off":
|
||||||
|
feedPreferences.setVolumeAdaptionSetting(VolumeAdaptionSetting.OFF);
|
||||||
|
break;
|
||||||
|
case "light":
|
||||||
|
feedPreferences.setVolumeAdaptionSetting(VolumeAdaptionSetting.LIGHT_REDUCTION);
|
||||||
|
break;
|
||||||
|
case "heavy":
|
||||||
|
feedPreferences.setVolumeAdaptionSetting(VolumeAdaptionSetting.HEAVY_REDUCTION);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
feed.savePreferences();
|
||||||
|
updateVolumeReductionValue();
|
||||||
|
sendVolumeAdaptionChangedIntent();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendVolumeAdaptionChangedIntent() {
|
||||||
|
EventBus.getDefault().post(
|
||||||
|
new VolumeAdaptionChangedEvent(feedPreferences.getVolumeAdaptionSetting(), feed.getId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateVolumeReductionValue() {
|
||||||
|
ListPreference volumeReductionPreference = (ListPreference) findPreference("volumeReduction");
|
||||||
|
|
||||||
|
switch (feedPreferences.getVolumeAdaptionSetting()) {
|
||||||
|
case OFF:
|
||||||
|
volumeReductionPreference.setValue("off");
|
||||||
|
break;
|
||||||
|
case LIGHT_REDUCTION:
|
||||||
|
volumeReductionPreference.setValue("light");
|
||||||
|
break;
|
||||||
|
case HEAVY_REDUCTION:
|
||||||
|
volumeReductionPreference.setValue("heavy");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void setupKeepUpdatedPreference() {
|
private void setupKeepUpdatedPreference() {
|
||||||
SwitchPreference pref = (SwitchPreference) findPreference("keepUpdated");
|
SwitchPreference pref = (SwitchPreference) findPreference("keepUpdated");
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,15 @@
|
||||||
android:summary="@string/feed_auto_download_global"
|
android:summary="@string/feed_auto_download_global"
|
||||||
android:key="autoDelete"/>
|
android:key="autoDelete"/>
|
||||||
|
|
||||||
|
<ListPreference
|
||||||
|
android:entries="@array/spnVolumeReductionItems"
|
||||||
|
android:entryValues="@array/spnVolumeReductionValues"
|
||||||
|
android:icon="?attr/ic_volume_adaption"
|
||||||
|
android:summary="@string/feed_volume_reduction_summary"
|
||||||
|
android:title="@string/feed_volume_reduction"
|
||||||
|
android:defaultValue="off"
|
||||||
|
android:key="volumeReduction"/>
|
||||||
|
|
||||||
<PreferenceCategory android:title="@string/auto_download_settings_label">
|
<PreferenceCategory android:title="@string/auto_download_settings_label">
|
||||||
<SwitchPreference
|
<SwitchPreference
|
||||||
android:key="autoDownload"
|
android:key="autoDownload"
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
package de.danoeh.antennapod.core.event.settings;
|
||||||
|
|
||||||
|
import de.danoeh.antennapod.core.feed.VolumeAdaptionSetting;
|
||||||
|
|
||||||
|
public class VolumeAdaptionChangedEvent {
|
||||||
|
private final VolumeAdaptionSetting volumeAdaptionSetting;
|
||||||
|
private final long feedId;
|
||||||
|
|
||||||
|
public VolumeAdaptionChangedEvent(VolumeAdaptionSetting volumeAdaptionSetting, long feedId) {
|
||||||
|
this.volumeAdaptionSetting = volumeAdaptionSetting;
|
||||||
|
this.feedId = feedId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public VolumeAdaptionSetting getVolumeAdaptionSetting() {
|
||||||
|
return volumeAdaptionSetting;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getFeedId() {
|
||||||
|
return feedId;
|
||||||
|
}
|
||||||
|
}
|
|
@ -171,7 +171,7 @@ public class Feed extends FeedFile implements ImageResource {
|
||||||
*/
|
*/
|
||||||
public Feed(String url, String lastUpdate, String title, String username, String password) {
|
public Feed(String url, String lastUpdate, String title, String username, String password) {
|
||||||
this(url, lastUpdate, title);
|
this(url, lastUpdate, title);
|
||||||
preferences = new FeedPreferences(0, true, FeedPreferences.AutoDeleteAction.GLOBAL, username, password);
|
preferences = new FeedPreferences(0, true, FeedPreferences.AutoDeleteAction.GLOBAL, VolumeAdaptionSetting.OFF, username, password);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Feed fromCursor(Cursor cursor) {
|
public static Feed fromCursor(Cursor cursor) {
|
||||||
|
|
|
@ -28,19 +28,23 @@ public class FeedPreferences {
|
||||||
NO
|
NO
|
||||||
}
|
}
|
||||||
private AutoDeleteAction auto_delete_action;
|
private AutoDeleteAction auto_delete_action;
|
||||||
|
|
||||||
|
private VolumeAdaptionSetting volumeAdaptionSetting;
|
||||||
|
|
||||||
private String username;
|
private String username;
|
||||||
private String password;
|
private String password;
|
||||||
private float feedPlaybackSpeed;
|
private float feedPlaybackSpeed;
|
||||||
|
|
||||||
public FeedPreferences(long feedID, boolean autoDownload, AutoDeleteAction auto_delete_action, String username, String password) {
|
public FeedPreferences(long feedID, boolean autoDownload, AutoDeleteAction auto_delete_action, VolumeAdaptionSetting volumeAdaptionSetting, String username, String password) {
|
||||||
this(feedID, autoDownload, true, auto_delete_action, username, password, new FeedFilter(), SPEED_USE_GLOBAL);
|
this(feedID, autoDownload, true, auto_delete_action, volumeAdaptionSetting, username, password, new FeedFilter(), SPEED_USE_GLOBAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
private FeedPreferences(long feedID, boolean autoDownload, boolean keepUpdated, AutoDeleteAction auto_delete_action, String username, String password, @NonNull FeedFilter filter, float feedPlaybackSpeed) {
|
private FeedPreferences(long feedID, boolean autoDownload, boolean keepUpdated, AutoDeleteAction auto_delete_action, VolumeAdaptionSetting volumeAdaptionSetting, String username, String password, @NonNull FeedFilter filter, float feedPlaybackSpeed) {
|
||||||
this.feedID = feedID;
|
this.feedID = feedID;
|
||||||
this.autoDownload = autoDownload;
|
this.autoDownload = autoDownload;
|
||||||
this.keepUpdated = keepUpdated;
|
this.keepUpdated = keepUpdated;
|
||||||
this.auto_delete_action = auto_delete_action;
|
this.auto_delete_action = auto_delete_action;
|
||||||
|
this.volumeAdaptionSetting = volumeAdaptionSetting;
|
||||||
this.username = username;
|
this.username = username;
|
||||||
this.password = password;
|
this.password = password;
|
||||||
this.filter = filter;
|
this.filter = filter;
|
||||||
|
@ -52,6 +56,7 @@ public class FeedPreferences {
|
||||||
int indexAutoDownload = cursor.getColumnIndex(PodDBAdapter.KEY_AUTO_DOWNLOAD);
|
int indexAutoDownload = cursor.getColumnIndex(PodDBAdapter.KEY_AUTO_DOWNLOAD);
|
||||||
int indexAutoRefresh = cursor.getColumnIndex(PodDBAdapter.KEY_KEEP_UPDATED);
|
int indexAutoRefresh = cursor.getColumnIndex(PodDBAdapter.KEY_KEEP_UPDATED);
|
||||||
int indexAutoDeleteAction = cursor.getColumnIndex(PodDBAdapter.KEY_AUTO_DELETE_ACTION);
|
int indexAutoDeleteAction = cursor.getColumnIndex(PodDBAdapter.KEY_AUTO_DELETE_ACTION);
|
||||||
|
int indexVolumeAdaption = cursor.getColumnIndex(PodDBAdapter.KEY_FEED_VOLUME_ADAPTION);
|
||||||
int indexUsername = cursor.getColumnIndex(PodDBAdapter.KEY_USERNAME);
|
int indexUsername = cursor.getColumnIndex(PodDBAdapter.KEY_USERNAME);
|
||||||
int indexPassword = cursor.getColumnIndex(PodDBAdapter.KEY_PASSWORD);
|
int indexPassword = cursor.getColumnIndex(PodDBAdapter.KEY_PASSWORD);
|
||||||
int indexIncludeFilter = cursor.getColumnIndex(PodDBAdapter.KEY_INCLUDE_FILTER);
|
int indexIncludeFilter = cursor.getColumnIndex(PodDBAdapter.KEY_INCLUDE_FILTER);
|
||||||
|
@ -63,12 +68,14 @@ public class FeedPreferences {
|
||||||
boolean autoRefresh = cursor.getInt(indexAutoRefresh) > 0;
|
boolean autoRefresh = cursor.getInt(indexAutoRefresh) > 0;
|
||||||
int autoDeleteActionIndex = cursor.getInt(indexAutoDeleteAction);
|
int autoDeleteActionIndex = cursor.getInt(indexAutoDeleteAction);
|
||||||
AutoDeleteAction autoDeleteAction = AutoDeleteAction.values()[autoDeleteActionIndex];
|
AutoDeleteAction autoDeleteAction = AutoDeleteAction.values()[autoDeleteActionIndex];
|
||||||
|
int volumeAdaptionValue = cursor.getInt(indexVolumeAdaption);
|
||||||
|
VolumeAdaptionSetting volumeAdaptionSetting = VolumeAdaptionSetting.fromInteger(volumeAdaptionValue);
|
||||||
String username = cursor.getString(indexUsername);
|
String username = cursor.getString(indexUsername);
|
||||||
String password = cursor.getString(indexPassword);
|
String password = cursor.getString(indexPassword);
|
||||||
String includeFilter = cursor.getString(indexIncludeFilter);
|
String includeFilter = cursor.getString(indexIncludeFilter);
|
||||||
String excludeFilter = cursor.getString(indexExcludeFilter);
|
String excludeFilter = cursor.getString(indexExcludeFilter);
|
||||||
float feedPlaybackSpeed = cursor.getFloat(indexFeedPlaybackSpeed);
|
float feedPlaybackSpeed = cursor.getFloat(indexFeedPlaybackSpeed);
|
||||||
return new FeedPreferences(feedId, autoDownload, autoRefresh, autoDeleteAction, username, password, new FeedFilter(includeFilter, excludeFilter), feedPlaybackSpeed);
|
return new FeedPreferences(feedId, autoDownload, autoRefresh, autoDeleteAction, volumeAdaptionSetting, username, password, new FeedFilter(includeFilter, excludeFilter), feedPlaybackSpeed);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -144,10 +151,18 @@ public class FeedPreferences {
|
||||||
return auto_delete_action;
|
return auto_delete_action;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public VolumeAdaptionSetting getVolumeAdaptionSetting() {
|
||||||
|
return volumeAdaptionSetting;
|
||||||
|
}
|
||||||
|
|
||||||
public void setAutoDeleteAction(AutoDeleteAction auto_delete_action) {
|
public void setAutoDeleteAction(AutoDeleteAction auto_delete_action) {
|
||||||
this.auto_delete_action = auto_delete_action;
|
this.auto_delete_action = auto_delete_action;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setVolumeAdaptionSetting(VolumeAdaptionSetting volumeAdaptionSetting) {
|
||||||
|
this.volumeAdaptionSetting = volumeAdaptionSetting;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean getCurrentAutoDelete() {
|
public boolean getCurrentAutoDelete() {
|
||||||
switch (auto_delete_action) {
|
switch (auto_delete_action) {
|
||||||
case GLOBAL:
|
case GLOBAL:
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
package de.danoeh.antennapod.core.feed;
|
||||||
|
|
||||||
|
public enum VolumeAdaptionSetting {
|
||||||
|
OFF(0, 1.0f),
|
||||||
|
LIGHT_REDUCTION(1, 0.5f),
|
||||||
|
HEAVY_REDUCTION(2, 0.2f);
|
||||||
|
|
||||||
|
private final int value;
|
||||||
|
private float adaptionFactor;
|
||||||
|
|
||||||
|
VolumeAdaptionSetting(int value, float adaptionFactor) {
|
||||||
|
this.value = value;
|
||||||
|
this.adaptionFactor = adaptionFactor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static VolumeAdaptionSetting fromInteger(int value) {
|
||||||
|
for (VolumeAdaptionSetting setting : values()) {
|
||||||
|
if (setting.value == value) {
|
||||||
|
return setting;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("Cannot map value to VolumeAdaptionSetting: " + value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int toInteger() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getAdaptionFactor() {
|
||||||
|
return adaptionFactor;
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,6 +4,7 @@ import android.util.Log;
|
||||||
import de.danoeh.antennapod.core.feed.Feed;
|
import de.danoeh.antennapod.core.feed.Feed;
|
||||||
import de.danoeh.antennapod.core.feed.FeedItem;
|
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||||
import de.danoeh.antennapod.core.feed.FeedPreferences;
|
import de.danoeh.antennapod.core.feed.FeedPreferences;
|
||||||
|
import de.danoeh.antennapod.core.feed.VolumeAdaptionSetting;
|
||||||
import de.danoeh.antennapod.core.service.download.DownloadRequest;
|
import de.danoeh.antennapod.core.service.download.DownloadRequest;
|
||||||
import de.danoeh.antennapod.core.service.download.DownloadStatus;
|
import de.danoeh.antennapod.core.service.download.DownloadStatus;
|
||||||
import de.danoeh.antennapod.core.storage.DownloadRequester;
|
import de.danoeh.antennapod.core.storage.DownloadRequester;
|
||||||
|
@ -37,7 +38,7 @@ public class FeedParserTask implements Callable<FeedHandlerResult> {
|
||||||
feed.setId(request.getFeedfileId());
|
feed.setId(request.getFeedfileId());
|
||||||
feed.setDownloaded(true);
|
feed.setDownloaded(true);
|
||||||
feed.setPreferences(new FeedPreferences(0, true, FeedPreferences.AutoDeleteAction.GLOBAL,
|
feed.setPreferences(new FeedPreferences(0, true, FeedPreferences.AutoDeleteAction.GLOBAL,
|
||||||
request.getUsername(), request.getPassword()));
|
VolumeAdaptionSetting.OFF, request.getUsername(), request.getPassword()));
|
||||||
feed.setPageNr(request.getArguments().getInt(DownloadRequester.REQUEST_ARG_PAGE_NR, 0));
|
feed.setPageNr(request.getArguments().getInt(DownloadRequester.REQUEST_ARG_PAGE_NR, 0));
|
||||||
|
|
||||||
DownloadError reason = null;
|
DownloadError reason = null;
|
||||||
|
|
|
@ -12,11 +12,11 @@ import android.util.Log;
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
import android.view.SurfaceHolder;
|
import android.view.SurfaceHolder;
|
||||||
|
|
||||||
import de.danoeh.antennapod.core.util.playback.PlaybackServiceStarter;
|
|
||||||
import org.antennapod.audio.MediaPlayer;
|
import org.antennapod.audio.MediaPlayer;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.EnumSet;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.FutureTask;
|
import java.util.concurrent.FutureTask;
|
||||||
|
@ -26,13 +26,17 @@ import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
|
import de.danoeh.antennapod.core.feed.FeedMedia;
|
||||||
|
import de.danoeh.antennapod.core.feed.FeedPreferences;
|
||||||
import de.danoeh.antennapod.core.feed.MediaType;
|
import de.danoeh.antennapod.core.feed.MediaType;
|
||||||
|
import de.danoeh.antennapod.core.feed.VolumeAdaptionSetting;
|
||||||
import de.danoeh.antennapod.core.feed.util.PlaybackSpeedUtils;
|
import de.danoeh.antennapod.core.feed.util.PlaybackSpeedUtils;
|
||||||
import de.danoeh.antennapod.core.preferences.UserPreferences;
|
import de.danoeh.antennapod.core.preferences.UserPreferences;
|
||||||
import de.danoeh.antennapod.core.util.RewindAfterPauseUtils;
|
import de.danoeh.antennapod.core.util.RewindAfterPauseUtils;
|
||||||
import de.danoeh.antennapod.core.util.playback.AudioPlayer;
|
import de.danoeh.antennapod.core.util.playback.AudioPlayer;
|
||||||
import de.danoeh.antennapod.core.util.playback.IPlayer;
|
import de.danoeh.antennapod.core.util.playback.IPlayer;
|
||||||
import de.danoeh.antennapod.core.util.playback.Playable;
|
import de.danoeh.antennapod.core.util.playback.Playable;
|
||||||
|
import de.danoeh.antennapod.core.util.playback.PlaybackServiceStarter;
|
||||||
import de.danoeh.antennapod.core.util.playback.VideoPlayer;
|
import de.danoeh.antennapod.core.util.playback.VideoPlayer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -308,7 +312,10 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
|
||||||
acquireWifiLockIfNecessary();
|
acquireWifiLockIfNecessary();
|
||||||
|
|
||||||
setPlaybackParams(PlaybackSpeedUtils.getCurrentPlaybackSpeed(media), UserPreferences.isSkipSilence());
|
setPlaybackParams(PlaybackSpeedUtils.getCurrentPlaybackSpeed(media), UserPreferences.isSkipSilence());
|
||||||
setVolume(UserPreferences.getLeftVolume(), UserPreferences.getRightVolume());
|
|
||||||
|
float leftVolume = UserPreferences.getLeftVolume();
|
||||||
|
float rightVolume = UserPreferences.getRightVolume();
|
||||||
|
setVolume(leftVolume, rightVolume);
|
||||||
|
|
||||||
if (playerStatus == PlayerStatus.PREPARED && media.getPosition() > 0) {
|
if (playerStatus == PlayerStatus.PREPARED && media.getPosition() > 0) {
|
||||||
int newPosition = RewindAfterPauseUtils.calculatePositionWithRewind(
|
int newPosition = RewindAfterPauseUtils.calculatePositionWithRewind(
|
||||||
|
@ -661,6 +668,15 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
|
||||||
*/
|
*/
|
||||||
private void setVolumeSync(float volumeLeft, float volumeRight) {
|
private void setVolumeSync(float volumeLeft, float volumeRight) {
|
||||||
playerLock.lock();
|
playerLock.lock();
|
||||||
|
Playable playable = getPlayable();
|
||||||
|
if (playable instanceof FeedMedia) {
|
||||||
|
FeedMedia feedMedia = (FeedMedia) playable;
|
||||||
|
FeedPreferences preferences = feedMedia.getItem().getFeed().getPreferences();
|
||||||
|
VolumeAdaptionSetting volumeAdaptionSetting = preferences.getVolumeAdaptionSetting();
|
||||||
|
float adaptionFactor = volumeAdaptionSetting.getAdaptionFactor();
|
||||||
|
volumeLeft *= adaptionFactor;
|
||||||
|
volumeRight *= adaptionFactor;
|
||||||
|
}
|
||||||
mediaPlayer.setVolume(volumeLeft, volumeRight);
|
mediaPlayer.setVolume(volumeLeft, volumeRight);
|
||||||
Log.d(TAG, "Media player volume was set to " + volumeLeft + " " + volumeRight);
|
Log.d(TAG, "Media player volume was set to " + volumeLeft + " " + volumeRight);
|
||||||
playerLock.unlock();
|
playerLock.unlock();
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package de.danoeh.antennapod.core.service.playback;
|
package de.danoeh.antennapod.core.service.playback;
|
||||||
|
|
||||||
import android.app.Notification;
|
|
||||||
import android.app.NotificationManager;
|
import android.app.NotificationManager;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.app.Service;
|
import android.app.Service;
|
||||||
|
@ -51,6 +50,7 @@ import de.danoeh.antennapod.core.R;
|
||||||
import de.danoeh.antennapod.core.event.MessageEvent;
|
import de.danoeh.antennapod.core.event.MessageEvent;
|
||||||
import de.danoeh.antennapod.core.event.PlaybackPositionEvent;
|
import de.danoeh.antennapod.core.event.PlaybackPositionEvent;
|
||||||
import de.danoeh.antennapod.core.event.ServiceEvent;
|
import de.danoeh.antennapod.core.event.ServiceEvent;
|
||||||
|
import de.danoeh.antennapod.core.event.settings.VolumeAdaptionChangedEvent;
|
||||||
import de.danoeh.antennapod.core.feed.Chapter;
|
import de.danoeh.antennapod.core.feed.Chapter;
|
||||||
import de.danoeh.antennapod.core.feed.Feed;
|
import de.danoeh.antennapod.core.feed.Feed;
|
||||||
import de.danoeh.antennapod.core.feed.FeedItem;
|
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||||
|
@ -70,7 +70,6 @@ import de.danoeh.antennapod.core.storage.FeedSearcher;
|
||||||
import de.danoeh.antennapod.core.feed.util.ImageResourceUtils;
|
import de.danoeh.antennapod.core.feed.util.ImageResourceUtils;
|
||||||
import de.danoeh.antennapod.core.util.IntentUtils;
|
import de.danoeh.antennapod.core.util.IntentUtils;
|
||||||
import de.danoeh.antennapod.core.util.NetworkUtils;
|
import de.danoeh.antennapod.core.util.NetworkUtils;
|
||||||
import de.danoeh.antennapod.core.util.QueueAccess;
|
|
||||||
import de.danoeh.antennapod.core.util.gui.NotificationUtils;
|
import de.danoeh.antennapod.core.util.gui.NotificationUtils;
|
||||||
import de.danoeh.antennapod.core.util.playback.ExternalMedia;
|
import de.danoeh.antennapod.core.util.playback.ExternalMedia;
|
||||||
import de.danoeh.antennapod.core.util.playback.Playable;
|
import de.danoeh.antennapod.core.util.playback.Playable;
|
||||||
|
@ -79,6 +78,7 @@ import io.reactivex.Observable;
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||||
import io.reactivex.disposables.Disposable;
|
import io.reactivex.disposables.Disposable;
|
||||||
import org.greenrobot.eventbus.EventBus;
|
import org.greenrobot.eventbus.EventBus;
|
||||||
|
import org.greenrobot.eventbus.Subscribe;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Controls the MediaPlayer that plays a FeedMedia-file
|
* Controls the MediaPlayer that plays a FeedMedia-file
|
||||||
|
@ -277,6 +277,7 @@ public class PlaybackService extends MediaBrowserServiceCompat {
|
||||||
registerReceiver(audioBecomingNoisy, new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY));
|
registerReceiver(audioBecomingNoisy, new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY));
|
||||||
registerReceiver(skipCurrentEpisodeReceiver, new IntentFilter(ACTION_SKIP_CURRENT_EPISODE));
|
registerReceiver(skipCurrentEpisodeReceiver, new IntentFilter(ACTION_SKIP_CURRENT_EPISODE));
|
||||||
registerReceiver(pausePlayCurrentEpisodeReceiver, new IntentFilter(ACTION_PAUSE_PLAY_CURRENT_EPISODE));
|
registerReceiver(pausePlayCurrentEpisodeReceiver, new IntentFilter(ACTION_PAUSE_PLAY_CURRENT_EPISODE));
|
||||||
|
EventBus.getDefault().register(this);
|
||||||
taskManager = new PlaybackServiceTaskManager(this, taskManagerCallback);
|
taskManager = new PlaybackServiceTaskManager(this, taskManagerCallback);
|
||||||
|
|
||||||
flavorHelper = new PlaybackServiceFlavorHelper(PlaybackService.this, flavorHelperCallback);
|
flavorHelper = new PlaybackServiceFlavorHelper(PlaybackService.this, flavorHelperCallback);
|
||||||
|
@ -1436,6 +1437,12 @@ public class PlaybackService extends MediaBrowserServiceCompat {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void volumeAdaptionChanged(VolumeAdaptionChangedEvent event) {
|
||||||
|
PlaybackVolumeUpdater playbackVolumeUpdater = new PlaybackVolumeUpdater();
|
||||||
|
playbackVolumeUpdater.updateVolumeIfNecessary(mediaPlayer, event.getFeedId(), event.getVolumeAdaptionSetting());
|
||||||
|
}
|
||||||
|
|
||||||
public static MediaType getCurrentMediaType() {
|
public static MediaType getCurrentMediaType() {
|
||||||
return currentMediaType;
|
return currentMediaType;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
package de.danoeh.antennapod.core.service.playback;
|
||||||
|
|
||||||
|
import de.danoeh.antennapod.core.feed.FeedMedia;
|
||||||
|
import de.danoeh.antennapod.core.feed.FeedPreferences;
|
||||||
|
import de.danoeh.antennapod.core.feed.VolumeAdaptionSetting;
|
||||||
|
import de.danoeh.antennapod.core.util.playback.Playable;
|
||||||
|
|
||||||
|
class PlaybackVolumeUpdater {
|
||||||
|
|
||||||
|
public void updateVolumeIfNecessary(PlaybackServiceMediaPlayer mediaPlayer, long feedId,
|
||||||
|
VolumeAdaptionSetting volumeAdaptionSetting) {
|
||||||
|
Playable playable = mediaPlayer.getPlayable();
|
||||||
|
|
||||||
|
if (playable instanceof FeedMedia) {
|
||||||
|
updateFeedMediaVolumeIfNecessary(mediaPlayer, feedId, volumeAdaptionSetting, (FeedMedia) playable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateFeedMediaVolumeIfNecessary(PlaybackServiceMediaPlayer mediaPlayer, long feedId,
|
||||||
|
VolumeAdaptionSetting volumeAdaptionSetting, FeedMedia feedMedia) {
|
||||||
|
if (feedMedia.getItem().getFeed().getId() == feedId) {
|
||||||
|
FeedPreferences preferences = feedMedia.getItem().getFeed().getPreferences();
|
||||||
|
preferences.setVolumeAdaptionSetting(volumeAdaptionSetting);
|
||||||
|
|
||||||
|
if (mediaPlayer.getPlayerStatus() == PlayerStatus.PLAYING) {
|
||||||
|
forceUpdateVolume(mediaPlayer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void forceUpdateVolume(PlaybackServiceMediaPlayer mediaPlayer) {
|
||||||
|
mediaPlayer.pause(false, false);
|
||||||
|
mediaPlayer.resume();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -294,11 +294,14 @@ class DBUpgrader {
|
||||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
|
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
|
||||||
+ " ADD COLUMN " + PodDBAdapter.KEY_FEED_PLAYBACK_SPEED + " REAL DEFAULT " + SPEED_USE_GLOBAL);
|
+ " ADD COLUMN " + PodDBAdapter.KEY_FEED_PLAYBACK_SPEED + " REAL DEFAULT " + SPEED_USE_GLOBAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (oldVersion < 1070401) {
|
if (oldVersion < 1070401) {
|
||||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
|
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
|
||||||
+ " ADD COLUMN " + PodDBAdapter.KEY_SORT_ORDER + " TEXT");
|
+ " ADD COLUMN " + PodDBAdapter.KEY_SORT_ORDER + " TEXT");
|
||||||
}
|
}
|
||||||
|
if (oldVersion < 1090000) {
|
||||||
|
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
|
||||||
|
+ " ADD COLUMN " + PodDBAdapter.KEY_FEED_VOLUME_ADAPTION + " INTEGER DEFAULT 0");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,6 @@ import android.database.SQLException;
|
||||||
import android.database.sqlite.SQLiteDatabase;
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
import android.database.sqlite.SQLiteDatabase.CursorFactory;
|
import android.database.sqlite.SQLiteDatabase.CursorFactory;
|
||||||
import android.database.sqlite.SQLiteOpenHelper;
|
import android.database.sqlite.SQLiteOpenHelper;
|
||||||
import android.os.Build;
|
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
@ -97,6 +96,7 @@ public class PodDBAdapter {
|
||||||
public static final String KEY_AUTO_DOWNLOAD = "auto_download";
|
public static final String KEY_AUTO_DOWNLOAD = "auto_download";
|
||||||
public static final String KEY_KEEP_UPDATED = "keep_updated";
|
public static final String KEY_KEEP_UPDATED = "keep_updated";
|
||||||
public static final String KEY_AUTO_DELETE_ACTION = "auto_delete_action";
|
public static final String KEY_AUTO_DELETE_ACTION = "auto_delete_action";
|
||||||
|
public static final String KEY_FEED_VOLUME_ADAPTION = "feed_volume_adaption";
|
||||||
public static final String KEY_PLAYED_DURATION = "played_duration";
|
public static final String KEY_PLAYED_DURATION = "played_duration";
|
||||||
public static final String KEY_USERNAME = "username";
|
public static final String KEY_USERNAME = "username";
|
||||||
public static final String KEY_PASSWORD = "password";
|
public static final String KEY_PASSWORD = "password";
|
||||||
|
@ -144,7 +144,8 @@ public class PodDBAdapter {
|
||||||
+ KEY_SORT_ORDER + " TEXT,"
|
+ KEY_SORT_ORDER + " TEXT,"
|
||||||
+ KEY_LAST_UPDATE_FAILED + " INTEGER DEFAULT 0,"
|
+ KEY_LAST_UPDATE_FAILED + " INTEGER DEFAULT 0,"
|
||||||
+ KEY_AUTO_DELETE_ACTION + " INTEGER DEFAULT 0,"
|
+ KEY_AUTO_DELETE_ACTION + " INTEGER DEFAULT 0,"
|
||||||
+ KEY_FEED_PLAYBACK_SPEED + " REAL DEFAULT " + SPEED_USE_GLOBAL + ")";
|
+ KEY_FEED_PLAYBACK_SPEED + " REAL DEFAULT " + SPEED_USE_GLOBAL + ","
|
||||||
|
+ KEY_FEED_VOLUME_ADAPTION + " INTEGER DEFAULT 0)";
|
||||||
|
|
||||||
private static final String CREATE_TABLE_FEED_ITEMS = "CREATE TABLE "
|
private static final String CREATE_TABLE_FEED_ITEMS = "CREATE TABLE "
|
||||||
+ TABLE_NAME_FEED_ITEMS + " (" + TABLE_PRIMARY_KEY + KEY_TITLE
|
+ TABLE_NAME_FEED_ITEMS + " (" + TABLE_PRIMARY_KEY + KEY_TITLE
|
||||||
|
@ -241,6 +242,7 @@ public class PodDBAdapter {
|
||||||
TABLE_NAME_FEEDS + "." + KEY_SORT_ORDER,
|
TABLE_NAME_FEEDS + "." + KEY_SORT_ORDER,
|
||||||
TABLE_NAME_FEEDS + "." + KEY_LAST_UPDATE_FAILED,
|
TABLE_NAME_FEEDS + "." + KEY_LAST_UPDATE_FAILED,
|
||||||
TABLE_NAME_FEEDS + "." + KEY_AUTO_DELETE_ACTION,
|
TABLE_NAME_FEEDS + "." + KEY_AUTO_DELETE_ACTION,
|
||||||
|
TABLE_NAME_FEEDS + "." + KEY_FEED_VOLUME_ADAPTION,
|
||||||
TABLE_NAME_FEEDS + "." + KEY_INCLUDE_FILTER,
|
TABLE_NAME_FEEDS + "." + KEY_INCLUDE_FILTER,
|
||||||
TABLE_NAME_FEEDS + "." + KEY_EXCLUDE_FILTER,
|
TABLE_NAME_FEEDS + "." + KEY_EXCLUDE_FILTER,
|
||||||
TABLE_NAME_FEEDS + "." + KEY_FEED_PLAYBACK_SPEED
|
TABLE_NAME_FEEDS + "." + KEY_FEED_PLAYBACK_SPEED
|
||||||
|
@ -403,6 +405,7 @@ public class PodDBAdapter {
|
||||||
values.put(KEY_AUTO_DOWNLOAD, prefs.getAutoDownload());
|
values.put(KEY_AUTO_DOWNLOAD, prefs.getAutoDownload());
|
||||||
values.put(KEY_KEEP_UPDATED, prefs.getKeepUpdated());
|
values.put(KEY_KEEP_UPDATED, prefs.getKeepUpdated());
|
||||||
values.put(KEY_AUTO_DELETE_ACTION, prefs.getAutoDeleteAction().ordinal());
|
values.put(KEY_AUTO_DELETE_ACTION, prefs.getAutoDeleteAction().ordinal());
|
||||||
|
values.put(KEY_FEED_VOLUME_ADAPTION, prefs.getVolumeAdaptionSetting().toInteger());
|
||||||
values.put(KEY_USERNAME, prefs.getUsername());
|
values.put(KEY_USERNAME, prefs.getUsername());
|
||||||
values.put(KEY_PASSWORD, prefs.getPassword());
|
values.put(KEY_PASSWORD, prefs.getPassword());
|
||||||
values.put(KEY_INCLUDE_FILTER, prefs.getFilter().getIncludeFilter());
|
values.put(KEY_INCLUDE_FILTER, prefs.getFilter().getIncludeFilter());
|
||||||
|
@ -1333,10 +1336,7 @@ public class PodDBAdapter {
|
||||||
* Helper class for opening the Antennapod database.
|
* Helper class for opening the Antennapod database.
|
||||||
*/
|
*/
|
||||||
private static class PodDBHelper extends SQLiteOpenHelper {
|
private static class PodDBHelper extends SQLiteOpenHelper {
|
||||||
|
private static final int VERSION = 1090000;
|
||||||
private static final int VERSION = 1070401;
|
|
||||||
|
|
||||||
private final Context context;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
|
@ -1348,7 +1348,6 @@ public class PodDBAdapter {
|
||||||
public PodDBHelper(final Context context, final String name,
|
public PodDBHelper(final Context context, final String name,
|
||||||
final CursorFactory factory) {
|
final CursorFactory factory) {
|
||||||
super(context, name, factory, VERSION, new PodDbErrorHandler());
|
super(context, name, factory, VERSION, new PodDbErrorHandler());
|
||||||
this.context = context;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1367,7 +1366,6 @@ public class PodDBAdapter {
|
||||||
db.execSQL(CREATE_INDEX_FEEDMEDIA_FEEDITEM);
|
db.execSQL(CREATE_INDEX_FEEDMEDIA_FEEDITEM);
|
||||||
db.execSQL(CREATE_INDEX_QUEUE_FEEDITEM);
|
db.execSQL(CREATE_INDEX_QUEUE_FEEDITEM);
|
||||||
db.execSQL(CREATE_INDEX_SIMPLECHAPTERS_FEEDITEM);
|
db.execSQL(CREATE_INDEX_SIMPLECHAPTERS_FEEDITEM);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF757575"
|
||||||
|
android:pathData="M14,3.23V5.29C16.89,6.15 19,8.83 19,12C19,15.17 16.89,17.84 14,18.7V20.77C18,19.86 21,16.28 21,12C21,7.72 18,4.14 14,3.23M16.5,12C16.5,10.23 15.5,8.71 14,7.97V16C15.5,15.29 16.5,13.76 16.5,12M3,9V15H7L12,20V4L7,9H3Z" />
|
||||||
|
</vector>
|
|
@ -0,0 +1,9 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFFFFFFF"
|
||||||
|
android:pathData="M14,3.23V5.29C16.89,6.15 19,8.83 19,12C19,15.17 16.89,17.84 14,18.7V20.77C18,19.86 21,16.28 21,12C21,7.72 18,4.14 14,3.23M16.5,12C16.5,10.23 15.5,8.71 14,7.97V16C15.5,15.29 16.5,13.76 16.5,12M3,9V15H7L12,20V4L7,9H3Z" />
|
||||||
|
</vector>
|
|
@ -13,6 +13,18 @@
|
||||||
<item>never</item>
|
<item>never</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="spnVolumeReductionItems">
|
||||||
|
<item>@string/feed_volume_reduction_off</item>
|
||||||
|
<item>@string/feed_volume_reduction_light</item>
|
||||||
|
<item>@string/feed_volume_reduction_heavy</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="spnVolumeReductionValues">
|
||||||
|
<item>off</item>
|
||||||
|
<item>light</item>
|
||||||
|
<item>heavy</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
<string-array name="smart_mark_as_played_values">
|
<string-array name="smart_mark_as_played_values">
|
||||||
<item>0</item>
|
<item>0</item>
|
||||||
<item>15</item>
|
<item>15</item>
|
||||||
|
|
|
@ -52,6 +52,7 @@
|
||||||
<attr name="ic_select_none" format="reference"/>
|
<attr name="ic_select_none" format="reference"/>
|
||||||
<attr name="ic_sort" format="reference"/>
|
<attr name="ic_sort" format="reference"/>
|
||||||
<attr name="ic_key" format="reference"/>
|
<attr name="ic_key" format="reference"/>
|
||||||
|
<attr name="ic_volume_adaption" format="reference"/>
|
||||||
<attr name="ic_sd_storage" format="reference"/>
|
<attr name="ic_sd_storage" format="reference"/>
|
||||||
<attr name="ic_create_new_folder" format="reference"/>
|
<attr name="ic_create_new_folder" format="reference"/>
|
||||||
<attr name="ic_cast_disconnect" format="reference"/>
|
<attr name="ic_cast_disconnect" format="reference"/>
|
||||||
|
|
|
@ -96,6 +96,11 @@
|
||||||
<string name="auto_download_apply_to_items_title">Apply to Previous Episodes</string>
|
<string name="auto_download_apply_to_items_title">Apply to Previous Episodes</string>
|
||||||
<string name="auto_download_apply_to_items_message">The new <i>Auto Download</i> setting will automatically be applied to new episodes.\nDo you also want to apply it to previously published episodes?</string>
|
<string name="auto_download_apply_to_items_message">The new <i>Auto Download</i> setting will automatically be applied to new episodes.\nDo you also want to apply it to previously published episodes?</string>
|
||||||
<string name="auto_delete_label">Auto Delete Episode</string>
|
<string name="auto_delete_label">Auto Delete Episode</string>
|
||||||
|
<string name="feed_volume_reduction">Volume Reduction</string>
|
||||||
|
<string name="feed_volume_reduction_summary">Turn down volume for episodes of this feed: \%s</string>
|
||||||
|
<string name="feed_volume_reduction_off">Off</string>
|
||||||
|
<string name="feed_volume_reduction_light">Light</string>
|
||||||
|
<string name="feed_volume_reduction_heavy">Heavy</string>
|
||||||
<string name="parallel_downloads_suffix">\u0020parallel downloads</string>
|
<string name="parallel_downloads_suffix">\u0020parallel downloads</string>
|
||||||
<string name="feed_auto_download_global">Global default</string>
|
<string name="feed_auto_download_global">Global default</string>
|
||||||
<string name="feed_auto_download_always">Always</string>
|
<string name="feed_auto_download_always">Always</string>
|
||||||
|
|
|
@ -76,6 +76,7 @@
|
||||||
<item name="ic_bookmark">@drawable/ic_bookmark_grey600_24dp</item>
|
<item name="ic_bookmark">@drawable/ic_bookmark_grey600_24dp</item>
|
||||||
<item name="batch_edit_fab_icon">@drawable/ic_fab_edit_white</item>
|
<item name="batch_edit_fab_icon">@drawable/ic_fab_edit_white</item>
|
||||||
<item name="ic_key">@drawable/ic_key_grey600</item>
|
<item name="ic_key">@drawable/ic_key_grey600</item>
|
||||||
|
<item name="ic_volume_adaption">@drawable/ic_volume_adaption_grey</item>
|
||||||
<item name="master_switch_background">@color/master_switch_background_light</item>
|
<item name="master_switch_background">@color/master_switch_background_light</item>
|
||||||
<item name="currently_playing_background">@color/highlight_light</item>
|
<item name="currently_playing_background">@color/highlight_light</item>
|
||||||
|
|
||||||
|
@ -164,6 +165,7 @@
|
||||||
<item name="ic_bookmark">@drawable/ic_bookmark_white_24dp</item>
|
<item name="ic_bookmark">@drawable/ic_bookmark_white_24dp</item>
|
||||||
<item name="batch_edit_fab_icon">@drawable/ic_fab_edit_white</item>
|
<item name="batch_edit_fab_icon">@drawable/ic_fab_edit_white</item>
|
||||||
<item name="ic_key">@drawable/ic_key_white</item>
|
<item name="ic_key">@drawable/ic_key_white</item>
|
||||||
|
<item name="ic_volume_adaption">@drawable/ic_volume_adaption_white</item>
|
||||||
<item name="master_switch_background">@color/master_switch_background_dark</item>
|
<item name="master_switch_background">@color/master_switch_background_dark</item>
|
||||||
<item name="currently_playing_background">@color/highlight_dark</item>
|
<item name="currently_playing_background">@color/highlight_dark</item>
|
||||||
<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
|
<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
package de.danoeh.antennapod.core.feed;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
import static org.hamcrest.Matchers.is;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
public class VolumeAdaptionSettingTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void mapOffToInteger() {
|
||||||
|
VolumeAdaptionSetting setting = VolumeAdaptionSetting.OFF;
|
||||||
|
assertThat(setting.toInteger(), is(equalTo(0)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void mapLightReductionToInteger() {
|
||||||
|
VolumeAdaptionSetting setting = VolumeAdaptionSetting.LIGHT_REDUCTION;
|
||||||
|
|
||||||
|
assertThat(setting.toInteger(), is(equalTo(1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void mapHeavyReductionToInteger() {
|
||||||
|
VolumeAdaptionSetting setting = VolumeAdaptionSetting.HEAVY_REDUCTION;
|
||||||
|
|
||||||
|
assertThat(setting.toInteger(), is(equalTo(2)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void mapIntegerToVolumeAdaptionSetting() {
|
||||||
|
assertThat(VolumeAdaptionSetting.fromInteger(0), is(equalTo(VolumeAdaptionSetting.OFF)));
|
||||||
|
assertThat(VolumeAdaptionSetting.fromInteger(1), is(equalTo(VolumeAdaptionSetting.LIGHT_REDUCTION)));
|
||||||
|
assertThat(VolumeAdaptionSetting.fromInteger(2), is(equalTo(VolumeAdaptionSetting.HEAVY_REDUCTION)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void cannotMapNegativeValues() {
|
||||||
|
VolumeAdaptionSetting.fromInteger(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void cannotMapValuesOutOfRange() {
|
||||||
|
VolumeAdaptionSetting.fromInteger(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void noAdaptionIfTurnedOff() {
|
||||||
|
float adaptionFactor = VolumeAdaptionSetting.OFF.getAdaptionFactor();
|
||||||
|
assertEquals(1.0f, adaptionFactor, 0.01f);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void lightReductionYieldsHigherValueThanHeavyReduction() {
|
||||||
|
float lightReductionFactor = VolumeAdaptionSetting.LIGHT_REDUCTION.getAdaptionFactor();
|
||||||
|
|
||||||
|
float heavyReductionFactor = VolumeAdaptionSetting.HEAVY_REDUCTION.getAdaptionFactor();
|
||||||
|
|
||||||
|
assertTrue("Light reduction must have higher factor than heavy reduction", lightReductionFactor > heavyReductionFactor);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,225 @@
|
||||||
|
package de.danoeh.antennapod.core.service.playback;
|
||||||
|
|
||||||
|
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.FeedPreferences;
|
||||||
|
import de.danoeh.antennapod.core.feed.VolumeAdaptionSetting;
|
||||||
|
import de.danoeh.antennapod.core.util.playback.Playable;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.mockito.Mockito.anyBoolean;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.never;
|
||||||
|
import static org.mockito.Mockito.times;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
public class PlaybackVolumeUpdaterTest {
|
||||||
|
|
||||||
|
private static final long FEED_ID = 42;
|
||||||
|
|
||||||
|
private PlaybackServiceMediaPlayer mediaPlayer;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
mediaPlayer = mock(PlaybackServiceMediaPlayer.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void noChangeIfNoFeedMediaPlaying() {
|
||||||
|
PlaybackVolumeUpdater playbackVolumeUpdater = new PlaybackVolumeUpdater();
|
||||||
|
|
||||||
|
when(mediaPlayer.getPlayerStatus()).thenReturn(PlayerStatus.PAUSED);
|
||||||
|
|
||||||
|
Playable noFeedMedia = mock(Playable.class);
|
||||||
|
when(mediaPlayer.getPlayable()).thenReturn(noFeedMedia);
|
||||||
|
|
||||||
|
playbackVolumeUpdater.updateVolumeIfNecessary(mediaPlayer, FEED_ID, VolumeAdaptionSetting.OFF);
|
||||||
|
|
||||||
|
verify(mediaPlayer, never()).pause(anyBoolean(), anyBoolean());
|
||||||
|
verify(mediaPlayer, never()).resume();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void noChangeIfPlayerStatusIsError() {
|
||||||
|
PlaybackVolumeUpdater playbackVolumeUpdater = new PlaybackVolumeUpdater();
|
||||||
|
|
||||||
|
when(mediaPlayer.getPlayerStatus()).thenReturn(PlayerStatus.ERROR);
|
||||||
|
|
||||||
|
FeedMedia feedMedia = mockFeedMedia();
|
||||||
|
when(mediaPlayer.getPlayable()).thenReturn(feedMedia);
|
||||||
|
|
||||||
|
playbackVolumeUpdater.updateVolumeIfNecessary(mediaPlayer, FEED_ID, VolumeAdaptionSetting.OFF);
|
||||||
|
|
||||||
|
verify(mediaPlayer, never()).pause(anyBoolean(), anyBoolean());
|
||||||
|
verify(mediaPlayer, never()).resume();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void noChangeIfPlayerStatusIsIndeterminate() {
|
||||||
|
PlaybackVolumeUpdater playbackVolumeUpdater = new PlaybackVolumeUpdater();
|
||||||
|
|
||||||
|
when(mediaPlayer.getPlayerStatus()).thenReturn(PlayerStatus.INDETERMINATE);
|
||||||
|
|
||||||
|
FeedMedia feedMedia = mockFeedMedia();
|
||||||
|
when(mediaPlayer.getPlayable()).thenReturn(feedMedia);
|
||||||
|
|
||||||
|
playbackVolumeUpdater.updateVolumeIfNecessary(mediaPlayer, FEED_ID, VolumeAdaptionSetting.OFF);
|
||||||
|
|
||||||
|
verify(mediaPlayer, never()).pause(anyBoolean(), anyBoolean());
|
||||||
|
verify(mediaPlayer, never()).resume();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void noChangeIfPlayerStatusIsStopped() {
|
||||||
|
PlaybackVolumeUpdater playbackVolumeUpdater = new PlaybackVolumeUpdater();
|
||||||
|
|
||||||
|
when(mediaPlayer.getPlayerStatus()).thenReturn(PlayerStatus.STOPPED);
|
||||||
|
|
||||||
|
FeedMedia feedMedia = mockFeedMedia();
|
||||||
|
when(mediaPlayer.getPlayable()).thenReturn(feedMedia);
|
||||||
|
|
||||||
|
playbackVolumeUpdater.updateVolumeIfNecessary(mediaPlayer, FEED_ID, VolumeAdaptionSetting.OFF);
|
||||||
|
|
||||||
|
verify(mediaPlayer, never()).pause(anyBoolean(), anyBoolean());
|
||||||
|
verify(mediaPlayer, never()).resume();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void noChangeIfPlayableIsNoItemOfAffectedFeed() {
|
||||||
|
when(mediaPlayer.getPlayerStatus()).thenReturn(PlayerStatus.PLAYING);
|
||||||
|
|
||||||
|
FeedMedia feedMedia = mockFeedMedia();
|
||||||
|
when(mediaPlayer.getPlayable()).thenReturn(feedMedia);
|
||||||
|
when(feedMedia.getItem().getFeed().getId()).thenReturn(FEED_ID + 1);
|
||||||
|
|
||||||
|
PlaybackVolumeUpdater playbackVolumeUpdater = new PlaybackVolumeUpdater();
|
||||||
|
playbackVolumeUpdater.updateVolumeIfNecessary(mediaPlayer, FEED_ID, VolumeAdaptionSetting.OFF);
|
||||||
|
|
||||||
|
verify(mediaPlayer, never()).pause(anyBoolean(), anyBoolean());
|
||||||
|
verify(mediaPlayer, never()).resume();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void updatesPreferencesForLoadedFeedMediaIfPlayerStatusIsPaused() {
|
||||||
|
PlaybackVolumeUpdater playbackVolumeUpdater = new PlaybackVolumeUpdater();
|
||||||
|
|
||||||
|
when(mediaPlayer.getPlayerStatus()).thenReturn(PlayerStatus.PAUSED);
|
||||||
|
|
||||||
|
FeedMedia feedMedia = mockFeedMedia();
|
||||||
|
when(mediaPlayer.getPlayable()).thenReturn(feedMedia);
|
||||||
|
FeedPreferences feedPreferences = feedMedia.getItem().getFeed().getPreferences();
|
||||||
|
|
||||||
|
playbackVolumeUpdater.updateVolumeIfNecessary(mediaPlayer, FEED_ID, VolumeAdaptionSetting.LIGHT_REDUCTION);
|
||||||
|
|
||||||
|
verify(feedPreferences, times(1)).setVolumeAdaptionSetting(VolumeAdaptionSetting.LIGHT_REDUCTION);
|
||||||
|
|
||||||
|
verify(mediaPlayer, never()).pause(anyBoolean(), anyBoolean());
|
||||||
|
verify(mediaPlayer, never()).resume();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void updatesPreferencesForLoadedFeedMediaIfPlayerStatusIsPrepared() {
|
||||||
|
PlaybackVolumeUpdater playbackVolumeUpdater = new PlaybackVolumeUpdater();
|
||||||
|
|
||||||
|
when(mediaPlayer.getPlayerStatus()).thenReturn(PlayerStatus.PREPARED);
|
||||||
|
|
||||||
|
FeedMedia feedMedia = mockFeedMedia();
|
||||||
|
when(mediaPlayer.getPlayable()).thenReturn(feedMedia);
|
||||||
|
FeedPreferences feedPreferences = feedMedia.getItem().getFeed().getPreferences();
|
||||||
|
|
||||||
|
playbackVolumeUpdater.updateVolumeIfNecessary(mediaPlayer, FEED_ID, VolumeAdaptionSetting.LIGHT_REDUCTION);
|
||||||
|
|
||||||
|
verify(feedPreferences, times(1)).setVolumeAdaptionSetting(VolumeAdaptionSetting.LIGHT_REDUCTION);
|
||||||
|
|
||||||
|
verify(mediaPlayer, never()).pause(anyBoolean(), anyBoolean());
|
||||||
|
verify(mediaPlayer, never()).resume();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void updatesPreferencesForLoadedFeedMediaIfPlayerStatusIsInitializing() {
|
||||||
|
PlaybackVolumeUpdater playbackVolumeUpdater = new PlaybackVolumeUpdater();
|
||||||
|
|
||||||
|
when(mediaPlayer.getPlayerStatus()).thenReturn(PlayerStatus.INITIALIZING);
|
||||||
|
|
||||||
|
FeedMedia feedMedia = mockFeedMedia();
|
||||||
|
when(mediaPlayer.getPlayable()).thenReturn(feedMedia);
|
||||||
|
FeedPreferences feedPreferences = feedMedia.getItem().getFeed().getPreferences();
|
||||||
|
|
||||||
|
playbackVolumeUpdater.updateVolumeIfNecessary(mediaPlayer, FEED_ID, VolumeAdaptionSetting.LIGHT_REDUCTION);
|
||||||
|
|
||||||
|
verify(feedPreferences, times(1)).setVolumeAdaptionSetting(VolumeAdaptionSetting.LIGHT_REDUCTION);
|
||||||
|
|
||||||
|
verify(mediaPlayer, never()).pause(anyBoolean(), anyBoolean());
|
||||||
|
verify(mediaPlayer, never()).resume();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void updatesPreferencesForLoadedFeedMediaIfPlayerStatusIsPreparing() {
|
||||||
|
PlaybackVolumeUpdater playbackVolumeUpdater = new PlaybackVolumeUpdater();
|
||||||
|
|
||||||
|
when(mediaPlayer.getPlayerStatus()).thenReturn(PlayerStatus.PREPARING);
|
||||||
|
|
||||||
|
FeedMedia feedMedia = mockFeedMedia();
|
||||||
|
when(mediaPlayer.getPlayable()).thenReturn(feedMedia);
|
||||||
|
FeedPreferences feedPreferences = feedMedia.getItem().getFeed().getPreferences();
|
||||||
|
|
||||||
|
playbackVolumeUpdater.updateVolumeIfNecessary(mediaPlayer, FEED_ID, VolumeAdaptionSetting.LIGHT_REDUCTION);
|
||||||
|
|
||||||
|
verify(feedPreferences, times(1)).setVolumeAdaptionSetting(VolumeAdaptionSetting.LIGHT_REDUCTION);
|
||||||
|
|
||||||
|
verify(mediaPlayer, never()).pause(anyBoolean(), anyBoolean());
|
||||||
|
verify(mediaPlayer, never()).resume();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void updatesPreferencesForLoadedFeedMediaIfPlayerStatusIsSeeking() {
|
||||||
|
PlaybackVolumeUpdater playbackVolumeUpdater = new PlaybackVolumeUpdater();
|
||||||
|
|
||||||
|
when(mediaPlayer.getPlayerStatus()).thenReturn(PlayerStatus.SEEKING);
|
||||||
|
|
||||||
|
FeedMedia feedMedia = mockFeedMedia();
|
||||||
|
when(mediaPlayer.getPlayable()).thenReturn(feedMedia);
|
||||||
|
FeedPreferences feedPreferences = feedMedia.getItem().getFeed().getPreferences();
|
||||||
|
|
||||||
|
playbackVolumeUpdater.updateVolumeIfNecessary(mediaPlayer, FEED_ID, VolumeAdaptionSetting.LIGHT_REDUCTION);
|
||||||
|
|
||||||
|
verify(feedPreferences, times(1)).setVolumeAdaptionSetting(VolumeAdaptionSetting.LIGHT_REDUCTION);
|
||||||
|
|
||||||
|
verify(mediaPlayer, never()).pause(anyBoolean(), anyBoolean());
|
||||||
|
verify(mediaPlayer, never()).resume();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void updatesPreferencesAndForcesVolumeChangeForLoadedFeedMediaIfPlayerStatusIsPlaying() {
|
||||||
|
PlaybackVolumeUpdater playbackVolumeUpdater = new PlaybackVolumeUpdater();
|
||||||
|
|
||||||
|
when(mediaPlayer.getPlayerStatus()).thenReturn(PlayerStatus.PLAYING);
|
||||||
|
|
||||||
|
FeedMedia feedMedia = mockFeedMedia();
|
||||||
|
when(mediaPlayer.getPlayable()).thenReturn(feedMedia);
|
||||||
|
FeedPreferences feedPreferences = feedMedia.getItem().getFeed().getPreferences();
|
||||||
|
|
||||||
|
playbackVolumeUpdater.updateVolumeIfNecessary(mediaPlayer, FEED_ID, VolumeAdaptionSetting.HEAVY_REDUCTION);
|
||||||
|
|
||||||
|
verify(feedPreferences, times(1)).setVolumeAdaptionSetting(VolumeAdaptionSetting.HEAVY_REDUCTION);
|
||||||
|
|
||||||
|
verify(mediaPlayer, times(1)).pause(false, false);
|
||||||
|
verify(mediaPlayer, times(1)).resume();
|
||||||
|
}
|
||||||
|
|
||||||
|
private FeedMedia mockFeedMedia() {
|
||||||
|
FeedMedia feedMedia = mock(FeedMedia.class);
|
||||||
|
FeedItem feedItem = mock(FeedItem.class);
|
||||||
|
Feed feed = mock(Feed.class);
|
||||||
|
FeedPreferences feedPreferences = mock(FeedPreferences.class);
|
||||||
|
|
||||||
|
when(feedMedia.getItem()).thenReturn(feedItem);
|
||||||
|
when(feedItem.getFeed()).thenReturn(feed);
|
||||||
|
when(feed.getId()).thenReturn(FEED_ID);
|
||||||
|
when(feed.getPreferences()).thenReturn(feedPreferences);
|
||||||
|
return feedMedia;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue