Enable nullness test for CachedContent/CachedContentIndex

PiperOrigin-RevId: 328551668
This commit is contained in:
bachinger 2020-08-26 17:57:29 +01:00 committed by Oliver Woodman
parent 94cff6ba50
commit feb4cce2b2
2 changed files with 44 additions and 27 deletions

View File

@ -16,6 +16,7 @@
package com.google.android.exoplayer2.upstream.cache;
import static com.google.android.exoplayer2.util.Assertions.checkArgument;
import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
import static com.google.android.exoplayer2.util.Assertions.checkState;
import static java.lang.Math.max;
import static java.lang.Math.min;
@ -219,9 +220,9 @@ import java.util.TreeSet;
public SimpleCacheSpan setLastTouchTimestamp(
SimpleCacheSpan cacheSpan, long lastTouchTimestamp, boolean updateFile) {
checkState(cachedSpans.remove(cacheSpan));
File file = cacheSpan.file;
File file = checkNotNull(cacheSpan.file);
if (updateFile) {
File directory = file.getParentFile();
File directory = checkNotNull(file.getParentFile());
long position = cacheSpan.position;
File newFile = SimpleCacheSpan.getCacheFile(directory, id, position, lastTouchTimestamp);
if (file.renameTo(newFile)) {
@ -244,7 +245,9 @@ import java.util.TreeSet;
/** Removes the given span from cache. */
public boolean removeSpan(CacheSpan span) {
if (cachedSpans.remove(span)) {
span.file.delete();
if (span.file != null) {
span.file.delete();
}
return true;
}
return false;

View File

@ -15,6 +15,9 @@
*/
package com.google.android.exoplayer2.upstream.cache;
import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
import static com.google.android.exoplayer2.util.Assertions.checkState;
import static com.google.android.exoplayer2.util.Util.castNonNull;
import static java.lang.Math.min;
import android.annotation.SuppressLint;
@ -61,6 +64,7 @@ import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.checkerframework.checker.nullness.compatqual.NullableType;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
/** Maintains the index of cached content. */
/* package */ class CachedContentIndex {
@ -155,13 +159,15 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
@Nullable byte[] legacyStorageSecretKey,
boolean legacyStorageEncrypt,
boolean preferLegacyStorage) {
Assertions.checkState(databaseProvider != null || legacyStorageDir != null);
checkState(databaseProvider != null || legacyStorageDir != null);
keyToContent = new HashMap<>();
idToKey = new SparseArray<>();
removedIds = new SparseBooleanArray();
newIds = new SparseBooleanArray();
@Nullable
Storage databaseStorage =
databaseProvider != null ? new DatabaseStorage(databaseProvider) : null;
@Nullable
Storage legacyStorage =
legacyStorageDir != null
? new LegacyStorage(
@ -170,7 +176,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
legacyStorageEncrypt)
: null;
if (databaseStorage == null || (legacyStorage != null && preferLegacyStorage)) {
storage = legacyStorage;
storage = castNonNull(legacyStorage);
previousStorage = databaseStorage;
} else {
storage = databaseStorage;
@ -325,7 +331,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
/** Returns a {@link ContentMetadata} for the given key. */
public ContentMetadata getContentMetadata(String key) {
CachedContent cachedContent = get(key);
@Nullable CachedContent cachedContent = get(key);
return cachedContent != null ? cachedContent.getMetadata() : DefaultContentMetadata.EMPTY;
}
@ -358,7 +364,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
* returns the smallest unused non-negative integer.
*/
@VisibleForTesting
/* package */ static int getNewId(SparseArray<String> idToKey) {
/* package */ static int getNewId(SparseArray<@NullableType String> idToKey) {
int size = idToKey.size();
int id = size == 0 ? 0 : (idToKey.keyAt(size - 1) + 1);
if (id < 0) { // In case if we pass max int value.
@ -512,8 +518,9 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
@Nullable private ReusableBufferedOutputStream bufferedOutputStream;
public LegacyStorage(File file, @Nullable byte[] secretKey, boolean encrypt) {
Cipher cipher = null;
SecretKeySpec secretKeySpec = null;
checkState(secretKey != null || !encrypt);
@Nullable Cipher cipher = null;
@Nullable SecretKeySpec secretKeySpec = null;
if (secretKey != null) {
Assertions.checkArgument(secretKey.length == 16);
try {
@ -550,7 +557,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
@Override
public void load(
HashMap<String, CachedContent> content, SparseArray<@NullableType String> idToKey) {
Assertions.checkState(!changed);
checkState(!changed);
if (!readFile(content, idToKey)) {
content.clear();
idToKey.clear();
@ -588,7 +595,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
return true;
}
DataInputStream input = null;
@Nullable DataInputStream input = null;
try {
InputStream inputStream = new BufferedInputStream(atomicFile.openRead());
input = new DataInputStream(inputStream);
@ -606,7 +613,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
input.readFully(initializationVector);
IvParameterSpec ivParameterSpec = new IvParameterSpec(initializationVector);
try {
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
cipher.init(Cipher.DECRYPT_MODE, castNonNull(secretKeySpec), ivParameterSpec);
} catch (InvalidKeyException | InvalidAlgorithmParameterException e) {
throw new IllegalStateException(e);
}
@ -647,6 +654,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
} else {
bufferedOutputStream.reset(outputStream);
}
ReusableBufferedOutputStream bufferedOutputStream = this.bufferedOutputStream;
output = new DataOutputStream(bufferedOutputStream);
output.writeInt(VERSION);
@ -655,11 +663,12 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
if (encrypt) {
byte[] initializationVector = new byte[16];
random.nextBytes(initializationVector);
castNonNull(random).nextBytes(initializationVector);
output.write(initializationVector);
IvParameterSpec ivParameterSpec = new IvParameterSpec(initializationVector);
try {
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
castNonNull(cipher)
.init(Cipher.ENCRYPT_MODE, castNonNull(secretKeySpec), ivParameterSpec);
} catch (InvalidKeyException | InvalidAlgorithmParameterException e) {
throw new IllegalStateException(e); // Should never happen.
}
@ -762,16 +771,17 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
+ " BLOB NOT NULL)";
private final DatabaseProvider databaseProvider;
private final SparseArray<CachedContent> pendingUpdates;
private final SparseArray<@NullableType CachedContent> pendingUpdates;
private String hexUid;
private String tableName;
private @MonotonicNonNull String hexUid;
private @MonotonicNonNull String tableName;
public static void delete(DatabaseProvider databaseProvider, long uid)
throws DatabaseIOException {
delete(databaseProvider, Long.toHexString(uid));
}
@SuppressWarnings("nullness:initialization.fields.uninitialized")
public DatabaseStorage(DatabaseProvider databaseProvider) {
this.databaseProvider = databaseProvider;
pendingUpdates = new SparseArray<>();
@ -788,26 +798,26 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
return VersionTable.getVersion(
databaseProvider.getReadableDatabase(),
VersionTable.FEATURE_CACHE_CONTENT_METADATA,
hexUid)
checkNotNull(hexUid))
!= VersionTable.VERSION_UNSET;
}
@Override
public void delete() throws DatabaseIOException {
delete(databaseProvider, hexUid);
delete(databaseProvider, checkNotNull(hexUid));
}
@Override
public void load(
HashMap<String, CachedContent> content, SparseArray<@NullableType String> idToKey)
throws IOException {
Assertions.checkState(pendingUpdates.size() == 0);
checkState(pendingUpdates.size() == 0);
try {
int version =
VersionTable.getVersion(
databaseProvider.getReadableDatabase(),
VersionTable.FEATURE_CACHE_CONTENT_METADATA,
hexUid);
checkNotNull(hexUid));
if (version != TABLE_VERSION) {
SQLiteDatabase writableDatabase = databaseProvider.getWritableDatabase();
writableDatabase.beginTransactionNonExclusive();
@ -871,7 +881,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
writableDatabase.beginTransactionNonExclusive();
try {
for (int i = 0; i < pendingUpdates.size(); i++) {
CachedContent cachedContent = pendingUpdates.valueAt(i);
@Nullable CachedContent cachedContent = pendingUpdates.valueAt(i);
if (cachedContent == null) {
deleteRow(writableDatabase, pendingUpdates.keyAt(i));
} else {
@ -906,7 +916,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
return databaseProvider
.getReadableDatabase()
.query(
tableName,
checkNotNull(tableName),
COLUMNS,
/* selection= */ null,
/* selectionArgs= */ null,
@ -917,13 +927,17 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
private void initializeTable(SQLiteDatabase writableDatabase) throws DatabaseIOException {
VersionTable.setVersion(
writableDatabase, VersionTable.FEATURE_CACHE_CONTENT_METADATA, hexUid, TABLE_VERSION);
dropTable(writableDatabase, tableName);
writableDatabase,
VersionTable.FEATURE_CACHE_CONTENT_METADATA,
checkNotNull(hexUid),
TABLE_VERSION);
dropTable(writableDatabase, checkNotNull(tableName));
writableDatabase.execSQL("CREATE TABLE " + tableName + " " + TABLE_SCHEMA);
}
private void deleteRow(SQLiteDatabase writableDatabase, int key) {
writableDatabase.delete(tableName, WHERE_ID_EQUALS, new String[] {Integer.toString(key)});
writableDatabase.delete(
checkNotNull(tableName), WHERE_ID_EQUALS, new String[] {Integer.toString(key)});
}
private void addOrUpdateRow(SQLiteDatabase writableDatabase, CachedContent cachedContent)
@ -936,7 +950,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
values.put(COLUMN_ID, cachedContent.id);
values.put(COLUMN_KEY, cachedContent.key);
values.put(COLUMN_METADATA, data);
writableDatabase.replaceOrThrow(tableName, /* nullColumnHack= */ null, values);
writableDatabase.replaceOrThrow(checkNotNull(tableName), /* nullColumnHack= */ null, values);
}
private static void delete(DatabaseProvider databaseProvider, String hexUid)