Fix ContentDataSource and enhance tests to validate read data
This commit is contained in:
parent
2da22e9e0f
commit
8bb643976f
@ -25,8 +25,8 @@
|
||||
tools:ignore="MissingApplicationIcon,HardcodedDebugMode">
|
||||
<uses-library android:name="android.test.runner"/>
|
||||
<provider
|
||||
android:authorities="exoplayer"
|
||||
android:name="com.google.android.exoplayer2.upstream.TestDataProvider"/>
|
||||
android:authorities="com.google.android.exoplayer2.core.test"
|
||||
android:name="com.google.android.exoplayer2.upstream.ContentDataSourceTest$TestContentProvider"/>
|
||||
</application>
|
||||
|
||||
<instrumentation
|
||||
|
Binary file not shown.
@ -1,16 +0,0 @@
|
||||
package com.google.android.exoplayer2.upstream;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.net.Uri;
|
||||
|
||||
final class AndroidDataSourceConstants {
|
||||
static final long SAMPLE_MP4_BYTES = 101597;
|
||||
static final String SAMPLE_MP4_PATH = "/mp4/sample.mp4";
|
||||
static final String TEST_DATA_PROVIDER_AUTHORITY = "exoplayer";
|
||||
static final Uri NULL_DESCRIPTOR_URI = new Uri.Builder()
|
||||
.scheme(ContentResolver.SCHEME_CONTENT)
|
||||
.authority(TEST_DATA_PROVIDER_AUTHORITY)
|
||||
.build();
|
||||
|
||||
private AndroidDataSourceConstants() {}
|
||||
}
|
@ -1,21 +1,62 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.google.android.exoplayer2.upstream;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.test.InstrumentationTestCase;
|
||||
import android.test.MoreAsserts;
|
||||
import com.google.android.exoplayer2.testutil.TestUtil;
|
||||
|
||||
import static com.google.android.exoplayer2.upstream.AndroidDataSourceConstants.SAMPLE_MP4_BYTES;
|
||||
import static com.google.android.exoplayer2.upstream.AndroidDataSourceConstants.SAMPLE_MP4_PATH;
|
||||
/**
|
||||
* Unit tests for {@link AssetDataSource}.
|
||||
*/
|
||||
public final class AssetDataSourceTest extends InstrumentationTestCase {
|
||||
|
||||
public class AssetDataSourceTest extends InstrumentationTestCase {
|
||||
private static final String DATA_PATH = "binary/1024_incrementing_bytes.mp3";
|
||||
private static final long DATA_LENGTH = 1024;
|
||||
|
||||
public void testAssetDataSource() throws Exception {
|
||||
final Context context = getInstrumentation().getContext();
|
||||
public void testReadFileUri() throws Exception {
|
||||
Context context = getInstrumentation().getContext();
|
||||
AssetDataSource dataSource = new AssetDataSource(context);
|
||||
Uri assetUri = Uri.parse("file:///android_asset" + SAMPLE_MP4_PATH);
|
||||
Uri assetUri = Uri.parse("file:///android_asset/" + DATA_PATH);
|
||||
DataSpec dataSpec = new DataSpec(assetUri);
|
||||
long sourceLengthBytes = dataSource.open(dataSpec);
|
||||
|
||||
assertEquals(SAMPLE_MP4_BYTES, sourceLengthBytes);
|
||||
try {
|
||||
long length = dataSource.open(dataSpec);
|
||||
assertEquals(DATA_LENGTH, length);
|
||||
byte[] readData = TestUtil.readToEnd(dataSource);
|
||||
MoreAsserts.assertEquals(TestUtil.getByteArray(getInstrumentation(), DATA_PATH), readData);
|
||||
} finally {
|
||||
dataSource.close();
|
||||
}
|
||||
}
|
||||
|
||||
public void testReadAssetUri() throws Exception {
|
||||
Context context = getInstrumentation().getContext();
|
||||
AssetDataSource dataSource = new AssetDataSource(context);
|
||||
Uri assetUri = Uri.parse("asset:///" + DATA_PATH);
|
||||
DataSpec dataSpec = new DataSpec(assetUri);
|
||||
try {
|
||||
long length = dataSource.open(dataSpec);
|
||||
assertEquals(DATA_LENGTH, length);
|
||||
byte[] readData = TestUtil.readToEnd(dataSource);
|
||||
MoreAsserts.assertEquals(TestUtil.getByteArray(getInstrumentation(), DATA_PATH), readData);
|
||||
} finally {
|
||||
dataSource.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,40 +1,127 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.google.android.exoplayer2.upstream;
|
||||
|
||||
import android.content.ContentProvider;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.ContentValues;
|
||||
import android.content.res.AssetFileDescriptor;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.test.InstrumentationTestCase;
|
||||
import android.test.MoreAsserts;
|
||||
import com.google.android.exoplayer2.testutil.TestUtil;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
|
||||
import static com.google.android.exoplayer2.upstream.AndroidDataSourceConstants.NULL_DESCRIPTOR_URI;
|
||||
import static com.google.android.exoplayer2.upstream.AndroidDataSourceConstants.SAMPLE_MP4_BYTES;
|
||||
import static com.google.android.exoplayer2.upstream.AndroidDataSourceConstants.SAMPLE_MP4_PATH;
|
||||
import static com.google.android.exoplayer2.upstream.AndroidDataSourceConstants.TEST_DATA_PROVIDER_AUTHORITY;
|
||||
/**
|
||||
* Unit tests for {@link ContentDataSource}.
|
||||
*/
|
||||
public final class ContentDataSourceTest extends InstrumentationTestCase {
|
||||
|
||||
public class ContentDataSourceTest extends InstrumentationTestCase {
|
||||
private static final String DATA_PATH = "binary/1024_incrementing_bytes.mp3";
|
||||
private static final long DATA_LENGTH = 1024;
|
||||
|
||||
public void testValidContentDataSource() throws Exception {
|
||||
Context context = getInstrumentation().getContext();
|
||||
ContentDataSource dataSource = new ContentDataSource(context);
|
||||
public void testReadValidUri() throws Exception {
|
||||
ContentDataSource dataSource = new ContentDataSource(getInstrumentation().getContext());
|
||||
Uri contentUri = new Uri.Builder()
|
||||
.scheme(ContentResolver.SCHEME_CONTENT)
|
||||
.authority(TEST_DATA_PROVIDER_AUTHORITY)
|
||||
.path(SAMPLE_MP4_PATH).build();
|
||||
.scheme(ContentResolver.SCHEME_CONTENT)
|
||||
.authority(TestContentProvider.AUTHORITY)
|
||||
.path(DATA_PATH).build();
|
||||
DataSpec dataSpec = new DataSpec(contentUri);
|
||||
long sourceLengthBytes = dataSource.open(dataSpec);
|
||||
|
||||
assertEquals(SAMPLE_MP4_BYTES, sourceLengthBytes);
|
||||
}
|
||||
|
||||
public void testNullContentDataSource() throws Exception {
|
||||
Context context = getInstrumentation().getContext();
|
||||
ContentDataSource dataSource = new ContentDataSource(context);
|
||||
DataSpec dataSpec = new DataSpec(NULL_DESCRIPTOR_URI);
|
||||
|
||||
try {
|
||||
dataSource.open(dataSpec);
|
||||
fail("Expected exception not thrown.");
|
||||
} catch (ContentDataSource.ContentDataSourceException e) {
|
||||
// Expected.
|
||||
long length = dataSource.open(dataSpec);
|
||||
assertEquals(DATA_LENGTH, length);
|
||||
byte[] readData = TestUtil.readToEnd(dataSource);
|
||||
MoreAsserts.assertEquals(TestUtil.getByteArray(getInstrumentation(), DATA_PATH), readData);
|
||||
} finally {
|
||||
dataSource.close();
|
||||
}
|
||||
}
|
||||
|
||||
public void testReadInvalidUri() throws Exception {
|
||||
ContentDataSource dataSource = new ContentDataSource(getInstrumentation().getContext());
|
||||
Uri contentUri = new Uri.Builder()
|
||||
.scheme(ContentResolver.SCHEME_CONTENT)
|
||||
.authority(TestContentProvider.AUTHORITY)
|
||||
.build();
|
||||
DataSpec dataSpec = new DataSpec(contentUri);
|
||||
try {
|
||||
dataSource.open(dataSpec);
|
||||
fail();
|
||||
} catch (ContentDataSource.ContentDataSourceException e) {
|
||||
// Expected.
|
||||
} finally {
|
||||
dataSource.close();
|
||||
}
|
||||
}
|
||||
|
||||
public static final class TestContentProvider extends ContentProvider {
|
||||
|
||||
private static final String AUTHORITY = "com.google.android.exoplayer2.core.test";
|
||||
|
||||
@Override
|
||||
public boolean onCreate() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cursor query(@NonNull Uri uri, String[] projection, String selection,
|
||||
String[] selectionArgs, String sortOrder) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AssetFileDescriptor openAssetFile(@NonNull Uri uri, @NonNull String mode)
|
||||
throws FileNotFoundException {
|
||||
if (uri.getPath() == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return getContext().getAssets().openFd(uri.getPath().replaceFirst("/", ""));
|
||||
} catch (IOException e) {
|
||||
FileNotFoundException exception = new FileNotFoundException(e.getMessage());
|
||||
exception.initCause(e);
|
||||
throw exception;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType(@NonNull Uri uri) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Uri insert(@NonNull Uri uri, ContentValues values) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int delete(@NonNull Uri uri, String selection,
|
||||
String[] selectionArgs) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int update(@NonNull Uri uri, ContentValues values,
|
||||
String selection, String[] selectionArgs) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,68 +0,0 @@
|
||||
package com.google.android.exoplayer2.upstream;
|
||||
|
||||
import android.content.ContentProvider;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.content.res.AssetFileDescriptor;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
|
||||
import static junit.framework.Assert.assertNotNull;
|
||||
|
||||
public class TestDataProvider extends ContentProvider {
|
||||
@Override
|
||||
public boolean onCreate() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Cursor query(@NonNull final Uri uri, @Nullable final String[] projection, @Nullable final String selection, @Nullable final String[] selectionArgs, @Nullable final String sortOrder) {
|
||||
throw new UnsupportedOperationException("Not implemented");
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public AssetFileDescriptor openAssetFile(@NonNull final Uri uri, @NonNull final String mode) throws FileNotFoundException {
|
||||
if (uri.equals(AndroidDataSourceConstants.NULL_DESCRIPTOR_URI)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
Context context = getContext();
|
||||
assertNotNull(context);
|
||||
return context.getAssets().openFd(uri.getPath().replaceFirst("/", ""));
|
||||
} catch (IOException e) {
|
||||
FileNotFoundException exception = new FileNotFoundException(e.getMessage());
|
||||
exception.initCause(e);
|
||||
throw exception;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getType(@NonNull final Uri uri) {
|
||||
throw new UnsupportedOperationException("Not implemented");
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Uri insert(@NonNull final Uri uri, @Nullable final ContentValues values) {
|
||||
throw new UnsupportedOperationException("Not implemented");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int delete(@NonNull final Uri uri, @Nullable final String selection, @Nullable final String[] selectionArgs) {
|
||||
throw new UnsupportedOperationException("Not implemented");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int update(@NonNull final Uri uri, @Nullable final ContentValues values, @Nullable final String selection, @Nullable final String[] selectionArgs) {
|
||||
throw new UnsupportedOperationException("Not implemented");
|
||||
}
|
||||
}
|
@ -76,8 +76,9 @@ public final class ContentDataSource implements DataSource {
|
||||
throw new FileNotFoundException("Could not open file descriptor for: " + uri);
|
||||
}
|
||||
inputStream = new FileInputStream(assetFileDescriptor.getFileDescriptor());
|
||||
long skipped = inputStream.skip(dataSpec.position);
|
||||
if (skipped < dataSpec.position) {
|
||||
long assertStartOffset = assetFileDescriptor.getStartOffset();
|
||||
long skipped = inputStream.skip(assertStartOffset + dataSpec.position) - assertStartOffset;
|
||||
if (skipped != dataSpec.position) {
|
||||
// We expect the skip to be satisfied in full. If it isn't then we're probably trying to
|
||||
// skip beyond the end of the data.
|
||||
throw new EOFException();
|
||||
|
@ -22,6 +22,7 @@ import com.google.android.exoplayer2.extractor.Extractor;
|
||||
import com.google.android.exoplayer2.extractor.PositionHolder;
|
||||
import com.google.android.exoplayer2.extractor.SeekMap;
|
||||
import com.google.android.exoplayer2.testutil.FakeExtractorInput.SimulatedIOException;
|
||||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import java.io.IOException;
|
||||
@ -64,6 +65,22 @@ public class TestUtil {
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] readToEnd(DataSource dataSource) throws IOException {
|
||||
byte[] data = new byte[1024];
|
||||
int position = 0;
|
||||
int bytesRead = 0;
|
||||
while (bytesRead != C.RESULT_END_OF_INPUT) {
|
||||
if (position == data.length) {
|
||||
data = Arrays.copyOf(data, data.length * 2);
|
||||
}
|
||||
bytesRead = dataSource.read(data, position, data.length - position);
|
||||
if (bytesRead != C.RESULT_END_OF_INPUT) {
|
||||
position += bytesRead;
|
||||
}
|
||||
}
|
||||
return Arrays.copyOf(data, position);
|
||||
}
|
||||
|
||||
public static FakeExtractorOutput consumeTestData(Extractor extractor, FakeExtractorInput input,
|
||||
long timeUs) throws IOException, InterruptedException {
|
||||
return consumeTestData(extractor, input, timeUs, false);
|
||||
|
Loading…
x
Reference in New Issue
Block a user