Add DataSource
contract test checking scheme case insensitivity
Systems accepting URIs should treat schemes as case-insensitive ([RFC 3986 Section 3.1](https://www.rfc-editor.org/rfc/rfc3986#section-3.1)): > An implementation should accept uppercase letters as equivalent to > lowercase in scheme names (e.g., allow "HTTP" as well as "http") for > the sake of robustness PiperOrigin-RevId: 528735287
This commit is contained in:
parent
ad2d4f5008
commit
b4b7e0e7c0
@ -124,6 +124,8 @@
|
|||||||
* Text:
|
* Text:
|
||||||
* SSA: Add support for UTF-16 files if they start with a byte order mark
|
* SSA: Add support for UTF-16 files if they start with a byte order mark
|
||||||
([#319](https://github.com/androidx/media/issues/319)).
|
([#319](https://github.com/androidx/media/issues/319)).
|
||||||
|
* Test Utilities:
|
||||||
|
* Check for URI scheme case insensitivity in `DataSourceContractTest`.
|
||||||
* Remove deprecated symbols:
|
* Remove deprecated symbols:
|
||||||
* Remove `DefaultAudioSink` constructors, use `DefaultAudioSink.Builder`
|
* Remove `DefaultAudioSink` constructors, use `DefaultAudioSink.Builder`
|
||||||
instead.
|
instead.
|
||||||
|
@ -75,13 +75,13 @@ public final class ContentDataSource extends BaseDataSource {
|
|||||||
@SuppressWarnings("InlinedApi") // We are inlining EXTRA_ACCEPT_ORIGINAL_MEDIA_FORMAT.
|
@SuppressWarnings("InlinedApi") // We are inlining EXTRA_ACCEPT_ORIGINAL_MEDIA_FORMAT.
|
||||||
public long open(DataSpec dataSpec) throws ContentDataSourceException {
|
public long open(DataSpec dataSpec) throws ContentDataSourceException {
|
||||||
try {
|
try {
|
||||||
Uri uri = dataSpec.uri;
|
Uri uri = dataSpec.uri.normalizeScheme();
|
||||||
this.uri = uri;
|
this.uri = uri;
|
||||||
|
|
||||||
transferInitializing(dataSpec);
|
transferInitializing(dataSpec);
|
||||||
|
|
||||||
AssetFileDescriptor assetFileDescriptor;
|
AssetFileDescriptor assetFileDescriptor;
|
||||||
if ("content".equals(dataSpec.uri.getScheme())) {
|
if ("content".equals(uri.getScheme())) {
|
||||||
Bundle providerOptions = new Bundle();
|
Bundle providerOptions = new Bundle();
|
||||||
// We don't want compatible media transcoding.
|
// We don't want compatible media transcoding.
|
||||||
providerOptions.putBoolean(MediaStore.EXTRA_ACCEPT_ORIGINAL_MEDIA_FORMAT, true);
|
providerOptions.putBoolean(MediaStore.EXTRA_ACCEPT_ORIGINAL_MEDIA_FORMAT, true);
|
||||||
|
@ -50,7 +50,7 @@ public final class DataSchemeDataSource extends BaseDataSource {
|
|||||||
public long open(DataSpec dataSpec) throws IOException {
|
public long open(DataSpec dataSpec) throws IOException {
|
||||||
transferInitializing(dataSpec);
|
transferInitializing(dataSpec);
|
||||||
this.dataSpec = dataSpec;
|
this.dataSpec = dataSpec;
|
||||||
Uri uri = dataSpec.uri;
|
Uri uri = dataSpec.uri.normalizeScheme();
|
||||||
String scheme = uri.getScheme();
|
String scheme = uri.getScheme();
|
||||||
Assertions.checkArgument(SCHEME_DATA.equals(scheme), "Unsupported scheme: " + scheme);
|
Assertions.checkArgument(SCHEME_DATA.equals(scheme), "Unsupported scheme: " + scheme);
|
||||||
String[] uriParts = Util.split(uri.getSchemeSpecificPart(), ",");
|
String[] uriParts = Util.split(uri.getSchemeSpecificPart(), ",");
|
||||||
|
@ -116,7 +116,7 @@ public final class RawResourceDataSource extends BaseDataSource {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long open(DataSpec dataSpec) throws RawResourceDataSourceException {
|
public long open(DataSpec dataSpec) throws RawResourceDataSourceException {
|
||||||
Uri uri = dataSpec.uri;
|
Uri uri = dataSpec.uri.normalizeScheme();
|
||||||
this.uri = uri;
|
this.uri = uri;
|
||||||
|
|
||||||
int resourceId;
|
int resourceId;
|
||||||
@ -150,10 +150,13 @@ public final class RawResourceDataSource extends BaseDataSource {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new RawResourceDataSourceException(
|
throw new RawResourceDataSourceException(
|
||||||
"URI must either use scheme "
|
"Unsupported URI scheme ("
|
||||||
|
+ uri.getScheme()
|
||||||
|
+ "). Only "
|
||||||
+ RAW_RESOURCE_SCHEME
|
+ RAW_RESOURCE_SCHEME
|
||||||
+ " or "
|
+ " and "
|
||||||
+ ContentResolver.SCHEME_ANDROID_RESOURCE,
|
+ ContentResolver.SCHEME_ANDROID_RESOURCE
|
||||||
|
+ " are supported.",
|
||||||
/* cause= */ null,
|
/* cause= */ null,
|
||||||
PlaybackException.ERROR_CODE_FAILED_RUNTIME_CHECK);
|
PlaybackException.ERROR_CODE_FAILED_RUNTIME_CHECK);
|
||||||
}
|
}
|
||||||
|
@ -68,7 +68,7 @@ public class ResolvingDataSourceContractTest extends DataSourceContractTest {
|
|||||||
new Resolver() {
|
new Resolver() {
|
||||||
@Override
|
@Override
|
||||||
public DataSpec resolveDataSpec(DataSpec dataSpec) throws IOException {
|
public DataSpec resolveDataSpec(DataSpec dataSpec) throws IOException {
|
||||||
return URI.equals(dataSpec.uri.toString())
|
return URI.equals(dataSpec.uri.normalizeScheme().toString())
|
||||||
? dataSpec.buildUpon().setUri(RESOLVED_URI).build()
|
? dataSpec.buildUpon().setUri(RESOLVED_URI).build()
|
||||||
: dataSpec;
|
: dataSpec;
|
||||||
}
|
}
|
||||||
|
@ -386,6 +386,44 @@ public abstract class DataSourceContractTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void uriSchemeIsCaseInsensitive() throws Exception {
|
||||||
|
ImmutableList<TestResource> resources = getTestResources();
|
||||||
|
Assertions.checkArgument(!resources.isEmpty(), "Must provide at least one test resource.");
|
||||||
|
|
||||||
|
for (int i = 0; i < resources.size(); i++) {
|
||||||
|
additionalFailureInfo.setInfo(getFailureLabel(resources, i));
|
||||||
|
TestResource resource = resources.get(i);
|
||||||
|
@Nullable String scheme = resource.getUri().getScheme();
|
||||||
|
if (scheme == null) {
|
||||||
|
// No scheme for which to check case-insensitivity.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
DataSource dataSource = createDataSource();
|
||||||
|
Uri uri =
|
||||||
|
resource
|
||||||
|
.getUri()
|
||||||
|
.buildUpon()
|
||||||
|
.scheme(invertAsciiCaseOfEveryOtherCharacter(scheme))
|
||||||
|
.build();
|
||||||
|
try {
|
||||||
|
long length = dataSource.open(new DataSpec.Builder().setUri(uri).build());
|
||||||
|
byte[] data =
|
||||||
|
unboundedReadsAreIndefinite()
|
||||||
|
? DataSourceUtil.readExactly(dataSource, resource.getExpectedBytes().length)
|
||||||
|
: DataSourceUtil.readToEnd(dataSource);
|
||||||
|
|
||||||
|
if (length != C.LENGTH_UNSET) {
|
||||||
|
assertThat(length).isEqualTo(resource.getExpectedBytes().length);
|
||||||
|
}
|
||||||
|
assertThat(data).isEqualTo(resource.getExpectedBytes());
|
||||||
|
} finally {
|
||||||
|
dataSource.close();
|
||||||
|
}
|
||||||
|
additionalFailureInfo.setInfo(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void resourceNotFound() throws Exception {
|
public void resourceNotFound() throws Exception {
|
||||||
DataSource dataSource = createDataSource();
|
DataSource dataSource = createDataSource();
|
||||||
|
@ -267,7 +267,7 @@ public class FakeDataSet {
|
|||||||
/** Returns a new {@link FakeData} with the given {@code uri}. */
|
/** Returns a new {@link FakeData} with the given {@code uri}. */
|
||||||
public FakeData newData(Uri uri) {
|
public FakeData newData(Uri uri) {
|
||||||
FakeData data = new FakeData(this, uri);
|
FakeData data = new FakeData(this, uri);
|
||||||
dataMap.put(uri, data);
|
dataMap.put(uri.normalizeScheme(), data);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -280,7 +280,7 @@ public class FakeDataSet {
|
|||||||
/** Returns the data for the given {@code uri}, or {@code defaultData} if no data is set. */
|
/** Returns the data for the given {@code uri}, or {@code defaultData} if no data is set. */
|
||||||
@Nullable
|
@Nullable
|
||||||
public FakeData getData(Uri uri) {
|
public FakeData getData(Uri uri) {
|
||||||
@Nullable FakeData data = dataMap.get(uri);
|
@Nullable FakeData data = dataMap.get(uri.normalizeScheme());
|
||||||
return data != null ? data : defaultData;
|
return data != null ? data : defaultData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,11 +51,11 @@ public final class FakeDataSetTest {
|
|||||||
.setData(uris[2], testData[3]);
|
.setData(uris[2], testData[3]);
|
||||||
|
|
||||||
assertThat(fakeDataSet.getAllData().size()).isEqualTo(4);
|
assertThat(fakeDataSet.getAllData().size()).isEqualTo(4);
|
||||||
assertThat(fakeDataSet.getData("unseen_uri")).isEqualTo(fakeDataSet.getData((Uri) null));
|
assertThat(fakeDataSet.getData("unseen_uri")).isEqualTo(fakeDataSet.getData("not a real key"));
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
assertThat(fakeDataSet.getData(uris[i]).uri).isEqualTo(uris[i]);
|
assertThat(fakeDataSet.getData(uris[i]).uri).isEqualTo(uris[i]);
|
||||||
}
|
}
|
||||||
assertThat(fakeDataSet.getData((Uri) null).getData()).isEqualTo(testData[0]);
|
assertThat(fakeDataSet.getData("not a real key").getData()).isEqualTo(testData[0]);
|
||||||
for (int i = 1; i < 4; i++) {
|
for (int i = 1; i < 4; i++) {
|
||||||
assertThat(fakeDataSet.getData(uris[i - 1]).getData()).isEqualTo(testData[i]);
|
assertThat(fakeDataSet.getData(uris[i - 1]).getData()).isEqualTo(testData[i]);
|
||||||
}
|
}
|
||||||
@ -79,7 +79,7 @@ public final class FakeDataSetTest {
|
|||||||
.appendReadError(exception)
|
.appendReadError(exception)
|
||||||
.endData();
|
.endData();
|
||||||
|
|
||||||
List<Segment> segments = fakeDataSet.getData((Uri) null).getSegments();
|
List<Segment> segments = fakeDataSet.getData("not a real key").getSegments();
|
||||||
assertThat(segments.size()).isEqualTo(5);
|
assertThat(segments.size()).isEqualTo(5);
|
||||||
assertSegment(segments.get(0), testData, 3, 0, null, null);
|
assertSegment(segments.get(0), testData, 3, 0, null, null);
|
||||||
assertSegment(segments.get(1), testData, 3, 3, null, null);
|
assertSegment(segments.get(1), testData, 3, 3, null, null);
|
||||||
@ -90,7 +90,15 @@ public final class FakeDataSetTest {
|
|||||||
byte[] allData = new byte[6];
|
byte[] allData = new byte[6];
|
||||||
System.arraycopy(testData, 0, allData, 0, 3);
|
System.arraycopy(testData, 0, allData, 0, 3);
|
||||||
System.arraycopy(testData, 0, allData, 3, 3);
|
System.arraycopy(testData, 0, allData, 3, 3);
|
||||||
assertThat(fakeDataSet.getData((Uri) null).getData()).isEqualTo(allData);
|
assertThat(fakeDataSet.getData("not a real key").getData()).isEqualTo(allData);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void uriSchemesAreCaseInsensitive() {
|
||||||
|
byte[] data = TestUtil.buildTestData(3);
|
||||||
|
FakeDataSet fakeDataSet = new FakeDataSet().setData("HtTp://example.test/path/to/data", data);
|
||||||
|
|
||||||
|
assertThat(fakeDataSet.getData("hTtP://example.test/path/to/data").getData()).isEqualTo(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void assertSegment(
|
private static void assertSegment(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user