mirror of
https://github.com/androidx/media.git
synced 2025-05-12 10:09:55 +08:00
Enable nullness test for CachedContent/CachedContentIndex
PiperOrigin-RevId: 328551668
This commit is contained in:
parent
94cff6ba50
commit
feb4cce2b2
@ -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;
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user