Fix remaining common module nullness issues.

PiperOrigin-RevId: 319183621
This commit is contained in:
tonihei 2020-07-01 09:44:49 +01:00 committed by Oliver Woodman
parent 7d46be5564
commit e4e743a35f
9 changed files with 100 additions and 62 deletions

View file

@ -23,6 +23,7 @@ import com.google.android.exoplayer2.decoder.SimpleDecoder;
import com.google.android.exoplayer2.decoder.SimpleOutputBuffer;
import com.google.android.exoplayer2.drm.DecryptionException;
import com.google.android.exoplayer2.drm.ExoMediaCrypto;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.Util;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
@ -166,13 +167,28 @@ import java.util.List;
}
ByteBuffer inputData = Util.castNonNull(inputBuffer.data);
CryptoInfo cryptoInfo = inputBuffer.cryptoInfo;
int result = inputBuffer.isEncrypted()
? opusSecureDecode(nativeDecoderContext, inputBuffer.timeUs, inputData, inputData.limit(),
outputBuffer, SAMPLE_RATE, exoMediaCrypto, cryptoInfo.mode,
cryptoInfo.key, cryptoInfo.iv, cryptoInfo.numSubSamples,
cryptoInfo.numBytesOfClearData, cryptoInfo.numBytesOfEncryptedData)
: opusDecode(nativeDecoderContext, inputBuffer.timeUs, inputData, inputData.limit(),
outputBuffer);
int result =
inputBuffer.isEncrypted()
? opusSecureDecode(
nativeDecoderContext,
inputBuffer.timeUs,
inputData,
inputData.limit(),
outputBuffer,
SAMPLE_RATE,
exoMediaCrypto,
cryptoInfo.mode,
Assertions.checkNotNull(cryptoInfo.key),
Assertions.checkNotNull(cryptoInfo.iv),
cryptoInfo.numSubSamples,
cryptoInfo.numBytesOfClearData,
cryptoInfo.numBytesOfEncryptedData)
: opusDecode(
nativeDecoderContext,
inputBuffer.timeUs,
inputData,
inputData.limit(),
outputBuffer);
if (result < 0) {
if (result == DRM_ERROR) {
String message = "Drm error: " + opusGetErrorMessage(nativeDecoderContext);
@ -253,8 +269,8 @@ import java.util.List;
byte[] key,
byte[] iv,
int numSubSamples,
int[] numBytesOfClearData,
int[] numBytesOfEncryptedData);
@Nullable int[] numBytesOfClearData,
@Nullable int[] numBytesOfEncryptedData);
private native void opusClose(long decoder);
private native void opusReset(long decoder);

View file

@ -124,11 +124,20 @@ import java.nio.ByteBuffer;
ByteBuffer inputData = Util.castNonNull(inputBuffer.data);
int inputSize = inputData.limit();
CryptoInfo cryptoInfo = inputBuffer.cryptoInfo;
final long result = inputBuffer.isEncrypted()
? vpxSecureDecode(vpxDecContext, inputData, inputSize, exoMediaCrypto,
cryptoInfo.mode, cryptoInfo.key, cryptoInfo.iv, cryptoInfo.numSubSamples,
cryptoInfo.numBytesOfClearData, cryptoInfo.numBytesOfEncryptedData)
: vpxDecode(vpxDecContext, inputData, inputSize);
final long result =
inputBuffer.isEncrypted()
? vpxSecureDecode(
vpxDecContext,
inputData,
inputSize,
exoMediaCrypto,
cryptoInfo.mode,
Assertions.checkNotNull(cryptoInfo.key),
Assertions.checkNotNull(cryptoInfo.iv),
cryptoInfo.numSubSamples,
cryptoInfo.numBytesOfClearData,
cryptoInfo.numBytesOfEncryptedData)
: vpxDecode(vpxDecContext, inputData, inputSize);
if (result != NO_ERROR) {
if (result == DRM_ERROR) {
String message = "Drm error: " + vpxGetErrorMessage(vpxDecContext);
@ -207,8 +216,8 @@ import java.nio.ByteBuffer;
byte[] key,
byte[] iv,
int numSubSamples,
int[] numBytesOfClearData,
int[] numBytesOfEncryptedData);
@Nullable int[] numBytesOfClearData,
@Nullable int[] numBytesOfEncryptedData);
private native int vpxGetFrame(long context, VideoDecoderOutputBuffer outputBuffer);

