Further clean up DownloadActions + DownloadActivity
- Made parts of DownloadActions public that were previously hidden. This is necessary so that when an app is listening to the DownloadManager, it can tell something about the tasks. - Simplified DownloadActivity some more. The helpers may migrate into their corresponding modules at some point, and also be converted to return structured TrackGroupArrays rather than a flat list of Formats. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=195269824
This commit is contained in:
parent
5a1431c904
commit
c5bf7f4513
@ -20,15 +20,14 @@ import static com.google.android.exoplayer2.demo.PlayerActivity.EXTENSION_EXTRA;
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcelable;
|
||||
import android.util.SparseBooleanArray;
|
||||
import android.view.View;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.ListView;
|
||||
import android.widget.Toast;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.Format;
|
||||
import com.google.android.exoplayer2.offline.DownloadAction;
|
||||
import com.google.android.exoplayer2.offline.DownloadService;
|
||||
import com.google.android.exoplayer2.offline.ProgressiveDownloadAction;
|
||||
@ -70,11 +69,9 @@ public class DownloadActivity extends Activity {
|
||||
private String sampleName;
|
||||
|
||||
private TrackNameProvider trackNameProvider;
|
||||
private AsyncTask manifestDownloaderTask;
|
||||
|
||||
private DownloadUtilMethods downloadUtilMethods;
|
||||
private DownloadHelper<? extends Parcelable> downloadHelper;
|
||||
private ListView representationList;
|
||||
private ArrayAdapter<RepresentationItem> arrayAdapter;
|
||||
private ArrayAdapter<String> arrayAdapter;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
@ -100,37 +97,44 @@ public class DownloadActivity extends Activity {
|
||||
int type = Util.inferContentType(sampleUri, extension);
|
||||
switch (type) {
|
||||
case C.TYPE_DASH:
|
||||
downloadUtilMethods = new DashDownloadUtilMethods(sampleUri, manifestDataSourceFactory);
|
||||
downloadHelper = new DashDownloadHelper(sampleUri, manifestDataSourceFactory);
|
||||
break;
|
||||
case C.TYPE_SS:
|
||||
downloadUtilMethods = new SsDownloadUtilMethods(sampleUri, manifestDataSourceFactory);
|
||||
downloadHelper = new SsDownloadHelper(sampleUri, manifestDataSourceFactory);
|
||||
break;
|
||||
case C.TYPE_HLS:
|
||||
downloadUtilMethods = new HlsDownloadUtilMethods(sampleUri, manifestDataSourceFactory);
|
||||
downloadHelper = new HlsDownloadHelper(sampleUri, manifestDataSourceFactory);
|
||||
break;
|
||||
case C.TYPE_OTHER:
|
||||
downloadUtilMethods = new ProgressiveDownloadUtilMethods(sampleUri);
|
||||
downloadHelper = new ProgressiveDownloadHelper(sampleUri);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Unsupported type: " + type);
|
||||
}
|
||||
|
||||
updateRepresentationsList();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
updateRepresentationsList();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
if (manifestDownloaderTask != null) {
|
||||
manifestDownloaderTask.cancel(true);
|
||||
manifestDownloaderTask = null;
|
||||
}
|
||||
super.onStop();
|
||||
new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
downloadHelper.init();
|
||||
runOnUiThread(
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
onInitialized();
|
||||
}
|
||||
});
|
||||
} catch (IOException e) {
|
||||
runOnUiThread(
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
onInitializationError();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
|
||||
// This method is referenced in the layout file
|
||||
@ -141,21 +145,31 @@ public class DownloadActivity extends Activity {
|
||||
startDownload();
|
||||
} else if (id == R.id.remove_all_button) {
|
||||
removeDownload();
|
||||
} else if (id == R.id.refresh_button) {
|
||||
updateRepresentationsList();
|
||||
} else if (id == R.id.play_button) {
|
||||
playDownload();
|
||||
}
|
||||
}
|
||||
|
||||
private void onInitialized() {
|
||||
for (int i = 0; i < downloadHelper.getTrackCount(); i++) {
|
||||
arrayAdapter.add(trackNameProvider.getTrackName(downloadHelper.getTrackFormat(i)));
|
||||
}
|
||||
}
|
||||
|
||||
private void onInitializationError() {
|
||||
Toast.makeText(
|
||||
getApplicationContext(), R.string.download_manifest_load_error, Toast.LENGTH_LONG)
|
||||
.show();
|
||||
}
|
||||
|
||||
private void startDownload() {
|
||||
ArrayList<Object> representationKeys = getSelectedRepresentationKeys();
|
||||
if (!representationKeys.isEmpty()) {
|
||||
int[] selectedTrackIndices = getSelectedTrackIndices();
|
||||
if (selectedTrackIndices.length > 0) {
|
||||
DownloadService.addDownloadAction(
|
||||
this,
|
||||
DemoDownloadService.class,
|
||||
downloadUtilMethods.getDownloadAction(
|
||||
/* isRemoveAction= */ false, sampleName, representationKeys));
|
||||
downloadHelper.getDownloadAction(
|
||||
/* isRemoveAction= */ false, sampleName, selectedTrackIndices));
|
||||
}
|
||||
}
|
||||
|
||||
@ -163,123 +177,87 @@ public class DownloadActivity extends Activity {
|
||||
DownloadService.addDownloadAction(
|
||||
this,
|
||||
DemoDownloadService.class,
|
||||
downloadUtilMethods.getDownloadAction(
|
||||
/* isRemoveAction= */ true, sampleName, Collections.emptyList()));
|
||||
downloadHelper.getDownloadAction(/* isRemoveAction= */ true, sampleName));
|
||||
for (int i = 0; i < representationList.getChildCount(); i++) {
|
||||
representationList.setItemChecked(i, false);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("SuspiciousToArrayCall")
|
||||
private void playDownload() {
|
||||
ArrayList<Object> selectedRepresentationKeys = getSelectedRepresentationKeys();
|
||||
if (selectedRepresentationKeys.isEmpty()) {
|
||||
int[] selectedTrackIndices = getSelectedTrackIndices();
|
||||
List<? extends Parcelable> keys = downloadHelper.getTrackKeys(selectedTrackIndices);
|
||||
if (keys.isEmpty()) {
|
||||
playerIntent.removeExtra(PlayerActivity.MANIFEST_FILTER_EXTRA);
|
||||
} else {
|
||||
Parcelable[] parcelables = new Parcelable[selectedRepresentationKeys.size()];
|
||||
selectedRepresentationKeys.toArray(parcelables);
|
||||
playerIntent.putExtra(
|
||||
PlayerActivity.MANIFEST_FILTER_EXTRA, new ParcelableArray<>(parcelables));
|
||||
Parcelable[] keysArray = keys.toArray(new Parcelable[selectedTrackIndices.length]);
|
||||
playerIntent.putExtra(PlayerActivity.MANIFEST_FILTER_EXTRA, new ParcelableArray<>(keysArray));
|
||||
}
|
||||
startActivity(playerIntent);
|
||||
}
|
||||
|
||||
private void updateRepresentationsList() {
|
||||
if (manifestDownloaderTask != null) {
|
||||
manifestDownloaderTask.cancel(true);
|
||||
}
|
||||
manifestDownloaderTask = new ManifestDownloaderTask().execute();
|
||||
}
|
||||
|
||||
private ArrayList<Object> getSelectedRepresentationKeys() {
|
||||
SparseBooleanArray checked = representationList.getCheckedItemPositions();
|
||||
ArrayList<Object> representations = new ArrayList<>(checked.size());
|
||||
for (int i = 0; i < checked.size(); i++) {
|
||||
if (checked.valueAt(i)) {
|
||||
int position = checked.keyAt(i);
|
||||
RepresentationItem item =
|
||||
(RepresentationItem) representationList.getItemAtPosition(position);
|
||||
representations.add(item.key);
|
||||
private int[] getSelectedTrackIndices() {
|
||||
ArrayList<Integer> checkedIndices = new ArrayList<>();
|
||||
for (int i = 0; i < representationList.getChildCount(); i++) {
|
||||
if (representationList.isItemChecked(i)) {
|
||||
checkedIndices.add(i);
|
||||
}
|
||||
}
|
||||
return representations;
|
||||
return Util.toArray(checkedIndices);
|
||||
}
|
||||
|
||||
private static final class RepresentationItem {
|
||||
private abstract static class DownloadHelper<K extends Parcelable> {
|
||||
|
||||
public final Parcelable key;
|
||||
public final String title;
|
||||
protected static final Format DUMMY_FORMAT =
|
||||
Format.createContainerFormat(null, null, null, null, Format.NO_VALUE, 0, null);
|
||||
|
||||
public RepresentationItem(Parcelable key, String title) {
|
||||
this.key = key;
|
||||
this.title = title;
|
||||
protected final Uri uri;
|
||||
protected final DataSource.Factory dataSourceFactory;
|
||||
protected final List<Format> trackFormats;
|
||||
protected final List<K> trackKeys;
|
||||
|
||||
public DownloadHelper(Uri uri, DataSource.Factory dataSourceFactory) {
|
||||
this.uri = uri;
|
||||
this.dataSourceFactory = dataSourceFactory;
|
||||
trackFormats = new ArrayList<>();
|
||||
trackKeys = new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return title;
|
||||
public abstract void init() throws IOException;
|
||||
|
||||
public int getTrackCount() {
|
||||
return trackFormats.size();
|
||||
}
|
||||
}
|
||||
|
||||
private final class ManifestDownloaderTask
|
||||
extends AsyncTask<Void, Void, List<RepresentationItem>> {
|
||||
public Format getTrackFormat(int trackIndex) {
|
||||
return trackFormats.get(trackIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<RepresentationItem> doInBackground(Void... ignore) {
|
||||
try {
|
||||
return downloadUtilMethods.loadRepresentationItems(trackNameProvider);
|
||||
} catch (IOException | InterruptedException e) {
|
||||
return null;
|
||||
public List<K> getTrackKeys(int... trackIndices) {
|
||||
if (trackFormats.size() == 1 && trackFormats.get(0) == DUMMY_FORMAT) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(List<RepresentationItem> items) {
|
||||
if (items == null) {
|
||||
Toast.makeText(
|
||||
getApplicationContext(), R.string.download_manifest_load_error, Toast.LENGTH_LONG)
|
||||
.show();
|
||||
return;
|
||||
}
|
||||
arrayAdapter.clear();
|
||||
for (RepresentationItem representationItem : items) {
|
||||
arrayAdapter.add(representationItem);
|
||||
List<K> keys = new ArrayList<>(trackIndices.length);
|
||||
for (int trackIndex : trackIndices) {
|
||||
keys.add(trackKeys.get(trackIndex));
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
}
|
||||
|
||||
private abstract static class DownloadUtilMethods {
|
||||
|
||||
protected final Uri manifestUri;
|
||||
|
||||
public DownloadUtilMethods(Uri manifestUri) {
|
||||
this.manifestUri = manifestUri;
|
||||
}
|
||||
|
||||
public abstract List<RepresentationItem> loadRepresentationItems(
|
||||
TrackNameProvider trackNameProvider) throws IOException, InterruptedException;
|
||||
|
||||
public abstract DownloadAction getDownloadAction(
|
||||
boolean isRemoveAction, String sampleName, List<Object> representationKeys);
|
||||
boolean isRemoveAction, String sampleName, int... trackIndices);
|
||||
}
|
||||
|
||||
private static final class DashDownloadUtilMethods extends DownloadUtilMethods {
|
||||
private static final class DashDownloadHelper extends DownloadHelper<RepresentationKey> {
|
||||
|
||||
private final DataSource.Factory manifestDataSourceFactory;
|
||||
|
||||
public DashDownloadUtilMethods(Uri manifestUri, DataSource.Factory manifestDataSourceFactory) {
|
||||
super(manifestUri);
|
||||
this.manifestDataSourceFactory = manifestDataSourceFactory;
|
||||
public DashDownloadHelper(Uri uri, DataSource.Factory dataSourceFactory) {
|
||||
super(uri, dataSourceFactory);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RepresentationItem> loadRepresentationItems(TrackNameProvider trackNameProvider)
|
||||
throws IOException, InterruptedException {
|
||||
DataSource dataSource = manifestDataSourceFactory.createDataSource();
|
||||
DashManifest manifest =
|
||||
ParsingLoadable.load(dataSource, new DashManifestParser(), manifestUri);
|
||||
public void init() throws IOException {
|
||||
DataSource dataSource = dataSourceFactory.createDataSource();
|
||||
DashManifest manifest = ParsingLoadable.load(dataSource, new DashManifestParser(), uri);
|
||||
|
||||
ArrayList<RepresentationItem> items = new ArrayList<>();
|
||||
for (int periodIndex = 0; periodIndex < manifest.getPeriodCount(); periodIndex++) {
|
||||
List<AdaptationSet> adaptationSets = manifest.getPeriod(periodIndex).adaptationSets;
|
||||
for (int adaptationIndex = 0; adaptationIndex < adaptationSets.size(); adaptationIndex++) {
|
||||
@ -287,119 +265,98 @@ public class DownloadActivity extends Activity {
|
||||
adaptationSets.get(adaptationIndex).representations;
|
||||
int representationsCount = representations.size();
|
||||
for (int i = 0; i < representationsCount; i++) {
|
||||
RepresentationKey key = new RepresentationKey(periodIndex, adaptationIndex, i);
|
||||
String trackName = trackNameProvider.getTrackName(representations.get(i).format);
|
||||
items.add(new RepresentationItem(key, trackName));
|
||||
trackFormats.add(representations.get(i).format);
|
||||
trackKeys.add(new RepresentationKey(periodIndex, adaptationIndex, i));
|
||||
}
|
||||
}
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DownloadAction getDownloadAction(
|
||||
boolean isRemoveAction, String sampleName, List<Object> representationKeys) {
|
||||
RepresentationKey[] keys =
|
||||
representationKeys.toArray(new RepresentationKey[representationKeys.size()]);
|
||||
return new DashDownloadAction(isRemoveAction, sampleName, manifestUri, keys);
|
||||
boolean isRemoveAction, String sampleName, int... trackIndices) {
|
||||
return new DashDownloadAction(uri, isRemoveAction, sampleName, getTrackKeys(trackIndices));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static final class HlsDownloadUtilMethods extends DownloadUtilMethods {
|
||||
private static final class HlsDownloadHelper extends DownloadHelper<RenditionKey> {
|
||||
|
||||
private final DataSource.Factory manifestDataSourceFactory;
|
||||
|
||||
public HlsDownloadUtilMethods(Uri manifestUri, DataSource.Factory manifestDataSourceFactory) {
|
||||
super(manifestUri);
|
||||
this.manifestDataSourceFactory = manifestDataSourceFactory;
|
||||
public HlsDownloadHelper(Uri uri, DataSource.Factory dataSourceFactory) {
|
||||
super(uri, dataSourceFactory);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RepresentationItem> loadRepresentationItems(TrackNameProvider trackNameProvider)
|
||||
throws IOException, InterruptedException {
|
||||
DataSource dataSource = manifestDataSourceFactory.createDataSource();
|
||||
HlsPlaylist<?> playlist =
|
||||
ParsingLoadable.load(dataSource, new HlsPlaylistParser(), manifestUri);
|
||||
public void init() throws IOException {
|
||||
DataSource dataSource = dataSourceFactory.createDataSource();
|
||||
HlsPlaylist<?> playlist = ParsingLoadable.load(dataSource, new HlsPlaylistParser(), uri);
|
||||
|
||||
ArrayList<RepresentationItem> items = new ArrayList<>();
|
||||
if (playlist instanceof HlsMediaPlaylist) {
|
||||
items.add(new RepresentationItem(null, "Stream"));
|
||||
trackFormats.add(DUMMY_FORMAT);
|
||||
} else {
|
||||
HlsMasterPlaylist masterPlaylist = (HlsMasterPlaylist) playlist;
|
||||
addRepresentationItems(masterPlaylist.variants, RenditionKey.GROUP_VARIANTS, items);
|
||||
addRepresentationItems(masterPlaylist.audios, RenditionKey.GROUP_AUDIOS, items);
|
||||
addRepresentationItems(masterPlaylist.subtitles, RenditionKey.GROUP_SUBTITLES, items);
|
||||
addRepresentationItems(masterPlaylist.variants, RenditionKey.GROUP_VARIANTS);
|
||||
addRepresentationItems(masterPlaylist.audios, RenditionKey.GROUP_AUDIOS);
|
||||
addRepresentationItems(masterPlaylist.subtitles, RenditionKey.GROUP_SUBTITLES);
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
private void addRepresentationItems(
|
||||
List<HlsUrl> renditions, int renditionGroup, List<RepresentationItem> out) {
|
||||
private void addRepresentationItems(List<HlsUrl> renditions, int renditionGroup) {
|
||||
for (int i = 0; i < renditions.size(); i++) {
|
||||
out.add(new RepresentationItem(new RenditionKey(renditionGroup, i), renditions.get(i).url));
|
||||
trackFormats.add(renditions.get(i).format);
|
||||
trackKeys.add(new RenditionKey(renditionGroup, i));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public DownloadAction getDownloadAction(
|
||||
boolean isRemoveAction, String sampleName, List<Object> representationKeys) {
|
||||
RenditionKey[] keys = representationKeys.toArray(new RenditionKey[representationKeys.size()]);
|
||||
return new HlsDownloadAction(isRemoveAction, sampleName, manifestUri, keys);
|
||||
boolean isRemoveAction, String sampleName, int... trackIndices) {
|
||||
return new HlsDownloadAction(uri, isRemoveAction, sampleName, getTrackKeys(trackIndices));
|
||||
}
|
||||
}
|
||||
|
||||
private static final class SsDownloadUtilMethods extends DownloadUtilMethods {
|
||||
private static final class SsDownloadHelper extends DownloadHelper<TrackKey> {
|
||||
|
||||
private final DataSource.Factory manifestDataSourceFactory;
|
||||
|
||||
public SsDownloadUtilMethods(Uri manifestUri, DataSource.Factory manifestDataSourceFactory) {
|
||||
super(manifestUri);
|
||||
this.manifestDataSourceFactory = manifestDataSourceFactory;
|
||||
public SsDownloadHelper(Uri uri, DataSource.Factory dataSourceFactory) {
|
||||
super(uri, dataSourceFactory);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RepresentationItem> loadRepresentationItems(TrackNameProvider trackNameProvider)
|
||||
throws IOException, InterruptedException {
|
||||
DataSource dataSource = manifestDataSourceFactory.createDataSource();
|
||||
SsManifest manifest = ParsingLoadable.load(dataSource, new SsManifestParser(), manifestUri);
|
||||
public void init() throws IOException {
|
||||
DataSource dataSource = dataSourceFactory.createDataSource();
|
||||
SsManifest manifest = ParsingLoadable.load(dataSource, new SsManifestParser(), uri);
|
||||
|
||||
ArrayList<RepresentationItem> items = new ArrayList<>();
|
||||
for (int i = 0; i < manifest.streamElements.length; i++) {
|
||||
SsManifest.StreamElement streamElement = manifest.streamElements[i];
|
||||
for (int j = 0; j < streamElement.formats.length; j++) {
|
||||
TrackKey key = new TrackKey(i, j);
|
||||
String trackName = trackNameProvider.getTrackName(streamElement.formats[j]);
|
||||
items.add(new RepresentationItem(key, trackName));
|
||||
trackFormats.add(streamElement.formats[j]);
|
||||
trackKeys.add(new TrackKey(i, j));
|
||||
}
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DownloadAction getDownloadAction(
|
||||
boolean isRemoveAction, String sampleName, List<Object> representationKeys) {
|
||||
TrackKey[] keys = representationKeys.toArray(new TrackKey[representationKeys.size()]);
|
||||
return new SsDownloadAction(isRemoveAction, sampleName, manifestUri, keys);
|
||||
boolean isRemoveAction, String sampleName, int... trackIndices) {
|
||||
return new SsDownloadAction(uri, isRemoveAction, sampleName, getTrackKeys(trackIndices));
|
||||
}
|
||||
}
|
||||
|
||||
private static final class ProgressiveDownloadUtilMethods extends DownloadUtilMethods {
|
||||
private static final class ProgressiveDownloadHelper extends DownloadHelper<Parcelable> {
|
||||
|
||||
public ProgressiveDownloadUtilMethods(Uri manifestUri) {
|
||||
super(manifestUri);
|
||||
public ProgressiveDownloadHelper(Uri uri) {
|
||||
super(uri, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RepresentationItem> loadRepresentationItems(TrackNameProvider trackNameProvider) {
|
||||
return Collections.singletonList(new RepresentationItem(null, "Stream"));
|
||||
public void init() {
|
||||
trackFormats.add(DUMMY_FORMAT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DownloadAction getDownloadAction(
|
||||
boolean isRemoveAction, String sampleName, List<Object> representationKeys) {
|
||||
boolean isRemoveAction, String sampleName, int... trackIndices) {
|
||||
return new ProgressiveDownloadAction(
|
||||
isRemoveAction, sampleName, manifestUri, /* customCacheKey= */ null);
|
||||
uri, isRemoveAction, sampleName, /* customCacheKey= */ null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -37,12 +37,6 @@
|
||||
android:onClick="onClick"
|
||||
android:text="@string/download_remove_all"/>
|
||||
|
||||
<Button android:id="@+id/refresh_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:onClick="onClick"
|
||||
android:text="@string/download_refresh"/>
|
||||
|
||||
<Button android:id="@+id/play_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
|
@ -51,8 +51,6 @@
|
||||
|
||||
<string name="download_remove_all">Remove all</string>
|
||||
|
||||
<string name="download_refresh">Refresh</string>
|
||||
|
||||
<string name="download_only_single_period_non_drm_protected">Currently only downloading of single period non-DRM protected content is demonstrated in this app.</string>
|
||||
|
||||
</resources>
|
||||
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.google.android.exoplayer2.offline;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.Nullable;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
@ -90,21 +91,25 @@ public abstract class DownloadAction {
|
||||
public final String type;
|
||||
/** The action version. */
|
||||
public final int version;
|
||||
/** The uri being downloaded or removed. */
|
||||
public final Uri uri;
|
||||
/** Whether this is a remove action. If false, this is a download action. */
|
||||
public final boolean isRemoveAction;
|
||||
/** Custom data for this action. May be the empty string if no custom data was specified. */
|
||||
/** Custom data for this action, or the empty string if no custom data was specified. */
|
||||
public final String data;
|
||||
|
||||
/**
|
||||
* @param type The type of the action.
|
||||
* @param version The action version.
|
||||
* @param uri The uri being downloaded or removed.
|
||||
* @param isRemoveAction Whether this is a remove action. If false, this is a download action.
|
||||
* @param data Optional custom data for this action. If null, an empty string is used.
|
||||
* @param data Optional custom data for this action.
|
||||
*/
|
||||
protected DownloadAction(
|
||||
String type, int version, boolean isRemoveAction, @Nullable String data) {
|
||||
String type, int version, Uri uri, boolean isRemoveAction, @Nullable String data) {
|
||||
this.type = type;
|
||||
this.version = version;
|
||||
this.uri = uri;
|
||||
this.isRemoveAction = isRemoveAction;
|
||||
this.data = data != null ? data : "";
|
||||
}
|
||||
@ -121,12 +126,14 @@ public abstract class DownloadAction {
|
||||
return output.toByteArray();
|
||||
}
|
||||
|
||||
/** Returns whether this is an action for the same media as the {@code other}. */
|
||||
public boolean isSameMedia(DownloadAction other) {
|
||||
return uri.equals(other.uri);
|
||||
}
|
||||
|
||||
/** Serializes itself into the {@code output}. */
|
||||
protected abstract void writeToStream(DataOutputStream output) throws IOException;
|
||||
|
||||
/** Returns whether this is an action for the same media as the {@code other}. */
|
||||
protected abstract boolean isSameMedia(DownloadAction other);
|
||||
|
||||
/** Creates a {@link Downloader} with the given parameters. */
|
||||
protected abstract Downloader createDownloader(
|
||||
DownloaderConstructorHelper downloaderConstructorHelper);
|
||||
@ -137,13 +144,18 @@ public abstract class DownloadAction {
|
||||
return false;
|
||||
}
|
||||
DownloadAction that = (DownloadAction) o;
|
||||
return data.equals(that.data) && isRemoveAction == that.isRemoveAction;
|
||||
return type.equals(that.type)
|
||||
&& version == that.version
|
||||
&& uri.equals(that.uri)
|
||||
&& isRemoveAction == that.isRemoveAction
|
||||
&& data.equals(that.data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = data.hashCode();
|
||||
int result = uri.hashCode();
|
||||
result = 31 * result + (isRemoveAction ? 1 : 0);
|
||||
result = 31 * result + data.hashCode();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,6 @@ package com.google.android.exoplayer2.offline;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.upstream.cache.CacheUtil;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
@ -27,7 +26,7 @@ import java.io.IOException;
|
||||
/** An action to download or remove downloaded progressive streams. */
|
||||
public final class ProgressiveDownloadAction extends DownloadAction {
|
||||
|
||||
private static final String TYPE = "ProgressiveDownloadAction";
|
||||
private static final String TYPE = "progressive";
|
||||
private static final int VERSION = 0;
|
||||
|
||||
public static final Deserializer DESERIALIZER =
|
||||
@ -35,28 +34,26 @@ public final class ProgressiveDownloadAction extends DownloadAction {
|
||||
@Override
|
||||
public ProgressiveDownloadAction readFromStream(int version, DataInputStream input)
|
||||
throws IOException {
|
||||
Uri uri = Uri.parse(input.readUTF());
|
||||
boolean isRemoveAction = input.readBoolean();
|
||||
String data = input.readUTF();
|
||||
Uri uri = Uri.parse(input.readUTF());
|
||||
String customCacheKey = input.readBoolean() ? input.readUTF() : null;
|
||||
return new ProgressiveDownloadAction(isRemoveAction, data, uri, customCacheKey);
|
||||
return new ProgressiveDownloadAction(uri, isRemoveAction, data, customCacheKey);
|
||||
}
|
||||
};
|
||||
|
||||
private final Uri uri;
|
||||
private final @Nullable String customCacheKey;
|
||||
public final @Nullable String customCacheKey;
|
||||
|
||||
/**
|
||||
* @param uri Uri of the data to be downloaded.
|
||||
* @param isRemoveAction Whether this is a remove action. If false, this is a download action.
|
||||
* @param data Optional custom data for this action. If null, an empty string is used.
|
||||
* @param uri Uri of the data to be downloaded.
|
||||
* @param customCacheKey A custom key that uniquely identifies the original stream. If not null it
|
||||
* is used for cache indexing.
|
||||
*/
|
||||
public ProgressiveDownloadAction(
|
||||
boolean isRemoveAction, @Nullable String data, Uri uri, @Nullable String customCacheKey) {
|
||||
super(TYPE, VERSION, isRemoveAction, data);
|
||||
this.uri = Assertions.checkNotNull(uri);
|
||||
Uri uri, boolean isRemoveAction, @Nullable String data, @Nullable String customCacheKey) {
|
||||
super(TYPE, VERSION, uri, isRemoveAction, data);
|
||||
this.customCacheKey = customCacheKey;
|
||||
}
|
||||
|
||||
@ -67,9 +64,9 @@ public final class ProgressiveDownloadAction extends DownloadAction {
|
||||
|
||||
@Override
|
||||
protected void writeToStream(DataOutputStream output) throws IOException {
|
||||
output.writeUTF(uri.toString());
|
||||
output.writeBoolean(isRemoveAction);
|
||||
output.writeUTF(data);
|
||||
output.writeUTF(uri.toString());
|
||||
boolean customCacheKeySet = customCacheKey != null;
|
||||
output.writeBoolean(customCacheKeySet);
|
||||
if (customCacheKeySet) {
|
||||
@ -78,11 +75,9 @@ public final class ProgressiveDownloadAction extends DownloadAction {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isSameMedia(DownloadAction other) {
|
||||
if (!(other instanceof ProgressiveDownloadAction)) {
|
||||
return false;
|
||||
}
|
||||
return getCacheKey().equals(((ProgressiveDownloadAction) other).getCacheKey());
|
||||
public boolean isSameMedia(DownloadAction other) {
|
||||
return ((other instanceof ProgressiveDownloadAction)
|
||||
&& getCacheKey().equals(((ProgressiveDownloadAction) other).getCacheKey()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -94,13 +89,12 @@ public final class ProgressiveDownloadAction extends DownloadAction {
|
||||
return false;
|
||||
}
|
||||
ProgressiveDownloadAction that = (ProgressiveDownloadAction) o;
|
||||
return uri.equals(that.uri) && Util.areEqual(customCacheKey, that.customCacheKey);
|
||||
return Util.areEqual(customCacheKey, that.customCacheKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = super.hashCode();
|
||||
result = 31 * result + uri.hashCode();
|
||||
result = 31 * result + (customCacheKey != null ? customCacheKey.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
|
@ -21,14 +21,16 @@ import com.google.android.exoplayer2.util.Assertions;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* {@link DownloadAction} for {@link SegmentDownloader}s.
|
||||
*
|
||||
* @param <K> The type of the representation key object.
|
||||
*/
|
||||
public abstract class SegmentDownloadAction<K extends Comparable> extends DownloadAction {
|
||||
public abstract class SegmentDownloadAction<K extends Comparable<K>> extends DownloadAction {
|
||||
|
||||
/**
|
||||
* Base class for {@link SegmentDownloadAction} {@link Deserializer}s.
|
||||
@ -44,78 +46,68 @@ public abstract class SegmentDownloadAction<K extends Comparable> extends Downlo
|
||||
@Override
|
||||
public final DownloadAction readFromStream(int version, DataInputStream input)
|
||||
throws IOException {
|
||||
Uri uri = Uri.parse(input.readUTF());
|
||||
boolean isRemoveAction = input.readBoolean();
|
||||
String data = input.readUTF();
|
||||
Uri manifestUri = Uri.parse(input.readUTF());
|
||||
int keyCount = input.readInt();
|
||||
K[] keys = createKeyArray(keyCount);
|
||||
List<K> keys = new ArrayList<>();
|
||||
for (int i = 0; i < keyCount; i++) {
|
||||
keys[i] = readKey(input);
|
||||
keys.add(readKey(input));
|
||||
}
|
||||
return createDownloadAction(isRemoveAction, data, manifestUri, keys);
|
||||
return createDownloadAction(uri, isRemoveAction, data, keys);
|
||||
}
|
||||
|
||||
/** Deserializes a key from the {@code input}. */
|
||||
protected abstract K readKey(DataInputStream input) throws IOException;
|
||||
|
||||
/** Returns a key array. */
|
||||
protected abstract K[] createKeyArray(int keyCount);
|
||||
|
||||
/** Returns a {@link DownloadAction}. */
|
||||
protected abstract DownloadAction createDownloadAction(
|
||||
boolean isRemoveAction, String data, Uri manifestUri, K[] keys);
|
||||
Uri manifestUri, boolean isRemoveAction, String data, List<K> keys);
|
||||
}
|
||||
|
||||
protected final Uri manifestUri;
|
||||
protected final K[] keys;
|
||||
public final List<K> keys;
|
||||
|
||||
/**
|
||||
* @param type The type of the action.
|
||||
* @param version The action version.
|
||||
* @param uri The URI of the media being downloaded.
|
||||
* @param isRemoveAction Whether the data will be removed. If {@code false} it will be downloaded.
|
||||
* @param data Optional custom data for this action. If null, an empty string is used.
|
||||
* @param manifestUri The {@link Uri} of the manifest to be downloaded.
|
||||
* @param keys Keys of representations to be downloaded. If empty, all representations are
|
||||
* downloaded. If {@code removeAction} is true, {@code keys} must be an empty array.
|
||||
* @param data Optional custom data for this action.
|
||||
* @param keys Keys of tracks to be downloaded. If empty, all tracks will be downloaded. If {@code
|
||||
* removeAction} is true, {@code keys} must be empty.
|
||||
*/
|
||||
protected SegmentDownloadAction(
|
||||
String type,
|
||||
int version,
|
||||
Uri uri,
|
||||
boolean isRemoveAction,
|
||||
@Nullable String data,
|
||||
Uri manifestUri,
|
||||
K[] keys) {
|
||||
super(type, version, isRemoveAction, data);
|
||||
this.manifestUri = manifestUri;
|
||||
List<K> keys) {
|
||||
super(type, version, uri, isRemoveAction, data);
|
||||
if (isRemoveAction) {
|
||||
Assertions.checkArgument(keys.length == 0);
|
||||
this.keys = keys;
|
||||
Assertions.checkArgument(keys.isEmpty());
|
||||
this.keys = Collections.emptyList();
|
||||
} else {
|
||||
this.keys = keys.clone();
|
||||
Arrays.sort(this.keys);
|
||||
ArrayList<K> mutableKeys = new ArrayList<>(keys);
|
||||
Collections.sort(mutableKeys);
|
||||
this.keys = Collections.unmodifiableList(mutableKeys);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void writeToStream(DataOutputStream output) throws IOException {
|
||||
output.writeUTF(uri.toString());
|
||||
output.writeBoolean(isRemoveAction);
|
||||
output.writeUTF(data);
|
||||
output.writeUTF(manifestUri.toString());
|
||||
output.writeInt(keys.length);
|
||||
for (K key : keys) {
|
||||
writeKey(output, key);
|
||||
output.writeInt(keys.size());
|
||||
for (int i = 0; i < keys.size(); i++) {
|
||||
writeKey(output, keys.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
/** Serializes the {@code key} into the {@code output}. */
|
||||
protected abstract void writeKey(DataOutputStream output, K key) throws IOException;
|
||||
|
||||
@Override
|
||||
public boolean isSameMedia(DownloadAction other) {
|
||||
return other instanceof SegmentDownloadAction
|
||||
&& manifestUri.equals(((SegmentDownloadAction<?>) other).manifestUri);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
@ -125,14 +117,13 @@ public abstract class SegmentDownloadAction<K extends Comparable> extends Downlo
|
||||
return false;
|
||||
}
|
||||
SegmentDownloadAction<?> that = (SegmentDownloadAction<?>) o;
|
||||
return manifestUri.equals(that.manifestUri) && Arrays.equals(keys, that.keys);
|
||||
return keys.equals(that.keys);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = super.hashCode();
|
||||
result = 31 * result + manifestUri.hashCode();
|
||||
result = 31 * result + Arrays.hashCode(keys);
|
||||
result = 31 * result + keys.hashCode();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,6 @@ package com.google.android.exoplayer2.offline;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.DataSpec;
|
||||
@ -77,20 +76,16 @@ public abstract class SegmentDownloader<M extends FilterableManifest<M, K>, K>
|
||||
/**
|
||||
* @param manifestUri The {@link Uri} of the manifest to be downloaded.
|
||||
* @param constructorHelper a {@link DownloaderConstructorHelper} instance.
|
||||
* @param trackKeys Track keys to select when downloading. If null or empty, all tracks are
|
||||
* downloaded.
|
||||
* @param trackKeys Track keys to select when downloading. If empty, all tracks are downloaded.
|
||||
*/
|
||||
public SegmentDownloader(
|
||||
Uri manifestUri, DownloaderConstructorHelper constructorHelper, @Nullable K[] trackKeys) {
|
||||
Uri manifestUri, DownloaderConstructorHelper constructorHelper, List<K> trackKeys) {
|
||||
this.manifestUri = manifestUri;
|
||||
this.cache = constructorHelper.getCache();
|
||||
this.dataSource = constructorHelper.buildCacheDataSource(false);
|
||||
this.offlineDataSource = constructorHelper.buildCacheDataSource(true);
|
||||
this.priorityTaskManager = constructorHelper.getPriorityTaskManager();
|
||||
keys = new ArrayList<>();
|
||||
if (trackKeys != null) {
|
||||
Collections.addAll(this.keys, trackKeys);
|
||||
}
|
||||
keys = new ArrayList<>(trackKeys);
|
||||
totalSegments = C.LENGTH_UNSET;
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,7 @@ package com.google.android.exoplayer2.offline;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.net.Uri;
|
||||
import com.google.android.exoplayer2.offline.DownloadAction.Deserializer;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import java.io.DataInputStream;
|
||||
@ -236,7 +237,7 @@ public class ActionFileTest {
|
||||
public static final int VERSION = 0;
|
||||
|
||||
private FakeDownloadAction(String type, String data) {
|
||||
super(type, VERSION, /* isRemoveAction= */ false, data);
|
||||
super(type, VERSION, Uri.parse("http://test.com"), /* isRemoveAction= */ false, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -244,37 +245,11 @@ public class ActionFileTest {
|
||||
output.writeUTF(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isSameMedia(DownloadAction other) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Downloader createDownloader(DownloaderConstructorHelper downloaderConstructorHelper) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// auto generated code
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
FakeDownloadAction that = (FakeDownloadAction) o;
|
||||
return version == that.version && data.equals(that.data) && type.equals(that.type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = type.hashCode();
|
||||
result = 31 * result + version;
|
||||
result = 31 * result + data.hashCode();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -18,8 +18,8 @@ package com.google.android.exoplayer2.offline;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.os.ConditionVariable;
|
||||
import android.support.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.offline.DownloadManager.DownloadListener;
|
||||
import com.google.android.exoplayer2.offline.DownloadManager.TaskState;
|
||||
@ -62,14 +62,20 @@ public class DownloadManagerTest {
|
||||
|
||||
private static final int MIN_RETRY_COUNT = 3;
|
||||
|
||||
private DownloadManager downloadManager;
|
||||
private Uri uri1;
|
||||
private Uri uri2;
|
||||
private Uri uri3;
|
||||
private DummyMainThread dummyMainThread;
|
||||
private File actionFile;
|
||||
private TestDownloadListener testDownloadListener;
|
||||
private DummyMainThread dummyMainThread;
|
||||
private DownloadManager downloadManager;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
uri1 = Uri.parse("http://abc.com/media1");
|
||||
uri2 = Uri.parse("http://abc.com/media2");
|
||||
uri3 = Uri.parse("http://abc.com/media3");
|
||||
dummyMainThread = new DummyMainThread();
|
||||
actionFile = Util.createTempFile(RuntimeEnvironment.application, "ExoPlayerTest");
|
||||
testDownloadListener = new TestDownloadListener();
|
||||
@ -85,17 +91,17 @@ public class DownloadManagerTest {
|
||||
|
||||
@Test
|
||||
public void testDownloadActionRuns() throws Throwable {
|
||||
doTestActionRuns(createDownloadAction("media 1"));
|
||||
doTestActionRuns(createDownloadAction(uri1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveActionRuns() throws Throwable {
|
||||
doTestActionRuns(createRemoveAction("media 1"));
|
||||
doTestActionRuns(createRemoveAction(uri1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDownloadRetriesThenFails() throws Throwable {
|
||||
FakeDownloadAction downloadAction = createDownloadAction("media 1");
|
||||
FakeDownloadAction downloadAction = createDownloadAction(uri1);
|
||||
downloadAction.post();
|
||||
FakeDownloader fakeDownloader = downloadAction.getFakeDownloader();
|
||||
fakeDownloader.enableDownloadIOException = true;
|
||||
@ -110,11 +116,11 @@ public class DownloadManagerTest {
|
||||
|
||||
@Test
|
||||
public void testDownloadNoRetryWhenCanceled() throws Throwable {
|
||||
FakeDownloadAction downloadAction = createDownloadAction("media 1").ignoreInterrupts();
|
||||
FakeDownloadAction downloadAction = createDownloadAction(uri1).ignoreInterrupts();
|
||||
downloadAction.getFakeDownloader().enableDownloadIOException = true;
|
||||
downloadAction.post().assertStarted();
|
||||
|
||||
FakeDownloadAction removeAction = createRemoveAction("media 1").post();
|
||||
FakeDownloadAction removeAction = createRemoveAction(uri1).post();
|
||||
|
||||
downloadAction.unblock().assertCanceled();
|
||||
removeAction.unblock();
|
||||
@ -124,7 +130,7 @@ public class DownloadManagerTest {
|
||||
|
||||
@Test
|
||||
public void testDownloadRetriesThenContinues() throws Throwable {
|
||||
FakeDownloadAction downloadAction = createDownloadAction("media 1");
|
||||
FakeDownloadAction downloadAction = createDownloadAction(uri1);
|
||||
downloadAction.post();
|
||||
FakeDownloader fakeDownloader = downloadAction.getFakeDownloader();
|
||||
fakeDownloader.enableDownloadIOException = true;
|
||||
@ -143,7 +149,7 @@ public class DownloadManagerTest {
|
||||
@Test
|
||||
@SuppressWarnings({"NonAtomicVolatileUpdate", "NonAtomicOperationOnVolatileField"})
|
||||
public void testDownloadRetryCountResetsOnProgress() throws Throwable {
|
||||
FakeDownloadAction downloadAction = createDownloadAction("media 1");
|
||||
FakeDownloadAction downloadAction = createDownloadAction(uri1);
|
||||
downloadAction.post();
|
||||
FakeDownloader fakeDownloader = downloadAction.getFakeDownloader();
|
||||
fakeDownloader.enableDownloadIOException = true;
|
||||
@ -163,41 +169,41 @@ public class DownloadManagerTest {
|
||||
|
||||
@Test
|
||||
public void testDifferentMediaDownloadActionsStartInParallel() throws Throwable {
|
||||
doTestActionsRunInParallel(createDownloadAction("media 1"), createDownloadAction("media 2"));
|
||||
doTestActionsRunInParallel(createDownloadAction(uri1), createDownloadAction(uri2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDifferentMediaDifferentActionsStartInParallel() throws Throwable {
|
||||
doTestActionsRunInParallel(createDownloadAction("media 1"), createRemoveAction("media 2"));
|
||||
doTestActionsRunInParallel(createDownloadAction(uri1), createRemoveAction(uri2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSameMediaDownloadActionsStartInParallel() throws Throwable {
|
||||
doTestActionsRunInParallel(createDownloadAction("media 1"), createDownloadAction("media 1"));
|
||||
doTestActionsRunInParallel(createDownloadAction(uri1), createDownloadAction(uri1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSameMediaRemoveActionWaitsDownloadAction() throws Throwable {
|
||||
doTestActionsRunSequentially(createDownloadAction("media 1"), createRemoveAction("media 1"));
|
||||
doTestActionsRunSequentially(createDownloadAction(uri1), createRemoveAction(uri1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSameMediaDownloadActionWaitsRemoveAction() throws Throwable {
|
||||
doTestActionsRunSequentially(createRemoveAction("media 1"), createDownloadAction("media 1"));
|
||||
doTestActionsRunSequentially(createRemoveAction(uri1), createDownloadAction(uri1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSameMediaRemoveActionWaitsRemoveAction() throws Throwable {
|
||||
doTestActionsRunSequentially(createRemoveAction("media 1"), createRemoveAction("media 1"));
|
||||
doTestActionsRunSequentially(createRemoveAction(uri1), createRemoveAction(uri1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSameMediaMultipleActions() throws Throwable {
|
||||
FakeDownloadAction downloadAction1 = createDownloadAction("media 1").ignoreInterrupts();
|
||||
FakeDownloadAction downloadAction2 = createDownloadAction("media 1").ignoreInterrupts();
|
||||
FakeDownloadAction removeAction1 = createRemoveAction("media 1");
|
||||
FakeDownloadAction downloadAction3 = createDownloadAction("media 1");
|
||||
FakeDownloadAction removeAction2 = createRemoveAction("media 1");
|
||||
FakeDownloadAction downloadAction1 = createDownloadAction(uri1).ignoreInterrupts();
|
||||
FakeDownloadAction downloadAction2 = createDownloadAction(uri1).ignoreInterrupts();
|
||||
FakeDownloadAction removeAction1 = createRemoveAction(uri1);
|
||||
FakeDownloadAction downloadAction3 = createDownloadAction(uri1);
|
||||
FakeDownloadAction removeAction2 = createRemoveAction(uri1);
|
||||
|
||||
// Two download actions run in parallel.
|
||||
downloadAction1.post().assertStarted();
|
||||
@ -229,9 +235,9 @@ public class DownloadManagerTest {
|
||||
|
||||
@Test
|
||||
public void testMultipleRemoveActionWaitsLastCancelsAllOther() throws Throwable {
|
||||
FakeDownloadAction removeAction1 = createRemoveAction("media 1").ignoreInterrupts();
|
||||
FakeDownloadAction removeAction2 = createRemoveAction("media 1");
|
||||
FakeDownloadAction removeAction3 = createRemoveAction("media 1");
|
||||
FakeDownloadAction removeAction1 = createRemoveAction(uri1).ignoreInterrupts();
|
||||
FakeDownloadAction removeAction2 = createRemoveAction(uri1);
|
||||
FakeDownloadAction removeAction3 = createRemoveAction(uri1);
|
||||
|
||||
removeAction1.post().assertStarted();
|
||||
removeAction2.post().assertDoesNotStart();
|
||||
@ -247,9 +253,9 @@ public class DownloadManagerTest {
|
||||
|
||||
@Test
|
||||
public void testGetTasks() throws Throwable {
|
||||
FakeDownloadAction removeAction = createRemoveAction("media 1");
|
||||
FakeDownloadAction downloadAction1 = createDownloadAction("media 1");
|
||||
FakeDownloadAction downloadAction2 = createDownloadAction("media 1");
|
||||
FakeDownloadAction removeAction = createRemoveAction(uri1);
|
||||
FakeDownloadAction downloadAction1 = createDownloadAction(uri1);
|
||||
FakeDownloadAction downloadAction2 = createDownloadAction(uri1);
|
||||
|
||||
removeAction.post().assertStarted();
|
||||
downloadAction1.post().assertDoesNotStart();
|
||||
@ -264,9 +270,9 @@ public class DownloadManagerTest {
|
||||
|
||||
@Test
|
||||
public void testMultipleWaitingDownloadActionStartsInParallel() throws Throwable {
|
||||
FakeDownloadAction removeAction = createRemoveAction("media 1");
|
||||
FakeDownloadAction downloadAction1 = createDownloadAction("media 1");
|
||||
FakeDownloadAction downloadAction2 = createDownloadAction("media 1");
|
||||
FakeDownloadAction removeAction = createRemoveAction(uri1);
|
||||
FakeDownloadAction downloadAction1 = createDownloadAction(uri1);
|
||||
FakeDownloadAction downloadAction2 = createDownloadAction(uri1);
|
||||
|
||||
removeAction.post().assertStarted();
|
||||
downloadAction1.post().assertDoesNotStart();
|
||||
@ -283,9 +289,9 @@ public class DownloadManagerTest {
|
||||
|
||||
@Test
|
||||
public void testDifferentMediaDownloadActionsPreserveOrder() throws Throwable {
|
||||
FakeDownloadAction removeAction = createRemoveAction("media 1").ignoreInterrupts();
|
||||
FakeDownloadAction downloadAction1 = createDownloadAction("media 1");
|
||||
FakeDownloadAction downloadAction2 = createDownloadAction("media 2");
|
||||
FakeDownloadAction removeAction = createRemoveAction(uri1).ignoreInterrupts();
|
||||
FakeDownloadAction downloadAction1 = createDownloadAction(uri1);
|
||||
FakeDownloadAction downloadAction2 = createDownloadAction(uri2);
|
||||
|
||||
removeAction.post().assertStarted();
|
||||
downloadAction1.post().assertDoesNotStart();
|
||||
@ -302,9 +308,9 @@ public class DownloadManagerTest {
|
||||
|
||||
@Test
|
||||
public void testDifferentMediaRemoveActionsDoNotPreserveOrder() throws Throwable {
|
||||
FakeDownloadAction downloadAction = createDownloadAction("media 1").ignoreInterrupts();
|
||||
FakeDownloadAction removeAction1 = createRemoveAction("media 1");
|
||||
FakeDownloadAction removeAction2 = createRemoveAction("media 2");
|
||||
FakeDownloadAction downloadAction = createDownloadAction(uri1).ignoreInterrupts();
|
||||
FakeDownloadAction removeAction1 = createRemoveAction(uri1);
|
||||
FakeDownloadAction removeAction2 = createRemoveAction(uri2);
|
||||
|
||||
downloadAction.post().assertStarted();
|
||||
removeAction1.post().assertDoesNotStart();
|
||||
@ -321,11 +327,11 @@ public class DownloadManagerTest {
|
||||
|
||||
@Test
|
||||
public void testStopAndResume() throws Throwable {
|
||||
FakeDownloadAction download1Action = createDownloadAction("media 1");
|
||||
FakeDownloadAction remove2Action = createRemoveAction("media 2");
|
||||
FakeDownloadAction download2Action = createDownloadAction("media 2");
|
||||
FakeDownloadAction remove1Action = createRemoveAction("media 1");
|
||||
FakeDownloadAction download3Action = createDownloadAction("media 3");
|
||||
FakeDownloadAction download1Action = createDownloadAction(uri1);
|
||||
FakeDownloadAction remove2Action = createRemoveAction(uri2);
|
||||
FakeDownloadAction download2Action = createDownloadAction(uri2);
|
||||
FakeDownloadAction remove1Action = createRemoveAction(uri1);
|
||||
FakeDownloadAction download3Action = createDownloadAction(uri3);
|
||||
|
||||
download1Action.post().assertStarted();
|
||||
remove2Action.post().assertStarted();
|
||||
@ -371,9 +377,9 @@ public class DownloadManagerTest {
|
||||
@Test
|
||||
public void testResumeBeforeTotallyStopped() throws Throwable {
|
||||
setUpDownloadManager(2);
|
||||
FakeDownloadAction download1Action = createDownloadAction("media 1").ignoreInterrupts();
|
||||
FakeDownloadAction download2Action = createDownloadAction("media 2");
|
||||
FakeDownloadAction download3Action = createDownloadAction("media 3");
|
||||
FakeDownloadAction download1Action = createDownloadAction(uri1).ignoreInterrupts();
|
||||
FakeDownloadAction download2Action = createDownloadAction(uri2);
|
||||
FakeDownloadAction download3Action = createDownloadAction(uri3);
|
||||
|
||||
download1Action.post().assertStarted();
|
||||
download2Action.post().assertStarted();
|
||||
@ -481,12 +487,12 @@ public class DownloadManagerTest {
|
||||
testDownloadListener.blockUntilTasksCompleteAndThrowAnyDownloadError();
|
||||
}
|
||||
|
||||
private FakeDownloadAction createDownloadAction(String mediaId) {
|
||||
return new FakeDownloadAction(/* isRemoveAction= */ false, mediaId);
|
||||
private FakeDownloadAction createDownloadAction(Uri uri) {
|
||||
return new FakeDownloadAction(uri, /* isRemoveAction= */ false);
|
||||
}
|
||||
|
||||
private FakeDownloadAction createRemoveAction(String mediaId) {
|
||||
return new FakeDownloadAction(/* isRemoveAction= */ true, mediaId);
|
||||
private FakeDownloadAction createRemoveAction(Uri uri) {
|
||||
return new FakeDownloadAction(uri, /* isRemoveAction= */ true);
|
||||
}
|
||||
|
||||
private void runOnMainThread(final Runnable r) throws Throwable {
|
||||
@ -530,28 +536,20 @@ public class DownloadManagerTest {
|
||||
|
||||
private class FakeDownloadAction extends DownloadAction {
|
||||
|
||||
private final String mediaId;
|
||||
private final FakeDownloader downloader;
|
||||
private final BlockingQueue<Integer> states;
|
||||
|
||||
private FakeDownloadAction(boolean isRemoveAction, @Nullable String mediaId) {
|
||||
super("FakeDownloadAction", /* version= */ 0, isRemoveAction, mediaId);
|
||||
this.mediaId = mediaId;
|
||||
private FakeDownloadAction(Uri uri, boolean isRemoveAction) {
|
||||
super("Fake", /* version= */ 0, uri, isRemoveAction, /* data= */ null);
|
||||
this.downloader = new FakeDownloader(isRemoveAction);
|
||||
this.states = new ArrayBlockingQueue<>(10);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeToStream(DataOutputStream output) throws IOException {
|
||||
protected void writeToStream(DataOutputStream output) {
|
||||
// do nothing.
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isSameMedia(DownloadAction other) {
|
||||
return other instanceof FakeDownloadAction
|
||||
&& mediaId.equals(((FakeDownloadAction) other).mediaId);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Downloader createDownloader(DownloaderConstructorHelper downloaderConstructorHelper) {
|
||||
return downloader;
|
||||
|
@ -49,20 +49,20 @@ public class ProgressiveDownloadActionTest {
|
||||
|
||||
@Test
|
||||
public void testDownloadActionIsNotRemoveAction() throws Exception {
|
||||
ProgressiveDownloadAction action = new ProgressiveDownloadAction(false, null, uri1, null);
|
||||
ProgressiveDownloadAction action = new ProgressiveDownloadAction(uri1, false, null, null);
|
||||
assertThat(action.isRemoveAction).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveActionisRemoveAction() throws Exception {
|
||||
ProgressiveDownloadAction action2 = new ProgressiveDownloadAction(true, null, uri1, null);
|
||||
ProgressiveDownloadAction action2 = new ProgressiveDownloadAction(uri1, true, null, null);
|
||||
assertThat(action2.isRemoveAction).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateDownloader() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
ProgressiveDownloadAction action = new ProgressiveDownloadAction(false, null, uri1, null);
|
||||
ProgressiveDownloadAction action = new ProgressiveDownloadAction(uri1, false, null, null);
|
||||
DownloaderConstructorHelper constructorHelper = new DownloaderConstructorHelper(
|
||||
Mockito.mock(Cache.class), DummyDataSource.FACTORY);
|
||||
assertThat(action.createDownloader(constructorHelper)).isNotNull();
|
||||
@ -70,75 +70,75 @@ public class ProgressiveDownloadActionTest {
|
||||
|
||||
@Test
|
||||
public void testSameUriCacheKeyDifferentAction_IsSameMedia() throws Exception {
|
||||
ProgressiveDownloadAction action1 = new ProgressiveDownloadAction(true, null, uri1, null);
|
||||
ProgressiveDownloadAction action2 = new ProgressiveDownloadAction(false, null, uri1, null);
|
||||
ProgressiveDownloadAction action1 = new ProgressiveDownloadAction(uri1, true, null, null);
|
||||
ProgressiveDownloadAction action2 = new ProgressiveDownloadAction(uri1, false, null, null);
|
||||
assertSameMedia(action1, action2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullCacheKeyDifferentUriAction_IsNotSameMedia() throws Exception {
|
||||
ProgressiveDownloadAction action3 = new ProgressiveDownloadAction(true, null, uri2, null);
|
||||
ProgressiveDownloadAction action4 = new ProgressiveDownloadAction(false, null, uri1, null);
|
||||
ProgressiveDownloadAction action3 = new ProgressiveDownloadAction(uri2, true, null, null);
|
||||
ProgressiveDownloadAction action4 = new ProgressiveDownloadAction(uri1, false, null, null);
|
||||
assertNotSameMedia(action3, action4);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSameCacheKeyDifferentUriAction_IsSameMedia() throws Exception {
|
||||
ProgressiveDownloadAction action5 = new ProgressiveDownloadAction(true, null, uri2, "key");
|
||||
ProgressiveDownloadAction action6 = new ProgressiveDownloadAction(false, null, uri1, "key");
|
||||
ProgressiveDownloadAction action5 = new ProgressiveDownloadAction(uri2, true, null, "key");
|
||||
ProgressiveDownloadAction action6 = new ProgressiveDownloadAction(uri1, false, null, "key");
|
||||
assertSameMedia(action5, action6);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSameUriDifferentCacheKeyAction_IsNotSameMedia() throws Exception {
|
||||
ProgressiveDownloadAction action7 = new ProgressiveDownloadAction(true, null, uri1, "key");
|
||||
ProgressiveDownloadAction action8 = new ProgressiveDownloadAction(false, null, uri1, "key2");
|
||||
ProgressiveDownloadAction action7 = new ProgressiveDownloadAction(uri1, true, null, "key");
|
||||
ProgressiveDownloadAction action8 = new ProgressiveDownloadAction(uri1, false, null, "key2");
|
||||
assertNotSameMedia(action7, action8);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSameUriNullCacheKeyAction_IsNotSameMedia() throws Exception {
|
||||
ProgressiveDownloadAction action1 = new ProgressiveDownloadAction(true, null, uri1, "key");
|
||||
ProgressiveDownloadAction action2 = new ProgressiveDownloadAction(false, null, uri1, null);
|
||||
ProgressiveDownloadAction action1 = new ProgressiveDownloadAction(uri1, true, null, "key");
|
||||
ProgressiveDownloadAction action2 = new ProgressiveDownloadAction(uri1, false, null, null);
|
||||
assertNotSameMedia(action1, action2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEquals() throws Exception {
|
||||
ProgressiveDownloadAction action1 = new ProgressiveDownloadAction(true, null, uri1, null);
|
||||
ProgressiveDownloadAction action1 = new ProgressiveDownloadAction(uri1, true, null, null);
|
||||
assertThat(action1.equals(action1)).isTrue();
|
||||
|
||||
ProgressiveDownloadAction action2 = new ProgressiveDownloadAction(true, null, uri1, null);
|
||||
ProgressiveDownloadAction action3 = new ProgressiveDownloadAction(true, null, uri1, null);
|
||||
ProgressiveDownloadAction action2 = new ProgressiveDownloadAction(uri1, true, null, null);
|
||||
ProgressiveDownloadAction action3 = new ProgressiveDownloadAction(uri1, true, null, null);
|
||||
assertThat(action2.equals(action3)).isTrue();
|
||||
|
||||
ProgressiveDownloadAction action4 = new ProgressiveDownloadAction(true, null, uri1, null);
|
||||
ProgressiveDownloadAction action5 = new ProgressiveDownloadAction(false, null, uri1, null);
|
||||
ProgressiveDownloadAction action4 = new ProgressiveDownloadAction(uri1, true, null, null);
|
||||
ProgressiveDownloadAction action5 = new ProgressiveDownloadAction(uri1, false, null, null);
|
||||
assertThat(action4.equals(action5)).isFalse();
|
||||
|
||||
ProgressiveDownloadAction action6 = new ProgressiveDownloadAction(true, null, uri1, null);
|
||||
ProgressiveDownloadAction action7 = new ProgressiveDownloadAction(true, null, uri1, "key");
|
||||
ProgressiveDownloadAction action6 = new ProgressiveDownloadAction(uri1, true, null, null);
|
||||
ProgressiveDownloadAction action7 = new ProgressiveDownloadAction(uri1, true, null, "key");
|
||||
assertThat(action6.equals(action7)).isFalse();
|
||||
|
||||
ProgressiveDownloadAction action8 = new ProgressiveDownloadAction(true, null, uri1, "key2");
|
||||
ProgressiveDownloadAction action9 = new ProgressiveDownloadAction(true, null, uri1, "key");
|
||||
ProgressiveDownloadAction action8 = new ProgressiveDownloadAction(uri1, true, null, "key2");
|
||||
ProgressiveDownloadAction action9 = new ProgressiveDownloadAction(uri1, true, null, "key");
|
||||
assertThat(action8.equals(action9)).isFalse();
|
||||
|
||||
ProgressiveDownloadAction action10 = new ProgressiveDownloadAction(true, null, uri1, null);
|
||||
ProgressiveDownloadAction action11 = new ProgressiveDownloadAction(true, null, uri2, null);
|
||||
ProgressiveDownloadAction action10 = new ProgressiveDownloadAction(uri1, true, null, null);
|
||||
ProgressiveDownloadAction action11 = new ProgressiveDownloadAction(uri2, true, null, null);
|
||||
assertThat(action10.equals(action11)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSerializerGetType() throws Exception {
|
||||
ProgressiveDownloadAction action = new ProgressiveDownloadAction(false, null, uri1, null);
|
||||
ProgressiveDownloadAction action = new ProgressiveDownloadAction(uri1, false, null, null);
|
||||
assertThat(action.type).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSerializerWriteRead() throws Exception {
|
||||
doTestSerializationRoundTrip(new ProgressiveDownloadAction(false, null, uri1, null));
|
||||
doTestSerializationRoundTrip(new ProgressiveDownloadAction(true, null, uri2, "key"));
|
||||
doTestSerializationRoundTrip(new ProgressiveDownloadAction(uri1, false, null, null));
|
||||
doTestSerializationRoundTrip(new ProgressiveDownloadAction(uri2, true, null, "key"));
|
||||
}
|
||||
|
||||
private void assertSameMedia(
|
||||
|
@ -24,11 +24,12 @@ import com.google.android.exoplayer2.source.dash.manifest.RepresentationKey;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/** An action to download or remove downloaded DASH streams. */
|
||||
public final class DashDownloadAction extends SegmentDownloadAction<RepresentationKey> {
|
||||
|
||||
private static final String TYPE = "DashDownloadAction";
|
||||
private static final String TYPE = "dash";
|
||||
private static final int VERSION = 0;
|
||||
|
||||
public static final Deserializer DESERIALIZER =
|
||||
@ -39,30 +40,28 @@ public final class DashDownloadAction extends SegmentDownloadAction<Representati
|
||||
return new RepresentationKey(input.readInt(), input.readInt(), input.readInt());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RepresentationKey[] createKeyArray(int keyCount) {
|
||||
return new RepresentationKey[keyCount];
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DownloadAction createDownloadAction(
|
||||
boolean isRemoveAction, String data, Uri manifestUri, RepresentationKey[] keys) {
|
||||
return new DashDownloadAction(isRemoveAction, data, manifestUri, keys);
|
||||
Uri uri, boolean isRemoveAction, String data, List<RepresentationKey> keys) {
|
||||
return new DashDownloadAction(uri, isRemoveAction, data, keys);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @see SegmentDownloadAction#SegmentDownloadAction(String, int, boolean, String, Uri,
|
||||
* Comparable[])
|
||||
* @param uri The DASH manifest URI.
|
||||
* @param isRemoveAction Whether the data will be removed. If {@code false} it will be downloaded.
|
||||
* @param data Optional custom data for this action. If null, an empty string is used.
|
||||
* @param keys Keys of representations to be downloaded. If empty, all representations are
|
||||
* downloaded. If {@code removeAction} is true, {@code keys} must be empty.
|
||||
*/
|
||||
public DashDownloadAction(
|
||||
boolean isRemoveAction, @Nullable String data, Uri manifestUri, RepresentationKey... keys) {
|
||||
super(TYPE, VERSION, isRemoveAction, data, manifestUri, keys);
|
||||
Uri uri, boolean isRemoveAction, @Nullable String data, List<RepresentationKey> keys) {
|
||||
super(TYPE, VERSION, uri, isRemoveAction, data, keys);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DashDownloader createDownloader(DownloaderConstructorHelper constructorHelper) {
|
||||
return new DashDownloader(manifestUri, constructorHelper, keys);
|
||||
return new DashDownloader(uri, constructorHelper, keys);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -49,8 +49,11 @@ import java.util.List;
|
||||
* new DownloaderConstructorHelper(cache, factory);
|
||||
* // Create a downloader for the first representation of the first adaptation set of the first
|
||||
* // period.
|
||||
* DashDownloader dashDownloader = new DashDownloader(
|
||||
* manifestUrl, constructorHelper, new RepresentationKey[] {new RepresentationKey(0, 0, 0)});
|
||||
* DashDownloader dashDownloader =
|
||||
* new DashDownloader(
|
||||
* manifestUrl,
|
||||
* constructorHelper,
|
||||
* Collections.singletonList(new RepresentationKey(0, 0, 0)));
|
||||
* // Perform the download.
|
||||
* dashDownloader.download();
|
||||
* // Access downloaded data using CacheDataSource
|
||||
@ -60,11 +63,11 @@ import java.util.List;
|
||||
*/
|
||||
public final class DashDownloader extends SegmentDownloader<DashManifest, RepresentationKey> {
|
||||
|
||||
/** @see SegmentDownloader#SegmentDownloader(Uri, DownloaderConstructorHelper, Object[]) */
|
||||
/** @see SegmentDownloader#SegmentDownloader(Uri, DownloaderConstructorHelper, List) */
|
||||
public DashDownloader(
|
||||
Uri manifestUri,
|
||||
DownloaderConstructorHelper constructorHelper,
|
||||
@Nullable RepresentationKey[] trackKeys) {
|
||||
List<RepresentationKey> trackKeys) {
|
||||
super(manifestUri, constructorHelper, trackKeys);
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,8 @@ import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@ -51,141 +53,120 @@ public class DashDownloadActionTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDownloadActionIsNotRemoveAction() throws Exception {
|
||||
DashDownloadAction action =
|
||||
new DashDownloadAction(/* isRemoveAction= */ false, /* data= */ null, uri1);
|
||||
public void testDownloadActionIsNotRemoveAction() {
|
||||
DashDownloadAction action = newAction(uri1, /* isRemoveAction= */ false, /* data= */ null);
|
||||
assertThat(action.isRemoveAction).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveActionisRemoveAction() throws Exception {
|
||||
DashDownloadAction action2 =
|
||||
new DashDownloadAction(/* isRemoveAction= */ true, /* data= */ null, uri1);
|
||||
public void testRemoveActionisRemoveAction() {
|
||||
DashDownloadAction action2 = newAction(uri1, /* isRemoveAction= */ true, /* data= */ null);
|
||||
assertThat(action2.isRemoveAction).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateDownloader() throws Exception {
|
||||
public void testCreateDownloader() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
DashDownloadAction action =
|
||||
new DashDownloadAction(/* isRemoveAction= */ false, /* data= */ null, uri1);
|
||||
DashDownloadAction action = newAction(uri1, /* isRemoveAction= */ false, /* data= */ null);
|
||||
DownloaderConstructorHelper constructorHelper = new DownloaderConstructorHelper(
|
||||
Mockito.mock(Cache.class), DummyDataSource.FACTORY);
|
||||
assertThat(action.createDownloader(constructorHelper)).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSameUriDifferentAction_IsSameMedia() throws Exception {
|
||||
DashDownloadAction action1 =
|
||||
new DashDownloadAction(/* isRemoveAction= */ true, /* data= */ null, uri1);
|
||||
DashDownloadAction action2 =
|
||||
new DashDownloadAction(/* isRemoveAction= */ false, /* data= */ null, uri1);
|
||||
public void testSameUriDifferentAction_IsSameMedia() {
|
||||
DashDownloadAction action1 = newAction(uri1, /* isRemoveAction= */ true, /* data= */ null);
|
||||
DashDownloadAction action2 = newAction(uri1, /* isRemoveAction= */ false, /* data= */ null);
|
||||
assertThat(action1.isSameMedia(action2)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDifferentUriAndAction_IsNotSameMedia() throws Exception {
|
||||
DashDownloadAction action3 =
|
||||
new DashDownloadAction(/* isRemoveAction= */ true, /* data= */ null, uri2);
|
||||
DashDownloadAction action4 =
|
||||
new DashDownloadAction(/* isRemoveAction= */ false, /* data= */ null, uri1);
|
||||
public void testDifferentUriAndAction_IsNotSameMedia() {
|
||||
DashDownloadAction action3 = newAction(uri2, /* isRemoveAction= */ true, /* data= */ null);
|
||||
DashDownloadAction action4 = newAction(uri1, /* isRemoveAction= */ false, /* data= */ null);
|
||||
assertThat(action3.isSameMedia(action4)).isFalse();
|
||||
}
|
||||
|
||||
@SuppressWarnings("EqualsWithItself")
|
||||
@Test
|
||||
public void testEquals() throws Exception {
|
||||
DashDownloadAction action1 =
|
||||
new DashDownloadAction(/* isRemoveAction= */ true, /* data= */ null, uri1);
|
||||
public void testEquals() {
|
||||
DashDownloadAction action1 = newAction(uri1, /* isRemoveAction= */ true, /* data= */ null);
|
||||
assertThat(action1.equals(action1)).isTrue();
|
||||
|
||||
DashDownloadAction action2 =
|
||||
new DashDownloadAction(/* isRemoveAction= */ true, /* data= */ null, uri1);
|
||||
DashDownloadAction action3 =
|
||||
new DashDownloadAction(/* isRemoveAction= */ true, /* data= */ null, uri1);
|
||||
DashDownloadAction action2 = newAction(uri1, /* isRemoveAction= */ true, /* data= */ null);
|
||||
DashDownloadAction action3 = newAction(uri1, /* isRemoveAction= */ true, /* data= */ null);
|
||||
assertEqual(action2, action3);
|
||||
|
||||
DashDownloadAction action4 =
|
||||
new DashDownloadAction(/* isRemoveAction= */ true, /* data= */ null, uri1);
|
||||
DashDownloadAction action5 =
|
||||
new DashDownloadAction(/* isRemoveAction= */ false, /* data= */ null, uri1);
|
||||
DashDownloadAction action4 = newAction(uri1, /* isRemoveAction= */ true, /* data= */ null);
|
||||
DashDownloadAction action5 = newAction(uri1, /* isRemoveAction= */ false, /* data= */ null);
|
||||
assertNotEqual(action4, action5);
|
||||
|
||||
DashDownloadAction action6 =
|
||||
new DashDownloadAction(/* isRemoveAction= */ false, /* data= */ null, uri1);
|
||||
DashDownloadAction action6 = newAction(uri1, /* isRemoveAction= */ false, /* data= */ null);
|
||||
DashDownloadAction action7 =
|
||||
new DashDownloadAction(
|
||||
/* isRemoveAction= */ false, /* data= */ null, uri1, new RepresentationKey(0, 0, 0));
|
||||
newAction(
|
||||
uri1, /* isRemoveAction= */ false, /* data= */ null, new RepresentationKey(0, 0, 0));
|
||||
assertNotEqual(action6, action7);
|
||||
|
||||
DashDownloadAction action8 =
|
||||
new DashDownloadAction(
|
||||
/* isRemoveAction= */ false, /* data= */ null, uri1, new RepresentationKey(1, 1, 1));
|
||||
newAction(
|
||||
uri1, /* isRemoveAction= */ false, /* data= */ null, new RepresentationKey(1, 1, 1));
|
||||
DashDownloadAction action9 =
|
||||
new DashDownloadAction(
|
||||
/* isRemoveAction= */ false, /* data= */ null, uri1, new RepresentationKey(0, 0, 0));
|
||||
newAction(
|
||||
uri1, /* isRemoveAction= */ false, /* data= */ null, new RepresentationKey(0, 0, 0));
|
||||
assertNotEqual(action8, action9);
|
||||
|
||||
DashDownloadAction action10 =
|
||||
new DashDownloadAction(/* isRemoveAction= */ true, /* data= */ null, uri1);
|
||||
DashDownloadAction action11 =
|
||||
new DashDownloadAction(/* isRemoveAction= */ true, /* data= */ null, uri2);
|
||||
DashDownloadAction action10 = newAction(uri1, /* isRemoveAction= */ true, /* data= */ null);
|
||||
DashDownloadAction action11 = newAction(uri2, /* isRemoveAction= */ true, /* data= */ null);
|
||||
assertNotEqual(action10, action11);
|
||||
|
||||
DashDownloadAction action12 =
|
||||
new DashDownloadAction(
|
||||
newAction(
|
||||
uri1,
|
||||
/* isRemoveAction= */ false,
|
||||
/* data= */ null,
|
||||
uri1,
|
||||
new RepresentationKey(0, 0, 0),
|
||||
new RepresentationKey(1, 1, 1));
|
||||
DashDownloadAction action13 =
|
||||
new DashDownloadAction(
|
||||
newAction(
|
||||
uri1,
|
||||
/* isRemoveAction= */ false,
|
||||
/* data= */ null,
|
||||
uri1,
|
||||
new RepresentationKey(1, 1, 1),
|
||||
new RepresentationKey(0, 0, 0));
|
||||
assertEqual(action12, action13);
|
||||
|
||||
DashDownloadAction action14 =
|
||||
new DashDownloadAction(
|
||||
/* isRemoveAction= */ false, /* data= */ null, uri1, new RepresentationKey(0, 0, 0));
|
||||
newAction(
|
||||
uri1, /* isRemoveAction= */ false, /* data= */ null, new RepresentationKey(0, 0, 0));
|
||||
DashDownloadAction action15 =
|
||||
new DashDownloadAction(
|
||||
newAction(
|
||||
uri1,
|
||||
/* isRemoveAction= */ false,
|
||||
/* data= */ null,
|
||||
uri1,
|
||||
new RepresentationKey(1, 1, 1),
|
||||
new RepresentationKey(0, 0, 0));
|
||||
assertNotEqual(action14, action15);
|
||||
|
||||
DashDownloadAction action16 =
|
||||
new DashDownloadAction(/* isRemoveAction= */ false, /* data= */ null, uri1);
|
||||
DashDownloadAction action17 =
|
||||
new DashDownloadAction(
|
||||
/* isRemoveAction= */ false, /* data= */ null, uri1, new RepresentationKey[0]);
|
||||
DashDownloadAction action16 = newAction(uri1, /* isRemoveAction= */ false, /* data= */ null);
|
||||
DashDownloadAction action17 = newAction(uri1, /* isRemoveAction= */ false, /* data= */ null);
|
||||
assertEqual(action16, action17);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSerializerGetType() throws Exception {
|
||||
DashDownloadAction action =
|
||||
new DashDownloadAction(/* isRemoveAction= */ false, /* data= */ null, uri1);
|
||||
public void testSerializerGetType() {
|
||||
DashDownloadAction action = newAction(uri1, /* isRemoveAction= */ false, /* data= */ null);
|
||||
assertThat(action.type).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSerializerWriteRead() throws Exception {
|
||||
doTestSerializationRoundTrip(newAction(uri1, /* isRemoveAction= */ false, /* data= */ null));
|
||||
doTestSerializationRoundTrip(newAction(uri1, /* isRemoveAction= */ true, /* data= */ null));
|
||||
doTestSerializationRoundTrip(
|
||||
new DashDownloadAction(/* isRemoveAction= */ false, /* data= */ null, uri1));
|
||||
doTestSerializationRoundTrip(
|
||||
new DashDownloadAction(/* isRemoveAction= */ true, /* data= */ null, uri1));
|
||||
doTestSerializationRoundTrip(
|
||||
new DashDownloadAction(
|
||||
newAction(
|
||||
uri2,
|
||||
/* isRemoveAction= */ false,
|
||||
/* data= */ null,
|
||||
uri2,
|
||||
new RepresentationKey(0, 0, 0),
|
||||
new RepresentationKey(1, 1, 1)));
|
||||
}
|
||||
@ -214,4 +195,10 @@ public class DashDownloadActionTest {
|
||||
assertThat(action).isEqualTo(action2);
|
||||
}
|
||||
|
||||
private static DashDownloadAction newAction(
|
||||
Uri uri, boolean isRemoveAction, String data, RepresentationKey... keys) {
|
||||
ArrayList<RepresentationKey> keysList = new ArrayList<>();
|
||||
Collections.addAll(keysList, keys);
|
||||
return new DashDownloadAction(uri, isRemoveAction, data, keysList);
|
||||
}
|
||||
}
|
||||
|
@ -38,6 +38,8 @@ import com.google.android.exoplayer2.upstream.cache.SimpleCache;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@ -302,7 +304,14 @@ public class DashDownloaderTest {
|
||||
}
|
||||
|
||||
private DashDownloader getDashDownloader(Factory factory, RepresentationKey... keys) {
|
||||
return new DashDownloader(TEST_MPD_URI, new DownloaderConstructorHelper(cache, factory), keys);
|
||||
return new DashDownloader(
|
||||
TEST_MPD_URI, new DownloaderConstructorHelper(cache, factory), keysList(keys));
|
||||
}
|
||||
|
||||
private static ArrayList<RepresentationKey> keysList(RepresentationKey... keys) {
|
||||
ArrayList<RepresentationKey> keysList = new ArrayList<>();
|
||||
Collections.addAll(keysList, keys);
|
||||
return keysList;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ import static com.google.android.exoplayer2.testutil.CacheAsserts.assertCachedDa
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.os.ConditionVariable;
|
||||
import com.google.android.exoplayer2.offline.DownloadManager;
|
||||
import com.google.android.exoplayer2.offline.DownloaderConstructorHelper;
|
||||
@ -36,6 +37,8 @@ import com.google.android.exoplayer2.upstream.cache.NoOpCacheEvictor;
|
||||
import com.google.android.exoplayer2.upstream.cache.SimpleCache;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
@ -244,11 +247,11 @@ public class DownloadManagerDashTest {
|
||||
}
|
||||
|
||||
private void handleDownloadAction(RepresentationKey... keys) {
|
||||
downloadManager.handleAction(new DashDownloadAction(false, null, TEST_MPD_URI, keys));
|
||||
downloadManager.handleAction(newAction(TEST_MPD_URI, false, null, keys));
|
||||
}
|
||||
|
||||
private void handleRemoveAction() {
|
||||
downloadManager.handleAction(new DashDownloadAction(true, null, TEST_MPD_URI));
|
||||
downloadManager.handleAction(newAction(TEST_MPD_URI, true, null));
|
||||
}
|
||||
|
||||
private void createDownloadManager() {
|
||||
@ -272,4 +275,11 @@ public class DownloadManagerDashTest {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static DashDownloadAction newAction(
|
||||
Uri uri, boolean isRemoveAction, String data, RepresentationKey... keys) {
|
||||
ArrayList<RepresentationKey> keysList = new ArrayList<>();
|
||||
Collections.addAll(keysList, keys);
|
||||
return new DashDownloadAction(uri, isRemoveAction, data, keysList);
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ import static com.google.android.exoplayer2.testutil.CacheAsserts.assertCachedDa
|
||||
import android.app.Notification;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.offline.DownloadManager;
|
||||
import com.google.android.exoplayer2.offline.DownloadManager.TaskState;
|
||||
@ -43,6 +44,8 @@ import com.google.android.exoplayer2.util.ConditionVariable;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
@ -219,11 +222,11 @@ public class DownloadServiceDashTest {
|
||||
}
|
||||
|
||||
private void removeAll() throws Throwable {
|
||||
callDownloadServiceOnStart(new DashDownloadAction(true, null, TEST_MPD_URI));
|
||||
callDownloadServiceOnStart(newAction(TEST_MPD_URI, true, null));
|
||||
}
|
||||
|
||||
private void downloadKeys(RepresentationKey... keys) throws Throwable {
|
||||
callDownloadServiceOnStart(new DashDownloadAction(false, null, TEST_MPD_URI, keys));
|
||||
private void downloadKeys(RepresentationKey... keys) {
|
||||
callDownloadServiceOnStart(newAction(TEST_MPD_URI, false, null, keys));
|
||||
}
|
||||
|
||||
private void callDownloadServiceOnStart(final DashDownloadAction action) {
|
||||
@ -238,4 +241,11 @@ public class DownloadServiceDashTest {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static DashDownloadAction newAction(
|
||||
Uri uri, boolean isRemoveAction, String data, RepresentationKey... keys) {
|
||||
ArrayList<RepresentationKey> keysList = new ArrayList<>();
|
||||
Collections.addAll(keysList, keys);
|
||||
return new DashDownloadAction(uri, isRemoveAction, data, keysList);
|
||||
}
|
||||
}
|
||||
|
@ -24,11 +24,12 @@ import com.google.android.exoplayer2.source.hls.playlist.RenditionKey;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/** An action to download or remove downloaded HLS streams. */
|
||||
public final class HlsDownloadAction extends SegmentDownloadAction<RenditionKey> {
|
||||
|
||||
private static final String TYPE = "HlsDownloadAction";
|
||||
private static final String TYPE = "hls";
|
||||
private static final int VERSION = 0;
|
||||
|
||||
public static final Deserializer DESERIALIZER =
|
||||
@ -41,30 +42,28 @@ public final class HlsDownloadAction extends SegmentDownloadAction<RenditionKey>
|
||||
return new RenditionKey(renditionGroup, trackIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RenditionKey[] createKeyArray(int keyCount) {
|
||||
return new RenditionKey[keyCount];
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DownloadAction createDownloadAction(
|
||||
boolean isRemoveAction, String data, Uri manifestUri, RenditionKey[] keys) {
|
||||
return new HlsDownloadAction(isRemoveAction, data, manifestUri, keys);
|
||||
Uri uri, boolean isRemoveAction, String data, List<RenditionKey> keys) {
|
||||
return new HlsDownloadAction(uri, isRemoveAction, data, keys);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @see SegmentDownloadAction#SegmentDownloadAction(String, int, boolean, String, Uri,
|
||||
* Comparable[])
|
||||
* @param uri The HLS playlist URI.
|
||||
* @param isRemoveAction Whether the data will be removed. If {@code false} it will be downloaded.
|
||||
* @param data Optional custom data for this action.
|
||||
* @param keys Keys of renditions to be downloaded. If empty, all renditions are downloaded. If
|
||||
* {@code removeAction} is true, {@code keys} must empty.
|
||||
*/
|
||||
public HlsDownloadAction(
|
||||
boolean isRemoveAction, @Nullable String data, Uri manifestUri, RenditionKey... keys) {
|
||||
super(TYPE, VERSION, isRemoveAction, data, manifestUri, keys);
|
||||
Uri uri, boolean isRemoveAction, @Nullable String data, List<RenditionKey> keys) {
|
||||
super(TYPE, VERSION, uri, isRemoveAction, data, keys);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected HlsDownloader createDownloader(DownloaderConstructorHelper constructorHelper) {
|
||||
return new HlsDownloader(manifestUri, constructorHelper, keys);
|
||||
return new HlsDownloader(uri, constructorHelper, keys);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -37,9 +37,11 @@ import java.util.List;
|
||||
/** A downloader for HLS streams. */
|
||||
public final class HlsDownloader extends SegmentDownloader<HlsMasterPlaylist, RenditionKey> {
|
||||
|
||||
/** @see SegmentDownloader#SegmentDownloader(Uri, DownloaderConstructorHelper, Object[]) */
|
||||
/** @see SegmentDownloader#SegmentDownloader(Uri, DownloaderConstructorHelper, List) */
|
||||
public HlsDownloader(
|
||||
Uri manifestUri, DownloaderConstructorHelper constructorHelper, RenditionKey[] trackKeys) {
|
||||
Uri manifestUri,
|
||||
DownloaderConstructorHelper constructorHelper,
|
||||
List<RenditionKey> trackKeys) {
|
||||
super(manifestUri, constructorHelper, trackKeys);
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,6 @@ import static com.google.android.exoplayer2.testutil.CacheAsserts.assertCachedDa
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.offline.DownloaderConstructorHelper;
|
||||
import com.google.android.exoplayer2.source.hls.playlist.RenditionKey;
|
||||
import com.google.android.exoplayer2.testutil.FakeDataSet;
|
||||
@ -44,6 +43,8 @@ import com.google.android.exoplayer2.upstream.cache.NoOpCacheEvictor;
|
||||
import com.google.android.exoplayer2.upstream.cache.SimpleCache;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@ -78,7 +79,7 @@ public class HlsDownloaderTest {
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
public void tearDown() {
|
||||
Util.recursiveDelete(tempFolder);
|
||||
}
|
||||
|
||||
@ -132,7 +133,7 @@ public class HlsDownloaderTest {
|
||||
.setRandomData(MEDIA_PLAYLIST_3_DIR + "fileSequence1.ts", 14)
|
||||
.setRandomData(MEDIA_PLAYLIST_3_DIR + "fileSequence2.ts", 15);
|
||||
|
||||
HlsDownloader downloader = getHlsDownloader(MASTER_PLAYLIST_URI, null);
|
||||
HlsDownloader downloader = getHlsDownloader(MASTER_PLAYLIST_URI, getKeys());
|
||||
downloader.download();
|
||||
|
||||
assertCachedData(cache, fakeDataSet);
|
||||
@ -152,7 +153,7 @@ public class HlsDownloaderTest {
|
||||
|
||||
@Test
|
||||
public void testDownloadMediaPlaylist() throws Exception {
|
||||
HlsDownloader downloader = getHlsDownloader(MEDIA_PLAYLIST_1_URI);
|
||||
HlsDownloader downloader = getHlsDownloader(MEDIA_PLAYLIST_1_URI, getKeys());
|
||||
downloader.download();
|
||||
|
||||
assertCachedData(
|
||||
@ -175,21 +176,21 @@ public class HlsDownloaderTest {
|
||||
.setRandomData("fileSequence1.ts", 11)
|
||||
.setRandomData("fileSequence2.ts", 12);
|
||||
|
||||
HlsDownloader downloader = getHlsDownloader(ENC_MEDIA_PLAYLIST_URI);
|
||||
HlsDownloader downloader = getHlsDownloader(ENC_MEDIA_PLAYLIST_URI, getKeys());
|
||||
downloader.download();
|
||||
assertCachedData(cache, fakeDataSet);
|
||||
}
|
||||
|
||||
private HlsDownloader getHlsDownloader(String mediaPlaylistUri, @Nullable RenditionKey... keys) {
|
||||
private HlsDownloader getHlsDownloader(String mediaPlaylistUri, List<RenditionKey> keys) {
|
||||
Factory factory = new Factory(null).setFakeDataSet(fakeDataSet);
|
||||
return new HlsDownloader(
|
||||
Uri.parse(mediaPlaylistUri), new DownloaderConstructorHelper(cache, factory), keys);
|
||||
}
|
||||
|
||||
private static RenditionKey[] getKeys(int... variantIndices) {
|
||||
RenditionKey[] renditionKeys = new RenditionKey[variantIndices.length];
|
||||
for (int i = 0; i < variantIndices.length; i++) {
|
||||
renditionKeys[i] = new RenditionKey(RenditionKey.GROUP_VARIANTS, variantIndices[i]);
|
||||
private static ArrayList<RenditionKey> getKeys(int... variantIndices) {
|
||||
ArrayList<RenditionKey> renditionKeys = new ArrayList<>();
|
||||
for (int variantIndex : variantIndices) {
|
||||
renditionKeys.add(new RenditionKey(RenditionKey.GROUP_VARIANTS, variantIndex));
|
||||
}
|
||||
return renditionKeys;
|
||||
}
|
||||
|
@ -24,11 +24,12 @@ import com.google.android.exoplayer2.source.smoothstreaming.manifest.TrackKey;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/** An action to download or remove downloaded SmoothStreaming streams. */
|
||||
public final class SsDownloadAction extends SegmentDownloadAction<TrackKey> {
|
||||
|
||||
private static final String TYPE = "SsDownloadAction";
|
||||
private static final String TYPE = "ss";
|
||||
private static final int VERSION = 0;
|
||||
|
||||
public static final Deserializer DESERIALIZER =
|
||||
@ -39,30 +40,28 @@ public final class SsDownloadAction extends SegmentDownloadAction<TrackKey> {
|
||||
return new TrackKey(input.readInt(), input.readInt());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TrackKey[] createKeyArray(int keyCount) {
|
||||
return new TrackKey[keyCount];
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DownloadAction createDownloadAction(
|
||||
boolean isRemoveAction, String data, Uri manifestUri, TrackKey[] keys) {
|
||||
return new SsDownloadAction(isRemoveAction, data, manifestUri, keys);
|
||||
Uri uri, boolean isRemoveAction, String data, List<TrackKey> keys) {
|
||||
return new SsDownloadAction(uri, isRemoveAction, data, keys);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @see SegmentDownloadAction#SegmentDownloadAction(String, int, boolean, String, Uri,
|
||||
* Comparable[])
|
||||
* @param uri The SmoothStreaming manifest URI.
|
||||
* @param isRemoveAction Whether the data will be removed. If {@code false} it will be downloaded.
|
||||
* @param data Optional custom data for this action.
|
||||
* @param keys Keys of tracks to be downloaded. If empty, all tracks are downloaded. If {@code
|
||||
* removeAction} is true, {@code keys} must be empty.
|
||||
*/
|
||||
public SsDownloadAction(
|
||||
boolean isRemoveAction, @Nullable String data, Uri manifestUri, TrackKey... keys) {
|
||||
super(TYPE, VERSION, isRemoveAction, data, manifestUri, keys);
|
||||
Uri uri, boolean isRemoveAction, @Nullable String data, List<TrackKey> keys) {
|
||||
super(TYPE, VERSION, uri, isRemoveAction, data, keys);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SsDownloader createDownloader(DownloaderConstructorHelper constructorHelper) {
|
||||
return new SsDownloader(manifestUri, constructorHelper, keys);
|
||||
return new SsDownloader(uri, constructorHelper, keys);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -42,8 +42,11 @@ import java.util.List;
|
||||
* DownloaderConstructorHelper constructorHelper =
|
||||
* new DownloaderConstructorHelper(cache, factory);
|
||||
* // Create a downloader for the first track of the first stream element.
|
||||
* SsDownloader ssDownloader = new SsDownloader(
|
||||
* manifestUrl, constructorHelper, new TrackKey[] {new TrackKey(0, 0)});
|
||||
* SsDownloader ssDownloader =
|
||||
* new SsDownloader(
|
||||
* manifestUrl,
|
||||
* constructorHelper,
|
||||
* Collections.singletonList(new TrackKey(0, 0)));
|
||||
* // Perform the download.
|
||||
* ssDownloader.download();
|
||||
* // Access downloaded data using CacheDataSource
|
||||
@ -53,9 +56,9 @@ import java.util.List;
|
||||
*/
|
||||
public final class SsDownloader extends SegmentDownloader<SsManifest, TrackKey> {
|
||||
|
||||
/** @see SegmentDownloader#SegmentDownloader(Uri, DownloaderConstructorHelper, Object[]) */
|
||||
/** @see SegmentDownloader#SegmentDownloader(Uri, DownloaderConstructorHelper, List) */
|
||||
public SsDownloader(
|
||||
Uri manifestUri, DownloaderConstructorHelper constructorHelper, TrackKey[] trackKeys) {
|
||||
Uri manifestUri, DownloaderConstructorHelper constructorHelper, List<TrackKey> trackKeys) {
|
||||
super(SsUtil.fixManifestUri(manifestUri), constructorHelper, trackKeys);
|
||||
}
|
||||
|
||||
@ -69,7 +72,7 @@ public final class SsDownloader extends SegmentDownloader<SsManifest, TrackKey>
|
||||
|
||||
@Override
|
||||
protected List<Segment> getSegments(
|
||||
DataSource dataSource, SsManifest manifest, boolean allowIncompleteList) throws IOException {
|
||||
DataSource dataSource, SsManifest manifest, boolean allowIncompleteList) {
|
||||
ArrayList<Segment> segments = new ArrayList<>();
|
||||
for (StreamElement streamElement : manifest.streamElements) {
|
||||
for (int i = 0; i < streamElement.formats.length; i++) {
|
||||
|
@ -123,8 +123,7 @@ public final class DashDownloadTest extends ActivityInstrumentationTestCase2<Hos
|
||||
}
|
||||
DownloaderConstructorHelper constructorHelper =
|
||||
new DownloaderConstructorHelper(cache, httpDataSourceFactory);
|
||||
return new DashDownloader(
|
||||
MANIFEST_URI, constructorHelper, keys.toArray(new RepresentationKey[keys.size()]));
|
||||
return new DashDownloader(MANIFEST_URI, constructorHelper, keys);
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user