Mark all methods accessing SQLite databases as potentially blocking.
They are all marked with a JavaDoc comment and the @WorkerThread annotation which is useful if apps are using threading annotations. All other public methods in the same classes are marked with @AnyThread to avoid the impression we forgot to annotate them. PiperOrigin-RevId: 281490301
This commit is contained in:
parent
fc0aa08d79
commit
febfeca2c6
@ -18,6 +18,7 @@ package com.google.android.exoplayer2.offline;
|
||||
import static com.google.android.exoplayer2.offline.Download.STATE_QUEUED;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.WorkerThread;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@ -47,6 +48,8 @@ public final class ActionFileUpgradeUtil {
|
||||
* <p>This method must not be called while the {@link DefaultDownloadIndex} is being used by a
|
||||
* {@link DownloadManager}.
|
||||
*
|
||||
* <p>This method may be slow and shouldn't normally be called on the main thread.
|
||||
*
|
||||
* @param actionFilePath The action file path.
|
||||
* @param downloadIdProvider A download ID provider, or {@code null}. If {@code null} then ID of
|
||||
* each download will be its custom cache key if one is specified, or else its URL.
|
||||
@ -55,6 +58,7 @@ public final class ActionFileUpgradeUtil {
|
||||
* @param addNewDownloadsAsCompleted Whether to add new downloads as completed.
|
||||
* @throws IOException If an error occurs loading or merging the requests.
|
||||
*/
|
||||
@WorkerThread
|
||||
@SuppressWarnings("deprecation")
|
||||
public static void upgradeAndDelete(
|
||||
File actionFilePath,
|
||||
|
@ -16,14 +16,18 @@
|
||||
package com.google.android.exoplayer2.offline;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.WorkerThread;
|
||||
import java.io.IOException;
|
||||
|
||||
/** An index of {@link Download Downloads}. */
|
||||
@WorkerThread
|
||||
public interface DownloadIndex {
|
||||
|
||||
/**
|
||||
* Returns the {@link Download} with the given {@code id}, or null.
|
||||
*
|
||||
* <p>This method may be slow and shouldn't normally be called on the main thread.
|
||||
*
|
||||
* @param id ID of a {@link Download}.
|
||||
* @return The {@link Download} with the given {@code id}, or null if a download state with this
|
||||
* id doesn't exist.
|
||||
@ -35,6 +39,8 @@ public interface DownloadIndex {
|
||||
/**
|
||||
* Returns a {@link DownloadCursor} to {@link Download}s with the given {@code states}.
|
||||
*
|
||||
* <p>This method may be slow and shouldn't normally be called on the main thread.
|
||||
*
|
||||
* @param states Returns only the {@link Download}s with this states. If empty, returns all.
|
||||
* @return A cursor to {@link Download}s with the given {@code states}.
|
||||
* @throws IOException If an error occurs reading the state.
|
||||
|
@ -15,14 +15,18 @@
|
||||
*/
|
||||
package com.google.android.exoplayer2.offline;
|
||||
|
||||
import androidx.annotation.WorkerThread;
|
||||
import java.io.IOException;
|
||||
|
||||
/** A writable index of {@link Download Downloads}. */
|
||||
@WorkerThread
|
||||
public interface WritableDownloadIndex extends DownloadIndex {
|
||||
|
||||
/**
|
||||
* Adds or replaces a {@link Download}.
|
||||
*
|
||||
* <p>This method may be slow and shouldn't normally be called on the main thread.
|
||||
*
|
||||
* @param download The {@link Download} to be added.
|
||||
* @throws IOException If an error occurs setting the state.
|
||||
*/
|
||||
@ -32,6 +36,8 @@ public interface WritableDownloadIndex extends DownloadIndex {
|
||||
* Removes the download with the given ID. Does nothing if a download with the given ID does not
|
||||
* exist.
|
||||
*
|
||||
* <p>This method may be slow and shouldn't normally be called on the main thread.
|
||||
*
|
||||
* @param id The ID of the download to remove.
|
||||
* @throws IOException If an error occurs removing the state.
|
||||
*/
|
||||
@ -40,6 +46,8 @@ public interface WritableDownloadIndex extends DownloadIndex {
|
||||
/**
|
||||
* Sets all {@link Download#STATE_DOWNLOADING} states to {@link Download#STATE_QUEUED}.
|
||||
*
|
||||
* <p>This method may be slow and shouldn't normally be called on the main thread.
|
||||
*
|
||||
* @throws IOException If an error occurs updating the state.
|
||||
*/
|
||||
void setDownloadingStatesToQueued() throws IOException;
|
||||
@ -47,6 +55,8 @@ public interface WritableDownloadIndex extends DownloadIndex {
|
||||
/**
|
||||
* Sets all states to {@link Download#STATE_REMOVING}.
|
||||
*
|
||||
* <p>This method may be slow and shouldn't normally be called on the main thread.
|
||||
*
|
||||
* @throws IOException If an error occurs updating the state.
|
||||
*/
|
||||
void setStatesToRemoving() throws IOException;
|
||||
@ -55,6 +65,8 @@ public interface WritableDownloadIndex extends DownloadIndex {
|
||||
* Sets the stop reason of the downloads in a terminal state ({@link Download#STATE_COMPLETED},
|
||||
* {@link Download#STATE_FAILED}).
|
||||
*
|
||||
* <p>This method may be slow and shouldn't normally be called on the main thread.
|
||||
*
|
||||
* @param stopReason The stop reason.
|
||||
* @throws IOException If an error occurs updating the state.
|
||||
*/
|
||||
@ -65,6 +77,8 @@ public interface WritableDownloadIndex extends DownloadIndex {
|
||||
* Download#STATE_COMPLETED}, {@link Download#STATE_FAILED}). Does nothing if a download with the
|
||||
* given ID does not exist, or if it's not in a terminal state.
|
||||
*
|
||||
* <p>This method may be slow and shouldn't normally be called on the main thread.
|
||||
*
|
||||
* @param id The ID of the download to update.
|
||||
* @param stopReason The stop reason.
|
||||
* @throws IOException If an error occurs updating the state.
|
||||
|
@ -16,6 +16,7 @@
|
||||
package com.google.android.exoplayer2.upstream.cache;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.WorkerThread;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@ -100,7 +101,10 @@ public interface Cache {
|
||||
/**
|
||||
* Releases the cache. This method must be called when the cache is no longer required. The cache
|
||||
* must not be used after calling this method.
|
||||
*
|
||||
* <p>This method may be slow and shouldn't normally be called on the main thread.
|
||||
*/
|
||||
@WorkerThread
|
||||
void release();
|
||||
|
||||
/**
|
||||
@ -162,23 +166,29 @@ public interface Cache {
|
||||
* calling {@link #commitFile(File, long)}. When the caller has finished writing, it must release
|
||||
* the lock by calling {@link #releaseHoleSpan}.
|
||||
*
|
||||
* <p>This method may be slow and shouldn't normally be called on the main thread.
|
||||
*
|
||||
* @param key The key of the data being requested.
|
||||
* @param position The position of the data being requested.
|
||||
* @return The {@link CacheSpan}.
|
||||
* @throws InterruptedException If the thread was interrupted.
|
||||
* @throws CacheException If an error is encountered.
|
||||
*/
|
||||
@WorkerThread
|
||||
CacheSpan startReadWrite(String key, long position) throws InterruptedException, CacheException;
|
||||
|
||||
/**
|
||||
* Same as {@link #startReadWrite(String, long)}. However, if the cache entry is locked, then
|
||||
* instead of blocking, this method will return null as the {@link CacheSpan}.
|
||||
*
|
||||
* <p>This method may be slow and shouldn't normally be called on the main thread.
|
||||
*
|
||||
* @param key The key of the data being requested.
|
||||
* @param position The position of the data being requested.
|
||||
* @return The {@link CacheSpan}. Or null if the cache entry is locked.
|
||||
* @throws CacheException If an error is encountered.
|
||||
*/
|
||||
@WorkerThread
|
||||
@Nullable
|
||||
CacheSpan startReadWriteNonBlocking(String key, long position) throws CacheException;
|
||||
|
||||
@ -186,6 +196,8 @@ public interface Cache {
|
||||
* Obtains a cache file into which data can be written. Must only be called when holding a
|
||||
* corresponding hole {@link CacheSpan} obtained from {@link #startReadWrite(String, long)}.
|
||||
*
|
||||
* <p>This method may be slow and shouldn't normally be called on the main thread.
|
||||
*
|
||||
* @param key The cache key for the data.
|
||||
* @param position The starting position of the data.
|
||||
* @param length The length of the data being written, or {@link C#LENGTH_UNSET} if unknown. Used
|
||||
@ -193,16 +205,20 @@ public interface Cache {
|
||||
* @return The file into which data should be written.
|
||||
* @throws CacheException If an error is encountered.
|
||||
*/
|
||||
@WorkerThread
|
||||
File startFile(String key, long position, long length) throws CacheException;
|
||||
|
||||
/**
|
||||
* Commits a file into the cache. Must only be called when holding a corresponding hole {@link
|
||||
* CacheSpan} obtained from {@link #startReadWrite(String, long)}
|
||||
* CacheSpan} obtained from {@link #startReadWrite(String, long)}.
|
||||
*
|
||||
* <p>This method may be slow and shouldn't normally be called on the main thread.
|
||||
*
|
||||
* @param file A newly written cache file.
|
||||
* @param length The length of the newly written cache file in bytes.
|
||||
* @throws CacheException If an error is encountered.
|
||||
*/
|
||||
@WorkerThread
|
||||
void commitFile(File file, long length) throws CacheException;
|
||||
|
||||
/**
|
||||
@ -216,9 +232,12 @@ public interface Cache {
|
||||
/**
|
||||
* Removes a cached {@link CacheSpan} from the cache, deleting the underlying file.
|
||||
*
|
||||
* <p>This method may be slow and shouldn't normally be called on the main thread.
|
||||
*
|
||||
* @param span The {@link CacheSpan} to remove.
|
||||
* @throws CacheException If an error is encountered.
|
||||
*/
|
||||
@WorkerThread
|
||||
void removeSpan(CacheSpan span) throws CacheException;
|
||||
|
||||
/**
|
||||
@ -247,10 +266,13 @@ public interface Cache {
|
||||
* Applies {@code mutations} to the {@link ContentMetadata} for the given key. A new {@link
|
||||
* CachedContent} is added if there isn't one already with the given key.
|
||||
*
|
||||
* <p>This method may be slow and shouldn't normally be called on the main thread.
|
||||
*
|
||||
* @param key The cache key for the data.
|
||||
* @param mutations Contains mutations to be applied to the metadata.
|
||||
* @throws CacheException If an error is encountered.
|
||||
*/
|
||||
@WorkerThread
|
||||
void applyContentMetadataMutations(String key, ContentMetadataMutations mutations)
|
||||
throws CacheException;
|
||||
|
||||
|
@ -19,6 +19,7 @@ import android.content.ContentValues;
|
||||
import android.database.Cursor;
|
||||
import android.database.SQLException;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import androidx.annotation.WorkerThread;
|
||||
import com.google.android.exoplayer2.database.DatabaseIOException;
|
||||
import com.google.android.exoplayer2.database.DatabaseProvider;
|
||||
import com.google.android.exoplayer2.database.VersionTable;
|
||||
@ -64,10 +65,13 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
/**
|
||||
* Deletes index data for the specified cache.
|
||||
*
|
||||
* <p>This method may be slow and shouldn't normally be called on the main thread.
|
||||
*
|
||||
* @param databaseProvider Provides the database in which the index is stored.
|
||||
* @param uid The cache UID.
|
||||
* @throws DatabaseIOException If an error occurs deleting the index data.
|
||||
*/
|
||||
@WorkerThread
|
||||
public static void delete(DatabaseProvider databaseProvider, long uid)
|
||||
throws DatabaseIOException {
|
||||
String hexUid = Long.toHexString(uid);
|
||||
@ -96,9 +100,12 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
/**
|
||||
* Initializes the index for the given cache UID.
|
||||
*
|
||||
* <p>This method may be slow and shouldn't normally be called on the main thread.
|
||||
*
|
||||
* @param uid The cache UID.
|
||||
* @throws DatabaseIOException If an error occurs initializing the index.
|
||||
*/
|
||||
@WorkerThread
|
||||
public void initialize(long uid) throws DatabaseIOException {
|
||||
try {
|
||||
String hexUid = Long.toHexString(uid);
|
||||
@ -129,9 +136,12 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
* Returns all file metadata keyed by file name. The returned map is mutable and may be modified
|
||||
* by the caller.
|
||||
*
|
||||
* <p>This method may be slow and shouldn't normally be called on the main thread.
|
||||
*
|
||||
* @return The file metadata keyed by file name.
|
||||
* @throws DatabaseIOException If an error occurs loading the metadata.
|
||||
*/
|
||||
@WorkerThread
|
||||
public Map<String, CacheFileMetadata> getAll() throws DatabaseIOException {
|
||||
try (Cursor cursor = getCursor()) {
|
||||
Map<String, CacheFileMetadata> fileMetadata = new HashMap<>(cursor.getCount());
|
||||
@ -150,11 +160,14 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
/**
|
||||
* Sets metadata for a given file.
|
||||
*
|
||||
* <p>This method may be slow and shouldn't normally be called on the main thread.
|
||||
*
|
||||
* @param name The name of the file.
|
||||
* @param length The file length.
|
||||
* @param lastTouchTimestamp The file last touch timestamp.
|
||||
* @throws DatabaseIOException If an error occurs setting the metadata.
|
||||
*/
|
||||
@WorkerThread
|
||||
public void set(String name, long length, long lastTouchTimestamp) throws DatabaseIOException {
|
||||
Assertions.checkNotNull(tableName);
|
||||
try {
|
||||
@ -172,9 +185,12 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
/**
|
||||
* Removes metadata.
|
||||
*
|
||||
* <p>This method may be slow and shouldn't normally be called on the main thread.
|
||||
*
|
||||
* @param name The name of the file whose metadata is to be removed.
|
||||
* @throws DatabaseIOException If an error occurs removing the metadata.
|
||||
*/
|
||||
@WorkerThread
|
||||
public void remove(String name) throws DatabaseIOException {
|
||||
Assertions.checkNotNull(tableName);
|
||||
try {
|
||||
@ -188,9 +204,12 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
/**
|
||||
* Removes metadata.
|
||||
*
|
||||
* <p>This method may be slow and shouldn't normally be called on the main thread.
|
||||
*
|
||||
* @param names The names of the files whose metadata is to be removed.
|
||||
* @throws DatabaseIOException If an error occurs removing the metadata.
|
||||
*/
|
||||
@WorkerThread
|
||||
public void removeAll(Set<String> names) throws DatabaseIOException {
|
||||
Assertions.checkNotNull(tableName);
|
||||
try {
|
||||
|
@ -18,6 +18,7 @@ package com.google.android.exoplayer2.upstream.cache;
|
||||
import android.net.Uri;
|
||||
import android.util.Pair;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.WorkerThread;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.DataSourceException;
|
||||
@ -104,6 +105,8 @@ public final class CacheUtil {
|
||||
* Caches the data defined by {@code dataSpec}, skipping already cached data. Caching stops early
|
||||
* if the end of the input is reached.
|
||||
*
|
||||
* <p>This method may be slow and shouldn't normally be called on the main thread.
|
||||
*
|
||||
* @param dataSpec Defines the data to be cached.
|
||||
* @param cache A {@link Cache} to store the data.
|
||||
* @param cacheKeyFactory An optional factory for cache keys.
|
||||
@ -113,6 +116,7 @@ public final class CacheUtil {
|
||||
* @throws IOException If an error occurs reading from the source.
|
||||
* @throws InterruptedException If the thread was interrupted directly or via {@code isCanceled}.
|
||||
*/
|
||||
@WorkerThread
|
||||
public static void cache(
|
||||
DataSpec dataSpec,
|
||||
Cache cache,
|
||||
@ -144,6 +148,8 @@ public final class CacheUtil {
|
||||
* PriorityTaskManager#add} to register with the manager before calling this method, and to call
|
||||
* {@link PriorityTaskManager#remove} afterwards to unregister.
|
||||
*
|
||||
* <p>This method may be slow and shouldn't normally be called on the main thread.
|
||||
*
|
||||
* @param dataSpec Defines the data to be cached.
|
||||
* @param cache A {@link Cache} to store the data.
|
||||
* @param cacheKeyFactory An optional factory for cache keys.
|
||||
@ -159,6 +165,7 @@ public final class CacheUtil {
|
||||
* @throws IOException If an error occurs reading from the source.
|
||||
* @throws InterruptedException If the thread was interrupted directly or via {@code isCanceled}.
|
||||
*/
|
||||
@WorkerThread
|
||||
public static void cache(
|
||||
DataSpec dataSpec,
|
||||
Cache cache,
|
||||
@ -333,10 +340,13 @@ public final class CacheUtil {
|
||||
/**
|
||||
* Removes all of the data specified by the {@code dataSpec}.
|
||||
*
|
||||
* <p>This methods blocks until the operation is complete.
|
||||
*
|
||||
* @param dataSpec Defines the data to be removed.
|
||||
* @param cache A {@link Cache} to store the data.
|
||||
* @param cacheKeyFactory An optional factory for cache keys.
|
||||
*/
|
||||
@WorkerThread
|
||||
public static void remove(
|
||||
DataSpec dataSpec, Cache cache, @Nullable CacheKeyFactory cacheKeyFactory) {
|
||||
remove(cache, buildCacheKey(dataSpec, cacheKeyFactory));
|
||||
@ -345,9 +355,12 @@ public final class CacheUtil {
|
||||
/**
|
||||
* Removes all of the data specified by the {@code key}.
|
||||
*
|
||||
* <p>This methods blocks until the operation is complete.
|
||||
*
|
||||
* @param cache A {@link Cache} to store the data.
|
||||
* @param key The key whose data should be removed.
|
||||
*/
|
||||
@WorkerThread
|
||||
public static void remove(Cache cache, String key) {
|
||||
NavigableSet<CacheSpan> cachedSpans = cache.getCachedSpans(key);
|
||||
for (CacheSpan cachedSpan : cachedSpans) {
|
||||
|
@ -25,6 +25,7 @@ import android.util.SparseArray;
|
||||
import android.util.SparseBooleanArray;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.annotation.WorkerThread;
|
||||
import com.google.android.exoplayer2.database.DatabaseIOException;
|
||||
import com.google.android.exoplayer2.database.DatabaseProvider;
|
||||
import com.google.android.exoplayer2.database.VersionTable;
|
||||
@ -104,10 +105,13 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
||||
/**
|
||||
* Deletes index data for the specified cache.
|
||||
*
|
||||
* <p>This method may be slow and shouldn't normally be called on the main thread.
|
||||
*
|
||||
* @param databaseProvider Provides the database in which the index is stored.
|
||||
* @param uid The cache UID.
|
||||
* @throws DatabaseIOException If an error occurs deleting the index data.
|
||||
*/
|
||||
@WorkerThread
|
||||
public static void delete(DatabaseProvider databaseProvider, long uid)
|
||||
throws DatabaseIOException {
|
||||
DatabaseStorage.delete(databaseProvider, uid);
|
||||
@ -174,9 +178,12 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
||||
/**
|
||||
* Loads the index data for the given cache UID.
|
||||
*
|
||||
* <p>This method may be slow and shouldn't normally be called on the main thread.
|
||||
*
|
||||
* @param uid The UID of the cache whose index is to be loaded.
|
||||
* @throws IOException If an error occurs initializing the index data.
|
||||
*/
|
||||
@WorkerThread
|
||||
public void initialize(long uid) throws IOException {
|
||||
storage.initialize(uid);
|
||||
if (previousStorage != null) {
|
||||
@ -199,8 +206,11 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
||||
/**
|
||||
* Stores the index data to index file if there is a change.
|
||||
*
|
||||
* <p>This method may be slow and shouldn't normally be called on the main thread.
|
||||
*
|
||||
* @throws IOException If an error occurs storing the index data.
|
||||
*/
|
||||
@WorkerThread
|
||||
public void store() throws IOException {
|
||||
storage.storeIncremental(keyToContent);
|
||||
// Make ids that were removed since the index was last stored eligible for re-use.
|
||||
|
@ -18,6 +18,7 @@ package com.google.android.exoplayer2.upstream.cache;
|
||||
import android.os.ConditionVariable;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.WorkerThread;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.database.DatabaseIOException;
|
||||
import com.google.android.exoplayer2.database.DatabaseProvider;
|
||||
@ -85,10 +86,13 @@ public final class SimpleCache implements Cache {
|
||||
/**
|
||||
* Deletes all content belonging to a cache instance.
|
||||
*
|
||||
* <p>This method may be slow and shouldn't normally be called on the main thread.
|
||||
*
|
||||
* @param cacheDir The cache directory.
|
||||
* @param databaseProvider The database in which index data is stored, or {@code null} if the
|
||||
* cache used a legacy index.
|
||||
*/
|
||||
@WorkerThread
|
||||
public static void delete(File cacheDir, @Nullable DatabaseProvider databaseProvider) {
|
||||
if (!cacheDir.exists()) {
|
||||
return;
|
||||
@ -147,6 +151,7 @@ public final class SimpleCache implements Cache {
|
||||
* @deprecated Use a constructor that takes a {@link DatabaseProvider} for improved performance.
|
||||
*/
|
||||
@Deprecated
|
||||
@SuppressWarnings("deprecation")
|
||||
public SimpleCache(File cacheDir, CacheEvictor evictor, @Nullable byte[] secretKey) {
|
||||
this(cacheDir, evictor, secretKey, secretKey != null);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user