View file

@ -21,6 +21,7 @@ import androidx.annotation.Nullable;
import com.google.android.exoplayer2.drm.DrmInitData;
import com.google.android.exoplayer2.drm.ExoMediaCrypto;
import com.google.android.exoplayer2.metadata.Metadata;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.MimeTypes;
import com.google.android.exoplayer2.util.Util;
import com.google.android.exoplayer2.video.ColorInfo;
@ -1309,7 +1310,7 @@ public final class Format implements Parcelable {
int initializationDataSize = in.readInt();
initializationData = new ArrayList<>(initializationDataSize);
for (int i = 0; i < initializationDataSize; i++) {
initializationData.add(in.createByteArray());
initializationData.add(Assertions.checkNotNull(in.createByteArray()));
}
drmInitData = in.readParcelable(DrmInitData.class.getClassLoader());
subsampleOffsetUs = in.readLong();

View file

@ -15,8 +15,10 @@
*/
package com.google.android.exoplayer2.decoder;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.Util;
/**
@ -30,13 +32,13 @@ public final class CryptoInfo {
*
* @see android.media.MediaCodec.CryptoInfo#iv
*/
public byte[] iv;
@Nullable public byte[] iv;
/**
* The 16 byte key id.
*
* @see android.media.MediaCodec.CryptoInfo#key
*/
public byte[] key;
@Nullable public byte[] key;
/**
* The type of encryption that has been applied. Must be one of the {@link C.CryptoMode} values.
*
@ -49,14 +51,14 @@ public final class CryptoInfo {
*
* @see android.media.MediaCodec.CryptoInfo#numBytesOfClearData
*/
public int[] numBytesOfClearData;
@Nullable public int[] numBytesOfClearData;
/**
* The number of trailing encrypted bytes in each sub-sample. If null, all bytes are treated as
* clear and {@link #numBytesOfClearData} must be specified.
*
* @see android.media.MediaCodec.CryptoInfo#numBytesOfEncryptedData
*/
public int[] numBytesOfEncryptedData;
@Nullable public int[] numBytesOfEncryptedData;
/**
* The number of subSamples that make up the buffer's contents.
*
@ -73,7 +75,7 @@ public final class CryptoInfo {
public int clearBlocks;
private final android.media.MediaCodec.CryptoInfo frameworkCryptoInfo;
private final PatternHolderV24 patternHolder;
@Nullable private final PatternHolderV24 patternHolder;
public CryptoInfo() {
frameworkCryptoInfo = new android.media.MediaCodec.CryptoInfo();
@ -102,7 +104,7 @@ public final class CryptoInfo {
frameworkCryptoInfo.iv = iv;
frameworkCryptoInfo.mode = mode;
if (Util.SDK_INT >= 24) {
patternHolder.set(encryptedBlocks, clearBlocks);
Assertions.checkNotNull(patternHolder).set(encryptedBlocks, clearBlocks);
}
}

View file

@ -41,7 +41,9 @@ import java.util.Set;
*
* @param <E> The type of element being stored.
*/
public final class CopyOnWriteMultiset<E> implements Iterable<E> {
// Intentionally extending @NonNull-by-default Object to disallow @Nullable E types.
@SuppressWarnings("TypeParameterExplicitlyExtendsObject")
public final class CopyOnWriteMultiset<E extends Object> implements Iterable<E> {
private final Object lock;

View file

@ -431,18 +431,18 @@ public final class NalUnitUtil {
return endOffset;
}
if (prefixFlags != null) {
if (prefixFlags[0]) {
clearPrefixFlags(prefixFlags);
return startOffset - 3;
} else if (length > 1 && prefixFlags[1] && data[startOffset] == 1) {
clearPrefixFlags(prefixFlags);
return startOffset - 2;
} else if (length > 2 && prefixFlags[2] && data[startOffset] == 0
&& data[startOffset + 1] == 1) {
clearPrefixFlags(prefixFlags);
return startOffset - 1;
}
if (prefixFlags[0]) {
clearPrefixFlags(prefixFlags);
return startOffset - 3;
} else if (length > 1 && prefixFlags[1] && data[startOffset] == 1) {
clearPrefixFlags(prefixFlags);
return startOffset - 2;
} else if (length > 2
&& prefixFlags[2]
&& data[startOffset] == 0
&& data[startOffset + 1] == 1) {
clearPrefixFlags(prefixFlags);
return startOffset - 1;
}
int limit = endOffset - 1;
@ -453,9 +453,7 @@ public final class NalUnitUtil {
// There isn't a NAL prefix here, or at the next two positions. Do nothing and let the
// loop advance the index by three.
} else if (data[i - 2] == 0 && data[i - 1] == 0 && data[i] == 1) {
if (prefixFlags != null) {
clearPrefixFlags(prefixFlags);
}
clearPrefixFlags(prefixFlags);
return i - 2;
} else {
// There isn't a NAL prefix here, but there might be at the next position. We should
@ -464,18 +462,20 @@ public final class NalUnitUtil {
}
}
if (prefixFlags != null) {
// True if the last three bytes in the data seen so far are {0,0,1}.
prefixFlags[0] = length > 2
? (data[endOffset - 3] == 0 && data[endOffset - 2] == 0 && data[endOffset - 1] == 1)
: length == 2 ? (prefixFlags[2] && data[endOffset - 2] == 0 && data[endOffset - 1] == 1)
: (prefixFlags[1] && data[endOffset - 1] == 1);
// True if the last two bytes in the data seen so far are {0,0}.
prefixFlags[1] = length > 1 ? data[endOffset - 2] == 0 && data[endOffset - 1] == 0
: prefixFlags[2] && data[endOffset - 1] == 0;
// True if the last byte in the data seen so far is {0}.
prefixFlags[2] = data[endOffset - 1] == 0;
}
// True if the last three bytes in the data seen so far are {0,0,1}.
prefixFlags[0] =
length > 2
? (data[endOffset - 3] == 0 && data[endOffset - 2] == 0 && data[endOffset - 1] == 1)
: length == 2
? (prefixFlags[2] && data[endOffset - 2] == 0 && data[endOffset - 1] == 1)
: (prefixFlags[1] && data[endOffset - 1] == 1);
// True if the last two bytes in the data seen so far are {0,0}.
prefixFlags[1] =
length > 1
? data[endOffset - 2] == 0 && data[endOffset - 1] == 0
: prefixFlags[2] && data[endOffset - 1] == 0;
// True if the last byte in the data seen so far is {0}.
prefixFlags[2] = data[endOffset - 1] == 0;
return endOffset;
}

View file

@ -1937,6 +1937,8 @@ public final class Util {
* @param context A context to access the connectivity manager.
* @return The {@link C.NetworkType} of the current network connection.
*/
// Intentional null check to guard against user input.
@SuppressWarnings("known.nonnull")
@C.NetworkType
public static int getNetworkType(Context context) {
if (context == null) {
@ -1944,6 +1946,7 @@ public final class Util {
return C.NETWORK_TYPE_UNKNOWN;
}
NetworkInfo networkInfo;
@Nullable
ConnectivityManager connectivityManager =
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivityManager == null) {
@ -1983,6 +1986,7 @@ public final class Util {
*/
public static String getCountryCode(@Nullable Context context) {
if (context != null) {
@Nullable
TelephonyManager telephonyManager =
(TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
if (telephonyManager != null) {
@ -2062,6 +2066,7 @@ public final class Util {
*/
public static boolean isTv(Context context) {
// See https://developer.android.com/training/tv/start/hardware.html#runtime-check.
@Nullable
UiModeManager uiModeManager =
(UiModeManager) context.getApplicationContext().getSystemService(UI_MODE_SERVICE);
return uiModeManager != null

View file

@ -40,19 +40,19 @@ public final class NalUnitUtilTest {
byte[] data = buildTestData();
// Should find NAL unit.
int result = NalUnitUtil.findNalUnit(data, 0, data.length, null);
int result = NalUnitUtil.findNalUnit(data, 0, data.length, new boolean[3]);
assertThat(result).isEqualTo(TEST_NAL_POSITION);
// Should find NAL unit whose prefix ends one byte before the limit.
result = NalUnitUtil.findNalUnit(data, 0, TEST_NAL_POSITION + 4, null);
result = NalUnitUtil.findNalUnit(data, 0, TEST_NAL_POSITION + 4, new boolean[3]);
assertThat(result).isEqualTo(TEST_NAL_POSITION);
// Shouldn't find NAL unit whose prefix ends at the limit (since the limit is exclusive).
result = NalUnitUtil.findNalUnit(data, 0, TEST_NAL_POSITION + 3, null);
result = NalUnitUtil.findNalUnit(data, 0, TEST_NAL_POSITION + 3, new boolean[3]);
assertThat(result).isEqualTo(TEST_NAL_POSITION + 3);
// Should find NAL unit whose prefix starts at the offset.
result = NalUnitUtil.findNalUnit(data, TEST_NAL_POSITION, data.length, null);
result = NalUnitUtil.findNalUnit(data, TEST_NAL_POSITION, data.length, new boolean[3]);
assertThat(result).isEqualTo(TEST_NAL_POSITION);
// Shouldn't find NAL unit whose prefix starts one byte past the offset.
result = NalUnitUtil.findNalUnit(data, TEST_NAL_POSITION + 1, data.length, null);
result = NalUnitUtil.findNalUnit(data, TEST_NAL_POSITION + 1, data.length, new boolean[3]);
assertThat(result).isEqualTo(data.length);
}

View file

@ -16,11 +16,14 @@
package com.google.android.exoplayer2.mediacodec;
import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
import android.media.MediaCodec;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import androidx.annotation.GuardedBy;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.annotation.VisibleForTesting;
import com.google.android.exoplayer2.C;
@ -292,8 +295,6 @@ class AsynchronousMediaCodecBufferEnqueuer implements MediaCodecInputBufferEnque
}
/** Performs a deep copy of {@code cryptoInfo} to {@code frameworkCryptoInfo}. */
// TODO: Remove suppression [internal b/78934030].
@SuppressWarnings("nullness:argument.type.incompatible")
private static void copy(
CryptoInfo cryptoInfo, android.media.MediaCodec.CryptoInfo frameworkCryptoInfo) {
// Update frameworkCryptoInfo fields directly because CryptoInfo.set performs an unnecessary
@ -303,8 +304,8 @@ class AsynchronousMediaCodecBufferEnqueuer implements MediaCodecInputBufferEnque
copy(cryptoInfo.numBytesOfClearData, frameworkCryptoInfo.numBytesOfClearData);
frameworkCryptoInfo.numBytesOfEncryptedData =
copy(cryptoInfo.numBytesOfEncryptedData, frameworkCryptoInfo.numBytesOfEncryptedData);
frameworkCryptoInfo.key = copy(cryptoInfo.key, frameworkCryptoInfo.key);
frameworkCryptoInfo.iv = copy(cryptoInfo.iv, frameworkCryptoInfo.iv);
frameworkCryptoInfo.key = checkNotNull(copy(cryptoInfo.key, frameworkCryptoInfo.key));
frameworkCryptoInfo.iv = checkNotNull(copy(cryptoInfo.iv, frameworkCryptoInfo.iv));
frameworkCryptoInfo.mode = cryptoInfo.mode;
if (Util.SDK_INT >= 24) {
android.media.MediaCodec.CryptoInfo.Pattern pattern =
@ -321,7 +322,8 @@ class AsynchronousMediaCodecBufferEnqueuer implements MediaCodecInputBufferEnque
* @param dst The destination array, which will be reused if it's at least as long as {@code src}.
* @return The copy, which may be {@code dst} if it was reused.
*/
private static int[] copy(int[] src, int[] dst) {
@Nullable
private static int[] copy(@Nullable int[] src, @Nullable int[] dst) {
if (src == null) {
return dst;
}
@ -341,7 +343,8 @@ class AsynchronousMediaCodecBufferEnqueuer implements MediaCodecInputBufferEnque
* @param dst The destination array, which will be reused if it's at least as long as {@code src}.
* @return The copy, which may be {@code dst} if it was reused.
*/
private static byte[] copy(byte[] src, byte[] dst) {
@Nullable
private static byte[] copy(@Nullable byte[] src, @Nullable byte[] dst) {
if (src == null) {
return dst;
}