Merge pull request #2963 from DroidsOnRoids/dev-v2

Source length calculation in ContentDataSource changed
This commit is contained in:
ojw28 2017-06-23 15:45:21 +01:00 committed by GitHub
commit 2da22e9e0f
6 changed files with 162 additions and 6 deletions

View file

@ -24,6 +24,9 @@
android:allowBackup="false"
tools:ignore="MissingApplicationIcon,HardcodedDebugMode">
<uses-library android:name="android.test.runner"/>
<provider
android:authorities="exoplayer"
android:name="com.google.android.exoplayer2.upstream.TestDataProvider"/>
</application>
<instrumentation

View file

@ -0,0 +1,16 @@
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() {}
}

View file

@ -0,0 +1,21 @@
package com.google.android.exoplayer2.upstream;
import android.content.Context;
import android.net.Uri;
import android.test.InstrumentationTestCase;
import static com.google.android.exoplayer2.upstream.AndroidDataSourceConstants.SAMPLE_MP4_BYTES;
import static com.google.android.exoplayer2.upstream.AndroidDataSourceConstants.SAMPLE_MP4_PATH;
public class AssetDataSourceTest extends InstrumentationTestCase {
public void testAssetDataSource() throws Exception {
final Context context = getInstrumentation().getContext();
AssetDataSource dataSource = new AssetDataSource(context);
Uri assetUri = Uri.parse("file:///android_asset" + SAMPLE_MP4_PATH);
DataSpec dataSpec = new DataSpec(assetUri);
long sourceLengthBytes = dataSource.open(dataSpec);
assertEquals(SAMPLE_MP4_BYTES, sourceLengthBytes);
}
}

View file

@ -0,0 +1,40 @@
package com.google.android.exoplayer2.upstream;
import android.content.ContentResolver;
import android.content.Context;
import android.net.Uri;
import android.test.InstrumentationTestCase;
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;
public class ContentDataSourceTest extends InstrumentationTestCase {
public void testValidContentDataSource() throws Exception {
Context context = getInstrumentation().getContext();
ContentDataSource dataSource = new ContentDataSource(context);
Uri contentUri = new Uri.Builder()
.scheme(ContentResolver.SCHEME_CONTENT)
.authority(TEST_DATA_PROVIDER_AUTHORITY)
.path(SAMPLE_MP4_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.
}
}
}

View file

@ -0,0 +1,68 @@
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");
}
}

View file

@ -22,6 +22,7 @@ import android.net.Uri;
import com.google.android.exoplayer2.C;
import java.io.EOFException;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
@ -71,6 +72,9 @@ public final class ContentDataSource implements DataSource {
try {
uri = dataSpec.uri;
assetFileDescriptor = resolver.openAssetFileDescriptor(uri, "r");
if (assetFileDescriptor == null) {
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) {
@ -81,12 +85,16 @@ public final class ContentDataSource implements DataSource {
if (dataSpec.length != C.LENGTH_UNSET) {
bytesRemaining = dataSpec.length;
} else {
bytesRemaining = inputStream.available();
if (bytesRemaining == 0) {
// FileInputStream.available() returns 0 if the remaining length cannot be determined, or
// if it's greater than Integer.MAX_VALUE. We don't know the true length in either case,
// so treat as unbounded.
bytesRemaining = C.LENGTH_UNSET;
bytesRemaining = assetFileDescriptor.getLength();
if (bytesRemaining == AssetFileDescriptor.UNKNOWN_LENGTH) {
// The asset must extend to the end of the file.
bytesRemaining = inputStream.available();
if (bytesRemaining == 0) {
// FileInputStream.available() returns 0 if the remaining length cannot be determined, or
// if it's greater than Integer.MAX_VALUE. We don't know the true length in either case,
// so treat as unbounded.
bytesRemaining = C.LENGTH_UNSET;
}
}
}
} catch (IOException e) {