diff --git a/library/core/src/main/java/com/google/android/exoplayer2/offline/ActionFileUpgradeUtil.java b/library/core/src/main/java/com/google/android/exoplayer2/offline/ActionFileUpgradeUtil.java index 9ecce6e150..999059e852 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/offline/ActionFileUpgradeUtil.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/offline/ActionFileUpgradeUtil.java @@ -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 { *

This method must not be called while the {@link DefaultDownloadIndex} is being used by a * {@link DownloadManager}. * + *

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, diff --git a/library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadIndex.java b/library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadIndex.java index 3de1b7b212..e0ccd23c71 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadIndex.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadIndex.java @@ -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. * + *

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}. * + *

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. diff --git a/library/core/src/main/java/com/google/android/exoplayer2/offline/WritableDownloadIndex.java b/library/core/src/main/java/com/google/android/exoplayer2/offline/WritableDownloadIndex.java index dc7085c85e..d49b4c39ca 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/offline/WritableDownloadIndex.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/offline/WritableDownloadIndex.java @@ -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}. * + *

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. * + *

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}. * + *

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}. * + *

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}). * + *

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. * + *

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. diff --git a/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/Cache.java b/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/Cache.java index 12905f908c..1d504159e6 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/Cache.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/Cache.java @@ -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. + * + *

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}. * + *

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}. * + *

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)}. * + *

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)}. + * + *

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,19 +232,22 @@ public interface Cache { /** * Removes a cached {@link CacheSpan} from the cache, deleting the underlying file. * + *

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; - /** - * Queries if a range is entirely available in the cache. - * - * @param key The cache key for the data. - * @param position The starting position of the data. - * @param length The length of the data. - * @return true if the data is available in the Cache otherwise false; - */ + /** + * Queries if a range is entirely available in the cache. + * + * @param key The cache key for the data. + * @param position The starting position of the data. + * @param length The length of the data. + * @return true if the data is available in the Cache otherwise false; + */ boolean isCached(String key, long position, long length); /** @@ -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. * + *

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; diff --git a/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/CacheFileMetadataIndex.java b/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/CacheFileMetadataIndex.java index 2488ae0ff3..978dbbc8f7 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/CacheFileMetadataIndex.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/CacheFileMetadataIndex.java @@ -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. * + *

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. * + *

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. * + *

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 getAll() throws DatabaseIOException { try (Cursor cursor = getCursor()) { Map fileMetadata = new HashMap<>(cursor.getCount()); @@ -150,11 +160,14 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; /** * Sets metadata for a given file. * + *

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. * + *

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. * + *

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 names) throws DatabaseIOException { Assertions.checkNotNull(tableName); try { diff --git a/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/CacheUtil.java b/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/CacheUtil.java index bbec189b4d..93b00718ab 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/CacheUtil.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/CacheUtil.java @@ -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. * + *

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. * + *

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}. * + *

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}. * + *

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 cachedSpans = cache.getCachedSpans(key); for (CacheSpan cachedSpan : cachedSpans) { diff --git a/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/CachedContentIndex.java b/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/CachedContentIndex.java index 22086f8ac8..5ed3e921ee 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/CachedContentIndex.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/CachedContentIndex.java @@ -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. * + *

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. * + *

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. * + *

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. diff --git a/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/SimpleCache.java b/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/SimpleCache.java index cf8056f5a9..a4fade25e0 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/SimpleCache.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/SimpleCache.java @@ -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. * + *

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); }