diff --git a/library/core/src/main/java/com/google/android/exoplayer2/upstream/DataSource.java b/library/core/src/main/java/com/google/android/exoplayer2/upstream/DataSource.java index 4a2354e180..ce3230fa43 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/upstream/DataSource.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/upstream/DataSource.java @@ -16,6 +16,7 @@ package com.google.android.exoplayer2.upstream; import android.net.Uri; +import android.support.annotation.Nullable; import com.google.android.exoplayer2.C; import java.io.IOException; @@ -79,7 +80,7 @@ public interface DataSource { * * @return The {@link Uri} from which data is being read, or null if the source is not open. */ - Uri getUri(); + @Nullable Uri getUri(); /** * Closes the source. diff --git a/library/core/src/main/java/com/google/android/exoplayer2/upstream/DataSpec.java b/library/core/src/main/java/com/google/android/exoplayer2/upstream/DataSpec.java index a6b89a334d..ad7a9d0147 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/upstream/DataSpec.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/upstream/DataSpec.java @@ -61,7 +61,7 @@ public final class DataSpec { /** * Body for a POST request, null otherwise. */ - public final byte[] postBody; + public final @Nullable byte[] postBody; /** * The absolute position of the data in the full stream. */ @@ -81,12 +81,12 @@ public final class DataSpec { * A key that uniquely identifies the original stream. Used for cache indexing. May be null if the * {@link DataSpec} is not intended to be used in conjunction with a cache. */ - @Nullable public final String key; + public final @Nullable String key; /** * Request flags. Currently {@link #FLAG_ALLOW_GZIP} and * {@link #FLAG_ALLOW_CACHING_UNKNOWN_LENGTH} are the only supported flags. */ - @Flags public final int flags; + public final @Flags int flags; /** * Construct a {@link DataSpec} for the given uri and with {@link #key} set to null. @@ -128,7 +128,8 @@ public final class DataSpec { * @param key {@link #key}. * @param flags {@link #flags}. */ - public DataSpec(Uri uri, long absoluteStreamPosition, long length, String key, @Flags int flags) { + public DataSpec( + Uri uri, long absoluteStreamPosition, long length, @Nullable String key, @Flags int flags) { this(uri, absoluteStreamPosition, absoluteStreamPosition, length, key, flags); } @@ -143,7 +144,12 @@ public final class DataSpec { * @param key {@link #key}. * @param flags {@link #flags}. */ - public DataSpec(Uri uri, long absoluteStreamPosition, long position, long length, String key, + public DataSpec( + Uri uri, + long absoluteStreamPosition, + long position, + long length, + @Nullable String key, @Flags int flags) { this(uri, null, absoluteStreamPosition, position, length, key, flags); } @@ -162,7 +168,7 @@ public final class DataSpec { */ public DataSpec( Uri uri, - byte[] postBody, + @Nullable byte[] postBody, long absoluteStreamPosition, long position, long length, @@ -222,4 +228,13 @@ public final class DataSpec { } } + /** + * Returns a copy of this {@link DataSpec} with the specified Uri. + * + * @param uri The new source {@link Uri}. + * @return The copied {@link DataSpec} with the specified Uri. + */ + public DataSpec withUri(Uri uri) { + return new DataSpec(uri, postBody, absoluteStreamPosition, position, length, key, flags); + } } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/upstream/PriorityDataSource.java b/library/core/src/main/java/com/google/android/exoplayer2/upstream/PriorityDataSource.java index a36ccd11b1..729f7fe179 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/upstream/PriorityDataSource.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/upstream/PriorityDataSource.java @@ -16,6 +16,7 @@ package com.google.android.exoplayer2.upstream; import android.net.Uri; +import android.support.annotation.Nullable; import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.PriorityTaskManager; import java.io.IOException; @@ -63,7 +64,7 @@ public final class PriorityDataSource implements DataSource { } @Override - public Uri getUri() { + public @Nullable Uri getUri() { return upstream.getUri(); } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/util/UriUtil.java b/library/core/src/main/java/com/google/android/exoplayer2/util/UriUtil.java index 6592273d03..071ebf2084 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/util/UriUtil.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/util/UriUtil.java @@ -143,6 +143,26 @@ public final class UriUtil { } } + /** + * Removes query parameter from an Uri, if present. + * + * @param uri The uri. + * @param queryParameterName The name of the query parameter. + * @return The uri without the query parameter. + */ + public static Uri removeQueryParameter(Uri uri, String queryParameterName) { + Uri.Builder builder = uri.buildUpon(); + builder.clearQuery(); + for (String key : uri.getQueryParameterNames()) { + if (!key.equals(queryParameterName)) { + for (String value : uri.getQueryParameters(key)) { + builder.appendQueryParameter(key, value); + } + } + } + return builder.build(); + } + /** * Removes dot segments from the path of a URI. * diff --git a/library/core/src/test/java/com/google/android/exoplayer2/util/UriUtilTest.java b/library/core/src/test/java/com/google/android/exoplayer2/util/UriUtilTest.java index a52867e1b2..82c62ecb3e 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/util/UriUtilTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/util/UriUtilTest.java @@ -15,9 +15,11 @@ */ package com.google.android.exoplayer2.util; +import static com.google.android.exoplayer2.util.UriUtil.removeQueryParameter; import static com.google.android.exoplayer2.util.UriUtil.resolve; import static com.google.common.truth.Truth.assertThat; +import android.net.Uri; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.RobolectricTestRunner; @@ -104,4 +106,36 @@ public final class UriUtilTest { assertThat(resolve("a:b", "../c")).isEqualTo("a:c"); } + @Test + public void removeOnlyQueryParameter() { + Uri uri = Uri.parse("http://uri?query=value"); + assertThat(removeQueryParameter(uri, "query").toString()).isEqualTo("http://uri"); + } + + @Test + public void removeFirstQueryParameter() { + Uri uri = Uri.parse("http://uri?query=value&second=value2"); + assertThat(removeQueryParameter(uri, "query").toString()).isEqualTo("http://uri?second=value2"); + } + + @Test + public void removeMiddleQueryParameter() { + Uri uri = Uri.parse("http://uri?first=value1&query=value&last=value2"); + assertThat(removeQueryParameter(uri, "query").toString()) + .isEqualTo("http://uri?first=value1&last=value2"); + } + + @Test + public void removeLastQueryParameter() { + Uri uri = Uri.parse("http://uri?first=value1&query=value"); + assertThat(removeQueryParameter(uri, "query").toString()).isEqualTo("http://uri?first=value1"); + } + + @Test + public void removeNonExistentQueryParameter() { + Uri uri = Uri.parse("http://uri"); + assertThat(removeQueryParameter(uri, "foo").toString()).isEqualTo("http://uri"); + uri = Uri.parse("http://uri?query=value"); + assertThat(removeQueryParameter(uri, "foo").toString()).isEqualTo("http://uri?query=value"); + } } diff --git a/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeDataSource.java b/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeDataSource.java index 2675e1f0d7..de623b59c9 100644 --- a/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeDataSource.java +++ b/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeDataSource.java @@ -217,6 +217,11 @@ public class FakeDataSource implements DataSource { return dataSpecs; } + /** Returns whether the data source is currently opened. */ + public final boolean isOpened() { + return opened; + } + protected void onDataRead(int bytesRead) throws IOException { // Do nothing. Can be overridden. } diff --git a/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeMediaSource.java b/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeMediaSource.java index 905adae092..ffc877bf42 100644 --- a/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeMediaSource.java +++ b/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeMediaSource.java @@ -159,6 +159,11 @@ public class FakeMediaSource extends BaseMediaSource { } } + /** Asserts that the source has been prepared. */ + public void assertPrepared() { + assertThat(preparedSource).isTrue(); + } + /** * Assert that the source and all periods have been released. */