Commit d8369571 by olly Committed by Toni

Remove some DataSource implementations from nullness blacklist

PiperOrigin-RevId: 249419193
parent a4d18a74
...@@ -15,11 +15,14 @@ ...@@ -15,11 +15,14 @@
*/ */
package com.google.android.exoplayer2.upstream; package com.google.android.exoplayer2.upstream;
import static com.google.android.exoplayer2.util.Util.castNonNull;
import android.content.Context; import android.content.Context;
import android.content.res.AssetManager; import android.content.res.AssetManager;
import android.net.Uri; import android.net.Uri;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.util.Assertions;
import java.io.EOFException; import java.io.EOFException;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
...@@ -40,8 +43,8 @@ public final class AssetDataSource extends BaseDataSource { ...@@ -40,8 +43,8 @@ public final class AssetDataSource extends BaseDataSource {
private final AssetManager assetManager; private final AssetManager assetManager;
private @Nullable Uri uri; @Nullable private Uri uri;
private @Nullable InputStream inputStream; @Nullable private InputStream inputStream;
private long bytesRemaining; private long bytesRemaining;
private boolean opened; private boolean opened;
...@@ -55,7 +58,7 @@ public final class AssetDataSource extends BaseDataSource { ...@@ -55,7 +58,7 @@ public final class AssetDataSource extends BaseDataSource {
public long open(DataSpec dataSpec) throws AssetDataSourceException { public long open(DataSpec dataSpec) throws AssetDataSourceException {
try { try {
uri = dataSpec.uri; uri = dataSpec.uri;
String path = uri.getPath(); String path = Assertions.checkNotNull(uri.getPath());
if (path.startsWith("/android_asset/")) { if (path.startsWith("/android_asset/")) {
path = path.substring(15); path = path.substring(15);
} else if (path.startsWith("/")) { } else if (path.startsWith("/")) {
...@@ -101,7 +104,7 @@ public final class AssetDataSource extends BaseDataSource { ...@@ -101,7 +104,7 @@ public final class AssetDataSource extends BaseDataSource {
try { try {
int bytesToRead = bytesRemaining == C.LENGTH_UNSET ? readLength int bytesToRead = bytesRemaining == C.LENGTH_UNSET ? readLength
: (int) Math.min(bytesRemaining, readLength); : (int) Math.min(bytesRemaining, readLength);
bytesRead = inputStream.read(buffer, offset, bytesToRead); bytesRead = castNonNull(inputStream).read(buffer, offset, bytesToRead);
} catch (IOException e) { } catch (IOException e) {
throw new AssetDataSourceException(e); throw new AssetDataSourceException(e);
} }
...@@ -121,7 +124,8 @@ public final class AssetDataSource extends BaseDataSource { ...@@ -121,7 +124,8 @@ public final class AssetDataSource extends BaseDataSource {
} }
@Override @Override
public @Nullable Uri getUri() { @Nullable
public Uri getUri() {
return uri; return uri;
} }
......
...@@ -15,20 +15,24 @@ ...@@ -15,20 +15,24 @@
*/ */
package com.google.android.exoplayer2.upstream; package com.google.android.exoplayer2.upstream;
import static com.google.android.exoplayer2.util.Util.castNonNull;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Assertions;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
/** /**
* A {@link DataSink} for writing to a byte array. * A {@link DataSink} for writing to a byte array.
*/ */
public final class ByteArrayDataSink implements DataSink { public final class ByteArrayDataSink implements DataSink {
private ByteArrayOutputStream stream; @MonotonicNonNull private ByteArrayOutputStream stream;
@Override @Override
public void open(DataSpec dataSpec) throws IOException { public void open(DataSpec dataSpec) {
if (dataSpec.length == C.LENGTH_UNSET) { if (dataSpec.length == C.LENGTH_UNSET) {
stream = new ByteArrayOutputStream(); stream = new ByteArrayOutputStream();
} else { } else {
...@@ -39,18 +43,19 @@ public final class ByteArrayDataSink implements DataSink { ...@@ -39,18 +43,19 @@ public final class ByteArrayDataSink implements DataSink {
@Override @Override
public void close() throws IOException { public void close() throws IOException {
stream.close(); castNonNull(stream).close();
} }
@Override @Override
public void write(byte[] buffer, int offset, int length) throws IOException { public void write(byte[] buffer, int offset, int length) {
stream.write(buffer, offset, length); castNonNull(stream).write(buffer, offset, length);
} }
/** /**
* Returns the data written to the sink since the last call to {@link #open(DataSpec)}, or null if * Returns the data written to the sink since the last call to {@link #open(DataSpec)}, or null if
* {@link #open(DataSpec)} has never been called. * {@link #open(DataSpec)} has never been called.
*/ */
@Nullable
public byte[] getData() { public byte[] getData() {
return stream == null ? null : stream.toByteArray(); return stream == null ? null : stream.toByteArray();
} }
......
...@@ -26,7 +26,7 @@ public final class ByteArrayDataSource extends BaseDataSource { ...@@ -26,7 +26,7 @@ public final class ByteArrayDataSource extends BaseDataSource {
private final byte[] data; private final byte[] data;
private @Nullable Uri uri; @Nullable private Uri uri;
private int readPosition; private int readPosition;
private int bytesRemaining; private int bytesRemaining;
private boolean opened; private boolean opened;
...@@ -58,7 +58,7 @@ public final class ByteArrayDataSource extends BaseDataSource { ...@@ -58,7 +58,7 @@ public final class ByteArrayDataSource extends BaseDataSource {
} }
@Override @Override
public int read(byte[] buffer, int offset, int readLength) throws IOException { public int read(byte[] buffer, int offset, int readLength) {
if (readLength == 0) { if (readLength == 0) {
return 0; return 0;
} else if (bytesRemaining == 0) { } else if (bytesRemaining == 0) {
...@@ -74,12 +74,13 @@ public final class ByteArrayDataSource extends BaseDataSource { ...@@ -74,12 +74,13 @@ public final class ByteArrayDataSource extends BaseDataSource {
} }
@Override @Override
public @Nullable Uri getUri() { @Nullable
public Uri getUri() {
return uri; return uri;
} }
@Override @Override
public void close() throws IOException { public void close() {
if (opened) { if (opened) {
opened = false; opened = false;
transferEnded(); transferEnded();
......
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
*/ */
package com.google.android.exoplayer2.upstream; package com.google.android.exoplayer2.upstream;
import static com.google.android.exoplayer2.util.Util.castNonNull;
import android.content.ContentResolver; import android.content.ContentResolver;
import android.content.Context; import android.content.Context;
import android.content.res.AssetFileDescriptor; import android.content.res.AssetFileDescriptor;
...@@ -43,9 +45,9 @@ public final class ContentDataSource extends BaseDataSource { ...@@ -43,9 +45,9 @@ public final class ContentDataSource extends BaseDataSource {
private final ContentResolver resolver; private final ContentResolver resolver;
private @Nullable Uri uri; @Nullable private Uri uri;
private @Nullable AssetFileDescriptor assetFileDescriptor; @Nullable private AssetFileDescriptor assetFileDescriptor;
private @Nullable FileInputStream inputStream; @Nullable private FileInputStream inputStream;
private long bytesRemaining; private long bytesRemaining;
private boolean opened; private boolean opened;
...@@ -60,13 +62,18 @@ public final class ContentDataSource extends BaseDataSource { ...@@ -60,13 +62,18 @@ public final class ContentDataSource extends BaseDataSource {
@Override @Override
public long open(DataSpec dataSpec) throws ContentDataSourceException { public long open(DataSpec dataSpec) throws ContentDataSourceException {
try { try {
uri = dataSpec.uri; Uri uri = dataSpec.uri;
this.uri = uri;
transferInitializing(dataSpec); transferInitializing(dataSpec);
assetFileDescriptor = resolver.openAssetFileDescriptor(uri, "r"); AssetFileDescriptor assetFileDescriptor = resolver.openAssetFileDescriptor(uri, "r");
this.assetFileDescriptor = assetFileDescriptor;
if (assetFileDescriptor == null) { if (assetFileDescriptor == null) {
throw new FileNotFoundException("Could not open file descriptor for: " + uri); throw new FileNotFoundException("Could not open file descriptor for: " + uri);
} }
inputStream = new FileInputStream(assetFileDescriptor.getFileDescriptor()); FileInputStream inputStream = new FileInputStream(assetFileDescriptor.getFileDescriptor());
this.inputStream = inputStream;
long assetStartOffset = assetFileDescriptor.getStartOffset(); long assetStartOffset = assetFileDescriptor.getStartOffset();
long skipped = inputStream.skip(assetStartOffset + dataSpec.position) - assetStartOffset; long skipped = inputStream.skip(assetStartOffset + dataSpec.position) - assetStartOffset;
if (skipped != dataSpec.position) { if (skipped != dataSpec.position) {
...@@ -110,7 +117,7 @@ public final class ContentDataSource extends BaseDataSource { ...@@ -110,7 +117,7 @@ public final class ContentDataSource extends BaseDataSource {
try { try {
int bytesToRead = bytesRemaining == C.LENGTH_UNSET ? readLength int bytesToRead = bytesRemaining == C.LENGTH_UNSET ? readLength
: (int) Math.min(bytesRemaining, readLength); : (int) Math.min(bytesRemaining, readLength);
bytesRead = inputStream.read(buffer, offset, bytesToRead); bytesRead = castNonNull(inputStream).read(buffer, offset, bytesToRead);
} catch (IOException e) { } catch (IOException e) {
throw new ContentDataSourceException(e); throw new ContentDataSourceException(e);
} }
...@@ -130,7 +137,8 @@ public final class ContentDataSource extends BaseDataSource { ...@@ -130,7 +137,8 @@ public final class ContentDataSource extends BaseDataSource {
} }
@Override @Override
public @Nullable Uri getUri() { @Nullable
public Uri getUri() {
return uri; return uri;
} }
......
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
*/ */
package com.google.android.exoplayer2.upstream; package com.google.android.exoplayer2.upstream;
import static com.google.android.exoplayer2.util.Util.castNonNull;
import android.net.Uri; import android.net.Uri;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import android.util.Base64; import android.util.Base64;
...@@ -29,9 +31,10 @@ public final class DataSchemeDataSource extends BaseDataSource { ...@@ -29,9 +31,10 @@ public final class DataSchemeDataSource extends BaseDataSource {
public static final String SCHEME_DATA = "data"; public static final String SCHEME_DATA = "data";
private @Nullable DataSpec dataSpec; @Nullable private DataSpec dataSpec;
@Nullable private byte[] data;
private int dataLength;
private int bytesRead; private int bytesRead;
private @Nullable byte[] data;
public DataSchemeDataSource() { public DataSchemeDataSource() {
super(/* isNetwork= */ false); super(/* isNetwork= */ false);
...@@ -54,15 +57,17 @@ public final class DataSchemeDataSource extends BaseDataSource { ...@@ -54,15 +57,17 @@ public final class DataSchemeDataSource extends BaseDataSource {
if (uriParts[0].contains(";base64")) { if (uriParts[0].contains(";base64")) {
try { try {
data = Base64.decode(dataString, 0); data = Base64.decode(dataString, 0);
dataLength = data.length;
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
throw new ParserException("Error while parsing Base64 encoded string: " + dataString, e); throw new ParserException("Error while parsing Base64 encoded string: " + dataString, e);
} }
} else { } else {
// TODO: Add support for other charsets. // TODO: Add support for other charsets.
data = Util.getUtf8Bytes(URLDecoder.decode(dataString, C.ASCII_NAME)); data = Util.getUtf8Bytes(URLDecoder.decode(dataString, C.ASCII_NAME));
dataLength = data.length;
} }
transferStarted(dataSpec); transferStarted(dataSpec);
return data.length; return dataLength;
} }
@Override @Override
...@@ -70,19 +75,20 @@ public final class DataSchemeDataSource extends BaseDataSource { ...@@ -70,19 +75,20 @@ public final class DataSchemeDataSource extends BaseDataSource {
if (readLength == 0) { if (readLength == 0) {
return 0; return 0;
} }
int remainingBytes = data.length - bytesRead; int remainingBytes = dataLength - bytesRead;
if (remainingBytes == 0) { if (remainingBytes == 0) {
return C.RESULT_END_OF_INPUT; return C.RESULT_END_OF_INPUT;
} }
readLength = Math.min(readLength, remainingBytes); readLength = Math.min(readLength, remainingBytes);
System.arraycopy(data, bytesRead, buffer, offset, readLength); System.arraycopy(castNonNull(data), bytesRead, buffer, offset, readLength);
bytesRead += readLength; bytesRead += readLength;
bytesTransferred(readLength); bytesTransferred(readLength);
return readLength; return readLength;
} }
@Override @Override
public @Nullable Uri getUri() { @Nullable
public Uri getUri() {
return dataSpec != null ? dataSpec.uri : null; return dataSpec != null ? dataSpec.uri : null;
} }
......
...@@ -42,17 +42,18 @@ public final class DummyDataSource implements DataSource { ...@@ -42,17 +42,18 @@ public final class DummyDataSource implements DataSource {
} }
@Override @Override
public int read(byte[] buffer, int offset, int readLength) throws IOException { public int read(byte[] buffer, int offset, int readLength) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override @Override
public @Nullable Uri getUri() { @Nullable
public Uri getUri() {
return null; return null;
} }
@Override @Override
public void close() throws IOException { public void close() {
// do nothing. // do nothing.
} }
} }
...@@ -15,9 +15,12 @@ ...@@ -15,9 +15,12 @@
*/ */
package com.google.android.exoplayer2.upstream; package com.google.android.exoplayer2.upstream;
import static com.google.android.exoplayer2.util.Util.castNonNull;
import android.net.Uri; import android.net.Uri;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.util.Assertions;
import java.io.EOFException; import java.io.EOFException;
import java.io.IOException; import java.io.IOException;
import java.io.RandomAccessFile; import java.io.RandomAccessFile;
...@@ -36,8 +39,8 @@ public final class FileDataSource extends BaseDataSource { ...@@ -36,8 +39,8 @@ public final class FileDataSource extends BaseDataSource {
} }
private @Nullable RandomAccessFile file; @Nullable private RandomAccessFile file;
private @Nullable Uri uri; @Nullable private Uri uri;
private long bytesRemaining; private long bytesRemaining;
private boolean opened; private boolean opened;
...@@ -48,9 +51,13 @@ public final class FileDataSource extends BaseDataSource { ...@@ -48,9 +51,13 @@ public final class FileDataSource extends BaseDataSource {
@Override @Override
public long open(DataSpec dataSpec) throws FileDataSourceException { public long open(DataSpec dataSpec) throws FileDataSourceException {
try { try {
uri = dataSpec.uri; Uri uri = dataSpec.uri;
this.uri = uri;
transferInitializing(dataSpec); transferInitializing(dataSpec);
file = new RandomAccessFile(dataSpec.uri.getPath(), "r"); RandomAccessFile file = new RandomAccessFile(Assertions.checkNotNull(uri.getPath()), "r");
this.file = file;
file.seek(dataSpec.position); file.seek(dataSpec.position);
bytesRemaining = dataSpec.length == C.LENGTH_UNSET ? file.length() - dataSpec.position bytesRemaining = dataSpec.length == C.LENGTH_UNSET ? file.length() - dataSpec.position
: dataSpec.length; : dataSpec.length;
...@@ -76,7 +83,8 @@ public final class FileDataSource extends BaseDataSource { ...@@ -76,7 +83,8 @@ public final class FileDataSource extends BaseDataSource {
} else { } else {
int bytesRead; int bytesRead;
try { try {
bytesRead = file.read(buffer, offset, (int) Math.min(bytesRemaining, readLength)); bytesRead =
castNonNull(file).read(buffer, offset, (int) Math.min(bytesRemaining, readLength));
} catch (IOException e) { } catch (IOException e) {
throw new FileDataSourceException(e); throw new FileDataSourceException(e);
} }
...@@ -91,7 +99,8 @@ public final class FileDataSource extends BaseDataSource { ...@@ -91,7 +99,8 @@ public final class FileDataSource extends BaseDataSource {
} }
@Override @Override
public @Nullable Uri getUri() { @Nullable
public Uri getUri() {
return uri; return uri;
} }
......
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
*/ */
package com.google.android.exoplayer2.upstream; package com.google.android.exoplayer2.upstream;
import static com.google.android.exoplayer2.util.Util.castNonNull;
import android.content.Context; import android.content.Context;
import android.content.res.AssetFileDescriptor; import android.content.res.AssetFileDescriptor;
import android.content.res.Resources; import android.content.res.Resources;
...@@ -22,6 +24,7 @@ import android.net.Uri; ...@@ -22,6 +24,7 @@ import android.net.Uri;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import android.text.TextUtils; import android.text.TextUtils;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.util.Assertions;
import java.io.EOFException; import java.io.EOFException;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
...@@ -64,9 +67,9 @@ public final class RawResourceDataSource extends BaseDataSource { ...@@ -64,9 +67,9 @@ public final class RawResourceDataSource extends BaseDataSource {
private final Resources resources; private final Resources resources;
private @Nullable Uri uri; @Nullable private Uri uri;
private @Nullable AssetFileDescriptor assetFileDescriptor; @Nullable private AssetFileDescriptor assetFileDescriptor;
private @Nullable InputStream inputStream; @Nullable private InputStream inputStream;
private long bytesRemaining; private long bytesRemaining;
private boolean opened; private boolean opened;
...@@ -81,21 +84,28 @@ public final class RawResourceDataSource extends BaseDataSource { ...@@ -81,21 +84,28 @@ public final class RawResourceDataSource extends BaseDataSource {
@Override @Override
public long open(DataSpec dataSpec) throws RawResourceDataSourceException { public long open(DataSpec dataSpec) throws RawResourceDataSourceException {
try { try {
uri = dataSpec.uri; Uri uri = dataSpec.uri;
this.uri = uri;
if (!TextUtils.equals(RAW_RESOURCE_SCHEME, uri.getScheme())) { if (!TextUtils.equals(RAW_RESOURCE_SCHEME, uri.getScheme())) {
throw new RawResourceDataSourceException("URI must use scheme " + RAW_RESOURCE_SCHEME); throw new RawResourceDataSourceException("URI must use scheme " + RAW_RESOURCE_SCHEME);
} }
int resourceId; int resourceId;
try { try {
resourceId = Integer.parseInt(uri.getLastPathSegment()); resourceId = Integer.parseInt(Assertions.checkNotNull(uri.getLastPathSegment()));
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
throw new RawResourceDataSourceException("Resource identifier must be an integer."); throw new RawResourceDataSourceException("Resource identifier must be an integer.");
} }
transferInitializing(dataSpec); transferInitializing(dataSpec);
assetFileDescriptor = resources.openRawResourceFd(resourceId); AssetFileDescriptor assetFileDescriptor = resources.openRawResourceFd(resourceId);
inputStream = new FileInputStream(assetFileDescriptor.getFileDescriptor()); this.assetFileDescriptor = assetFileDescriptor;
if (assetFileDescriptor == null) {
throw new RawResourceDataSourceException("Resource is compressed: " + uri);
}
FileInputStream inputStream = new FileInputStream(assetFileDescriptor.getFileDescriptor());
this.inputStream = inputStream;
inputStream.skip(assetFileDescriptor.getStartOffset()); inputStream.skip(assetFileDescriptor.getStartOffset());
long skipped = inputStream.skip(dataSpec.position); long skipped = inputStream.skip(dataSpec.position);
if (skipped < dataSpec.position) { if (skipped < dataSpec.position) {
...@@ -133,7 +143,7 @@ public final class RawResourceDataSource extends BaseDataSource { ...@@ -133,7 +143,7 @@ public final class RawResourceDataSource extends BaseDataSource {
try { try {
int bytesToRead = bytesRemaining == C.LENGTH_UNSET ? readLength int bytesToRead = bytesRemaining == C.LENGTH_UNSET ? readLength
: (int) Math.min(bytesRemaining, readLength); : (int) Math.min(bytesRemaining, readLength);
bytesRead = inputStream.read(buffer, offset, bytesToRead); bytesRead = castNonNull(inputStream).read(buffer, offset, bytesToRead);
} catch (IOException e) { } catch (IOException e) {
throw new RawResourceDataSourceException(e); throw new RawResourceDataSourceException(e);
} }
...@@ -153,7 +163,8 @@ public final class RawResourceDataSource extends BaseDataSource { ...@@ -153,7 +163,8 @@ public final class RawResourceDataSource extends BaseDataSource {
} }
@Override @Override
public @Nullable Uri getUri() { @Nullable
public Uri getUri() {
return uri; return uri;
} }
......
...@@ -52,11 +52,11 @@ public final class UdpDataSource extends BaseDataSource { ...@@ -52,11 +52,11 @@ public final class UdpDataSource extends BaseDataSource {
private final byte[] packetBuffer; private final byte[] packetBuffer;
private final DatagramPacket packet; private final DatagramPacket packet;
private @Nullable Uri uri; @Nullable private Uri uri;
private @Nullable DatagramSocket socket; @Nullable private DatagramSocket socket;
private @Nullable MulticastSocket multicastSocket; @Nullable private MulticastSocket multicastSocket;
private @Nullable InetAddress address; @Nullable private InetAddress address;
private @Nullable InetSocketAddress socketAddress; @Nullable private InetSocketAddress socketAddress;
private boolean opened; private boolean opened;
private int packetRemaining; private int packetRemaining;
...@@ -144,7 +144,8 @@ public final class UdpDataSource extends BaseDataSource { ...@@ -144,7 +144,8 @@ public final class UdpDataSource extends BaseDataSource {
} }
@Override @Override
public @Nullable Uri getUri() { @Nullable
public Uri getUri() {
return uri; return uri;
} }
......
...@@ -15,6 +15,9 @@ ...@@ -15,6 +15,9 @@
*/ */
package com.google.android.exoplayer2.upstream.crypto; package com.google.android.exoplayer2.upstream.crypto;
import static com.google.android.exoplayer2.util.Util.castNonNull;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.upstream.DataSink; import com.google.android.exoplayer2.upstream.DataSink;
import com.google.android.exoplayer2.upstream.DataSpec; import com.google.android.exoplayer2.upstream.DataSpec;
import java.io.IOException; import java.io.IOException;
...@@ -27,9 +30,9 @@ public final class AesCipherDataSink implements DataSink { ...@@ -27,9 +30,9 @@ public final class AesCipherDataSink implements DataSink {
private final DataSink wrappedDataSink; private final DataSink wrappedDataSink;
private final byte[] secretKey; private final byte[] secretKey;
private final byte[] scratch; @Nullable private final byte[] scratch;
private AesFlushingCipher cipher; @Nullable private AesFlushingCipher cipher;
/** /**
* Create an instance whose {@code write} methods have the side effect of overwriting the input * Create an instance whose {@code write} methods have the side effect of overwriting the input
...@@ -52,9 +55,10 @@ public final class AesCipherDataSink implements DataSink { ...@@ -52,9 +55,10 @@ public final class AesCipherDataSink implements DataSink {
* @param scratch Scratch space. Data is decrypted into this array before being written to the * @param scratch Scratch space. Data is decrypted into this array before being written to the
* wrapped {@link DataSink}. It should be of appropriate size for the expected writes. If a * wrapped {@link DataSink}. It should be of appropriate size for the expected writes. If a
* write is larger than the size of this array the write will still succeed, but multiple * write is larger than the size of this array the write will still succeed, but multiple
* cipher calls will be required to complete the operation. * cipher calls will be required to complete the operation. If {@code null} then decryption
* will overwrite the input {@code data}.
*/ */
public AesCipherDataSink(byte[] secretKey, DataSink wrappedDataSink, byte[] scratch) { public AesCipherDataSink(byte[] secretKey, DataSink wrappedDataSink, @Nullable byte[] scratch) {
this.wrappedDataSink = wrappedDataSink; this.wrappedDataSink = wrappedDataSink;
this.secretKey = secretKey; this.secretKey = secretKey;
this.scratch = scratch; this.scratch = scratch;
...@@ -72,15 +76,16 @@ public final class AesCipherDataSink implements DataSink { ...@@ -72,15 +76,16 @@ public final class AesCipherDataSink implements DataSink {
public void write(byte[] data, int offset, int length) throws IOException { public void write(byte[] data, int offset, int length) throws IOException {
if (scratch == null) { if (scratch == null) {
// In-place mode. Writes over the input data. // In-place mode. Writes over the input data.
cipher.updateInPlace(data, offset, length); castNonNull(cipher).updateInPlace(data, offset, length);
wrappedDataSink.write(data, offset, length); wrappedDataSink.write(data, offset, length);
} else { } else {
// Use scratch space. The original data remains intact. // Use scratch space. The original data remains intact.
int bytesProcessed = 0; int bytesProcessed = 0;
while (bytesProcessed < length) { while (bytesProcessed < length) {
int bytesToProcess = Math.min(length - bytesProcessed, scratch.length); int bytesToProcess = Math.min(length - bytesProcessed, scratch.length);
cipher.update(data, offset + bytesProcessed, bytesToProcess, scratch, 0); castNonNull(cipher)
wrappedDataSink.write(scratch, 0, bytesToProcess); .update(data, offset + bytesProcessed, bytesToProcess, scratch, /* outOffset= */ 0);
wrappedDataSink.write(scratch, /* offset= */ 0, bytesToProcess);
bytesProcessed += bytesToProcess; bytesProcessed += bytesToProcess;
} }
} }
......
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
*/ */
package com.google.android.exoplayer2.upstream.crypto; package com.google.android.exoplayer2.upstream.crypto;
import static com.google.android.exoplayer2.util.Util.castNonNull;
import android.net.Uri; import android.net.Uri;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
...@@ -34,7 +36,7 @@ public final class AesCipherDataSource implements DataSource { ...@@ -34,7 +36,7 @@ public final class AesCipherDataSource implements DataSource {
private final DataSource upstream; private final DataSource upstream;
private final byte[] secretKey; private final byte[] secretKey;
private @Nullable AesFlushingCipher cipher; @Nullable private AesFlushingCipher cipher;
public AesCipherDataSource(byte[] secretKey, DataSource upstream) { public AesCipherDataSource(byte[] secretKey, DataSource upstream) {
this.upstream = upstream; this.upstream = upstream;
...@@ -64,7 +66,7 @@ public final class AesCipherDataSource implements DataSource { ...@@ -64,7 +66,7 @@ public final class AesCipherDataSource implements DataSource {
if (read == C.RESULT_END_OF_INPUT) { if (read == C.RESULT_END_OF_INPUT) {
return C.RESULT_END_OF_INPUT; return C.RESULT_END_OF_INPUT;
} }
cipher.updateInPlace(data, offset, read); castNonNull(cipher).updateInPlace(data, offset, read);
return read; return read;
} }
......
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
*/ */
package com.google.android.exoplayer2.upstream.crypto; package com.google.android.exoplayer2.upstream.crypto;
import androidx.annotation.Nullable;
/** /**
* Utility functions for the crypto package. * Utility functions for the crypto package.
*/ */
...@@ -24,10 +26,10 @@ package com.google.android.exoplayer2.upstream.crypto; ...@@ -24,10 +26,10 @@ package com.google.android.exoplayer2.upstream.crypto;
/** /**
* Returns the hash value of the input as a long using the 64 bit FNV-1a hash function. The hash * Returns the hash value of the input as a long using the 64 bit FNV-1a hash function. The hash
* values produced by this function are less likely to collide than those produced by * values produced by this function are less likely to collide than those produced by {@link
* {@link #hashCode()}. * #hashCode()}.
*/ */
public static long getFNV64Hash(String input) { public static long getFNV64Hash(@Nullable String input) {
if (input == null) { if (input == null) {
return 0; return 0;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment